diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index b47b780c5e32b9..d4aa3a2fcc342c 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:50 + image: ghcr.io/project-chip/chip-build:53 steps: - name: Checkout diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 03e3c76c625b7d..190a71f2c167dd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -138,7 +138,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -281,7 +281,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -333,7 +333,7 @@ jobs: scripts/run_in_build_env.sh 'virtualenv pyenv' source pyenv/bin/activate pip3 install -r src/setup_payload/python/requirements.txt - python3 src/setup_payload/tests/run_python_setup_payload_gen_test.py out/chip-tool + python3 src/setup_payload/tests/run_python_setup_payload_test.py out/chip-tool build_linux_python_lighting_device: name: Build on Linux (python lighting-app) @@ -342,7 +342,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -451,7 +451,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index 4cbc381d931f69..7531d97c00a10c 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 options: --user root steps: @@ -56,7 +56,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:50 + image: ghcr.io/project-chip/chip-build-esp32:53 options: --user root steps: @@ -77,7 +77,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nrf-platform:50 + image: ghcr.io/project-chip/chip-build-nrf-platform:53 options: --user root steps: @@ -98,7 +98,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:50 + image: ghcr.io/project-chip/chip-build-telink:53 options: --user root steps: diff --git a/.github/workflows/cirque.yaml b/.github/workflows/cirque.yaml index 837e948da51ca3..1f30377b83dcf2 100644 --- a/.github/workflows/cirque.yaml +++ b/.github/workflows/cirque.yaml @@ -42,7 +42,7 @@ jobs: # need to run with privilege, which isn't supported by job.XXX.contaner # https://github.com/actions/container-action/issues/2 # container: - # image: ghcr.io/project-chip/chip-build-cirque:50 + # image: ghcr.io/project-chip/chip-build-cirque:53 # volumes: # - "/tmp:/tmp" # - "/dev/pts:/dev/pts" diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index ad2a513209cc65..ba9c0f1d9f02c3 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -97,10 +97,10 @@ jobs: bootstrap-logs-framework-${{ matrix.options.flavor }} - name: Build example All Clusters Server run: | - scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug chip_config_network_layer_ble=false + scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug/all-clusters-app chip_config_network_layer_ble=false - name: Build example OTA Provider run: | - scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/debug chip_config_network_layer_ble=false + scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/debug/ota-provider-app chip_config_network_layer_ble=false - name: Build example OTA Requestor run: | scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux out/debug/ota-requestor-app chip_config_network_layer_ble=false non_spec_compliant_ota_action_delay_floor=0 @@ -113,13 +113,8 @@ jobs: run: | mkdir -p /tmp/darwin/framework-tests echo "This is a simple log" > /tmp/darwin/framework-tests/end_user_support_log.txt - ../../../out/debug/chip-all-clusters-app --interface-id -1 --end_user_support_log /tmp/darwin/framework-tests/end_user_support_log.txt > >(tee /tmp/darwin/framework-tests/all-cluster-app.log) 2> >(tee /tmp/darwin/framework-tests/all-cluster-app-err.log >&2) & - ../../../out/debug/chip-all-clusters-app --interface-id -1 --dac_provider ../../../credentials/development/commissioner_dut/struct_cd_origin_pid_vid_correct/test_case_vector.json --product-id 32768 --discriminator 3839 --secured-device-port 5539 --KVS /tmp/chip-all-clusters-app-kvs2 > >(tee /tmp/darwin/framework-tests/all-cluster-app-origin-vid.log) 2> >(tee /tmp/darwin/framework-tests/all-cluster-app-origin-vid-err.log >&2) & - ../../../out/debug/chip-all-clusters-app --interface-id -1 --discriminator 101 --passcode 1001 --KVS /tmp/chip-all-clusters-app-kvs101 --secured-device-port 5531 & - ../../../out/debug/chip-all-clusters-app --interface-id -1 --discriminator 102 --passcode 1002 --KVS /tmp/chip-all-clusters-app-kvs102 --secured-device-port 5532 & - ../../../out/debug/chip-all-clusters-app --interface-id -1 --discriminator 103 --passcode 1003 --KVS /tmp/chip-all-clusters-app-kvs103 --secured-device-port 5533 & - ../../../out/debug/chip-all-clusters-app --interface-id -1 --discriminator 104 --passcode 1004 --KVS /tmp/chip-all-clusters-app-kvs104 --secured-device-port 5534 & - ../../../out/debug/chip-all-clusters-app --interface-id -1 --discriminator 105 --passcode 1005 --KVS /tmp/chip-all-clusters-app-kvs105 --secured-device-port 5535 & + ../../../out/debug/all-clusters-app/chip-all-clusters-app --interface-id -1 --end_user_support_log /tmp/darwin/framework-tests/end_user_support_log.txt > >(tee /tmp/darwin/framework-tests/all-cluster-app.log) 2> >(tee /tmp/darwin/framework-tests/all-cluster-app-err.log >&2) & + ../../../out/debug/all-clusters-app/chip-all-clusters-app --interface-id -1 --dac_provider ../../../credentials/development/commissioner_dut/struct_cd_origin_pid_vid_correct/test_case_vector.json --product-id 32768 --discriminator 3839 --secured-device-port 5539 --KVS /tmp/chip-all-clusters-app-kvs2 > >(tee /tmp/darwin/framework-tests/all-cluster-app-origin-vid.log) 2> >(tee /tmp/darwin/framework-tests/all-cluster-app-origin-vid-err.log >&2) & export TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 diff --git a/.github/workflows/doxygen.yaml b/.github/workflows/doxygen.yaml index 41228ea6996123..cdd535b382f3e5 100644 --- a/.github/workflows/doxygen.yaml +++ b/.github/workflows/doxygen.yaml @@ -81,7 +81,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-doxygen:50 + image: ghcr.io/project-chip/chip-build-doxygen:53 if: github.actor != 'restyled-io[bot]' diff --git a/.github/workflows/examples-ameba.yaml b/.github/workflows/examples-ameba.yaml index cf97a7125d88c3..a75593e4240b81 100644 --- a/.github/workflows/examples-ameba.yaml +++ b/.github/workflows/examples-ameba.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-ameba:50 + image: ghcr.io/project-chip/chip-build-ameba:53 options: --user root steps: diff --git a/.github/workflows/examples-asr.yaml b/.github/workflows/examples-asr.yaml index 74b13f09d5b7a8..bd6287b1a7c656 100644 --- a/.github/workflows/examples-asr.yaml +++ b/.github/workflows/examples-asr.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-asr:50 + image: ghcr.io/project-chip/chip-build-asr:53 options: --user root steps: diff --git a/.github/workflows/examples-bouffalolab.yaml b/.github/workflows/examples-bouffalolab.yaml index bb08679879d594..ab1ba6acdb2360 100644 --- a/.github/workflows/examples-bouffalolab.yaml +++ b/.github/workflows/examples-bouffalolab.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-bouffalolab:50 + image: ghcr.io/project-chip/chip-build-bouffalolab:53 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 32f82d1840f0e8..8d26fe6fa88adc 100644 --- a/.github/workflows/examples-cc13xx_26xx.yaml +++ b/.github/workflows/examples-cc13xx_26xx.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-ti:50 + image: ghcr.io/project-chip/chip-build-ti:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-cc32xx.yaml b/.github/workflows/examples-cc32xx.yaml index f98444ff832c8d..e0509250c39a18 100644 --- a/.github/workflows/examples-cc32xx.yaml +++ b/.github/workflows/examples-cc32xx.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-ti:50 + image: ghcr.io/project-chip/chip-build-ti:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index fff336dd1a636e..39d61fb09f2608 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:50 + image: ghcr.io/project-chip/chip-build-efr32:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index accfec7a8ed35d..c8170de4e0fec9 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:50 + image: ghcr.io/project-chip/chip-build-esp32:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -126,7 +126,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:50 + image: ghcr.io/project-chip/chip-build-esp32:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index 68b868c8816305..a7a1fb1ab14b14 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-infineon:50 + image: ghcr.io/project-chip/chip-build-infineon:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index 379a0e8291901b..f8e7632c60e0ed 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-crosscompile:50 + image: ghcr.io/project-chip/chip-build-crosscompile:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-imx.yaml b/.github/workflows/examples-linux-imx.yaml index 85296a193652d3..dd053382ccf079 100644 --- a/.github/workflows/examples-linux-imx.yaml +++ b/.github/workflows/examples-linux-imx.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-imx:50 + image: ghcr.io/project-chip/chip-build-imx:53 steps: - name: Checkout diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 6ab36546dee02e..b020b0cff1a1a3 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 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 679f4be57a35db..84ab3bfa137c0e 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:41 + image: ghcr.io/project-chip/chip-build:53 steps: - name: Checkout @@ -67,7 +67,7 @@ jobs: run: | ./scripts/run_in_build_env.sh \ "python3 ./scripts/tests/run_tv_casting_test.py" - timeout-minutes: 1 + timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports diff --git a/.github/workflows/examples-mbed.yaml b/.github/workflows/examples-mbed.yaml index 39c5d23f674697..a774fbf52f1ae7 100644 --- a/.github/workflows/examples-mbed.yaml +++ b/.github/workflows/examples-mbed.yaml @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-mbed-os:50 + image: ghcr.io/project-chip/chip-build-mbed-os:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 0ffe67de0faa13..8b489aec59e5dd 100644 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index fe3d0494b9e918..8689925c6f35f6 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nrf-platform:50 + image: ghcr.io/project-chip/chip-build-nrf-platform:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-nuttx.yaml b/.github/workflows/examples-nuttx.yaml index bfe90b7363e4a6..a074e17bedb029 100644 --- a/.github/workflows/examples-nuttx.yaml +++ b/.github/workflows/examples-nuttx.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nuttx:51 + image: ghcr.io/project-chip/chip-build-nuttx:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 2222253b3e760a..f437461ea8c5bb 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-k32w:50 + image: ghcr.io/project-chip/chip-build-k32w:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml index cb3caeaf9f6338..c2fbe82b806bfa 100644 --- a/.github/workflows/examples-openiotsdk.yaml +++ b/.github/workflows/examples-openiotsdk.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-openiotsdk:50 + image: ghcr.io/project-chip/chip-build-openiotsdk:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" options: --privileged diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index 2448a0f8cda8fc..29bdb3f8abae12 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -63,8 +63,6 @@ jobs: --enable-flashbundle \ --target qpg-qpg6105-lock \ --target qpg-qpg6105-light \ - --target qpg-qpg6105-shell \ - --target qpg-qpg6105-persistent-storage \ --target qpg-qpg6105-light-switch \ --target qpg-qpg6105-thermostat \ build \ diff --git a/.github/workflows/examples-rw61x.yaml b/.github/workflows/examples-rw61x.yaml index 526c50d65405ff..efc56c2ec125c8 100644 --- a/.github/workflows/examples-rw61x.yaml +++ b/.github/workflows/examples-rw61x.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-rw61x:50 + image: ghcr.io/project-chip/chip-build-rw61x:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index f5cc530badffe6..050ec72a48db5a 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -50,7 +50,7 @@ jobs: uses: ./.github/actions/checkout-submodules-and-bootstrap with: platform: stm32 - + extra-submodule-parameters: --recursive - name: Set up environment for size reports uses: ./.github/actions/setup-size-reports if: ${{ !env.ACT }} diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 9d83015ecf3d0e..331ee5543932e9 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:50 + image: ghcr.io/project-chip/chip-build-telink:53 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-tizen.yaml b/.github/workflows/examples-tizen.yaml index 8be983a86136bf..295f6d158c87d9 100644 --- a/.github/workflows/examples-tizen.yaml +++ b/.github/workflows/examples-tizen.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-tizen:50 + image: ghcr.io/project-chip/chip-build-tizen:53 options: --user root volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -50,6 +50,12 @@ jobs: with: platform: tizen + - name: Set up environment for size reports + uses: ./.github/actions/setup-size-reports + if: ${{ !env.ACT }} + with: + gh-context: ${{ toJson(github) }} + - name: Build Tizen examples run: | ./scripts/run_in_build_env.sh \ @@ -61,3 +67,20 @@ jobs: build \ --copy-artifacts-to out/artifacts \ " + + - name: Bloat report - chip-tool + run: | + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + tizen arm chip-tool-ubsan out/tizen-arm-chip-tool-ubsan/chip-tool \ + /tmp/bloat_reports/ + - name: Bloat report - all-clusters-app + run: | + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + tizen arm all-clusters-app out/tizen-arm-all-clusters/chip-all-clusters-app \ + /tmp/bloat_reports/ + + - name: Uploading Size Reports + uses: ./.github/actions/upload-size-reports + if: ${{ !env.ACT }} + with: + platform-name: Tizen diff --git a/.github/workflows/full-android.yaml b/.github/workflows/full-android.yaml index 5f06f0c6c609d0..eec019ed11b85d 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:50 + image: ghcr.io/project-chip/chip-build-android:53 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index ee3eebc254f5e9..55d0ccd18c75e1 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:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index deab4d1f7e7e93..16bec4c8187ca3 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-java:50 + image: ghcr.io/project-chip/chip-build-java:53 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4685948fd7bd12..bd5385580b9c22 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -98,7 +98,6 @@ jobs: --known-failure controller/ExamplePersistentStorage.cpp \ --known-failure controller/ExamplePersistentStorage.h \ --known-failure app/AttributeAccessToken.h \ - --known-failure app/CommandHandler.h \ --known-failure app/CommandHandlerInterface.h \ --known-failure app/CommandResponseSender.h \ --known-failure app/CommandSenderLegacyCallback.h \ diff --git a/.github/workflows/minimal-build.yaml b/.github/workflows/minimal-build.yaml index 46f1d0b1fce68e..7e2170baedf5b5 100644 --- a/.github/workflows/minimal-build.yaml +++ b/.github/workflows/minimal-build.yaml @@ -26,14 +26,14 @@ concurrency: cancel-in-progress: true jobs: - minimal: + minimal-all-clusters: name: Linux / configure build of all-clusters-app if: github.actor != 'restyled-io[bot]' runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-minimal:50 + image: ghcr.io/project-chip/chip-build-minimal:53 steps: - name: Checkout @@ -47,3 +47,25 @@ jobs: - name: Configure and build All Clusters App run: | CC=gcc CXX=g++ scripts/configure --project=examples/all-clusters-app/linux && ./ninja-build + + minimal-network-manager: + name: Linux / configure build of network-manager-app + + if: github.actor != 'restyled-io[bot]' + runs-on: ubuntu-latest + + container: + image: ghcr.io/project-chip/chip-build-minimal:50 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Checkout submodules # but don't bootstrap! + uses: ./.github/actions/checkout-submodules + with: + platform: linux + + - name: Configure and build Network Manager App + run: | + CC=gcc CXX=g++ scripts/configure --project=examples/network-manager-app/linux && ./ninja-build diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index 8e9816be2d329d..8129351ce9bf7c 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32-qemu:50 + image: ghcr.io/project-chip/chip-build-esp32-qemu:53 volumes: - "/tmp/log_output:/tmp/test_logs" @@ -78,7 +78,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-tizen-qemu:50 + image: ghcr.io/project-chip/chip-build-tizen-qemu:53 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index 80fdf053003569..2605f723edf5ff 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:50 + image: ghcr.io/project-chip/chip-build-esp32:53 steps: - name: Checkout @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:50 + image: ghcr.io/project-chip/chip-build-efr32:53 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index 3be4eed04fd66d..90afb58f5f06ec 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:50 + image: ghcr.io/project-chip/chip-build-android:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 38354a70151e83..420e4f7c2bb50b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -189,6 +189,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/window-covering.xml \ src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/matter-devices.xml \ @@ -439,7 +440,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" @@ -542,7 +543,6 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_3.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_4.py" --script-args "--endpoint 1 --int-arg PIXIT.OPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_5.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' - scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_1_1.py" --script-args "--endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_1.py" --script-args "--endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_2.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_3.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' @@ -563,6 +563,8 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCOPSTATE_2_4.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_DA_1_2.py' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestIdChecks.py' + - name: Uploading core files uses: actions/upload-artifact@v4 if: ${{ failure() && !env.ACT }} diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index 061f66e19818dd..fc209e42ea7b01 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index a496dbdb4870f0..1ce0250f6a623e 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:50 + image: ghcr.io/project-chip/chip-build:53 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index d1f066820d71fb..fb2d2de06becfd 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:50 + image: ghcr.io/project-chip/chip-build:53 defaults: run: shell: sh diff --git a/.gitmodules b/.gitmodules index 26fff510eebfb5..55d44f9dba9e9f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -313,7 +313,7 @@ [submodule "third_party/st/STM32CubeWB"] path = third_party/st/STM32CubeWB url = https://github.com/STMicroelectronics/STM32CubeWB.git - branch = v1.17.0 + branch = v1.18.0 platforms = stm32 [submodule "p6/lwip-network-interface-integration"] path = third_party/infineon/psoc6/psoc6_sdk/libs/lwip-network-interface-integration diff --git a/.gn b/.gn index b9586c7fce69ea..f844fd20e9b87d 100644 --- a/.gn +++ b/.gn @@ -25,6 +25,7 @@ script_executable = "python3" default_args = { pw_unit_test_AUTOMATIC_RUNNER = "$dir_pigweed/targets/host/run_test" + pw_unit_test_CONFIG = "//config/pw_unit_test:define_overrides" pw_build_PIP_CONSTRAINTS = [ "//scripts/setup/constraints.txt" ] pw_build_PIP_REQUIREMENTS = [ "//scripts/setup/requirements.build.txt" ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 415d4980d00d24..d38758524ac8a5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,25 +7,29 @@ "${workspaceFolder}/build/default/src/lib/**", "${workspaceFolder}/config/standalone/", "${workspaceFolder}/config/standalone/**", + "${workspaceFolder}/darwin/Framework/CHIP/**", "${workspaceFolder}/examples/**", "${workspaceFolder}/src/**", + "${workspaceFolder}/src/app/**", + "${workspaceFolder}/src/ble/**", + "${workspaceFolder}/src/controller/**", + "${workspaceFolder}/src/credentials/**", + "${workspaceFolder}/src/crypto/**", + "${workspaceFolder}/src/darwin/**", "${workspaceFolder}/src/include/", "${workspaceFolder}/src/include/**", + "${workspaceFolder}/src/inet/**", "${workspaceFolder}/src/lib/**", - "${workspaceFolder}/src/system/**", - "${workspaceFolder}/third_party/nlassert/repo/include/**", - "${workspaceFolder}/third_party/nlio/repo/include/**", - "${workspaceFolder}/darwin/Framework/CHIP/**", + "${workspaceFolder}/src/lwip/**", "${workspaceFolder}/src/messaging/**", + "${workspaceFolder}/src/platform/**", "${workspaceFolder}/src/protocols/**", + "${workspaceFolder}/src/setup_payload/**", + "${workspaceFolder}/src/system/**", "${workspaceFolder}/src/tracing/**", "${workspaceFolder}/src/transport/**", - "${workspaceFolder}/src/inet/**", - "${workspaceFolder}/src/credentials/**", - "${workspaceFolder}/src/data_model/**", - "${workspaceFolder}/src/app/**", - "${workspaceFolder}/src/crytpo/**", - "${workspaceFolder}/src/platform/**" + "${workspaceFolder}/third_party/nlassert/repo/include/**", + "${workspaceFolder}/third_party/nlio/repo/include/**" ], "[cpp]": { "editor.defaultFormatter": "xaver.clang-format" diff --git a/build/chip/linux/BUILD.gn b/build/chip/linux/BUILD.gn index c86f803a70f3d3..a530d5a611a25e 100644 --- a/build/chip/linux/BUILD.gn +++ b/build/chip/linux/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,4 +21,5 @@ pkg_config("glib") { "glib-2.0", "gio-unix-2.0", ] + optional = true # Only certain conditionally-compiled modules depend on glib } diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 63b5eef6003b1b..1e634152a61d49 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -356,6 +356,7 @@ config("runtime_default") { } if (current_os == "linux" || current_os == "tizen" || current_os == "webos") { libs = [ + "atomic", "dl", "pthread", "rt", diff --git a/build/config/linux/pkg-config.py b/build/config/linux/pkg-config.py index 4d6e773a00d666..f44667242de807 100755 --- a/build/config/linux/pkg-config.py +++ b/build/config/linux/pkg-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # Copyright (c) 2013 The Chromium Authors. All rights reserved. -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -127,6 +127,7 @@ def RewritePath(path, strip_prefix, sysroot): def main(): parser = OptionParser() parser.add_option('-d', '--debug', action='store_true') + parser.add_option('-o', '--optional', action='store_true') parser.add_option('-p', action='store', dest='pkg_config', type='string', default='pkg-config') parser.add_option('-v', action='append', dest='strip_out', type='string') @@ -209,6 +210,10 @@ def main(): try: flag_string = subprocess.check_output(cmd).decode('utf-8') except Exception: + if options.optional: + sys.stderr.write('Ignoring failure to run pkg-config for optional library.\n') + print(json.dumps([False])) # Output a GN array indicating missing optional packages + return 0 sys.stderr.write('Could not run pkg-config.\n') return 1 @@ -248,10 +253,10 @@ def main(): else: cflags.append(flag) - # Output a GN array, the first one is the cflags, the second are the libs. The + # Output a GN array, indicating success and our output lists. # JSON formatter prints GN compatible lists when everything is a list of # strings. - print(json.dumps([includes, cflags, libs, lib_dirs])) + print(json.dumps([True, includes, cflags, libs, lib_dirs])) return 0 diff --git a/build/config/linux/pkg_config.gni b/build/config/linux/pkg_config.gni index 016defafbc3617..d6892d97fb976f 100644 --- a/build/config/linux/pkg_config.gni +++ b/build/config/linux/pkg_config.gni @@ -1,5 +1,5 @@ # Copyright (c) 2013 The Chromium Authors. All rights reserved. -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -43,9 +43,14 @@ # # You can also use "extra args" to filter out results (see pkg-config.py): # extra_args = [ "-v, "foo" ] +# # To ignore libs and ldflags (only cflags/defines will be set, which is useful # when doing manual dynamic linking), set: # ignore_libs = true +# +# To allow the build to proceed if (any of) the requested packages are absent, set: +# optional = true +# In this case the resulting config object will be empty. import("//build_overrides/build.gni") import("${build_root}/config/sysroot.gni") @@ -109,37 +114,42 @@ template("pkg_config") { } else { args = pkg_config_args + invoker.packages } + if (defined(invoker.optional) && invoker.optional) { + args += [ "-o" ] + } if (defined(invoker.extra_args)) { args += invoker.extra_args } + # pkgresult = [present, includes, cflags, libs, lib_dirs] pkgresult = exec_script(pkg_config_script, args, "value") - cflags = pkgresult[1] + if (pkgresult[0]) { + cflags = pkgresult[2] - foreach(include, pkgresult[0]) { - cflags += [ "-I$include" ] - } + foreach(include, pkgresult[1]) { + cflags += [ "-I$include" ] + } - if (!defined(invoker.ignore_libs) || !invoker.ignore_libs) { - libs = pkgresult[2] - lib_dirs = pkgresult[3] - } + if (!defined(invoker.ignore_libs) || !invoker.ignore_libs) { + libs = pkgresult[3] + lib_dirs = pkgresult[4] + } - # Link libraries statically for OSS-Fuzz fuzzer build - if (oss_fuzz) { - libs = [] - ldflags = [ "-Wl,-Bstatic" ] - foreach(lib, pkgresult[2]) { - ldflags += [ "-l$lib" ] + # Link libraries statically for OSS-Fuzz fuzzer build + if (oss_fuzz) { + libs = [] + ldflags = [ "-Wl,-Bstatic" ] + foreach(lib, pkgresult[3]) { + ldflags += [ "-l$lib" ] + } + ldflags += [ "-Wl,-Bdynamic" ] + lib_dirs = pkgresult[4] } - ldflags += [ "-Wl,-Bdynamic" ] - lib_dirs = pkgresult[3] - } - forward_variables_from(invoker, - [ - "defines", - "visibility", - ]) + forward_variables_from(invoker, [ "defines" ]) + } } + + # Always forward visibility + forward_variables_from(invoker, [ "visibility" ]) } diff --git a/build/toolchain/android/android_toolchain.gni b/build/toolchain/android/android_toolchain.gni index e4eed1b30b577e..f1242b6cbcd855 100644 --- a/build/toolchain/android/android_toolchain.gni +++ b/build/toolchain/android/android_toolchain.gni @@ -69,6 +69,5 @@ template("android_clang_toolchain") { ar = _ndk_prefix + "llvm-ar" cc = _ndk_prefix + _tool_name_root + "clang" cxx = _ndk_prefix + _tool_name_root + "clang++" - link_generate_map_file = false } } diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index b4b39daf711fb0..dce52ec7644df8 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni @@ -16,11 +16,9 @@ import("//build_overrides/pigweed.gni") import("$dir_pw_toolchain/generate_toolchain.gni") declare_args() { - # Generate Linker map files. Can skip since they can + # Generate Linker map files. By default it is disabled since they can # be quite large. - # - # Note that toolchains can individually override this - chip_generate_link_map_file = true + chip_generate_link_map_file = false } template("gcc_toolchain") { @@ -48,11 +46,7 @@ template("gcc_toolchain") { cxx = invoker.cxx } - if (defined(invoker.link_generate_map_file)) { - link_generate_map_file = invoker.link_generate_map_file - } else { - link_generate_map_file = chip_generate_link_map_file - } + link_generate_map_file = chip_generate_link_map_file is_host_toolchain = invoker_toolchain_args.current_os == host_os link_group = invoker_toolchain_args.current_os != "mac" && diff --git a/config/pw_unit_test/BUILD.gn b/config/pw_unit_test/BUILD.gn new file mode 100644 index 00000000000000..20889115f74538 --- /dev/null +++ b/config/pw_unit_test/BUILD.gn @@ -0,0 +1,32 @@ +# 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/tests.gni") + +import("$dir_pw_build/target_types.gni") +pw_source_set("define_overrides") { + public_configs = [ ":define_options" ] +} + +config("define_options") { + if (chip_fake_platform && chip_link_tests) { + defines = [ "PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE=65536" ] + } else { + defines = [ "PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE=16384" ] + } +} diff --git a/config/qpg/chip-gn/build.sh b/config/qpg/chip-gn/build.sh index ce0306c2ab9809..541da2625253eb 100755 --- a/config/qpg/chip-gn/build.sh +++ b/config/qpg/chip-gn/build.sh @@ -23,6 +23,7 @@ env GN_ROOT_TARGET=$(dirname "$0") CHIP_ROOT=$GN_ROOT_TARGET/../../../ OUTDIR=$CHIP_ROOT/out +GN_ARGS="qpg_target_ic=\"qpg6105\" qpg_flavour=\"_ext_flash\"" mkdir -p "$OUTDIR" gn \ @@ -33,6 +34,7 @@ gn \ --export-compile-commands \ gen \ --check \ + --args="$GN_ARGS" \ --fail-on-unused-args \ "$OUTDIR" ninja -C "$OUTDIR" diff --git a/credentials/generate-revocation-set.py b/credentials/generate-revocation-set.py index 534edc15b0f203..bfc5ce560c1f80 100644 --- a/credentials/generate-revocation-set.py +++ b/credentials/generate-revocation-set.py @@ -1,7 +1,7 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2023-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import base64 import json +import logging import subprocess import sys from enum import Enum @@ -30,6 +31,16 @@ import requests from click_option_group import RequiredMutuallyExclusiveOptionGroup, optgroup from cryptography import x509 +from cryptography.hazmat.primitives.asymmetric import ec + +# 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, +} class RevocationType(Enum): @@ -44,20 +55,144 @@ class RevocationType(Enum): TEST_NODE_URL_REST = "https://on.test-net.dcl.csa-iot.org" -def use_dcld(dcld, production, cmdlist): - return [dcld] + cmdlist + (['--node', PRODUCTION_NODE_URL] if production else []) - - def extract_single_integer_attribute(subject, oid): attribute_list = subject.get_attributes_for_oid(oid) if len(attribute_list) == 1: - if attribute_list[0].value.isdigit(): - return int(attribute_list[0].value) + return int(attribute_list[0].value, 16) return None +class DCLDClient: + ''' + A client for interacting with DCLD using either the REST API or command line interface (CLI). + + ''' + + def __init__(self, use_rest: bool, dcld_exe: str, production: bool, rest_node_url: str): + ''' + Initialize the client + + use_rest: bool + Use RESTful API with HTTPS against `rest_node_url` + dcld_exe: str + Path to `dcld` executable + production: bool + Use MainNet DCL URL with dcld executable + rest_node_url: str + RESTful API URL + ''' + + self.use_rest = use_rest + self.dcld_exe = dcld_exe + self.production = production + self.rest_node_url = rest_node_url + + def build_dcld_command_line(self, cmdlist: list[str]) -> list[str]: + ''' + Build command line for `dcld` executable. + + Parameters + ---------- + cmdlist: list[str] + List of command line arguments to append to some predefined arguments + + Returns + ------- + list[str] + The complete command list including the DCLD executable and node option if in production + ''' + + return [self.dcld_exe] + cmdlist + (['--node', PRODUCTION_NODE_URL] if self.production else []) + + def get_dcld_cmd_output_json(self, cmdlist: list[str]) -> dict: + ''' + Executes a DCLD CLI command and returns the JSON output. + + Parameters + ---------- + cmdlist: list[str] + List of command line arguments to append to some predefined arguments + + Returns + ------- + dict + The JSON output from the command + ''' + + # Set the output as JSON + subprocess.Popen([self.dcld_exe, 'config', 'output', 'json']) + + cmdpipe = subprocess.Popen(self.build_dcld_command_line(cmdlist), + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return json.loads(cmdpipe.stdout.read()) + + def get_revocation_points(self) -> list[dict]: + ''' + Get revocation points from DCL + + Returns + ------- + list[dict] + List of revocation points + ''' + + if self.use_rest: + response = requests.get(f"{self.rest_node_url}/dcl/pki/revocation-points").json() + else: + response = self.get_dcld_cmd_output_json(['query', 'pki', 'all-revocation-points']) + + return response["PkiRevocationDistributionPoint"] + + def get_paa_cert_for_crl_issuer(self, crl_signer_issuer_name_b64, crl_signer_authority_key_id) -> str: + ''' + Get PAA certificate for CRL issuer + + Parameters + ---------- + crl_signer_issuer_name_b64: str + The issuer name of the CRL signer. + crl_signer_authority_key_id: str + The authority key ID of the CRL signer. + + Returns + ------- + str + PAA certificate in PEM format + ''' + if self.use_rest: + response = requests.get( + f"{self.rest_node_url}/dcl/pki/certificates/{crl_signer_issuer_name_b64}/{crl_signer_authority_key_id}").json() + else: + response = self.get_dcld_cmd_output_json( + ['query', 'pki', 'x509-cert', '-u', crl_signer_issuer_name_b64, '-k', crl_signer_authority_key_id]) + + return response["approvedCertificates"]["certs"][0]["pemCert"] + + def get_revocations_points_by_skid(self, issuer_subject_key_id) -> list[dict]: + ''' + Get revocation points by subject key ID + + Parameters + ---------- + issuer_subject_key_id: str + Subject key ID + + Returns + ------- + list[dict] + List of revocation points + ''' + if self.use_rest: + response = requests.get(f"{self.rest_node_url}/dcl/pki/revocation-points/{issuer_subject_key_id}").json() + else: + response = self.get_dcld_cmd_output_json(['query', 'pki', 'revocation-points', + '--issuer-subject-key-id', issuer_subject_key_id]) + + return response["pkiRevocationDistributionPointsByIssuerSubjectKeyID"]["points"] + + @click.command() @click.help_option('-h', '--help') @optgroup.group('Input data sources', cls=RequiredMutuallyExclusiveOptionGroup) @@ -66,9 +201,19 @@ def extract_single_integer_attribute(subject, oid): @optgroup.option('--use-main-net-http', is_flag=True, type=str, help="Use RESTful API with HTTPS against public MainNet observer.") @optgroup.option('--use-test-net-http', is_flag=True, type=str, help="Use RESTful API with HTTPS against public TestNet observer.") @optgroup.group('Optional arguments') -@optgroup.option('--output', default='sample_revocation_set_list.json', type=str, metavar='FILEPATH', help="Output filename (default: sample_revocation_set_list.json)") -def main(use_main_net_dcld, use_test_net_dcld, use_main_net_http, use_test_net_http, output): - """DCL PAA mirroring tools""" +@optgroup.option('--output', default='sample_revocation_set_list.json', type=str, metavar='FILEPATH', + help="Output filename (default: sample_revocation_set_list.json)") +@optgroup.option('--log-level', default='INFO', show_default=True, type=click.Choice(__LOG_LEVELS__.keys(), + case_sensitive=False), callback=lambda c, p, v: __LOG_LEVELS__[v], + help='Determines the verbosity of script output') +def main(use_main_net_dcld: str, use_test_net_dcld: str, use_main_net_http: bool, use_test_net_http: bool, output: str, log_level: str): + """Tool to construct revocation set from DCL""" + + logging.basicConfig( + level=log_level, + format='%(asctime)s %(name)s %(levelname)-7s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' + ) production = False dcld = use_test_net_dcld @@ -83,28 +228,20 @@ def main(use_main_net_dcld, use_test_net_dcld, use_main_net_http, use_test_net_h rest_node_url = PRODUCTION_NODE_URL_REST if production else TEST_NODE_URL_REST - # TODO: Extract this to a helper function - if use_rest: - revocation_point_list = requests.get(f"{rest_node_url}/dcl/pki/revocation-points").json()["PkiRevocationDistributionPoint"] - else: - cmdlist = ['config', 'output', 'json'] - subprocess.Popen([dcld] + cmdlist) - - cmdlist = ['query', 'pki', 'all-revocation-points'] - - cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + dcld_client = DCLDClient(use_rest, dcld, production, rest_node_url) - revocation_point_list = json.loads(cmdpipe.stdout.read())["PkiRevocationDistributionPoint"] + revocation_point_list = dcld_client.get_revocation_points() revocation_set = [] for revocation_point in revocation_point_list: # 1. Validate Revocation Type - if revocation_point["revocationType"] != RevocationType.CRL: + if revocation_point["revocationType"] != RevocationType.CRL.value: + logging.warning("Revocation Type is not CRL, continue...") continue # 2. Parse the certificate - crl_signer_certificate = x509.load_pem_x509_certificate(revocation_point["crlSignerCertificate"]) + crl_signer_certificate = x509.load_pem_x509_certificate(bytes(revocation_point["crlSignerCertificate"], 'utf-8')) vid = revocation_point["vid"] pid = revocation_point["pid"] @@ -119,12 +256,15 @@ def main(use_main_net_dcld, use_test_net_dcld, use_main_net_http, use_test_net_h if crl_vid is not None: if vid != crl_vid: # TODO: Need to log all situations where a continue is called + logging.warning("VID is not CRL VID, continue...") continue else: if crl_vid is None or vid != crl_vid: + logging.warning("VID is not CRL VID, continue...") continue if crl_pid is not None: if pid != crl_pid: + logging.warning("PID is not CRL PID, continue...") continue # 5. Validate the certification path containing CRLSignerCertificate. @@ -133,99 +273,110 @@ def main(use_main_net_dcld, use_test_net_dcld, use_main_net_http, use_test_net_h crl_signer_authority_key_id = crl_signer_certificate.extensions.get_extension_for_oid( x509.OID_AUTHORITY_KEY_IDENTIFIER).value.key_identifier - paa_certificate = None + # Convert CRL Signer AKID to colon separated hex + crl_signer_authority_key_id = crl_signer_authority_key_id.hex().upper() + crl_signer_authority_key_id = ':'.join([crl_signer_authority_key_id[i:i+2] + for i in range(0, len(crl_signer_authority_key_id), 2)]) - # TODO: Extract this to a helper function - if use_rest: - response = requests.get( - f"{rest_node_url}/dcl/pki/certificates/{crl_signer_issuer_name}/{crl_signer_authority_key_id}").json()["approvedCertificates"]["certs"][0] - paa_certificate = response["pemCert"] - else: - cmdlist = ['query', 'pki', 'x509-cert', '-u', crl_signer_issuer_name, '-k', crl_signer_authority_key_id] - cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE) - paa_certificate = json.loads(cmdpipe.stdout.read())["approvedCertificates"]["certs"][0]["pemCert"] + paa_certificate = dcld_client.get_paa_cert_for_crl_issuer(crl_signer_issuer_name, crl_signer_authority_key_id) if paa_certificate is None: + logging.warning("PAA Certificate not found, continue...") continue - paa_certificate_object = x509.load_pem_x509_certificate(paa_certificate) + paa_certificate_object = x509.load_pem_x509_certificate(bytes(paa_certificate, 'utf-8')) + + # TODO: use verify_directly_issued_by() method when we upgrade cryptography to v40.0.0 + # Verify issuer matches with subject + if crl_signer_certificate.issuer != paa_certificate_object.subject: + logging.warning("CRL Signer Certificate issuer does not match with PAA Certificate subject, continue...") + continue + # Check crl signers AKID matches with SKID of paa_certificate_object's AKID + paa_skid = paa_certificate_object.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER).value.key_identifier + crl_akid = crl_signer_certificate.extensions.get_extension_for_oid(x509.OID_AUTHORITY_KEY_IDENTIFIER).value.key_identifier + if paa_skid != crl_akid: + logging.warning("CRL Signer's AKID does not match with PAA Certificate SKID, continue...") + continue + + # verify if PAA singed the crl signer certificate try: - crl_signer_certificate.verify_directly_issued_by(paa_certificate_object) + paa_certificate_object.public_key().verify(crl_signer_certificate.signature, + crl_signer_certificate.tbs_certificate_bytes, + ec.ECDSA(crl_signer_certificate.signature_hash_algorithm)) except Exception: + logging.warning("CRL Signer Certificate is not signed by PAA Certificate, continue...") continue # 6. Obtain the CRL - r = requests.get(revocation_point["dataURL"]) - crl_file = x509.load_der_x509_crl(r.content) + logging.debug(f"Fetching CRL from {revocation_point['dataURL']}") + try: + r = requests.get(revocation_point["dataURL"], timeout=5) + except Exception: + logging.error('Failed to fetch CRL') + continue + + try: + crl_file = x509.load_der_x509_crl(r.content) + except Exception: + logging.error('Failed to load CRL') + continue # 7. Perform CRL File Validation crl_authority_key_id = crl_file.extensions.get_extension_for_oid(x509.OID_AUTHORITY_KEY_IDENTIFIER).value.key_identifier crl_signer_subject_key_id = crl_signer_certificate.extensions.get_extension_for_oid( x509.OID_SUBJECT_KEY_IDENTIFIER).value.key_identifier if crl_authority_key_id != crl_signer_subject_key_id: + logging.warning("CRL Authority Key ID is not CRL Signer Subject Key ID, continue...") continue issuer_subject_key_id = ''.join('{:02X}'.format(x) for x in crl_authority_key_id) - same_issuer_points = None + # b. + same_issuer_points = dcld_client.get_revocations_points_by_skid(issuer_subject_key_id) + count_with_matching_vid_issuer_skid = sum(item.get('vid') == vid for item in same_issuer_points) - # TODO: Extract this to a helper function - if use_rest: - response = requests.get( - f"{rest_node_url}/dcl/pki/revocation-points/{issuer_subject_key_id}").json()["pkiRevocationDistributionPointsByIssuerSubjectKeyID"] - same_issuer_points = response["points"] - else: - cmdlist = ['query', 'pki', 'revocation-points', '--issuer-subject-key-id', issuer_subject_key_id] - cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE) - same_issuer_points = json.loads(cmdpipe.stdout.read())[ - "pkiRevocationDistributionPointsByIssuerSubjectKeyID"]["points"] - - matching_entries = False - for same_issuer_point in same_issuer_points: - if same_issuer_point["vid"] == vid: - matching_entries = True - break - - if matching_entries: + if count_with_matching_vid_issuer_skid > 1: try: issuing_distribution_point = crl_file.extensions.get_extension_for_oid( x509.OID_ISSUING_DISTRIBUTION_POINT).value except Exception: + logging.warning("CRL Issuing Distribution Point not found, continue...") continue uri_list = issuing_distribution_point.full_name if len(uri_list) == 1 and isinstance(uri_list[0], x509.UniformResourceIdentifier): if uri_list[0].value != revocation_point["dataURL"]: + logging.warning("CRL Issuing Distribution Point URI is not CRL URL, continue...") continue else: + logging.warning("CRL Issuing Distribution Point URI is not CRL URL, continue...") continue # 9. Assign CRL File Issuer certificate_authority_name = base64.b64encode(crl_file.issuer.public_bytes()).decode('utf-8') + logging.debug(f"CRL File Issuer: {certificate_authority_name}") serialnumber_list = [] # 10. Iterate through the Revoked Certificates List for revoked_cert in crl_file: + # a. try: revoked_cert_issuer = revoked_cert.extensions.get_extension_for_oid( x509.CRLEntryExtensionOID.CERTIFICATE_ISSUER).value.get_values_for_type(x509.DirectoryName).value if revoked_cert_issuer is not None: if revoked_cert_issuer != certificate_authority_name: + logging.warning("CRL Issuer is not CRL File Issuer, continue...") continue except Exception: pass # b. - try: - revoked_cert_authority_key_id = revoked_cert.extensions.get_extension_for_oid( - x509.OID_AUTHORITY_KEY_IDENTIFIER).value.key_identifier - - if revoked_cert_authority_key_id is None or revoked_cert_authority_key_id != crl_signer_subject_key_id: - continue - except Exception: - continue + # TODO: Verify that the certificate chain of the entry is linking to the same PAA + # that issued the CRLSignerCertificate for this entry, including path through + # CRLSignerDelegator if present. If the PAAs under which were issued the certificate + # and the CRLSignerCertificate are different, ignore the entry. # c. and d. serialnumber_list.append(bytes(str('{:02X}'.format(revoked_cert.serial_number)), 'utf-8').decode('utf-8')) diff --git a/data_model/clusters/ACL-Cluster.xml b/data_model/clusters/ACL-Cluster.xml index b965eb84234e0d..a193ef2ac3206f 100644 --- a/data_model/clusters/ACL-Cluster.xml +++ b/data_model/clusters/ACL-Cluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/AccountLogin.xml b/data_model/clusters/AccountLogin.xml index db87d05dc74902..8a9ed7d9389f40 100644 --- a/data_model/clusters/AccountLogin.xml +++ b/data_model/clusters/AccountLogin.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/AdminCommissioningCluster.xml b/data_model/clusters/AdminCommissioningCluster.xml index eea41bc65b6e2c..ccbb579134dc00 100644 --- a/data_model/clusters/AdminCommissioningCluster.xml +++ b/data_model/clusters/AdminCommissioningCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/AirQuality.xml b/data_model/clusters/AirQuality.xml index 2e188b97d23336..c05717863c5ff4 100644 --- a/data_model/clusters/AirQuality.xml +++ b/data_model/clusters/AirQuality.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/AlarmBase.xml b/data_model/clusters/AlarmBase.xml index f4ffc6344a8b90..fd0ccb5bc19d46 100644 --- a/data_model/clusters/AlarmBase.xml +++ b/data_model/clusters/AlarmBase.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ApplicationBasic.xml b/data_model/clusters/ApplicationBasic.xml index fa197a8d1e5cca..ee39b8a421209d 100644 --- a/data_model/clusters/ApplicationBasic.xml +++ b/data_model/clusters/ApplicationBasic.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ApplicationLauncher.xml b/data_model/clusters/ApplicationLauncher.xml index 6b84436e73d42d..57d6858dd8ce14 100644 --- a/data_model/clusters/ApplicationLauncher.xml +++ b/data_model/clusters/ApplicationLauncher.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/AudioOutput.xml b/data_model/clusters/AudioOutput.xml index 468ba2750152a6..27bb5a20bb7952 100644 --- a/data_model/clusters/AudioOutput.xml +++ b/data_model/clusters/AudioOutput.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/BallastConfiguration.xml b/data_model/clusters/BallastConfiguration.xml index f25bef22cb4b6c..0f37d86067e994 100644 --- a/data_model/clusters/BallastConfiguration.xml +++ b/data_model/clusters/BallastConfiguration.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/BasicInformationCluster.xml b/data_model/clusters/BasicInformationCluster.xml index 82b9283b0d21d6..137e8b70408bf8 100644 --- a/data_model/clusters/BasicInformationCluster.xml +++ b/data_model/clusters/BasicInformationCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/Binding-Cluster.xml b/data_model/clusters/Binding-Cluster.xml index 937b9164e2a4f8..444c99b315348d 100644 --- a/data_model/clusters/Binding-Cluster.xml +++ b/data_model/clusters/Binding-Cluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/BooleanState.xml b/data_model/clusters/BooleanState.xml index 9205310c58f2be..5bb29f53ae0c3e 100644 --- a/data_model/clusters/BooleanState.xml +++ b/data_model/clusters/BooleanState.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/BooleanStateConfiguration.xml b/data_model/clusters/BooleanStateConfiguration.xml index a9c370b95fe15c..01444d565294b3 100644 --- a/data_model/clusters/BooleanStateConfiguration.xml +++ b/data_model/clusters/BooleanStateConfiguration.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Channel.xml b/data_model/clusters/Channel.xml index 1809f5262e7166..17144c9032c3e5 100644 --- a/data_model/clusters/Channel.xml +++ b/data_model/clusters/Channel.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ColorControl.xml b/data_model/clusters/ColorControl.xml index b913009f852761..456b3ff14cfff9 100644 --- a/data_model/clusters/ColorControl.xml +++ b/data_model/clusters/ColorControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ContentAppObserver.xml b/data_model/clusters/ContentAppObserver.xml index 184cce14924cda..d6808baf982215 100644 --- a/data_model/clusters/ContentAppObserver.xml +++ b/data_model/clusters/ContentAppObserver.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ContentControl.xml b/data_model/clusters/ContentControl.xml index 14996a7c28011a..b2539cf445c289 100644 --- a/data_model/clusters/ContentControl.xml +++ b/data_model/clusters/ContentControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/ContentLauncher.xml b/data_model/clusters/ContentLauncher.xml index b8f80de2e51ea7..9a5674efa8eb64 100644 --- a/data_model/clusters/ContentLauncher.xml +++ b/data_model/clusters/ContentLauncher.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/DemandResponseLoadControl.xml b/data_model/clusters/DemandResponseLoadControl.xml deleted file mode 100644 index 206201b347612c..00000000000000 --- a/data_model/clusters/DemandResponseLoadControl.xml +++ /dev/null @@ -1,554 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/Descriptor-Cluster.xml b/data_model/clusters/Descriptor-Cluster.xml index 1b17fb4fdfdaea..659b2ffaa5ddc0 100644 --- a/data_model/clusters/Descriptor-Cluster.xml +++ b/data_model/clusters/Descriptor-Cluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/DeviceEnergyManagement.xml b/data_model/clusters/DeviceEnergyManagement.xml index e493c5b332182e..f74d7e572550cc 100644 --- a/data_model/clusters/DeviceEnergyManagement.xml +++ b/data_model/clusters/DeviceEnergyManagement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/DiagnosticLogsCluster.xml b/data_model/clusters/DiagnosticLogsCluster.xml index 5b67564b18f298..38520e81a85e16 100644 --- a/data_model/clusters/DiagnosticLogsCluster.xml +++ b/data_model/clusters/DiagnosticLogsCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/DiagnosticsEthernet.xml b/data_model/clusters/DiagnosticsEthernet.xml index 9d4822479ef5a6..dfcd3d11c41f52 100644 --- a/data_model/clusters/DiagnosticsEthernet.xml +++ b/data_model/clusters/DiagnosticsEthernet.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/DiagnosticsGeneral.xml b/data_model/clusters/DiagnosticsGeneral.xml index 1141123c83b6be..4da912b03dc3df 100644 --- a/data_model/clusters/DiagnosticsGeneral.xml +++ b/data_model/clusters/DiagnosticsGeneral.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/DiagnosticsSoftware.xml b/data_model/clusters/DiagnosticsSoftware.xml index 2c0b0b8a91a6ae..7cb3c9ff39ad2f 100644 --- a/data_model/clusters/DiagnosticsSoftware.xml +++ b/data_model/clusters/DiagnosticsSoftware.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/DiagnosticsThread.xml b/data_model/clusters/DiagnosticsThread.xml index a05d5dc1b2d2fc..120efaddf8c08e 100644 --- a/data_model/clusters/DiagnosticsThread.xml +++ b/data_model/clusters/DiagnosticsThread.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/DiagnosticsWiFi.xml b/data_model/clusters/DiagnosticsWiFi.xml index 49ef964da7a545..b3951d967dc31f 100644 --- a/data_model/clusters/DiagnosticsWiFi.xml +++ b/data_model/clusters/DiagnosticsWiFi.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/DishwasherAlarm.xml b/data_model/clusters/DishwasherAlarm.xml index b3b67e2bffb500..bdc399f9399486 100644 --- a/data_model/clusters/DishwasherAlarm.xml +++ b/data_model/clusters/DishwasherAlarm.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: short --> - + diff --git a/data_model/clusters/DoorLock.xml b/data_model/clusters/DoorLock.xml index 16d26420fe2009..fcf86f3a95aa24 100644 --- a/data_model/clusters/DoorLock.xml +++ b/data_model/clusters/DoorLock.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ElectricalEnergyMeasurement.xml b/data_model/clusters/ElectricalEnergyMeasurement.xml index 98020764397116..f8bbec4c03db95 100644 --- a/data_model/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/clusters/ElectricalEnergyMeasurement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ElectricalPowerMeasurement.xml b/data_model/clusters/ElectricalPowerMeasurement.xml index c695e8db031790..cfb8ce9018e73c 100644 --- a/data_model/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/clusters/ElectricalPowerMeasurement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/EnergyCalendar.xml b/data_model/clusters/EnergyCalendar.xml deleted file mode 100644 index 8d3f1b343bb4a7..00000000000000 --- a/data_model/clusters/EnergyCalendar.xml +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/EnergyEVSE.xml b/data_model/clusters/EnergyEVSE.xml index d7786da5cda99d..4b881f5a1135a4 100644 --- a/data_model/clusters/EnergyEVSE.xml +++ b/data_model/clusters/EnergyEVSE.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/EnergyPreference.xml b/data_model/clusters/EnergyPreference.xml index c3676520ed6d01..eafb527a868b22 100644 --- a/data_model/clusters/EnergyPreference.xml +++ b/data_model/clusters/EnergyPreference.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/EnergyPrice.xml b/data_model/clusters/EnergyPrice.xml deleted file mode 100644 index 1683fe1bbc13cf..00000000000000 --- a/data_model/clusters/EnergyPrice.xml +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/FanControl.xml b/data_model/clusters/FanControl.xml index 756a7bd27466b3..224f811261f68b 100644 --- a/data_model/clusters/FanControl.xml +++ b/data_model/clusters/FanControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: short --> - + diff --git a/data_model/clusters/FlowMeasurement.xml b/data_model/clusters/FlowMeasurement.xml index 29f9d9d7ae58f9..71178874d57c14 100644 --- a/data_model/clusters/FlowMeasurement.xml +++ b/data_model/clusters/FlowMeasurement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/GeneralCommissioningCluster.xml b/data_model/clusters/GeneralCommissioningCluster.xml index e7877635bbac68..e440222780ea02 100644 --- a/data_model/clusters/GeneralCommissioningCluster.xml +++ b/data_model/clusters/GeneralCommissioningCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/Group-Key-Management-Cluster.xml b/data_model/clusters/Group-Key-Management-Cluster.xml index 8867a395299bbd..c1819628e34d7b 100644 --- a/data_model/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/clusters/Group-Key-Management-Cluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/Groups.xml b/data_model/clusters/Groups.xml index 72902e878cbe9f..1f168e13fad933 100644 --- a/data_model/clusters/Groups.xml +++ b/data_model/clusters/Groups.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ICDManagement.xml b/data_model/clusters/ICDManagement.xml index 534b8340143083..512dfd119efef7 100644 --- a/data_model/clusters/ICDManagement.xml +++ b/data_model/clusters/ICDManagement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA // Update Name --> - + diff --git a/data_model/clusters/Identify.xml b/data_model/clusters/Identify.xml index 1cdc33aa0df727..8044ceb33dc3bd 100644 --- a/data_model/clusters/Identify.xml +++ b/data_model/clusters/Identify.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/IlluminanceMeasurement.xml b/data_model/clusters/IlluminanceMeasurement.xml index c39daa0e6bdc4d..d3228b845ca058 100644 --- a/data_model/clusters/IlluminanceMeasurement.xml +++ b/data_model/clusters/IlluminanceMeasurement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/KeypadInput.xml b/data_model/clusters/KeypadInput.xml index 4cfb509b06d0be..57d6ef4650e013 100644 --- a/data_model/clusters/KeypadInput.xml +++ b/data_model/clusters/KeypadInput.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Label-Cluster-FixedLabelCluster.xml b/data_model/clusters/Label-Cluster-FixedLabelCluster.xml index e73bfc274a9da4..98106b6fc33e40 100644 --- a/data_model/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/clusters/Label-Cluster-FixedLabelCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Label-Cluster-LabelCluster.xml b/data_model/clusters/Label-Cluster-LabelCluster.xml index f107a0a7b3f12b..0ca5566f0dc132 100644 --- a/data_model/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/clusters/Label-Cluster-LabelCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Label-Cluster-UserLabelCluster.xml b/data_model/clusters/Label-Cluster-UserLabelCluster.xml index f7e809ab785c00..eba0099ffb59d2 100644 --- a/data_model/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/clusters/Label-Cluster-UserLabelCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/LaundryDryerControls.xml b/data_model/clusters/LaundryDryerControls.xml index a3f7b911fc9e9c..af4f787c0432b7 100644 --- a/data_model/clusters/LaundryDryerControls.xml +++ b/data_model/clusters/LaundryDryerControls.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/LaundryWasherControls.xml b/data_model/clusters/LaundryWasherControls.xml index 16879842721473..6c4f4bc0b0c3a5 100644 --- a/data_model/clusters/LaundryWasherControls.xml +++ b/data_model/clusters/LaundryWasherControls.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/LevelControl.xml b/data_model/clusters/LevelControl.xml index 5cacf7e89a5162..fa6cbe397a672a 100644 --- a/data_model/clusters/LevelControl.xml +++ b/data_model/clusters/LevelControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/clusters/LocalizationTimeFormat.xml b/data_model/clusters/LocalizationTimeFormat.xml index fb8ceea3ee17a8..db8b809b0341a9 100644 --- a/data_model/clusters/LocalizationTimeFormat.xml +++ b/data_model/clusters/LocalizationTimeFormat.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/LocalizationUnit.xml b/data_model/clusters/LocalizationUnit.xml index be7ea6a0aa2d78..2c6e1ecbd648e6 100644 --- a/data_model/clusters/LocalizationUnit.xml +++ b/data_model/clusters/LocalizationUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/LowPower.xml b/data_model/clusters/LowPower.xml index 4c228d3154dfa1..cf75cb0c680164 100644 --- a/data_model/clusters/LowPower.xml +++ b/data_model/clusters/LowPower.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/MediaInput.xml b/data_model/clusters/MediaInput.xml index b7d9d2ef017035..a92985ff924a75 100644 --- a/data_model/clusters/MediaInput.xml +++ b/data_model/clusters/MediaInput.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/MediaPlayback.xml b/data_model/clusters/MediaPlayback.xml index e9194b6854c569..03175277dc12c5 100644 --- a/data_model/clusters/MediaPlayback.xml +++ b/data_model/clusters/MediaPlayback.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Messages.xml b/data_model/clusters/Messages.xml index 61f21bef9c95f3..402310c4b92eea 100644 --- a/data_model/clusters/Messages.xml +++ b/data_model/clusters/Messages.xml @@ -96,7 +96,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/MicrowaveOvenControl.xml b/data_model/clusters/MicrowaveOvenControl.xml index 27f31dcba966b7..ecc9d23b143d4b 100644 --- a/data_model/clusters/MicrowaveOvenControl.xml +++ b/data_model/clusters/MicrowaveOvenControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/ModeBase.xml b/data_model/clusters/ModeBase.xml index 2a11f85d343b39..dcd6cf1c448028 100644 --- a/data_model/clusters/ModeBase.xml +++ b/data_model/clusters/ModeBase.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/clusters/Mode_DeviceEnergyManagement.xml b/data_model/clusters/Mode_DeviceEnergyManagement.xml index 592c7d4290a342..e167e8649650ba 100644 --- a/data_model/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/clusters/Mode_DeviceEnergyManagement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_Dishwasher.xml b/data_model/clusters/Mode_Dishwasher.xml index 4ff6e78714f648..40a19828d44ebb 100644 --- a/data_model/clusters/Mode_Dishwasher.xml +++ b/data_model/clusters/Mode_Dishwasher.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_EVSE.xml b/data_model/clusters/Mode_EVSE.xml index de88cb3717c8bf..27a1adcfcd5a2a 100644 --- a/data_model/clusters/Mode_EVSE.xml +++ b/data_model/clusters/Mode_EVSE.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_LaundryWasher.xml b/data_model/clusters/Mode_LaundryWasher.xml index c59b2c3fef9051..5d3cce891790e1 100644 --- a/data_model/clusters/Mode_LaundryWasher.xml +++ b/data_model/clusters/Mode_LaundryWasher.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_MicrowaveOven.xml b/data_model/clusters/Mode_MicrowaveOven.xml index 6e8a129444b9fd..6f1e8ed895f489 100644 --- a/data_model/clusters/Mode_MicrowaveOven.xml +++ b/data_model/clusters/Mode_MicrowaveOven.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_Oven.xml b/data_model/clusters/Mode_Oven.xml index f6c7111bb844cd..9c596e01467418 100644 --- a/data_model/clusters/Mode_Oven.xml +++ b/data_model/clusters/Mode_Oven.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_RVCClean.xml b/data_model/clusters/Mode_RVCClean.xml index 0738d20c0c23dd..eed508072f6460 100644 --- a/data_model/clusters/Mode_RVCClean.xml +++ b/data_model/clusters/Mode_RVCClean.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_RVCRun.xml b/data_model/clusters/Mode_RVCRun.xml index b5811a0a6cfe05..314afe1be2a984 100644 --- a/data_model/clusters/Mode_RVCRun.xml +++ b/data_model/clusters/Mode_RVCRun.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Mode_Refrigerator.xml b/data_model/clusters/Mode_Refrigerator.xml index d51e30b68d1320..b4550283daf9e5 100644 --- a/data_model/clusters/Mode_Refrigerator.xml +++ b/data_model/clusters/Mode_Refrigerator.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/NetworkCommissioningCluster.xml b/data_model/clusters/NetworkCommissioningCluster.xml index f9810212a79659..855947e5dda349 100644 --- a/data_model/clusters/NetworkCommissioningCluster.xml +++ b/data_model/clusters/NetworkCommissioningCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/NetworkIdentityManagement.xml b/data_model/clusters/NetworkIdentityManagement.xml deleted file mode 100644 index 20e264277a4330..00000000000000 --- a/data_model/clusters/NetworkIdentityManagement.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/OTAProvider.xml b/data_model/clusters/OTAProvider.xml index baf3996d3b911f..2a5be10961f02c 100644 --- a/data_model/clusters/OTAProvider.xml +++ b/data_model/clusters/OTAProvider.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/OTARequestor.xml b/data_model/clusters/OTARequestor.xml index 592e900ff6720b..f6a5ff0365abed 100644 --- a/data_model/clusters/OTARequestor.xml +++ b/data_model/clusters/OTARequestor.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/OTASoftwareUpdate.xml b/data_model/clusters/OTASoftwareUpdate.xml deleted file mode 100644 index 16389bd7fe9b67..00000000000000 --- a/data_model/clusters/OTASoftwareUpdate.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/OccupancySensing.xml b/data_model/clusters/OccupancySensing.xml index 9479f2041d6c6b..48756121d24769 100644 --- a/data_model/clusters/OccupancySensing.xml +++ b/data_model/clusters/OccupancySensing.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/OnOff.xml b/data_model/clusters/OnOff.xml index 0b1e32af50cddb..9366985e5ce35e 100644 --- a/data_model/clusters/OnOff.xml +++ b/data_model/clusters/OnOff.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/OperationalCredentialCluster.xml b/data_model/clusters/OperationalCredentialCluster.xml index 1a2becd5c478a2..2aa070f96b2573 100644 --- a/data_model/clusters/OperationalCredentialCluster.xml +++ b/data_model/clusters/OperationalCredentialCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/OperationalState.xml b/data_model/clusters/OperationalState.xml index 98990eac3ded4d..3648a8c81ec8f4 100644 --- a/data_model/clusters/OperationalState.xml +++ b/data_model/clusters/OperationalState.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/OperationalState_Oven.xml b/data_model/clusters/OperationalState_Oven.xml index c44ac37b7ccac9..fbcc634330faa7 100644 --- a/data_model/clusters/OperationalState_Oven.xml +++ b/data_model/clusters/OperationalState_Oven.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/OperationalState_RVC.xml b/data_model/clusters/OperationalState_RVC.xml index 7e37a6b5f6f01b..f33791fcf86407 100644 --- a/data_model/clusters/OperationalState_RVC.xml +++ b/data_model/clusters/OperationalState_RVC.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/PowerSourceCluster.xml b/data_model/clusters/PowerSourceCluster.xml index 28a9154116ed7c..1c01cc548bfdee 100644 --- a/data_model/clusters/PowerSourceCluster.xml +++ b/data_model/clusters/PowerSourceCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/PowerSourceConfigurationCluster.xml b/data_model/clusters/PowerSourceConfigurationCluster.xml index 11e3bd47dd9186..6a47ce1b54cdbd 100644 --- a/data_model/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/clusters/PowerSourceConfigurationCluster.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/PowerTopology.xml b/data_model/clusters/PowerTopology.xml index dac690fdcc465d..4ebdda614a4aec 100644 --- a/data_model/clusters/PowerTopology.xml +++ b/data_model/clusters/PowerTopology.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/PressureMeasurement.xml b/data_model/clusters/PressureMeasurement.xml index d9c4a4584404fe..a46e911253941f 100644 --- a/data_model/clusters/PressureMeasurement.xml +++ b/data_model/clusters/PressureMeasurement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/WiFiNetworkManagement.xml b/data_model/clusters/ProxyConfiguration-Cluster.xml similarity index 75% rename from data_model/clusters/WiFiNetworkManagement.xml rename to data_model/clusters/ProxyConfiguration-Cluster.xml index 1a3fceec2747d3..8ad566ec8527b2 100644 --- a/data_model/clusters/WiFiNetworkManagement.xml +++ b/data_model/clusters/ProxyConfiguration-Cluster.xml @@ -1,6 +1,6 @@ - + - + - + + + + + + + + + + + + + + + + - - - + + + + - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/ThreadBorderRouterDiagnostics.xml b/data_model/clusters/ProxyDiscovery-Cluster.xml similarity index 73% rename from data_model/clusters/ThreadBorderRouterDiagnostics.xml rename to data_model/clusters/ProxyDiscovery-Cluster.xml index 5527c486a0cc51..6fa4a9eb6f3a06 100644 --- a/data_model/clusters/ThreadBorderRouterDiagnostics.xml +++ b/data_model/clusters/ProxyDiscovery-Cluster.xml @@ -1,6 +1,6 @@ - + - + - + - - - - - + + - - - - - + + + + + + + + + + - - - - - + + - - - - - + + + + + + + + + + diff --git a/data_model/clusters/PumpConfigurationControl.xml b/data_model/clusters/PumpConfigurationControl.xml index cfd2971a395ecb..79fafe659c95e2 100644 --- a/data_model/clusters/PumpConfigurationControl.xml +++ b/data_model/clusters/PumpConfigurationControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/RefrigeratorAlarm.xml b/data_model/clusters/RefrigeratorAlarm.xml index caad94da1f6fad..a3a75011813cd1 100644 --- a/data_model/clusters/RefrigeratorAlarm.xml +++ b/data_model/clusters/RefrigeratorAlarm.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: short --> - + diff --git a/data_model/clusters/Scenes.xml b/data_model/clusters/Scenes.xml index d9c0ee76fe37d2..bf68f8528fa159 100644 --- a/data_model/clusters/Scenes.xml +++ b/data_model/clusters/Scenes.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/SmokeCOAlarm.xml b/data_model/clusters/SmokeCOAlarm.xml index d3d35f13f15f25..25c034ac94082c 100644 --- a/data_model/clusters/SmokeCOAlarm.xml +++ b/data_model/clusters/SmokeCOAlarm.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Switch.xml b/data_model/clusters/Switch.xml index e7170049ac051f..c7b607c637c74c 100644 --- a/data_model/clusters/Switch.xml +++ b/data_model/clusters/Switch.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/TargetNavigator.xml b/data_model/clusters/TargetNavigator.xml index cfb3a0c17a6f99..c5fb59919585c1 100644 --- a/data_model/clusters/TargetNavigator.xml +++ b/data_model/clusters/TargetNavigator.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/TemperatureControl.xml b/data_model/clusters/TemperatureControl.xml index 70fc100d83bbab..3f5fa9c00332d6 100644 --- a/data_model/clusters/TemperatureControl.xml +++ b/data_model/clusters/TemperatureControl.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/TemperatureMeasurement.xml b/data_model/clusters/TemperatureMeasurement.xml index 540af82bcedd18..176fad6b246a60 100644 --- a/data_model/clusters/TemperatureMeasurement.xml +++ b/data_model/clusters/TemperatureMeasurement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/Thermostat.xml b/data_model/clusters/Thermostat.xml index 71a0c48c6a8eb8..75640c697e0478 100644 --- a/data_model/clusters/Thermostat.xml +++ b/data_model/clusters/Thermostat.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/ThermostatUserInterfaceConfiguration.xml b/data_model/clusters/ThermostatUserInterfaceConfiguration.xml index 63fdba001c67a9..b4ecd49f93ae4a 100644 --- a/data_model/clusters/ThermostatUserInterfaceConfiguration.xml +++ b/data_model/clusters/ThermostatUserInterfaceConfiguration.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/clusters/TimeSync.xml b/data_model/clusters/TimeSync.xml index 68e98a1bf427fe..9d4057db8bdb85 100644 --- a/data_model/clusters/TimeSync.xml +++ b/data_model/clusters/TimeSync.xml @@ -58,7 +58,7 @@ Davis, CA 95616, USA :imagesdir: service_device_management/images :xrefstyle: full --> - + diff --git a/data_model/clusters/Mode_WaterHeater.xml b/data_model/clusters/ValidProxies-Cluster.xml similarity index 70% rename from data_model/clusters/Mode_WaterHeater.xml rename to data_model/clusters/ValidProxies-Cluster.xml index 56f1a1e9a66951..b9db8e1762647f 100644 --- a/data_model/clusters/Mode_WaterHeater.xml +++ b/data_model/clusters/ValidProxies-Cluster.xml @@ -1,6 +1,6 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ValveConfigurationControl.xml b/data_model/clusters/ValveConfigurationControl.xml index 548fed7d7357c2..b0f2ec91b0fa95 100644 --- a/data_model/clusters/ValveConfigurationControl.xml +++ b/data_model/clusters/ValveConfigurationControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/WakeOnLAN.xml b/data_model/clusters/WakeOnLAN.xml index deb5af5a75ac7d..4f6e032c084b38 100644 --- a/data_model/clusters/WakeOnLAN.xml +++ b/data_model/clusters/WakeOnLAN.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/WaterHeaterManagement.xml b/data_model/clusters/WaterHeaterManagement.xml deleted file mode 100644 index cc641c8269fb3c..00000000000000 --- a/data_model/clusters/WaterHeaterManagement.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/WiFiPerDeviceCredentials.xml b/data_model/clusters/WiFiPerDeviceCredentials.xml deleted file mode 100644 index 807ea27c64053b..00000000000000 --- a/data_model/clusters/WiFiPerDeviceCredentials.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/WindowCovering.xml b/data_model/clusters/WindowCovering.xml index 7b0afd461fcb96..af59da5a9f72de 100644 --- a/data_model/clusters/WindowCovering.xml +++ b/data_model/clusters/WindowCovering.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + diff --git a/data_model/clusters/bridge-clusters-ActionsCluster.xml b/data_model/clusters/bridge-clusters-ActionsCluster.xml index e02b12e43d64a4..5b9b54429b9429 100644 --- a/data_model/clusters/bridge-clusters-ActionsCluster.xml +++ b/data_model/clusters/bridge-clusters-ActionsCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :sectnums: --> - + diff --git a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index db85cc296b8922..a7c990182a7dde 100644 --- a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml +++ b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :sectnums: --> - + diff --git a/data_model/clusters/cluster_ids.json b/data_model/clusters/cluster_ids.json index be7c9464690ea8..40a46edd00722e 100644 --- a/data_model/clusters/cluster_ids.json +++ b/data_model/clusters/cluster_ids.json @@ -32,6 +32,9 @@ "63": "GroupKeyManagement", "64": "Fixed Label", "65": "User Label", + "66": "ProxyConfiguration", + "67": "ProxyDiscovery", + "68": "ValidProxies", "69": "Boolean State", "70": "ICDManagement", "72": "Oven Cavity Operational State", @@ -60,17 +63,12 @@ "129": "Valve Configuration and Control", "144": "Electrical Power Measurement", "145": "Electrical Energy Measurement", - "148": "Water Heater Management", - "149": "Energy Price", - "150": "Demand Response and Load Control", "151": "Messages", "152": "Device Energy Management", "153": "Energy EVSE", - "154": "Energy Calendar", "155": "Energy Preference", "156": "Power Topology", "157": "Energy EVSE Mode", - "158": "Water Heater Mode", "159": "Device Energy Management Mode", "257": "Door Lock", "258": "Window Covering", @@ -96,8 +94,6 @@ "1069": "PM10 Concentration Measurement", "1070": "Total Volatile Organic Compounds Concentration Measurement", "1071": "Radon Concentration Measurement", - "1104": "Network Identity Management", - "1105": "Wi", "1283": "Wake on LAN", "1284": "Channel", "1285": "Target Navigator", diff --git a/data_model/clusters/energy_management.xml b/data_model/clusters/energy_management.xml deleted file mode 100644 index 93858d1d1b3c89..00000000000000 --- a/data_model/clusters/energy_management.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/network_infrastructure.xml b/data_model/clusters/network_infrastructure.xml deleted file mode 100644 index 8045740d5de0b6..00000000000000 --- a/data_model/clusters/network_infrastructure.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/device_types/BooleanSensor.xml b/data_model/device_types/BooleanSensor.xml deleted file mode 100644 index 185fdc47176813..00000000000000 --- a/data_model/device_types/BooleanSensor.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/ColorDimmerSwitch.xml b/data_model/device_types/ColorDimmerSwitch.xml index e391700918e1c4..190ab6c7fc8b7e 100644 --- a/data_model/device_types/ColorDimmerSwitch.xml +++ b/data_model/device_types/ColorDimmerSwitch.xml @@ -80,7 +80,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/ColorTemperatureLight.xml b/data_model/device_types/ColorTemperatureLight.xml index e782dd24f58f4f..4f7cf64a9fd0a2 100644 --- a/data_model/device_types/ColorTemperatureLight.xml +++ b/data_model/device_types/ColorTemperatureLight.xml @@ -107,10 +107,16 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/device_types/ControlBridge.xml b/data_model/device_types/ControlBridge.xml index 27e00f69403728..04ff66db808cc9 100644 --- a/data_model/device_types/ControlBridge.xml +++ b/data_model/device_types/ControlBridge.xml @@ -80,7 +80,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/DimmableLight.xml b/data_model/device_types/DimmableLight.xml index ec66b81a610451..059a0802f77906 100644 --- a/data_model/device_types/DimmableLight.xml +++ b/data_model/device_types/DimmableLight.xml @@ -106,10 +106,16 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/device_types/DimmablePlug-InUnit.xml b/data_model/device_types/DimmablePlug-InUnit.xml index bbd043912ab6d7..4d344bfc9fb89c 100644 --- a/data_model/device_types/DimmablePlug-InUnit.xml +++ b/data_model/device_types/DimmablePlug-InUnit.xml @@ -107,10 +107,16 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/device_types/DimmerSwitch.xml b/data_model/device_types/DimmerSwitch.xml index 008e54eee8efc3..0ad9f23638349a 100644 --- a/data_model/device_types/DimmerSwitch.xml +++ b/data_model/device_types/DimmerSwitch.xml @@ -80,7 +80,10 @@ Davis, CA 95616, USA - + + + + \ No newline at end of file diff --git a/data_model/device_types/DoorLockController.xml b/data_model/device_types/DoorLockController.xml index 30342b95a126bd..4d031a37be1eec 100644 --- a/data_model/device_types/DoorLockController.xml +++ b/data_model/device_types/DoorLockController.xml @@ -68,7 +68,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/EnergyTariff.xml b/data_model/device_types/EnergyTariff.xml deleted file mode 100644 index bf27554ff281db..00000000000000 --- a/data_model/device_types/EnergyTariff.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/EnergyTariffCalendar.xml b/data_model/device_types/EnergyTariffCalendar.xml deleted file mode 100644 index ee3a6b9347db38..00000000000000 --- a/data_model/device_types/EnergyTariffCalendar.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/ExtendedColorLight.xml b/data_model/device_types/ExtendedColorLight.xml index 75988addc3f8cd..b4057d6b5bc997 100644 --- a/data_model/device_types/ExtendedColorLight.xml +++ b/data_model/device_types/ExtendedColorLight.xml @@ -107,10 +107,16 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/device_types/HeatingCoolingUnit.xml b/data_model/device_types/HeatingCoolingUnit.xml deleted file mode 100644 index 39fbb766111b31..00000000000000 --- a/data_model/device_types/HeatingCoolingUnit.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/NetworkInfraIntro-CommonRequirements.xml b/data_model/device_types/NetworkInfraIntro-CommonRequirements.xml deleted file mode 100644 index 454dc857f0b8db..00000000000000 --- a/data_model/device_types/NetworkInfraIntro-CommonRequirements.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/device_types/NetworkInfraIntro-Introduction.xml b/data_model/device_types/NetworkInfraIntro-Introduction.xml deleted file mode 100644 index e5bc56b1f095ac..00000000000000 --- a/data_model/device_types/NetworkInfraIntro-Introduction.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/device_types/NetworkInfraIntro.xml b/data_model/device_types/NetworkInfraIntro.xml deleted file mode 100644 index 22d91b6f459c6d..00000000000000 --- a/data_model/device_types/NetworkInfraIntro.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/device_types/NetworkInfraManager.xml b/data_model/device_types/NetworkInfraManager.xml deleted file mode 100644 index 67c3ee49f75f92..00000000000000 --- a/data_model/device_types/NetworkInfraManager.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/OnOffLight.xml b/data_model/device_types/OnOffLight.xml index fe98ac6b6d7028..f71c0bf77fa42c 100644 --- a/data_model/device_types/OnOffLight.xml +++ b/data_model/device_types/OnOffLight.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + @@ -106,10 +106,16 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/device_types/OnOffLightSwitch.xml b/data_model/device_types/OnOffLightSwitch.xml index 9896264d5b9e4f..d6ac7f79520d26 100644 --- a/data_model/device_types/OnOffLightSwitch.xml +++ b/data_model/device_types/OnOffLightSwitch.xml @@ -77,7 +77,10 @@ Davis, CA 95616, USA - + + + + \ No newline at end of file diff --git a/data_model/device_types/OnOffPlug-inUnit.xml b/data_model/device_types/OnOffPlug-inUnit.xml index dbcb7f7e739629..3be1ed0f9eb13d 100644 --- a/data_model/device_types/OnOffPlug-inUnit.xml +++ b/data_model/device_types/OnOffPlug-inUnit.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + @@ -106,10 +106,16 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/device_types/OnOffSensor.xml b/data_model/device_types/OnOffSensor.xml index cdd59585119fa2..935a438fb0bbef 100644 --- a/data_model/device_types/OnOffSensor.xml +++ b/data_model/device_types/OnOffSensor.xml @@ -80,7 +80,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/Pump.xml b/data_model/device_types/Pump.xml index f8c0ce92b1229d..461725136abaec 100644 --- a/data_model/device_types/Pump.xml +++ b/data_model/device_types/Pump.xml @@ -77,7 +77,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/PumpController.xml b/data_model/device_types/PumpController.xml index 3b27f35737197b..3dcb36899ec908 100644 --- a/data_model/device_types/PumpController.xml +++ b/data_model/device_types/PumpController.xml @@ -82,7 +82,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/RoomAirConditioner.xml b/data_model/device_types/RoomAirConditioner.xml index 7f3acd50eb2c91..305a893dabc0fe 100644 --- a/data_model/device_types/RoomAirConditioner.xml +++ b/data_model/device_types/RoomAirConditioner.xml @@ -78,7 +78,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/Thermostat.xml b/data_model/device_types/Thermostat.xml index 16c0efe75620a0..49ba4b6779f084 100644 --- a/data_model/device_types/Thermostat.xml +++ b/data_model/device_types/Thermostat.xml @@ -95,7 +95,10 @@ Davis, CA 95616, USA - + + + + diff --git a/data_model/device_types/ThreadBorderRouter.xml b/data_model/device_types/ThreadBorderRouter.xml deleted file mode 100644 index a0aee3bfeb0433..00000000000000 --- a/data_model/device_types/ThreadBorderRouter.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/ThreePhasePowerSource.xml b/data_model/device_types/ThreePhasePowerSource.xml deleted file mode 100644 index 726af1a16c10a4..00000000000000 --- a/data_model/device_types/ThreePhasePowerSource.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/Valve.xml b/data_model/device_types/Valve.xml deleted file mode 100644 index 4ce864b01ab246..00000000000000 --- a/data_model/device_types/Valve.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/WaterHeater.xml b/data_model/device_types/WaterHeater.xml deleted file mode 100644 index eeebfee95ea300..00000000000000 --- a/data_model/device_types/WaterHeater.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/WindowCovering.xml b/data_model/device_types/WindowCovering.xml index e647e8aa005959..a2d54453b7337f 100644 --- a/data_model/device_types/WindowCovering.xml +++ b/data_model/device_types/WindowCovering.xml @@ -77,6 +77,7 @@ Davis, CA 95616, USA + diff --git a/data_model/device_types/WindowCoveringController.xml b/data_model/device_types/WindowCoveringController.xml index 406953630947ea..c48f327754c599 100644 --- a/data_model/device_types/WindowCoveringController.xml +++ b/data_model/device_types/WindowCoveringController.xml @@ -80,6 +80,7 @@ Davis, CA 95616, USA + diff --git a/data_model/spec_sha b/data_model/spec_sha index cb39a57acee19b..274f0d55122714 100644 --- a/data_model/spec_sha +++ b/data_model/spec_sha @@ -1 +1 @@ -5cf986ac3980bb2b658bae7bf13df8aeec021999 +ab9cf4653d40fe9193bbc7fe9febf74c08bf7dfa diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md index 97f0f76b3b0436..10833e0c0c1ed7 100644 --- a/docs/QUICK_START.md +++ b/docs/QUICK_START.md @@ -10,7 +10,7 @@ and platforms. |
Controller / Admin
|
Node
| Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [**chip-tool**](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) (Linux / Mac)
Includes docs for all the cluster commands supported
| **all-clusters-app**
  • [M5Stack](https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/esp32/README.md) (ESP)
  • [Linux](https://github.com/project-chip/connectedhomeip/tree/master/examples/all-clusters-app/linux) simulation | Use the command line tool on a laptop to pair with and control an embedded Wi-Fi platform. This demo supports the “all-clusters-app”, so it provides the basic onoff light test and more. | -| [**chip-device-ctrl.py**](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) | **all-clusters-app**
  • [M5Stack](https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/esp32/README.md) (ESP)
  • [Linux](https://github.com/project-chip/connectedhomeip/tree/master/examples/all-clusters-app/linux) simulation | Same as above, but uses the pychip tool as Controller Node. | +| [**chip-repl**](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) | **all-clusters-app**
  • [M5Stack](https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/esp32/README.md) (ESP)
  • [Linux](https://github.com/project-chip/connectedhomeip/tree/master/examples/all-clusters-app/linux) simulation | Same as above, but uses the Python CHIP REPL as Controller Node. | ## Thread Nodes diff --git a/docs/getting_started/first_example.md b/docs/getting_started/first_example.md new file mode 100644 index 00000000000000..4aba0d4e480204 --- /dev/null +++ b/docs/getting_started/first_example.md @@ -0,0 +1,123 @@ +# An SDK example + +The SDK provides a number of example devices and controllers that can be used to +familiarize yourself with the SDK and the Matter ecosystem. + +## Example Devices + +The example devices (occasionally referred to as "apps") are located in the +[examples](../../examples/) directory. The examples often implement one +particular device type. Some have implementations for various platforms. + +The linux platform examples are provided as examples, and are used in the CI. +These can be used for preliminary testing. + +The all-clusters-app is used by the QA team for testing. This app implements +nearly all the available clusters and does not conform to a specific device +type. This app is not a good starting place for product development. + +## Example Controllers + +The SDK has two example controllers that can be used to interact with devices +for testing. + +[chip-tool](../../examples/chip-tool/) is a C++ command line controller with an +interactive shell. More information on chip-tool can be found in the +[chip-tool guide](../guides/chip_tool_guide.md). + +[chip-repl](../../src/controller/python/chip-repl.py) is a shell for the python +controller. The chip-repl is part of the python controller framework, often used +for testing. More information about the python controller can be found in the +[python testing](../testing/python.md) documentation. + +## Building your first demo app (lighting) + +The examples directory contains a set of apps using an example device +composition \.zap file. For more information about device composition and zap, +see [ZAP documentation](./zap.md). + +This quick start guide will walk you through + +- Building an app (lighting app) for the host platform +- Interacting with the app using chip\-tool \(controller\) + +### Building the lighting app + +- Install prerequisites from docs/guides/BUILDING\.md +- Run bootstrap or activate to install all the required tools etc. + - `. scripts/bootstrap.sh` \- run this first\, or if builds fail + - `. scripts/activate.sh` \- faster\, use if you’ve already bootstrapped + and are just starting a new terminal + +The build system we use is Ninja / GN. You can use a standard gn gen / ninja to +build as normal, or use the scripts to build specific variants. More information +about the build system can be found at [BUILDING.md](../guides/BUILDING.md). The +official quickstart guide for the build system is located ag +https://gn.googlesource.com/gn/+/master/docs/quick_start.md and a full reference +can be found at https://gn.googlesource.com/gn/+/main/docs/reference.md. + +To build with the scripts, use scripts/build/build_examples\.py - +`scripts/build/build_examples.py targets` - +`scripts/build/build_examples.py --target build` - builds to +`out//` + +Scripts can be used to build both the lighting app and chip tool + +- Lighting app \(device\) + - `./scripts/build/build_examples.py --target linux-x64-light-no-ble build` + - This will build an executable to + `./out/linux-x64-light-no-ble/chip-lighting-app` + +* NOTE that the host name (linux-x64 here) may be different on different + systems ex. darwin + +- chip-tool (controller) + - `./scripts/build/build_examples.py --target linux-x64-chip-tool build` + - This will build an executable to `./out/linux-x64-chip-tool/chip-tool` + +### Building / Interacting with Matter Examples + +The first thing you need to do is to commission the device. First start up the +app in one terminal. By default it will start up with the default discriminator +(3840) and passcode (20202021) and save its non-volatile information in a KVS in +/temp/chip_kvs. You can change these, and multiple other options on the command +line. For a full description, use the `--help` command. + +Start the lighting app in one terminal using + +`./out/linux-x64-light-no-ble/chip-lighting-app` + +The lighting app will print out all its setup information. You can get the setup +codes, discriminator and passcode from the logs. + +Open a new terminal to use chip tool. Commission the device using: + +`./out/linux-x64-chip-tool/chip-tool pairing code 0x12344321 MT:-24J0AFN00KA0648G0` + +NOTE: pairing is the old name for commissioning. 0x12344321 is the node ID you +want to assign to the node. 0x12344321 is the default for testing. +MT:-24J0AFN00KA0648G0 is the QR code for a device with the default discriminator +and passcode. If you have changed these, the code will be different. + +#### Basic device interactions - Sending a command + +`./chip-tool onoff on 0x12344321 1` + +where: + +- onoff is the cluster name +- on is the command name +- 0x12344321 is the node ID you used for commissioning +- 1 is the endpoint + +#### Basic device interactions - Reading an attribute + +`./chip-tool onoff read on-off 0x12344321 1` + +where: + +- onoff is the cluster name +- read is the desired action +- on is the attribute name +- 0x12344321 is the node ID you used for commissioning +- 1 is the endpoint diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index b961701cc98bc8..cca67e19b0c8fc 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -11,6 +11,7 @@ The following docs are a brief introduction to SDK development. ``` +- [Running your first example](./first_example.md) - [SDK Basics](./SDKBasics.md) - [ZAP](./zap.md) - [Discover from a host computer](./discovery_from_a_host_computer.md) diff --git a/docs/guides/python_chip_controller_advanced_usage.md b/docs/guides/python_chip_controller_advanced_usage.md index c3d3f55ddc5095..2eee5472fdda23 100644 --- a/docs/guides/python_chip_controller_advanced_usage.md +++ b/docs/guides/python_chip_controller_advanced_usage.md @@ -7,8 +7,9 @@ tool or Matter accessories on Linux.
    -- [Bluetooth LE virtualization on Linux](#bluetooth-le-virtualization-on-linux) -- [Debugging with gdb](#debugging-with-gdb) +- [Using Python CHIP Controller advanced features](#using-python-chip-controller-advanced-features) + - [Bluetooth LE virtualization on Linux](#bluetooth-le-virtualization-on-linux) + - [Debugging with gdb](#debugging-with-gdb)
    @@ -62,38 +63,38 @@ interfaces working as Bluetooth LE central and peripheral, respectively. TX bytes:3488 acl:95 sco:0 commands:110 errors:0 ``` -4. Run the Python CHIP Controller with Bluetooth LE adapter defined from a +4. Run the Python CHIP Controller REPL with Bluetooth LE adapter defined from a command line: - For example, add `--bluetooth-adapter=hci2` to use the virtual interface - `hci2` listed above. + For example, add `--ble-adapter=2` to use the virtual interface `hci2` + listed above. ``` - chip-device-ctrl --bluetooth-adapter=hci2 + chip-repl --ble-adapter=2 ```
    ## Debugging with gdb -You can run the chip-device-ctrl under GDB for debugging, however, since the -Matter core support library is a dynamic library, you cannot read the symbols -unless it is fully loaded. +You can run the chip-repl under GDB for debugging, however, since the Matter SDK +library is a dynamic library, you cannot read the symbols unless it is fully +loaded. The following block is a example debug session using GDB: ``` # GDB cannot run scripts directly -# so you need to run Python3 with the path of device controller -# Here, we use the feature from bash to get the path of chip-device-ctrl without typing it. -$ gdb --args python3 `which chip-device-ctrl` -GNU gdb (Ubuntu 10.1-2ubuntu2) 10.1.90.20210411-git -Copyright (C) 2021 Free Software Foundation, Inc. +# so you need to run Python3 with the path of device controller REPL +# Here, we use the feature from bash to get the path of chip-repl without typing it. +$ gdb --args python3 `which chip-repl` +GNU gdb (GDB) 14.2 +Copyright (C) 2023 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. -This GDB was configured as "aarch64-linux-gnu". +This GDB was configured as "x86_64-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . @@ -103,6 +104,12 @@ Find the GDB manual and other documentation resources online at: For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from python3... + +This GDB supports auto-downloading debuginfo from the following URLs: + +Enable debuginfod for this session? (y or [n]) n +Debuginfod has been disabled. +To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit. (No debugging symbols found in python3) (gdb) ``` @@ -119,38 +126,68 @@ library, let run the Matter device controller first. ``` (gdb) run -Starting program: /usr/bin/python3 /home/ubuntu/.local/bin/chip-device-ctrl +Starting program: /home/sag/projects/project-chip/connectedhomeip/out/venv/bin/python3 /home/sag/projects/project-chip/connectedhomeip/out/venv/bin/chip-repl [Thread debugging using libthread_db enabled] -Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1". -CHIP:DIS: Init admin pairing table with server storage. -CHIP:IN: local node id is 0x000000000001b669 -CHIP:DL: MDNS failed to join multicast group on wpan0 for address type IPv4: Inet Error 1016 (0x000003F8): Address not found -CHIP:ZCL: Using ZAP configuration... -CHIP:ZCL: deactivate report event -CHIP:CTL: Getting operational keys -CHIP:CTL: Generating operational certificate for the controller -CHIP:CTL: Getting root certificate for the controller from the issuer -CHIP:CTL: Generating credentials -CHIP:CTL: Loaded credentials successfully -CHIP:DL: Platform main loop started. -Chip Device Controller Shell +Using host libthread_db library "/usr/lib/libthread_db.so.1". +Python 3.11.9 (main, Apr 29 2024, 11:59:58) [GCC 13.2.1 20240417] +Type 'copyright', 'credits' or 'license' for more information +IPython 8.24.0 -- An enhanced Interactive Python. Type '?' for help. +[1716395111.775747][364405:364405] CHIP:CTL: Setting attestation nonce to random value +[1716395111.776196][364405:364405] CHIP:CTL: Setting CSR nonce to random value +InitBLE 0[1716395111.776809][364405:364405] CHIP:DL: writing settings to file (/tmp/chip_counters.ini-T7hX27) +[1716395111.776854][364405:364405] CHIP:DL: renamed tmp file to file (/tmp/chip_counters.ini) +[1716395111.776860][364405:364405] CHIP:DL: NVS set: chip-counters/reboot-count = 9 (0x9) +[1716395111.777261][364405:364405] CHIP:DL: Got Ethernet interface: eno2 +[1716395111.777555][364405:364405] CHIP:DL: Found the primary Ethernet interface:eno2 +[1716395111.777868][364405:364405] CHIP:DL: Got WiFi interface: wlp7s0 +[1716395111.777877][364405:364405] CHIP:DL: Failed to reset WiFi statistic counts +────────────────────────────────────────────────────────────────────────────────────────────────────────── Matter REPL ────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + + Welcome to the Matter Python REPL! + + For help, please type matterhelp() + + To get more information on a particular object/class, you can pass + that into matterhelp() as well. + + +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +2024-05-22 18:25:11 allenwind PersistentStorage[364405] WARNING Initializing persistent storage from file: /tmp/repl-storage.json +2024-05-22 18:25:11 allenwind PersistentStorage[364405] WARNING Loading configuration from /tmp/repl-storage.json... +2024-05-22 18:25:11 allenwind CertificateAuthorityManager[364405] WARNING Loading certificate authorities from storage... +2024-05-22 18:25:11 allenwind CertificateAuthority[364405] WARNING New CertificateAuthority at index 1 +2024-05-22 18:25:11 allenwind CertificateAuthority[364405] WARNING Loading fabric admins from storage... +2024-05-22 18:25:11 allenwind FabricAdmin[364405] WARNING New FabricAdmin: FabricId: 0x0000000000000001, VendorId = 0xFFF1 +2024-05-22 18:25:11 allenwind FabricAdmin[364405] WARNING Allocating new controller with CaIndex: 1, FabricId: 0x0000000000000001, NodeId: 0x000000000001B669, CatTags: [] + + +The following objects have been created: + certificateAuthorityManager: Manages a list of CertificateAuthority instances. + caList: The list of CertificateAuthority instances. + caList: A specific FabricAdmin object at index m for the nth CertificateAuthority instance. -chip-device-ctrl > + +Default CHIP Device Controller (NodeId: 112233): has been initialized to manage caList[0].adminList[0] (FabricId = 1), and is available as devCtrl + +In [1]: ``` -The prompt `chip-device-ctrl >` indicates that the Matter core library is loaded -by Python, you can browse the symbols in the Matter core library, setting -breakpoints on functions and many other functions provided by GDB. +The prompt `In [1]:` indicates that the Matter SDK library has been loaded and +initialized by the Python Controller REPL, you can browse the symbols in the +Matter core library, setting breakpoints on functions and many other functions +provided by GDB. -You can use `Ctrl-C` to send SIGINT to the controller anytime you want so you -can set breakpoints. +You can use `Ctrl-Z` to send `SIGTSTP` to the Python 3 REPL process anytime you +want so you can set breakpoints (unfortunately Ctrl+C seems to be captured by +the REPL). -> (`Ctrl-C` pressed here.) +In [1]: (`Ctrl-Z` pressed here.) ``` -Thread 1 "python3" received signal SIGINT, Interrupt. -0x0000fffff7db79ec in __GI___select (nfds=, readfds=0xffffffffe760, writefds=0x0, exceptfds=0x0, timeout=) at ../sysdeps/unix/sysv/linux/select.c:49 -49 ../sysdeps/unix/sysv/linux/select.c: No such file or directory. +Thread 1 "python3" received signal SIGTSTP, Stopped (user). +0x00007ffff7650ceb in kill () from /usr/lib/libc.so.6 (gdb) ``` @@ -159,40 +196,27 @@ command in GDB (`b` for short) ``` (gdb) b DeviceCommissioner::PairDevice -Breakpoint 1 at 0xfffff5b0f6b4 (2 locations) +Breakpoint 1 at 0x7fffed453943: DeviceCommissioner::PairDevice. (4 locations) (gdb) ``` -Type `continue` (`c` for short) to continue the device controller, you may need -another hit of `Enter` to see the prompt. +Type `signal SIGCONT` to continue the device controller after stopping it with +signal stop, you may need another hit of `Enter` to see the prompt. ``` -(gdb) c -Continuing. - -chip-device-ctrl > +(gdb) signal SIGCONT +Continuing with signal SIGCONT. +In [1]: ``` Let do pairing over IP to see the effect of the breakpoint we just set. ``` -chip-device-ctrl > connect -ip 192.168.50.5 20202021 1 -Device is assigned with nodeid = 1 - -Thread 1 "python3" hit Breakpoint 1, 0x0000fffff5b0f6b4 in chip::Controller::DeviceCommissioner::PairDevice(unsigned long, chip::RendezvousParameters&)@plt () - from /home/ubuntu/.local/lib/python3.9/site-packages/chip/_ChipDeviceCtrl.so -(gdb) -``` - -The `@plt` symbol means it is a symbol used by dynamic library loader, type `c` -(for `continue`) and it will break on the real function. +In [1]: devCtrl.CommissionWithCode("MT:-24J0AFN00KA0648G00", 1234) -``` -(gdb) c -Continuing. - -Thread 1 "python3" hit Breakpoint 1, chip::Controller::DeviceCommissioner::PairDevice (this=0xd28540, remoteDeviceId=1, params=...) at ../../src/controller/CHIPDeviceController.cpp:827 -827 { +Thread 5 "python3" hit Breakpoint 1.1, chip::Controller::DeviceCommissioner::PairDevice (this=0x7fffd8003a90, remoteDeviceId=1234, setUpCode=0x7ffff453d490 "MT:-24J0AFN00KA0648G00", params=..., + discoveryType=chip::Controller::DiscoveryType::kAll, resolutionData=...) at ../../src/controller/CHIPDeviceController.cpp:646 +646 { (gdb) ``` @@ -201,46 +225,44 @@ then you can use `bt` (for `backtrace`) to see the backtrace of the call stack. ``` (gdb) bt -#0 chip::Controller::DeviceCommissioner::PairDevice(unsigned long, chip::RendezvousParameters&) (this=0xd28540, remoteDeviceId=1, params=...) - at ../../src/controller/CHIPDeviceController.cpp:827 -#1 0x0000fffff5b3095c in pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner*, char const*, uint32_t, chip::NodeId) - (devCtrl=0xd28540, peerAddrStr=0xfffff467ace0 "192.168.50.5", setupPINCode=20202021, nodeid=1) at ../../src/controller/python/ChipDeviceController-ScriptBinding.cpp:234 -#2 0x0000fffff7639148 in () at /lib/aarch64-linux-gnu/libffi.so.8 -#3 0x0000fffff7638750 in () at /lib/aarch64-linux-gnu/libffi.so.8 -#4 0x0000fffff7665a44 in () at /usr/lib/python3.9/lib-dynload/_ctypes.cpython-39-aarch64-linux-gnu.so -#5 0x0000fffff7664c7c in () at /usr/lib/python3.9/lib-dynload/_ctypes.cpython-39-aarch64-linux-gnu.so -#6 0x00000000004a54f0 in _PyObject_MakeTpCall () -#7 0x000000000049cb10 in _PyEval_EvalFrameDefault () -#8 0x0000000000496d1c in () -#9 0x00000000004b1eb0 in _PyFunction_Vectorcall () -#10 0x0000000000498264 in _PyEval_EvalFrameDefault () -#11 0x00000000004b1cb8 in _PyFunction_Vectorcall () -#12 0x0000000000498418 in _PyEval_EvalFrameDefault () -#13 0x0000000000496d1c in () -#14 0x00000000004b1eb0 in _PyFunction_Vectorcall () -#15 0x0000000000498418 in _PyEval_EvalFrameDefault () -#16 0x00000000004b1cb8 in _PyFunction_Vectorcall () -#17 0x00000000004c6bc8 in () -#18 0x0000000000498264 in _PyEval_EvalFrameDefault () -#19 0x00000000004b1cb8 in _PyFunction_Vectorcall () -#20 0x0000000000498418 in _PyEval_EvalFrameDefault () -#21 0x00000000004966f8 in () -#22 0x00000000004b1f18 in _PyFunction_Vectorcall () -#23 0x0000000000498418 in _PyEval_EvalFrameDefault () -#24 0x00000000004b1cb8 in _PyFunction_Vectorcall () -#25 0x0000000000498264 in _PyEval_EvalFrameDefault () -#26 0x00000000004966f8 in () -#27 0x0000000000496490 in _PyEval_EvalCodeWithName () -#28 0x0000000000595b7c in PyEval_EvalCode () -#29 0x00000000005c6a5c in () -#30 0x00000000005c0a70 in () -#31 0x00000000005c69a8 in () -#32 0x00000000005c6148 in PyRun_SimpleFileExFlags () -#33 0x00000000005b60bc in Py_RunMain () -#34 0x0000000000585a08 in Py_BytesMain () -#35 0x0000fffff7d0c9d4 in __libc_start_main (main= - 0x5858fc <_start+60>, argc=2, argv=0xfffffffff498, init=, fini=, rtld_fini=, stack_end=) at ../csu/libc-start.c:332 -#36 0x00000000005858f8 in _start () +(gdb) bt +#0 chip::Controller::DeviceCommissioner::PairDevice + (this=0x7fffd8003a90, remoteDeviceId=1234, setUpCode=0x7fffef2555d0 "MT:-24J0AFN00KA0648G00", params=..., discoveryType=chip::Controller::DiscoveryType::kAll, resolutionData=...) + at ../../src/controller/CHIPDeviceController.cpp:646 +#1 0x00007fffed040825 in pychip_DeviceController_ConnectWithCode (devCtrl=0x7fffd8003a90, onboardingPayload=0x7fffef2555d0 "MT:-24J0AFN00KA0648G00", nodeid=1234, discoveryType=2 '\002') + at ../../src/controller/python/ChipDeviceController-ScriptBinding.cpp:395 +#2 0x00007ffff6ad5596 in ??? () at /usr/lib/libffi.so.8 +#3 0x00007ffff6ad200e in ??? () at /usr/lib/libffi.so.8 +#4 0x00007ffff6ad4bd3 in ffi_call () at /usr/lib/libffi.so.8 +#5 0x00007ffff6aeaffc in ??? () at /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so +#6 0x00007ffff6aeb4b4 in ??? () at /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so +#7 0x00007ffff794a618 in _PyObject_MakeTpCall () at /usr/lib/libpython3.11.so.1.0 +#8 0x00007ffff78f3d03 in _PyEval_EvalFrameDefault () at /usr/lib/libpython3.11.so.1.0 +#9 0x00007ffff7adef90 in ??? () at /usr/lib/libpython3.11.so.1.0 +#10 0x00007ffff79ebc0b in _PyObject_FastCallDictTstate () at /usr/lib/libpython3.11.so.1.0 +#11 0x00007ffff79ebe02 in _PyObject_Call_Prepend () at /usr/lib/libpython3.11.so.1.0 +#12 0x00007ffff79ec114 in ??? () at /usr/lib/libpython3.11.so.1.0 +#13 0x00007ffff794a618 in _PyObject_MakeTpCall () at /usr/lib/libpython3.11.so.1.0 +#14 0x00007ffff78f3d03 in _PyEval_EvalFrameDefault () at /usr/lib/libpython3.11.so.1.0 +#15 0x00007ffff7adef90 in ??? () at /usr/lib/libpython3.11.so.1.0 +#16 0x00007ffff7955b97 in PyObject_Vectorcall () at /usr/lib/libpython3.11.so.1.0 +#17 0x00007ffff6aea174 in ??? () at /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so +#18 0x00007ffff6aea28c in ??? () at /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so +#19 0x00007ffff6ad5152 in ??? () at /usr/lib/libffi.so.8 +#20 0x00007ffff6ad57b8 in ??? () at /usr/lib/libffi.so.8 +#21 0x00007fffed5de848 in chip::DeviceLayer::Internal::GenericPlatformManagerImpl::_DispatchEvent + (this=0x7fffed88dc90 , event=0x7fffe6fffe30) at ../../src/include/platform/internal/GenericPlatformManagerImpl.ipp:304 +#22 0x00007fffed5dd90d in chip::DeviceLayer::PlatformManager::DispatchEvent (this=0x7fffed88dc80 , event=0x7fffe6fffe30) at ../../src/include/platform/PlatformManager.h:503 +#23 0x00007fffed5df45b in chip::DeviceLayer::Internal::GenericPlatformManagerImpl_POSIX::ProcessDeviceEvents + (this=0x7fffed88dc90 ) at ../../src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp:185 +#24 0x00007fffed5dee64 in chip::DeviceLayer::Internal::GenericPlatformManagerImpl_POSIX::_RunEventLoop (this=0x7fffed88dc90 ) +--Type for more, q to quit, c to continue without paging-- + at ../../src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp:227 +#25 0x00007fffed5dd888 in chip::DeviceLayer::PlatformManager::RunEventLoop (this=0x7fffed88dc80 ) at ../../src/include/platform/PlatformManager.h:403 +#26 0x00007fffed5df3fe in chip::DeviceLayer::Internal::GenericPlatformManagerImpl_POSIX::EventLoopTaskMain (arg=0x7fffed88dc90 ) + at ../../src/include/platform/internal/GenericPlatformManagerImpl_POSIX.ipp:256 +#27 0x00007ffff76a6ded in ??? () at /usr/lib/libc.so.6 +#28 0x00007ffff772a0dc in ??? () at /usr/lib/libc.so.6 (gdb) ``` diff --git a/docs/guides/python_chip_controller_building.md b/docs/guides/python_chip_controller_building.md index c940f2c92575e7..8a7acc884ab2fa 100644 --- a/docs/guides/python_chip_controller_building.md +++ b/docs/guides/python_chip_controller_building.md @@ -1,25 +1,20 @@ -# Deprecation notice - -chip-device-ctrl is no longer maintained and should not be used. - -Matter-repl is the current python controller implementation. - # Working with Python CHIP Controller -The Python CHIP Controller is a tool that allows to commission a Matter device -into the network and to communicate with it using the Zigbee Cluster Library -(ZCL) messages. +The Python CHIP controller is a library that allows to create a Matter fabric +and commission Matter devices with it. -> The chip-device-ctrl tool will be deprecated, and will be replaced by -> chip-repl. Continue reading to see how to do the same thing with chip-repl. +The `chip-repl` is a REPl which sets up a Python CHIP Controller and allows to +explore the Python CHIP Controller API and communicate with devices from the +command line.
    - [Source files](#source-files) -- [Building Android CHIPTool](#building-and-installing) -- [Running the tool](#running-the-tool) -- [Using Python CHIP Controller for Matter accessory testing](#using-python-chip-controller-for-matter-accessory-testing) -- [List of commands](#list-of-commands) +- [Building Python CHIP Controller](#building-and-installing) +- [Running the CHIP REPL](#running-the-chip-repl) +- [Using Python CHIP Controller REPL for Matter accessory testing](#using-python-chip-controller-repl-for-matter-accessory-testing) +- [Example usage of the Python CHIP Controller REPL](#example-usage-of-the-python-chip-controller-repl) +- [Explore Clusters, Attributes and Commands](#explore-clusters-attributes-and-commands)
    @@ -85,35 +80,31 @@ To build and run the Python CHIP controller: scripts/build_python.sh -m platform -i separate ``` - > Note: To get more details about available build configurations, run the + > Note: This builds the Python CHIP Controller along with the CHIP REPL as + > Python wheels and installs it into a separate Python virtual environment. + > To get more details about available build configurations, run the > following command: `scripts/build_python.sh --help`
    -## Running the tool +## Running the CHIP REPL -1. Activate the Python virtual environment: +1. Activate the Python virtual environment with the Python CHIP Controller + installed: ``` source out/python_env/bin/activate ``` -2. Run the Python CHIP controller with root privileges, which is required to - obtain access to the Bluetooth interface: - - ``` - sudo out/python_env/bin/chip-device-ctrl - ``` - - You can also select the Bluetooth LE interface using command line argument: +2. Run the CHIP REPL to explore the API of the Python CHIP controller: ``` - sudo out/python_env/bin/chip-device-ctrl --bluetooth-adapter=hci2 + chip-repl ```
    -## Using Python CHIP Controller for Matter accessory testing +## Using Python CHIP Controller REPL for Matter accessory testing This section describes how to use Python CHIP controller to test the Matter accessory. Below steps depend on the application clusters that you implemented @@ -135,13 +126,14 @@ require physical trigger, for example pushing a button. Follow the documentation of the Matter accessory example to learn how Bluetooth LE advertising is enabled for the given example. -### Step 3: Discover Matter accessory device over Bluetooth LE +### Step 3: Discover commissionable Matter accessory device -An uncommissioned accessory device advertises over Bluetooth LE. Run the -following command to scan all advertised Matter devices: +An uncommissioned accessory device advertises over Bluetooth LE or via mDNS if +already on the network. Run the following command to scan all advertised Matter +devices: ``` -chip-device-ctrl > ble-scan +devCtrl.DiscoverCommissionableNodes() ``` ### Step 4: Set network pairing credentials @@ -177,11 +169,12 @@ network interface, such as Thread or Wi-Fi. datasets directly from the Thread Border Router, you might also use a different out-of-band method. -2. Set the previously obtained Active Operational Dataset as a hex-encoded value - using the following command: +2. Set the previously obtained Active Operational Dataset as a byte array using + the following command: ``` - chip-device-ctrl > set-pairing-thread-credential 0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8 + thread_dataset = bytes.fromhex("0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8") + devCtrl.SetThreadOperationalDataset(thread_dataset) ``` #### Setting Wi-Fi network credentials @@ -190,11 +183,9 @@ Assuming your Wi-Fi SSID is _TESTSSID_, and your Wi-Fi password is _P455W4RD_, set the credentials to the controller by executing the following command: ``` -chip-device-ctrl > set-pairing-wifi-credential TESTSSID P455W4RD +devCtrl.SetWiFiCredentials(, ) ``` -**REPL Command**: `devCtrl.SetWiFiCredentials(, )` - ### Step 5: Commission the Matter accessory device over Bluetooth LE The controller uses a 12-bit value called **discriminator** to discern between @@ -222,16 +213,26 @@ with the following assumptions for the Matter accessory device: - The temporary Node ID is _1234_ ``` -chip-device-ctrl > connect -ble 3840 20202021 1234 +devCtrl.ConnectBLE(3840, 20202021, 1234) ``` -**REPL Command:** -`devCtrl.ConnectBLE(, , )` - You can skip the last parameter, the Node ID, in the command. If you skip it, the controller will assign it randomly. In that case, note down the Node ID, because it is required later in the configuration process. +It is also possible to use the QR setup code instead. It typically is shown on +the terminal of the device as well. For example: + +``` +CHIP:SVR: SetupQRCode: [MT:-24J0AFN00KA0648G00] +``` + +Use the following command to commission the device with the QR code: + +``` +devCtrl.CommissionWithCode("MT:-24J0AFN00KA0648G00", 1234) +``` + After connecting the device over Bluetooth LE, the controller will go through the following stages: @@ -255,429 +256,155 @@ the following stages: finished and the Python CHIP controller is now using only the IPv6 traffic to reach the device. -### Step 6: Control application ZCL clusters. +### Step 6: Control application clusters. For the light bulb example, execute the following command to toggle the LED state: ``` -chip-device-ctrl > zcl OnOff Toggle 1234 1 0 +await devCtrl.SendCommand(1234, 1, Clusters.OnOff.Commands.Toggle()) ``` -**REPL Command:** -`await devCtrl.SendCommand(1234, 1, Clusters.OnOff.Commands.Toggle())` - To change the brightness of the LED, use the following command, with the level value somewhere between 0 and 255. ``` -chip-device-ctrl > zcl LevelControl MoveToLevel 1234 1 0 level=50 +commandToSend = LevelControl.Commands.MoveToLevel(level=50, transitionTime=Null, optionsMask=0, optionsOverride=0) +await devCtrl.SendCommand(1234, 1, commandToSend) ``` -**REPL Command:** -`await devCtrl.SendCommand(1234, 1, LevelControl.Commands.MoveToLevel(level=50, transitionTime=Null, optionsMask=0, optionsOverride=0))` - ### Step 7: Read basic information out of the accessory. Every Matter accessory device supports a Basic Information Cluster, which maintains collection of attributes that a controller can obtain from a device, -such as the vendor name, the product name, or software version. Use `zclread` -command to read those values from the device: +such as the vendor name, the product name, or software version. Use +`ReadAttribute()` command to read those values from the device: ``` -chip-device-ctrl > zclread BasicInformation VendorName 1234 1 0 -chip-device-ctrl > zclread BasicInformation ProductName 1234 1 0 -chip-device-ctrl > zclread BasicInformation SoftwareVersion 1234 1 0 +attributes = [ + (0, Clusters.BasicInformation.Attributes.VendorName), + (0, Clusters.BasicInformation.Attributes.ProductName), + (0, Clusters.BasicInformation.Attributes.SoftwareVersion), +] +await devCtrl.ReadAttribute(1234, attributes) ``` -**REPL Command:** -`await devCtrl.ReadAttribute(1234, [(1, Clusters.BasicInformation.Attributes.VendorName)])` - -> Use the `zcl ? BasicInformation` command to list all available commands for -> Basic Information Cluster. -> > In REPL, you can type `Clusters.BasicInformation.Attributes.` and then use the > TAB key.
    -## List of commands - -### `ble-adapter-print` +## Example usage of the Python CHIP Controller REPL -> BLE adapter operations is not yet supported in REPL +These section covers a few useful commands of the Python CHIP Controller along +with examples demonstrating how they can be called from the REPL. -Print the available Bluetooth adapters on device. Takes no arguments: - -``` -chip-device-ctrl > ble-adapter-print -2021-03-04 16:09:40,930 ChipBLEMgr INFO AdapterName: hci0 AdapterAddress: 00:AA:01:00:00:23 -``` +The +[CHIP Device Controller API documentation offer](https://project-chip.github.io/connectedhomeip-doc/testing/ChipDeviceCtrlAPI.html#chip-chipdevicectrl) +the full list of available commands. -### `ble-debug-log` - -> BLE adapter operations is not yet supported in REPL - -Enable the Bluetooth LE debug logs. - -``` -chip-device-ctrl > ble-debug-log 1 -``` - -### `ble-scan [-t ] [identifier]` - -> BLE adapter operations is not yet supported in REPL - -Start a scan action to search for valid CHIP devices over Bluetooth LE (for at -most _timeout_ seconds). Stop when the device is matching the identifier or the -counter times out. - -``` -chip-device-ctrl > ble-scan -2021-05-29 22:28:05,461 ChipBLEMgr INFO scanning started -2021-05-29 22:28:07,206 ChipBLEMgr INFO Name = ChipLight -2021-05-29 22:28:07,206 ChipBLEMgr INFO ID = f016e23d-0d00-35d5-93e7-588acdbc7e54 -2021-05-29 22:28:07,207 ChipBLEMgr INFO RSSI = -79 -2021-05-29 22:28:07,207 ChipBLEMgr INFO Address = E0:4D:84:3C:BB:C3 -2021-05-29 22:28:07,209 ChipBLEMgr INFO Pairing State = 0 -2021-05-29 22:28:07,209 ChipBLEMgr INFO Discriminator = 3840 -2021-05-29 22:28:07,209 ChipBLEMgr INFO Vendor Id = 9050 -2021-05-29 22:28:07,209 ChipBLEMgr INFO Product Id = 20044 -2021-05-29 22:28:07,210 ChipBLEMgr INFO Adv UUID = 0000fff6-0000-1000-8000-00805f9b34fb -2021-05-29 22:28:07,210 ChipBLEMgr INFO Adv Data = 00000f5a234c4e -2021-05-29 22:28:07,210 ChipBLEMgr INFO -2021-05-29 22:28:16,246 ChipBLEMgr INFO scanning stopped -``` - -### `set-pairing-thread-credential ` +### `SetThreadOperationalDataset()` Provides the controller with Thread network credentials that will be used in the device commissioning procedure to configure the device with a Thread interface. ``` -chip-device-ctrl > set-pairing-thread-credential 0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8 +thread_dataset = bytes.fromhex("0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8") +devCtrl.SetThreadOperationalDataset(thread_dataset) ``` -**REPL Commands:** -`devCtrl.SetThreadOperationalDataset(bytes.FromHex("0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8"))` - -### `set-pairing-wifi-credential ` +### `SetWiFiCredentials(: str, : str)` Provides the controller with Wi-Fi network credentials that will be used in the device commissioning procedure to configure the device with a Wi-Fi interface. ``` -chip-device-ctrl > set-pairing-wifi-credential TESTSSID P455W4RD +devCtrl.SetWiFiCredentials('TESTSSID', 'P455W4RD') ``` -**REPL Commands:** `devCtrl.SetWiFiCredentials('TESTSSID', 'P455W4RD')` - -### `connect -ip
    []` - -Do key exchange and establish a secure session between controller and device -using IP transport. - -The Node ID will be used by controller to distinguish multiple devices. This -does not match the spec and will be removed later. The nodeid will not be -persisted by controller / device. - -If no nodeid given, a random Node ID will be used. - -**REPL Commands:** -`devCtrl.CommissionIP(b'', , )` - -### `connect -ble []` - -Do key exchange and establish a secure session between controller and device -using Bluetooth LE transport. - -The Node ID will be used by controller to distinguish multiple devices. This -does not match the spec and will be removed later. The nodeid will not be -persisted by controller / device. - -If no nodeid given, a random Node ID will be used. - -**REPL Commands:** -`devCtrl.ConnectBLE(, , )` +### `CommissionWithCode(: str, : int, : DiscoveryType)` -### `close-session ` +Commission with the given nodeid from the setupPayload. setupPayload may be a QR +or the manual setup code. -If case there exists an open session (PASE or CASE) to the device with a given -Node ID, mark it as expired. - -**REPL Commands:** `devCtrl.CloseSession()` - -### `discover` - -> To be implemented in REPL - -Discover available Matter accessory devices: - -``` -chip-device-ctrl > discover -all ``` - -### `resolve ` - -> To be implemented in REPL - -Resolve DNS-SD name corresponding with the given Node ID and update address of -the node in the device controller: - -``` -chip-device-ctrl > resolve 1234 +devCtrl.CommissionWithCode("MT:-24J0AFN00KA0648G00", 1234) ``` -### `setup-payload generate [-v ] [-p ] [-cf ] [-dc ] [-dv ] [-ps ]` - -> To be implemented in REPL +### `SendCommand(: int, : int, Clusters..Commands.())` -Print the generated Onboarding Payload Contents in human-readable (Manual -Pairing Code) and machine-readable (QR Code) format: +Send a Matter command to the device. For example: +```python +commandToSend = Clusters.LevelControl.Commands.MoveWithOnOff(moveMode=1, rate=2, optionsMask=0, optionsOverride=0) +await devCtrl.SendCommand(1234, 1, commandToSend) ``` -chip-device-ctrl > setup-payload generate -v 9050 -p 65279 -cf 0 -dc 2 -dv 2976 -ps 34567890 -Manual pairing code: [26318621095] -SetupQRCode: [MT:YNJV7VSC00CMVH7SR00] -``` - -### `setup-payload parse-manual ` - -> To be implemented in REPL - -Print the commissioning information encoded in the Manual Pairing Code: - -``` -chip-device-ctrl > setup-payload parse-manual 34970112332 -Version: 0 -VendorID: 0 -ProductID: 0 -CommissioningFlow: 0 -RendezvousInformation: 0 -Discriminator: 3840 -SetUpPINCode: 20202021 -``` - -### `setup-payload parse-qr ` -> To be implemented in REPL - -Print the commissioning information encoded in the QR Code payload: +To see available arguments just create a command object without argument: ``` -chip-device-ctrl > setup-payload parse-qr "VP:vendorpayload%MT:W0GU2OTB00KA0648G00" -Version: 0 -VendorID: 9050 -ProductID: 20043 -CommissioningFlow: 0 -RendezvousInformation: 2 [BLE] -Discriminator: 3840 -SetUpPINCode: 20202021 +Clusters.LevelControl.Commands.MoveWithOnOff() ``` -### `zcl [arguments]` - -Send a ZCL command to the device. For example: +Shows which arguments are available: ``` -chip-device-ctrl > zcl LevelControl MoveWithOnOff 12344321 1 0 moveMode=1 rate=2 +MoveWithOnOff( +│ moveMode=0, +│ rate=Null, +│ optionsMask=0, +│ optionsOverride=0 +) ``` -**Format of arguments** +### `ReadAttribute(: int, [(: int, Clusters..Attributes.)])` -For any integer and char string (null terminated) types, just use `key=value`, -for example: `rate=2`, `string=123`, `string_2="123 456"` - -For byte string type, use `key=encoding:value`, currently, we support `str` and -`hex` encoding, the `str` encoding will encode a NULL terminated string. For -example, `networkId=hex:0123456789abcdef` (for -`[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]`), `ssid=str:Test` (for -`['T', 'e', 's', 't', 0x00]`). - -For boolean type, use `key=True` or `key=False`. - -**REPL Commands:** +Read the value of an attribute. For example: ```python -# await devCtrl.SendCommand(, , Clusters..Commands.()) -# e.g. -await devCtrl.SendCommand(12344321, 1, Clusters.LevelControl.Commands.MoveWithOnOff(moveMode=1, rate=2, optionsMask=0, optionsOverride=0)) -``` - -### `zcl ?` - -List available clusters: - -``` -chip-device-ctrl > zcl ? -AccountLogin -ApplicationBasic -ApplicationLauncher -AudioOutput -BarrierControl -BasicInformation -Binding -BridgedDeviceBasicInformation -ColorControl -ContentLaunch -Descriptor -DoorLock -EthernetNetworkDiagnostics -FixedLabel -GeneralCommissioning -GeneralDiagnostics -GroupKeyManagement -Groups -Identify -KeypadInput -LevelControl -LowPower -MediaInput -MediaPlayback -NetworkCommissioning -OnOff -OperationalCredentials -PumpConfigurationAndControl -RelativeHumidityMeasurement -ScenesManagement -SoftwareDiagnostics -Switch -Channel -TargetNavigator -TemperatureMeasurement -TestCluster -Thermostat -TrustedRootCertificates -WakeOnLan -WindowCovering -``` - -**REPL Commands** - -Type `Clusters.` and hit TAB - -### `zcl ? ` - -List available commands in cluster. For example, for _Basic Information_ -cluster: - -``` -chip-device-ctrl > zcl ? BasicInformation -DataModelRevision -VendorName -VendorID -ProductName -ProductID -UserLabel -Location -HardwareVersion -HardwareVersionString -SoftwareVersion -SoftwareVersionString -ManufacturingDate -PartNumber -ProductURL -ProductLabel -SerialNumber -LocalConfigDisabled -ClusterRevision -``` - -**REPL Commands** - -Type `Clusters.(cluster name).Commands.` and hit TAB - -### `zclread [arguments]` - -Read the value of ZCL attribute. For example: - -``` -chip-device-ctrl > zclread BasicInformation VendorName 1234 1 0 -``` - -**REPL Commands** - -```python -# devCtrl.ReadAttribute(, [(, Clusters..Attributes.)]) -# e.g. -await devCtrl.ReadAttribute(1234, [(1, Clusters.BasicInformation.Attributes.VendorName)]) -``` - -### `zclwrite ` - -Write the value to a ZCL attribute. For example: - -``` -chip-device-ctrl > zclwrite TestCluster Int8u 1 1 0 1 -chip-device-ctrl > zclwrite TestCluster Boolean 1 1 0 True -chip-device-ctrl > zclwrite TestCluster OctetString 1 1 0 str:123123 -chip-device-ctrl > zclwrite TestCluster CharString 1 1 0 233233 +await devCtrl.ReadAttribute(1234, [(0, Clusters.BasicInformation.Attributes.VendorName)]) ``` -Note: The format of the value is the same as the format of argument values for -ZCL cluster commands. +### `WriteAttribute(: int, [(: int, Clusters..Attributes.(value=))])` -**REPL Commands** +Write a value to an attribute. For example: ```python -# devCtrl.WriteAttribute(, [(, Clusters..Attributes.(value=))]) -# e.g. -await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.Int8u(value=1))]) -await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.Boolean(value=True))]) -await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.OctetString(value=b'123123\x00'))]) -await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.CharString(value='233233'))]) +await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.Int8u(value=1))]) +await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.Boolean(value=True))]) +await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.OctetString(value=b'123123\x00'))]) +await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.CharString(value='233233'))]) ``` -### `zclsubscribe ` +### `ReadAttribute(: int, [(: int, Clusters..Attributes.)], reportInterval=(: int, : int))` -Configure ZCL attribute reporting settings. For example: - -``` -chip-device-ctrl > zclsubscribe OccupancySensing Occupancy 1234 1 10 20 -``` - -**REPL Commands** +Configure Matter attribute reporting settings. For example: ```python -# devCtrl.ReadAttribute(, [(, Clusters..Attributes.)], reportInterval=(, )) -# e.g. -await devCtrl.ReadAttribute(1, [(1, Clusters.OccupancySensing.Attributes.Occupancy)], reportInterval=(10, 20)) +await devCtrl.ReadAttribute(1234, [(1, Clusters.OccupancySensing.Attributes.Occupancy)], reportInterval=(10, 20)) ``` -### `zclsubscribe -shutdown ` - -Shutdown an existing attribute subscription. +To shutdown an existing attribute subscription use the `Shutdown()` function on +the returned subscription object: -``` -chip-device-ctrl > zclsubscribe -shutdown 0xdeadbeefcafe +```python +sub = await devCtrl.ReadAttribute(1234, [(1, Clusters.OccupancySensing.Attributes.Occupancy)], reportInterval=(10, 20)) +sub.Shutdown() ``` -The subscription id can be obtained from previous subscription messages: +## Explore Clusters, Attributes and Commands -``` -chip-device-ctrl > zclsubscribe OnOff OnOff 1 1 10 20 -(omitted messages) -[1633922898.965587][1117858:1117866] CHIP:DMG: SubscribeResponse = -[1633922898.965599][1117858:1117866] CHIP:DMG: { -[1633922898.965610][1117858:1117866] CHIP:DMG: SubscriptionId = 0xdeadbeefcafe, -[1633922898.965622][1117858:1117866] CHIP:DMG: MinIntervalFloorSeconds = 0xa, -[1633922898.965633][1117858:1117866] CHIP:DMG: MaxIntervalCeilingSeconds = 0x14, -[1633922898.965644][1117858:1117866] CHIP:DMG: } -[1633922898.965662][1117858:1117866] CHIP:ZCL: SubscribeResponse: -[1633922898.965673][1117858:1117866] CHIP:ZCL: SubscriptionId: 0xdeadbeefcafe -[1633922898.965683][1117858:1117866] CHIP:ZCL: ApplicationIdentifier: 0 -[1633922898.965694][1117858:1117866] CHIP:ZCL: status: EMBER_ZCL_STATUS_SUCCESS (0x00) -[1633922898.965709][1117858:1117866] CHIP:ZCL: attributeValue: false -(omitted messages) -``` +In the Python REPL the Clusters and Attributes are classes. The `Clusters` +module contains all clusters. Tab completion can be used to explore available +clusters, attributes and commands. -The subscription id is `0xdeadbeefcafe` in this case +For example, to get a list of Clusters, type `Clusters.` and hit tab. Continue +to hit tab to cycle through the available Clusters. Pressing return will select +the Cluster. -**REPL Commands** +To explore Attributes, use the same technique but with the Attributes sub-class +of the Clusters class, for example, type `Clusters.(cluster name).Attributes.` +and hit tab. -```python -# SubscriptionTransaction.Shutdown() -# e.g. -sub = await devCtrl.ReadAttribute(1, [(1, Clusters.OccupancySensing.Attributes.Occupancy)], reportInterval=(10, 20)) -sub.Shutdown() -``` +The same is true for Commands, use the Commands sub-class. type +`Clusters.(cluster name).Commands.` and hit tab. diff --git a/docs/spec_clusters.md b/docs/spec_clusters.md index 02715424bbb5d8..976b9f85e42c19 100644 --- a/docs/spec_clusters.md +++ b/docs/spec_clusters.md @@ -36,6 +36,9 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |63 |0x003F |GroupKeyManagement | |64 |0x0040 |Fixed Label | |65 |0x0041 |User Label | +|66 |0x0042 |ProxyConfiguration | +|67 |0x0043 |ProxyDiscovery | +|68 |0x0044 |ValidProxies | |69 |0x0045 |Boolean State | |70 |0x0046 |ICDManagement | |72 |0x0048 |Oven Cavity Operational State | @@ -64,17 +67,12 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |129 |0x0081 |Valve Configuration and Control | |144 |0x0090 |Electrical Power Measurement | |145 |0x0091 |Electrical Energy Measurement | -|148 |0x0094 |Water Heater Management | -|149 |0x0095 |Energy Price | -|150 |0x0096 |Demand Response and Load Control | |151 |0x0097 |Messages | |152 |0x0098 |Device Energy Management | |153 |0x0099 |Energy EVSE | -|154 |0x009A |Energy Calendar | |155 |0x009B |Energy Preference | |156 |0x009C |Power Topology | |157 |0x009D |Energy EVSE Mode | -|158 |0x009E |Water Heater Mode | |159 |0x009F |Device Energy Management Mode | |257 |0x0101 |Door Lock | |258 |0x0102 |Window Covering | @@ -100,8 +98,6 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |1069 |0x042D |PM10 Concentration Measurement | |1070 |0x042E |Total Volatile Organic Compounds Concentration Measurement| |1071 |0x042F |Radon Concentration Measurement | -|1104 |0x0450 |Network Identity Management | -|1105 |0x0451 |Wi | |1283 |0x0503 |Wake on LAN | |1284 |0x0504 |Channel | |1285 |0x0505 |Target Navigator | diff --git a/docs/testing/python.md b/docs/testing/python.md index 1f946a38333ecd..51f734ace3ab15 100644 --- a/docs/testing/python.md +++ b/docs/testing/python.md @@ -480,16 +480,64 @@ second_ctrl = fa.new_fabric_admin.NewController(nodeId=node_id) # Running tests locally -You can run the python script as-is for local testing against an already-running -DUT +## Setup -`./scripts/tests/run_python_test.py` is a convenient script to fire up an -example DUT on the host, with factory reset support +The scripts require the python wheel to be compiled and installed before +running. To compile and install the wheel, do the following: -`./scripts/tests/run_python_test.py --factoryreset --app --app-args "whatever" --script --script-args "whatever"` +First activate the matter environment using either + +``` +. ./scripts/bootstrap.sh +``` + +or + +``` +. ./scripts/activate.sh +``` + +bootstrap.sh should be used for for the first setup, activate.sh may be used for +subsequent setups as it is faster. + +Next build the python wheels and create / activate a venv (called `py` here, but +any name may be used) + +``` +./scripts/build_python.sh -i py +source py/bin/activate +``` + +## Running tests -Note that devices must be commissioned by the python test harness to run tests. -chip-tool and the python test harness DO NOT share a fabric. +- Note that devices must be commissioned by the python test harness to run + tests. chip-tool and the python test harness DO NOT share a fabric. + +Once the wheel is installed, you can run the python script as a normal python +file for local testing against an already-running DUT. This can be an example +app on the host computer (running in a different terminal), or a separate device +that will be commissioned either over BLE or WiFi. + +For example, to run the TC-ACE-1.2 tests against an un-commissioned DUT: + +``` +python3 src/python_testing/TC_ACE_1_2.py --commissioning-method on-network --qr-code MT:-24J0AFN00KA0648G00 +``` + +Some tests require additional arguments (ex. PIXITs or configuration variables +for the CI). These arguments can be passed as sets of key-value pairs using the +`---arg` command line arguments. For example + +``` +--int-arg PIXIT.ACE.APPENDPOINT:1 PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff PIXIT.ACE.APPATTRIBUTE:OnOff +``` + +## Local host app testing + +`./scripts/tests/run_python_test.py` is a convenient script that starts an +example DUT on the host and includes factory reset support + +`./scripts/tests/run_python_test.py --factoryreset --app --app-args "whatever" --script --script-args "whatever"` # Running tests in CI diff --git a/docs/testing/yaml.md b/docs/testing/yaml.md index 107c761fbef71e..e7353d09697e30 100644 --- a/docs/testing/yaml.md +++ b/docs/testing/yaml.md @@ -279,6 +279,17 @@ function can be use. See [TestEqualities](https://github.com/project-chip/connectedhomeip/blob/master/src/app/tests/suites/TestEqualities.yaml) for an example of how to use this pseudo-cluster. +#### Setting step timeouts + +The timeout argument can be used for each individual test step to set the time +the runner will wait for a test step to complete before reporting a failure. + +Note that this timeout is different than the subscription report timeout and the +subscription report timeout is not currently adjustable in YAML. + +There several other options for configuring test steps as shown in the +[YAML schema](./yaml_schema.md) document. + ## Running YAML tests YAML scripts are parsed and run using a python-based runner program that parses @@ -304,6 +315,24 @@ There are several options for running tests locally. Because the YAML runner uses python, it is necessary to compile and install the chip python package before using any YAML runner script. +First activate the matter environment using either + +``` +. ./scripts/bootstrap.sh +``` + +or + +``` +. ./scripts/activate.sh +``` + +bootstrap.sh should be used for for the first setup, activate.sh may be used for +subsequent setups as it is faster. + +Next build the python wheels and create a venv (called `py` here, but any name +may be used) + ``` ./scripts/build_python.sh -i py source py/bin/activate diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index eedfb7190e2f27..e23b2508a5ee54 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -112,6 +112,8 @@ Generally regenerate using one of: | 1069 | 0x42D | Pm10ConcentrationMeasurement | | 1070 | 0x42E | TotalVolatileOrganicCompoundsConcentrationMeasurement | | 1071 | 0x42F | RadonConcentrationMeasurement | +| 1105 | 0x451 | WiFiNetworkManagement | +| 1107 | 0x453 | ThreadNetworkDirectory | | 1283 | 0x503 | WakeOnLan | | 1284 | 0x504 | Channel | | 1285 | 0x505 | TargetNavigator | diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 2c54d75c7e6b06..804d1eae5fbd32 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -2609,7 +2609,7 @@ cluster BooleanState = 69 { } /** This cluster supports remotely monitoring and, where supported, changing the operational state of an Oven. */ -provisional cluster OvenCavityOperationalState = 72 { +cluster OvenCavityOperationalState = 72 { revision 1; enum ErrorStateEnum : enum8 { @@ -2675,7 +2675,7 @@ provisional cluster OvenCavityOperationalState = 72 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster OvenMode = 73 { +cluster OvenMode = 73 { revision 1; enum ModeTag : enum16 { @@ -3334,7 +3334,7 @@ cluster DishwasherAlarm = 93 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster MicrowaveOvenMode = 94 { +cluster MicrowaveOvenMode = 94 { revision 1; enum ModeTag : enum16 { @@ -3752,7 +3752,7 @@ cluster ActivatedCarbonFilterMonitoring = 114 { } /** This cluster is used to configure a boolean sensor. */ -provisional cluster BooleanStateConfiguration = 128 { +cluster BooleanStateConfiguration = 128 { revision 1; bitmap AlarmModeBitmap : bitmap8 { @@ -3810,7 +3810,7 @@ provisional cluster BooleanStateConfiguration = 128 { } /** This cluster is used to configure a valve. */ -provisional cluster ValveConfigurationAndControl = 129 { +cluster ValveConfigurationAndControl = 129 { revision 1; enum StatusCodeEnum : enum8 { @@ -3876,7 +3876,7 @@ provisional cluster ValveConfigurationAndControl = 129 { } /** This cluster provides a mechanism for querying data about electrical power as measured by the server. */ -provisional cluster ElectricalPowerMeasurement = 144 { +cluster ElectricalPowerMeasurement = 144 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -3981,7 +3981,7 @@ provisional cluster ElectricalPowerMeasurement = 144 { } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ -provisional cluster ElectricalEnergyMeasurement = 145 { +cluster ElectricalEnergyMeasurement = 145 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -4278,7 +4278,7 @@ provisional cluster DeviceEnergyManagement = 152 { } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ -provisional cluster EnergyEvse = 153 { +cluster EnergyEvse = 153 { revision 2; enum EnergyTransferStoppedReasonEnum : enum8 { @@ -4490,7 +4490,7 @@ provisional cluster EnergyPreference = 155 { } /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ -provisional cluster PowerTopology = 156 { +cluster PowerTopology = 156 { revision 1; bitmap Feature : bitmap32 { @@ -4511,7 +4511,7 @@ provisional cluster PowerTopology = 156 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster EnergyEvseMode = 157 { +cluster EnergyEvseMode = 157 { revision 1; enum ModeTag : enum16 { diff --git a/examples/android/CHIPTool/app/build.gradle b/examples/android/CHIPTool/app/build.gradle index 368930259ea66a..4502b7f7a18897 100644 --- a/examples/android/CHIPTool/app/build.gradle +++ b/examples/android/CHIPTool/app/build.gradle @@ -43,9 +43,6 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } - packagingOptions { - exclude 'META-INF/main.kotlin_module' - } buildFeatures { viewBinding = true diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt index f5a451f240f0e3..2b2078dde5e688 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt @@ -238,6 +238,16 @@ class CHIPToolActivity : } } + override fun onResume() { + super.onResume() + ChipClient.startDnssd(this) + } + + override fun onPause() { + ChipClient.stopDnssd(this) + super.onPause() + } + companion object { private const val TAG = "CHIPToolActivity" private const val ADDRESS_COMMISSIONING_FRAGMENT_TAG = "address_commissioning_fragment" diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt index bee06caf2b50d6..de8e598ee0ed9c 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/ChipClient.kt @@ -114,6 +114,21 @@ object ChipClient { icdCheckInCallback = callback } + fun startDnssd(context: Context) { + if (!this::chipDeviceController.isInitialized) { + getDeviceController(context) + } else { + chipDeviceController.startDnssd() + } + } + + fun stopDnssd(context: Context) { + if (!this::chipDeviceController.isInitialized) { + getDeviceController(context) + } + chipDeviceController.stopDnssd() + } + /** * Wrapper around [ChipDeviceController.getConnectedDevicePointer] to return the value directly. */ diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt index 43eeb2b892c51c..81693c94d355cf 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt @@ -230,6 +230,10 @@ class AddressUpdateFragment : ICDCheckInCallback, Fragment() { val runnable = object : Runnable { override fun run() { + if (!isAdded) { + Log.d(TAG, "Fragment is not attached") + return + } if (icdTotalRemainStayActiveTimeMs >= ICD_PROGRESS_STEP) { icdDeviceRemainStayActiveTimeMs -= ICD_PROGRESS_STEP icdTotalRemainStayActiveTimeMs -= ICD_PROGRESS_STEP diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt index ea131c0e726bcb..411f51eae3de73 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt @@ -61,7 +61,6 @@ class CHIPDeviceDetailsFragment : Fragment() { binding.discriminatorEd.setText(deviceInfo.discriminator.toString()) binding.serialNumberEd.setText(deviceInfo.serialNumber) binding.discoveryCapabilitiesTv.text = "${deviceInfo.discoveryCapabilities}" - if (deviceInfo.optionalQrCodeInfoMap.isEmpty()) { binding.vendorTagsLabelTv.visibility = View.GONE binding.vendorTagsContainer.visibility = View.GONE diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt index 28cfaa11f162c6..b2afd8a9985474 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt @@ -24,6 +24,7 @@ import kotlinx.parcelize.Parcelize import matter.onboardingpayload.DiscoveryCapability import matter.onboardingpayload.OnboardingPayload import matter.onboardingpayload.OnboardingPayloadException +import matter.onboardingpayload.OptionalQRCodeInfoType /** Class to hold the CHIP device information. */ @Parcelize @@ -57,6 +58,13 @@ data class CHIPDeviceInfo( if (serialNumber.isNotEmpty()) { onboardingPayload.addSerialNumber(serialNumber) } + optionalQrCodeInfoMap.forEach { (_, info) -> + if (info.type == OptionalQRCodeInfoType.TYPE_STRING && info.data != null) { + onboardingPayload.addOptionalVendorData(info.tag, info.data) + } else { + onboardingPayload.addOptionalVendorData(info.tag, info.intDataValue) + } + } return onboardingPayload } @@ -78,8 +86,8 @@ data class CHIPDeviceInfo( setupPayload.getLongDiscriminatorValue(), setupPayload.setupPinCode, setupPayload.commissioningFlow, - setupPayload.optionalQRCodeInfo.mapValues { (_, info) -> - QrCodeInfo(info.tag, info.type, info.data, info.int32) + setupPayload.getAllOptionalVendorData().associate { info -> + info.tag to QrCodeInfo(info.tag, info.type, info.data, info.int32) }, setupPayload.discoveryCapabilities, setupPayload.hasShortDiscriminator, diff --git a/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml b/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml index 4997681993ca29..a1deab648adc9f 100644 --- a/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml +++ b/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml @@ -151,7 +151,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" - android:layout_below="@id/vendorTagsLabelTv" + android:layout_below="@id/vendorTagsContainer" android:layout_alignParentStart="true" android:textSize="20sp"/> + android:textSize="12sp"/> diff --git a/examples/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp index 3643f5ea1eb02a..a894b5d0150ca6 100644 --- a/examples/bridge-app/linux/main.cpp +++ b/examples/bridge-app/linux/main.cpp @@ -899,13 +899,11 @@ void ApplicationInit() // Setup Mock Devices Light1.SetReachable(true); Light2.SetReachable(true); - Light1.SetChangeCallback(&HandleDeviceOnOffStatusChanged); Light2.SetChangeCallback(&HandleDeviceOnOffStatusChanged); TempSensor1.SetReachable(true); - TempSensor1.SetReachable(true); - + TempSensor2.SetReachable(true); TempSensor1.SetChangeCallback(&HandleDeviceTempSensorStatusChanged); TempSensor2.SetChangeCallback(&HandleDeviceTempSensorStatusChanged); @@ -914,7 +912,6 @@ void ApplicationInit() ActionLight2.SetReachable(true); ActionLight3.SetReachable(true); ActionLight4.SetReachable(true); - ActionLight1.SetChangeCallback(&HandleDeviceOnOffStatusChanged); ActionLight2.SetChangeCallback(&HandleDeviceOnOffStatusChanged); ActionLight3.SetChangeCallback(&HandleDeviceOnOffStatusChanged); @@ -929,7 +926,6 @@ void ApplicationInit() ComposedTempSensor2.SetReachable(true); ComposedPowerSource.SetReachable(true); ComposedPowerSource.SetBatChargeLevel(58); - ComposedTempSensor1.SetChangeCallback(&HandleDeviceTempSensorStatusChanged); ComposedTempSensor2.SetChangeCallback(&HandleDeviceTempSensorStatusChanged); ComposedPowerSource.SetChangeCallback(&HandleDevicePowerSourceStatusChanged); diff --git a/examples/chef/chef.py b/examples/chef/chef.py index 816840f8584a45..6176c6e8c280ac 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -696,11 +696,20 @@ def main() -> int: if options.build_target == "esp32": shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/esp32") if options.enable_ipv4: - shell.run_cmd( - "sed -i 's/CONFIG_DISABLE_IPV4=y/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/g' sdkconfig ") + if sys.platform == "darwin": + shell.run_cmd( + "sed -i '' 's/CONFIG_DISABLE_IPV4=y/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/g' sdkconfig ") + else: + shell.run_cmd( + "sed -i 's/CONFIG_DISABLE_IPV4=y/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/g' sdkconfig ") else: - shell.run_cmd( - "sed -i 's/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/CONFIG_DISABLE_IPV4=y/g' sdkconfig ") + if sys.platform == "darwin": + shell.run_cmd( + "sed -i '' 's/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/CONFIG_DISABLE_IPV4=y/g' sdkconfig ") + else: + shell.run_cmd( + "sed -i 's/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/CONFIG_DISABLE_IPV4=y/g' sdkconfig ") + shell.run_cmd("idf.py build") shell.run_cmd("idf.py build flashing_script") shell.run_cmd( @@ -802,6 +811,7 @@ def main() -> int: 'chip_shell_cmd_server = false', 'chip_build_libshell = true', 'chip_enable_openthread = false', + 'chip_generate_link_map_file = true', 'chip_config_network_layer_ble = false', 'chip_device_project_config_include = ""', 'chip_project_config_include = ""', diff --git a/examples/chef/common/chef-descriptor-namespace.h b/examples/chef/common/chef-descriptor-namespace.h new file mode 100644 index 00000000000000..e7e8e85df5a551 --- /dev/null +++ b/examples/chef/common/chef-descriptor-namespace.h @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces +constexpr const uint8_t kNamespaceCommonLevel = 5; +// Common Number Namespace: 5, tag 0 (Low) +constexpr const uint8_t kTagCommonLow = 0; +// Common Number Namespace: 5, tag 1 (Medium) +constexpr const uint8_t kTagCommonMedium = 1; +// Common Number Namespace: 5, tag 2 (High) +constexpr const uint8_t kTagCommonHigh = 2; + +constexpr const uint8_t kNamespaceCommonNumber = 7; +// Common Number Namespace: 7, tag 0 (Zero) +constexpr const uint8_t kTagCommonZero = 0; +// Common Number Namespace: 7, tag 1 (One) +constexpr const uint8_t kTagCommonOne = 1; +// Common Number Namespace: 7, tag 2 (Two) +constexpr const uint8_t kTagCommonTwo = 2; + +constexpr const uint8_t kNamespacePosition = 8; +// Common Position Namespace: 8, tag: 0 (Left) +constexpr const uint8_t kTagPositionLeft = 0; +// Common Position Namespace: 8, tag: 1 (Right) +constexpr const uint8_t kTagPositionRight = 1; +// Common Position Namespace: 8, tag: 2 (Top) +constexpr const uint8_t kTagPositionTop = 2; +// Common Position Namespace: 8, tag: 3 (Bottom) +constexpr const uint8_t kTagPositionBottom = 3; +// Common Position Namespace: 8, tag: 4 (Middle) +constexpr const uint8_t kTagPositionMiddle = 4; +// Common Position Namespace: 8, tag: 5 (Row) +constexpr const uint8_t kTagPositionRow = 5; +// Common Position Namespace: 8, tag: 6 (Column) +constexpr const uint8_t kTagPositionColumn = 6; diff --git a/examples/chef/common/chef-rpc-actions-worker.cpp b/examples/chef/common/chef-rpc-actions-worker.cpp new file mode 100644 index 00000000000000..98bba768e7f4d8 --- /dev/null +++ b/examples/chef/common/chef-rpc-actions-worker.cpp @@ -0,0 +1,158 @@ +/* + * + * 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 "chef-rpc-actions-worker.h" +#include +#include +#include +#include +#include +#include +#include + +using chip::app::DataModel::Nullable; + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::rpc; + +static std::map gActionsDelegateMap{}; + +ActionsDelegate * RpcFindActionsDelegate(ClusterId clusterId) +{ + if (gActionsDelegateMap.find(clusterId) != gActionsDelegateMap.end()) + { + return gActionsDelegateMap[clusterId]; + } + + return nullptr; +} + +static void RpcActionsTaskCallback(System::Layer * systemLayer, void * data) +{ + ChefRpcActionsWorker * worker = (ChefRpcActionsWorker *) data; + + worker->ProcessActionQueue(); +} + +bool ChefRpcActionsCallback(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, uint32_t actionId, + std::vector args) +{ + ActionTask task(endpointId, clusterId, static_cast(type), delayMs, actionId, args); + + return ChefRpcActionsWorker::Instance().EnqueueAction(task); +} + +bool ChefRpcActionsWorker::EnqueueAction(ActionTask task) +{ + bool kickTimer = false; + + if (queue.empty()) + { + kickTimer = true; // kick timer when the first task is adding to the queue + } + + queue.push(task); + + if (kickTimer) + { + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(task.delayMs), RpcActionsTaskCallback, this); + } + return true; +} + +void ChefRpcActionsWorker::ProcessActionQueue() +{ + // Dequeue the first item + ActionTask task = queue.front(); + queue.pop(); + + ActionsDelegate * delegate = RpcFindActionsDelegate(task.clusterId); + if (nullptr == delegate) + { + ChipLogError(NotSpecified, + "Cannot run action due to not finding delegate: endpointId=%d, clusterId=%04lx, attributeId=%04lx", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId)); + return; + } + + ActionType type = static_cast(task.type); + + switch (type) + { + case ActionType::WRITE_ATTRIBUTE: { + ChipLogProgress(NotSpecified, "Writing Attribute: endpointId=%d, clusterId=%04lx, attributeId=%04lx, args.size=%lu", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.args.size())); + delegate->AttributeWriteHandler(task.endpointId, static_cast(task.actionId), task.args); + } + break; + case ActionType::RUN_COMMAND: { + ChipLogProgress(NotSpecified, "Running Command: endpointId=%d, clusterId=%04lx, commandId=%04lx, args.size=%lu", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.args.size())); + delegate->CommandHandler(task.endpointId, static_cast(task.actionId), task.args); + } + break; + case ActionType::EMIT_EVENT: { + ChipLogProgress(NotSpecified, "Emitting Event: endpointId=%d, clusterId=%04lx, eventIdId=%04lx, args.size=%lu", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.args.size())); + delegate->EventHandler(task.endpointId, static_cast(task.actionId), task.args); + } + break; + default: + break; + } + + if (queue.empty()) + { + // Return due to no more actions in queue + return; + } + + // Run next action + task = queue.front(); + ChipLogProgress(NotSpecified, "StartTimer: endpointId=%d, clusterId=%04lx, eventIdId=%04lx, task.delyMs=%lu", task.endpointId, + static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.delayMs)); + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(task.delayMs), RpcActionsTaskCallback, this); +} + +void ChefRpcActionsWorker::RegisterRpcActionsDelegate(ClusterId clusterId, ActionsDelegate * delegate) +{ + // Register by cluster + if (nullptr == RpcFindActionsDelegate(clusterId)) + { + gActionsDelegateMap[clusterId] = delegate; + return; + } +} + +ChefRpcActionsWorker::ChefRpcActionsWorker() +{ + chip::rpc::SubscribeActions(ChefRpcActionsCallback); +} + +static ChefRpcActionsWorker instance; + +ChefRpcActionsWorker & ChefRpcActionsWorker::Instance() +{ + return instance; +} diff --git a/examples/chef/common/chef-rpc-actions-worker.h b/examples/chef/common/chef-rpc-actions-worker.h new file mode 100644 index 00000000000000..3ca16f4c8a716e --- /dev/null +++ b/examples/chef/common/chef-rpc-actions-worker.h @@ -0,0 +1,79 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "Rpc.h" + +namespace chip { +namespace app { + +class ActionsDelegate +{ +public: + ActionsDelegate(ClusterId clusterId) : mClusterId(clusterId){}; + + virtual ~ActionsDelegate() = default; + + virtual void AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector args) = 0; + virtual void CommandHandler(chip::EndpointId endpointId, chip::CommandId commandId, std::vector args) = 0; + virtual void EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector args) = 0; + +protected: + ClusterId mClusterId; +}; + +struct ActionTask +{ + chip::EndpointId endpointId; + chip::ClusterId clusterId; + chip::rpc::ActionType type; // Aligned with Storage buf + uint32_t delayMs; + uint32_t actionId; + std::vector args; + ActionTask(chip::EndpointId endpoint, chip::ClusterId cluster, chip::rpc::ActionType actionType, uint32_t delay, uint32_t id, + std::vector arg) : + endpointId(endpoint), + clusterId(cluster), type(actionType), delayMs(delay), actionId(id), args(arg){}; + ~ActionTask(){}; +}; + +class ChefRpcActionsWorker +{ +public: + static ChefRpcActionsWorker & Instance(); + + ChefRpcActionsWorker(); + + bool EnqueueAction(ActionTask task); + void ProcessActionQueue(); + void RegisterRpcActionsDelegate(ClusterId clusterId, ActionsDelegate * delegate); + +private: + std::queue queue; +}; + +} // namespace app +} // namespace chip diff --git a/examples/chef/common/clusters/switch/SwitchEventHandler.cpp b/examples/chef/common/clusters/switch/SwitchEventHandler.cpp new file mode 100644 index 00000000000000..dd32e2b907bb5a --- /dev/null +++ b/examples/chef/common/clusters/switch/SwitchEventHandler.cpp @@ -0,0 +1,82 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_SWITCH_SERVER +#include +#include +#include +#include + +#include "SwitchEventHandler.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Switch; +using namespace chip::DeviceLayer; + +void SwitchEventHandler::OnSwitchLatched(EndpointId endpointId, uint8_t newPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); + + Clusters::SwitchServer::Instance().OnSwitchLatch(endpointId, newPosition); +} + +void SwitchEventHandler::OnInitialPress(EndpointId endpointId, uint8_t newPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); + + Clusters::SwitchServer::Instance().OnInitialPress(endpointId, newPosition); +} + +void SwitchEventHandler::OnLongPress(EndpointId endpointId, uint8_t newPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); + + Clusters::SwitchServer::Instance().OnLongPress(endpointId, newPosition); +} + +void SwitchEventHandler::OnShortRelease(EndpointId endpointId, uint8_t previousPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d", __func__, endpointId, previousPosition); + + Clusters::SwitchServer::Instance().OnShortRelease(endpointId, previousPosition); +} + +void SwitchEventHandler::OnLongRelease(EndpointId endpointId, uint8_t previousPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d", __func__, endpointId, previousPosition); + + Clusters::SwitchServer::Instance().OnLongRelease(endpointId, previousPosition); +} + +void SwitchEventHandler::OnMultiPressOngoing(EndpointId endpointId, uint8_t newPosition, uint8_t count) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d, count=%d", __func__, endpointId, newPosition, count); + + Clusters::SwitchServer::Instance().OnMultiPressOngoing(endpointId, newPosition, count); +} + +void SwitchEventHandler::OnMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uint8_t count) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d, count=%d", __func__, endpointId, previousPosition, count); + + Clusters::SwitchServer::Instance().OnMultiPressComplete(endpointId, previousPosition, count); +} +#endif // MATTER_DM_PLUGIN_SWITCH_SERVER diff --git a/examples/chef/common/clusters/switch/SwitchEventHandler.h b/examples/chef/common/clusters/switch/SwitchEventHandler.h new file mode 100644 index 00000000000000..1648e19cc829c5 --- /dev/null +++ b/examples/chef/common/clusters/switch/SwitchEventHandler.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace Switch { + +class SwitchEventHandler +{ +public: + SwitchEventHandler(){}; + + /** + * Should be called when the latching switch is moved to a new position. + */ + void OnSwitchLatched(EndpointId endpointId, uint8_t newPosition); + + /** + * Should be called when the momentary switch starts to be pressed. + */ + void OnInitialPress(EndpointId endpointId, uint8_t newPosition); + + /** + * Should be called when the momentary switch has been pressed for a "long" time. + */ + void OnLongPress(EndpointId endpointId, uint8_t newPosition); + + /** + * Should be called when the momentary switch has been released. + */ + void OnShortRelease(EndpointId endpointId, uint8_t previousPosition); + + /** + * Should be called when the momentary switch has been released after having been pressed for a long time. + */ + void OnLongRelease(EndpointId endpointId, 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 OnMultiPressOngoing(EndpointId endpointId, 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 OnMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uint8_t count); + +private: +}; + +} // namespace Switch +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/chef/common/clusters/switch/SwitchManager.cpp b/examples/chef/common/clusters/switch/SwitchManager.cpp new file mode 100644 index 00000000000000..45d39dd4bce1a4 --- /dev/null +++ b/examples/chef/common/clusters/switch/SwitchManager.cpp @@ -0,0 +1,172 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef MATTER_DM_PLUGIN_SWITCH_SERVER +#include "SwitchEventHandler.h" +#include +#include +#include +#include +#include +#include + +#include "chef-descriptor-namespace.h" +#include "chef-rpc-actions-worker.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Switch; +using namespace chip::DeviceLayer; + +using namespace chip::rpc; +using namespace chip::app; + +class SwitchActionsDelegate : public chip::app::ActionsDelegate +{ +public: + SwitchActionsDelegate(ClusterId clusterId, SwitchEventHandler * eventHandler) : + ActionsDelegate(clusterId), mEventHandler(eventHandler){}; + ~SwitchActionsDelegate() override{}; + + void AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector args) override; + void CommandHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector args) override{}; + void EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector args) override; + +private: + SwitchEventHandler * mEventHandler; +}; + +void SwitchActionsDelegate::AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, + std::vector args) +{ + if (args.empty()) + { + ChipLogError(NotSpecified, "Queue is empty "); + return; + } + + switch (attributeId) + { + case Switch::Attributes::NumberOfPositions::Id: { + uint8_t data = static_cast(args[0]); + app::Clusters::Switch::Attributes::NumberOfPositions::Set(endpointId, data); + } + break; + case Switch::Attributes::CurrentPosition::Id: { + uint8_t data = static_cast(args[0]); + app::Clusters::Switch::Attributes::CurrentPosition::Set(endpointId, data); + } + break; + case Switch::Attributes::MultiPressMax::Id: { + uint8_t data = static_cast(args[0]); + app::Clusters::Switch::Attributes::MultiPressMax::Set(endpointId, data); + } + break; + default: + break; + } +} + +void SwitchActionsDelegate::EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector args) +{ + if (args.empty()) + { + ChipLogError(NotSpecified, "Queue is empty "); + return; + } + switch (eventId) + { + case Events::SwitchLatched::Id: { + uint8_t newPosition = static_cast(args[0]); + mEventHandler->OnSwitchLatched(endpointId, newPosition); + } + break; + case Events::InitialPress::Id: { + uint8_t newPosition = static_cast(args[0]); + mEventHandler->OnInitialPress(endpointId, newPosition); + } + break; + case Events::LongPress::Id: { + uint8_t newPosition = static_cast(args[0]); + mEventHandler->OnLongPress(endpointId, newPosition); + } + break; + case Events::ShortRelease::Id: { + uint8_t previousPosition = static_cast(args[0]); + mEventHandler->OnShortRelease(endpointId, previousPosition); + } + break; + case Events::LongRelease::Id: { + uint8_t previousPosition = static_cast(args[0]); + mEventHandler->OnLongRelease(endpointId, previousPosition); + } + break; + case Events::MultiPressOngoing::Id: { + if (args.size() < 2) + { + ChipLogError(NotSpecified, "MultiPressOngoing has too few arguments"); + return; + } + uint8_t newPosition = static_cast(args[0]); + uint8_t currentNumberOfPressesCounted = static_cast(args[1]); + mEventHandler->OnMultiPressOngoing(endpointId, newPosition, currentNumberOfPressesCounted); + } + break; + case Events::MultiPressComplete::Id: { + if (args.size() < 2) + { + ChipLogError(NotSpecified, "MultiPressComplete has too few arguments"); + return; + } + uint8_t previousPosition = static_cast(args[0]); + uint8_t totalNumberOfPressesCounted = static_cast(args[1]); + mEventHandler->OnMultiPressComplete(endpointId, previousPosition, totalNumberOfPressesCounted); + } + break; + default: + break; + } +}; + +const Clusters::Descriptor::Structs::SemanticTagStruct::Type gLatchingSwitch[] = { + { .namespaceID = kNamespaceCommonLevel, + .tag = kTagCommonLow, + .label = chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("Low", 3)) }) }, + { .namespaceID = kNamespaceCommonLevel, + .tag = kTagCommonMedium, + .label = chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("Medium", 6)) }) }, + { .namespaceID = kNamespaceCommonLevel, + .tag = kTagCommonHigh, + .label = chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("High", 4)) }) } +}; + +static SwitchEventHandler * gSwitchEventHandler = new SwitchEventHandler(); +static SwitchActionsDelegate * gSwitchActionsDelegate = new SwitchActionsDelegate(Clusters::Switch::Id, gSwitchEventHandler); + +void emberAfSwitchClusterInitCallback(EndpointId endpointId) +{ + ChipLogProgress(Zcl, "Chef: emberAfSwitchClusterInitCallback"); + + ChefRpcActionsWorker::Instance().RegisterRpcActionsDelegate(Clusters::Switch::Id, gSwitchActionsDelegate); + SetTagList(/* endpoint= */ 1, Span(gLatchingSwitch)); +} +#endif // MATTER_DM_PLUGIN_SWITCH_SERVER diff --git a/examples/chef/common/stubs.cpp b/examples/chef/common/stubs.cpp index 5756aaa35b7e26..437dfe9e6221be 100644 --- a/examples/chef/common/stubs.cpp +++ b/examples/chef/common/stubs.cpp @@ -236,6 +236,16 @@ void emberAfWakeOnLanClusterInitCallback(EndpointId endpoint) } #endif +void ApplicationInit() +{ + ChipLogProgress(NotSpecified, "Chef Application Init !!!") +} + +void ApplicationShutdown() +{ + ChipLogProgress(NotSpecified, "Chef Application Down !!!") +} + // No-op function, used to force linking this file, // instead of the weak functions from other files extern "C" void chef_include_stubs_impl(void) {} diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter new file mode 100644 index 00000000000000..89319a4b61b4e2 --- /dev/null +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -0,0 +1,1498 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 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; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 1; // NOTE: Default/not specifically set + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute 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 provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute optional char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + 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; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + readonly attribute optional int16u threadVersion = 10; + 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 ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 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; + + request struct RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + 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 TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** 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 1; + + bitmap Feature : bitmap32 { + kLatchingSwitch = 0x1; + kMomentarySwitch = 0x2; + kMomentarySwitchRelease = 0x4; + kMomentarySwitchLongPress = 0x8; + kMomentarySwitchMultiPress = 0x10; + } + + 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 + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 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 OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 0x0001; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command OpenCommissioningWindow; + handle command OpenBasicCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } +} +endpoint 1 { + device type ma_powersource = 17, version 1; + device type ma_genericswitch = 15, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute tagList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster PowerSource { + persist attribute status default = 1; + persist attribute order default = 1; + persist attribute description default = "Battery"; + persist attribute batVoltage; + persist attribute batPercentRemaining default = 100; + persist attribute batTimeRemaining; + persist attribute batChargeLevel; + ram attribute batReplacementNeeded; + ram attribute batReplaceability; + ram attribute batPresent; + ram attribute batReplacementDescription; + persist attribute batQuantity default = 1; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0A; + ram attribute clusterRevision default = 1; + } + + server cluster Switch { + emits event InitialPress; + emits event LongPress; + emits event ShortRelease; + emits event LongRelease; + persist attribute numberOfPositions default = 3; + persist attribute currentPosition default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0xE; + ram attribute clusterRevision default = 1; + } +} + + diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap new file mode 100644 index 00000000000000..1f84a7aab45a71 --- /dev/null +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap @@ -0,0 +1,2804 @@ +{ + "fileFormat": 2, + "featureLevel": 102, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "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": "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, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "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": "Extension", + "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": "SubjectsPerAccessControlEntry", + "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": "TargetsPerAccessControlEntry", + "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": "AccessControlEntriesPerFabric", + "code": 4, + "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": "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "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, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "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": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "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 Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 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, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "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": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "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": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "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, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "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": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "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": "GroupTable", + "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": "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": "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 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + }, + "deviceTypes": [ + { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + }, + { + "code": 17, + "profileId": 259, + "label": "MA-powersource", + "name": "MA-powersource" + } + ], + "deviceVersions": [ + 1, + 1 + ], + "deviceIdentifiers": [ + 15, + 17 + ], + "deviceTypeName": "MA-genericswitch", + "deviceTypeCode": 15, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TagList", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "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": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "Battery", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPercentRemaining", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "100", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatTimeRemaining", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatChargeLevel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "BatChargeLevelEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementNeeded", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplaceability", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "BatReplaceabilityEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPresent", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementDescription", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatQuantity", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0A", + "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": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "NumberOfPositions", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentPosition", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xE", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "InitialPress", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongPress", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShortRelease", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongRelease", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": null + } + ] +} \ No newline at end of file diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index 8e2d0166cc44a9..cda268e6d211f0 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -256,6 +256,265 @@ cluster BasicInformation = 40 { command MfgSpecificPing(): DefaultSuccess = 0; } +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + /** This cluster is used to manage global aspects of the Commissioning flow. */ cluster GeneralCommissioning = 48 { revision 1; // NOTE: Default/not specifically set @@ -1166,6 +1425,7 @@ endpoint 0 { } } endpoint 1 { + device type ma_powersource = 17, version 1; device type ma_genericswitch = 15, version 1; @@ -1188,6 +1448,7 @@ endpoint 1 { callback attribute serverList; callback attribute clientList; callback attribute partsList; + callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -1196,9 +1457,31 @@ endpoint 1 { callback attribute clusterRevision; } + server cluster PowerSource { + persist attribute status default = 1; + persist attribute order default = 1; + persist attribute description default = "Battery"; + persist attribute batVoltage; + persist attribute batPercentRemaining default = 100; + persist attribute batTimeRemaining; + persist attribute batChargeLevel default = 0; + ram attribute batReplacementNeeded; + ram attribute batReplaceability; + ram attribute batPresent; + ram attribute batReplacementDescription; + persist attribute batQuantity default = 1; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0A; + ram attribute clusterRevision default = 1; + } + server cluster Switch { emits event SwitchLatched; - persist attribute numberOfPositions default = 2; + persist attribute numberOfPositions default = 5; persist attribute currentPosition default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap index 172c6d31772296..8e62878f7a4e40 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 100, + "featureLevel": 102, "creator": "zap", "keyValuePairs": [ { @@ -29,6 +29,7 @@ "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/app-templates.json", "type": "gen-templates-json", + "category": "matter", "version": "chip-v1" } ], @@ -1935,13 +1936,21 @@ "profileId": 259, "label": "MA-genericswitch", "name": "MA-genericswitch" + }, + { + "code": 17, + "profileId": 259, + "label": "MA-powersource", + "name": "MA-powersource" } ], "deviceVersions": [ + 1, 1 ], "deviceIdentifiers": [ - 15 + 15, + 17 ], "deviceTypeName": "MA-genericswitch", "deviceTypeCode": 15, @@ -2175,6 +2184,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "TagList", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -2273,6 +2298,320 @@ } ] }, + { + "name": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "Battery", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPercentRemaining", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "100", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatTimeRemaining", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatChargeLevel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "BatChargeLevelEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementNeeded", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplaceability", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "BatReplaceabilityEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPresent", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementDescription", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatQuantity", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0A", + "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": "Switch", "code": 59, @@ -2291,7 +2630,7 @@ "storageOption": "NVM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/esp32/main/CMakeLists.txt b/examples/chef/esp32/main/CMakeLists.txt index ac436a7919637b..c6b37a0675fa4c 100644 --- a/examples/chef/esp32/main/CMakeLists.txt +++ b/examples/chef/esp32/main/CMakeLists.txt @@ -70,6 +70,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/../common/clusters/low-power/" "${CMAKE_SOURCE_DIR}/../common/clusters/media-input/" "${CMAKE_SOURCE_DIR}/../common/clusters/media-playback/" + "${CMAKE_SOURCE_DIR}/../common/clusters/switch/" "${CMAKE_SOURCE_DIR}/../common/clusters/target-navigator/" "${CMAKE_SOURCE_DIR}/../common/clusters/wake-on-lan/" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" diff --git a/examples/chef/esp32/main/main.cpp b/examples/chef/esp32/main/main.cpp index c5f29dc0f847d8..b61fcf22bc1d19 100644 --- a/examples/chef/esp32/main/main.cpp +++ b/examples/chef/esp32/main/main.cpp @@ -152,6 +152,8 @@ void printQRCode() app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::ESPWiFiDriver::GetInstance())); +extern void ApplicationInit(); + void InitServer(intptr_t) { // Start IM server @@ -172,6 +174,10 @@ void InitServer(intptr_t) // Register a function to receive events from the CHIP device layer. Note that calls to // this function will happen on the CHIP event loop thread, not the app_main thread. PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + + // Application code should always be initialised after the initialisation of + // server. + ApplicationInit(); } extern "C" void app_main(void) diff --git a/examples/chef/esp32/sdkconfig.defaults b/examples/chef/esp32/sdkconfig.defaults index 327e0d2538f022..fc09afaa38a00a 100644 --- a/examples/chef/esp32/sdkconfig.defaults +++ b/examples/chef/esp32/sdkconfig.defaults @@ -62,6 +62,7 @@ CONFIG_MBEDTLS_HKDF_C=y # IRAM optimizations CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y # Increase LwIP IPv6 address number CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 diff --git a/examples/chef/esp32/sdkconfig_rpc.defaults b/examples/chef/esp32/sdkconfig_rpc.defaults index bf2bcc8a7b7bc7..1b9f9ddc30134f 100644 --- a/examples/chef/esp32/sdkconfig_rpc.defaults +++ b/examples/chef/esp32/sdkconfig_rpc.defaults @@ -61,5 +61,6 @@ CONFIG_MBEDTLS_HKDF_C=y # IRAM optimizations CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP=y diff --git a/examples/chef/linux/BUILD.gn b/examples/chef/linux/BUILD.gn index 264ced698b62e8..ce0bed596850ef 100644 --- a/examples/chef/linux/BUILD.gn +++ b/examples/chef/linux/BUILD.gn @@ -47,6 +47,7 @@ executable("${sample_name}") { "${project_dir}/common/chef-laundry-washer-mode.cpp", "${project_dir}/common/chef-operational-state-delegate-impl.cpp", "${project_dir}/common/chef-resource-monitoring-delegates.cpp", + "${project_dir}/common/chef-rpc-actions-worker.cpp", "${project_dir}/common/chef-rvc-mode-delegate.cpp", "${project_dir}/common/chef-rvc-operational-state-delegate.cpp", "${project_dir}/common/clusters/audio-output/AudioOutputManager.cpp", @@ -58,6 +59,8 @@ executable("${sample_name}") { "${project_dir}/common/clusters/low-power/LowPowerManager.cpp", "${project_dir}/common/clusters/media-input/MediaInputManager.cpp", "${project_dir}/common/clusters/media-playback/MediaPlaybackManager.cpp", + "${project_dir}/common/clusters/switch/SwitchEventHandler.cpp", + "${project_dir}/common/clusters/switch/SwitchManager.cpp", "${project_dir}/common/clusters/target-navigator/TargetNavigatorManager.cpp", "${project_dir}/common/clusters/wake-on-lan/WakeOnLanManager.cpp", "${project_dir}/common/stubs.cpp", @@ -80,6 +83,7 @@ executable("${sample_name}") { if (chip_enable_pw_rpc) { defines = [ "PW_RPC_ENABLED", + "PW_RPC_ACTIONS_SERVICE=1", "PW_RPC_ATTRIBUTE_SERVICE=1", "PW_RPC_BOOLEAN_STATE_SERVICE=1", "PW_RPC_BUTTON_SERVICE=1", @@ -107,6 +111,7 @@ executable("${sample_name}") { "$dir_pw_trace_tokenized", "$dir_pw_trace_tokenized:trace_rpc_service", "${chip_root}/config/linux/lib/pw_rpc:pw_rpc", + "${chip_root}/examples/common/pigweed:actions_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:attributes_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:boolean_state_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:button_service.nanopb_rpc", diff --git a/examples/chef/linux/main.cpp b/examples/chef/linux/main.cpp index d799b4da3b53e6..7f54490eccf0de 100644 --- a/examples/chef/linux/main.cpp +++ b/examples/chef/linux/main.cpp @@ -29,10 +29,6 @@ using namespace chip::Shell; using namespace chip::app; using namespace chip::app::Clusters; -void ApplicationInit() {} - -void ApplicationShutdown() {} - int main(int argc, char * argv[]) { if (ChipLinuxAppInit(argc, argv) != 0) diff --git a/examples/chef/nrfconnect/CMakeLists.txt b/examples/chef/nrfconnect/CMakeLists.txt index 0e943cd90719f3..a22f6b6972bb15 100644 --- a/examples/chef/nrfconnect/CMakeLists.txt +++ b/examples/chef/nrfconnect/CMakeLists.txt @@ -99,6 +99,8 @@ target_sources(app PRIVATE ${CHEF}/common/clusters/low-power/LowPowerManager.cpp ${CHEF}/common/clusters/media-input/MediaInputManager.cpp ${CHEF}/common/clusters/media-playback/MediaPlaybackManager.cpp + ${CHEF}/common/clusters/switch/SwitchEventHandler.cpp + ${CHEF}/common/clusters/switch/SwitchManager.cpp ${CHEF}/common/clusters/target-navigator/TargetNavigatorManager.cpp ${CHEF}/common/clusters/wake-on-lan/WakeOnLanManager.cpp ${CHEF}/common/stubs.cpp diff --git a/examples/chef/nrfconnect/main.cpp b/examples/chef/nrfconnect/main.cpp index c79694e2e792a7..ca9d25655e3d52 100644 --- a/examples/chef/nrfconnect/main.cpp +++ b/examples/chef/nrfconnect/main.cpp @@ -64,6 +64,13 @@ chip::Crypto::PSAOperationalKeystore sPSAOperationalKeystore{}; #endif } // namespace +extern void ApplicationInit(); + +void InitServer(intptr_t) +{ + ApplicationInit(); +} + int main() { CHIP_ERROR err = CHIP_NO_ERROR; @@ -168,6 +175,8 @@ int main() cmd_app_server_init(); #endif + chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer); + #if CONFIG_CHIP_LIB_SHELL Engine::Root().RunMainLoop(); #endif diff --git a/examples/chip-tool/commands/clusters/ClusterCommand.h b/examples/chip-tool/commands/clusters/ClusterCommand.h index 792588a886dffb..171c664481c9dd 100644 --- a/examples/chip-tool/commands/clusters/ClusterCommand.h +++ b/examples/chip-tool/commands/clusters/ClusterCommand.h @@ -55,6 +55,15 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub return InteractionModelCommands::SendCommand(device, endpointId, clusterId, commandId, value); } + CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, + chip::CommandId commandId, + const chip::app::Clusters::IcdManagement::Commands::UnregisterClient::Type & value) + { + ReturnErrorOnFailure(InteractionModelCommands::SendCommand(device, endpointId, clusterId, commandId, value)); + mScopedNodeId = chip::ScopedNodeId(value.checkInNodeID, device->GetSecureSession().Value()->GetFabricIndex()); + return CHIP_NO_ERROR; + } + CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, chip::CommandId commandId, const chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsRequest::Type & value) @@ -109,6 +118,11 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub return; } } + if ((path.mEndpointId == chip::kRootEndpointId) && (path.mClusterId == chip::app::Clusters::IcdManagement::Id) && + (path.mCommandId == chip::app::Clusters::IcdManagement::Commands::UnregisterClient::Id)) + { + ModelCommand::ClearICDEntry(mScopedNodeId); + } } virtual void OnError(const chip::app::CommandSender * client, CHIP_ERROR error) override @@ -208,7 +222,7 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub private: chip::ClusterId mClusterId; chip::CommandId mCommandId; - + chip::ScopedNodeId mScopedNodeId; CHIP_ERROR mError = CHIP_NO_ERROR; CustomArgument mPayload; }; diff --git a/examples/chip-tool/commands/clusters/ModelCommand.cpp b/examples/chip-tool/commands/clusters/ModelCommand.cpp index 94b2b36c5538a3..2a549e62d4668b 100644 --- a/examples/chip-tool/commands/clusters/ModelCommand.cpp +++ b/examples/chip-tool/commands/clusters/ModelCommand.cpp @@ -76,6 +76,15 @@ void ModelCommand::Shutdown() CHIPCommand::Shutdown(); } +void ModelCommand::ClearICDEntry(const chip::ScopedNodeId & nodeId) +{ + CHIP_ERROR deleteEntryError = CHIPCommand::sICDClientStorage.DeleteEntry(nodeId); + if (deleteEntryError != CHIP_NO_ERROR) + { + ChipLogError(chipTool, "Failed to delete ICD entry: %" CHIP_ERROR_FORMAT, deleteEntryError.Format()); + } +} + void ModelCommand::CheckPeerICDType() { if (mIsPeerLIT.HasValue()) diff --git a/examples/chip-tool/commands/clusters/ModelCommand.h b/examples/chip-tool/commands/clusters/ModelCommand.h index d4e8eac613f468..79c31cf865930d 100644 --- a/examples/chip-tool/commands/clusters/ModelCommand.h +++ b/examples/chip-tool/commands/clusters/ModelCommand.h @@ -67,6 +67,8 @@ class ModelCommand : public CHIPCommand virtual CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) { return CHIP_ERROR_BAD_REQUEST; }; + virtual void ClearICDEntry(const chip::ScopedNodeId & nodeId); + void Shutdown() override; protected: diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index 5f6c179779f3c2..76c8ac8a58cc19 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -436,7 +436,7 @@ void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioning info.icd.idleModeDuration, info.icd.activeModeDuration, info.icd.activeModeThreshold); } -void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) +void PairingCommand::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icdCounter) { char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; @@ -444,7 +444,7 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate); app::ICDClientInfo clientInfo; - clientInfo.peer_node = ScopedNodeId(nodeId, CurrentCommissioner().GetFabricIndex()); + clientInfo.peer_node = nodeId; clientInfo.monitored_subject = mICDMonitoredSubject.Value(); clientInfo.start_icd_counter = icdCounter; @@ -457,7 +457,7 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte if (err != CHIP_NO_ERROR) { CHIPCommand::sICDClientStorage.RemoveKey(clientInfo); - ChipLogError(chipTool, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", ChipLogValueX64(nodeId), + ChipLogError(chipTool, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", ChipLogValueX64(nodeId.GetNodeId()), err.AsString()); SetCommandExitStatus(err); return; @@ -465,18 +465,18 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte mDeviceIsICD = true; - ChipLogProgress(chipTool, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId)); + ChipLogProgress(chipTool, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId.GetNodeId())); ChipLogProgress(chipTool, "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 " / Monitored Subject: " ChipLogFormatX64 " / Symmetric Key: %s / ICDCounter %u", - ChipLogValueX64(nodeId), ChipLogValueX64(mICDCheckInNodeId.Value()), + ChipLogValueX64(nodeId.GetNodeId()), ChipLogValueX64(mICDCheckInNodeId.Value()), ChipLogValueX64(mICDMonitoredSubject.Value()), icdSymmetricKeyHex, icdCounter); } -void PairingCommand::OnICDStayActiveComplete(NodeId deviceId, uint32_t promisedActiveDuration) +void PairingCommand::OnICDStayActiveComplete(ScopedNodeId deviceId, uint32_t promisedActiveDuration) { ChipLogProgress(chipTool, "ICD Stay Active Complete for device " ChipLogFormatX64 " / promisedActiveDuration: %u", - ChipLogValueX64(deviceId), promisedActiveDuration); + ChipLogValueX64(deviceId.GetNodeId()), promisedActiveDuration); } void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 99b0fd0c91882e..aaa8dc714e1017 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -197,8 +197,8 @@ class PairingCommand : public CHIPCommand, void OnPairingDeleted(CHIP_ERROR error) override; void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; - void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; - void OnICDStayActiveComplete(NodeId deviceId, uint32_t promisedActiveDuration) override; + void OnICDRegistrationComplete(chip::ScopedNodeId deviceId, uint32_t icdCounter) override; + void OnICDStayActiveComplete(chip::ScopedNodeId deviceId, uint32_t promisedActiveDuration) override; /////////// DeviceDiscoveryDelegate Interface ///////// void OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) override; diff --git a/examples/common/pigweed/BUILD.gn b/examples/common/pigweed/BUILD.gn index e056f2ef228a8a..c0178e419a1d5d 100644 --- a/examples/common/pigweed/BUILD.gn +++ b/examples/common/pigweed/BUILD.gn @@ -35,6 +35,14 @@ pw_proto_library("echo_service") { prefix = "echo_service" } +pw_proto_library("actions_service") { + sources = [ "protos/actions_service.proto" ] + inputs = [ "protos/actions_service.options" ] + deps = [ "$dir_pw_protobuf:common_protos" ] + strip_prefix = "protos" + prefix = "actions_service" +} + pw_proto_library("attributes_service") { sources = [ "protos/attributes_service.proto" ] inputs = [ "protos/attributes_service.options" ] diff --git a/examples/common/pigweed/protos/actions_service.options b/examples/common/pigweed/protos/actions_service.options new file mode 100644 index 00000000000000..24ce3e80648ae6 --- /dev/null +++ b/examples/common/pigweed/protos/actions_service.options @@ -0,0 +1 @@ +chip.rpc.ActionsRequest.actions max_count:16 // max action size diff --git a/examples/common/pigweed/protos/actions_service.proto b/examples/common/pigweed/protos/actions_service.proto new file mode 100644 index 00000000000000..dbf3a99ceb32ac --- /dev/null +++ b/examples/common/pigweed/protos/actions_service.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package chip.rpc; + +import 'pw_protobuf_protos/common.proto'; + +enum ActionType { + WRITE_ATTRIBUTE = 0x00; // Write an cluster Attribute + RUN_COMMAND = 0x01; // Run a cluster Command + EMIT_EVENT = 0x02; // Emit a cluster Events +} + +message Action { + ActionType type = 1; // ActionType above + uint32 delayMs = 2; // Delay and run action after xx ms + uint32 actionId = 3; // Align with Cluster Attribute/Event/Command ID + optional uint32 arg1 = 4; // 1st attribute + optional uint32 arg2 = 5; // 2nd attribute + optional uint32 arg3 = 6; // 3rd attribute +} + +message ActionsRequest { + uint32 endpoint_id = 1; + uint32 cluster_id = 2; + repeated Action actions = 3; // Actions including Attribute Write / Event / Command +} + +service Actions { + rpc Set(ActionsRequest) returns (pw.protobuf.Empty){} +} diff --git a/examples/common/pigweed/rpc_console/py/BUILD.gn b/examples/common/pigweed/rpc_console/py/BUILD.gn index a050fb64747302..a03dc980872739 100644 --- a/examples/common/pigweed/rpc_console/py/BUILD.gn +++ b/examples/common/pigweed/rpc_console/py/BUILD.gn @@ -39,6 +39,7 @@ pw_python_package("chip_rpc") { "$dir_pw_rpc/py", "$dir_pw_system/py", "$dir_pw_tokenizer/py", + "${chip_root}/examples/common/pigweed:actions_service.python", "${chip_root}/examples/common/pigweed:attributes_service.python", "${chip_root}/examples/common/pigweed:boolean_state_service.python", "${chip_root}/examples/common/pigweed:button_service.python", diff --git a/examples/common/pigweed/rpc_console/py/chip_rpc/console.py b/examples/common/pigweed/rpc_console/py/chip_rpc/console.py index f5ed5b5ab4d582..1591722bfdbeab 100644 --- a/examples/common/pigweed/rpc_console/py/chip_rpc/console.py +++ b/examples/common/pigweed/rpc_console/py/chip_rpc/console.py @@ -46,6 +46,7 @@ # Protos # isort: off +from actions_service import actions_service_pb2 from attributes_service import attributes_service_pb2 from boolean_state_service import boolean_state_service_pb2 from button_service import button_service_pb2 @@ -128,6 +129,7 @@ def show_console(device: str, baudrate: int, # "set_wakeup_fd only works in main thread of the main interpreter" use_ipython=True, compiled_protos=[ + actions_service_pb2, attributes_service_pb2, boolean_state_service_pb2, button_service_pb2, diff --git a/examples/common/pigweed/rpc_services/Actions.h b/examples/common/pigweed/rpc_services/Actions.h new file mode 100644 index 00000000000000..a2cbba0cb49a7a --- /dev/null +++ b/examples/common/pigweed/rpc_services/Actions.h @@ -0,0 +1,127 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +#include "actions_service/actions_service.rpc.pb.h" +#include "app/util/attribute-storage.h" +#include "pigweed/rpc_services/internal/StatusUtils.h" +#include +#include +#include + +namespace chip { +namespace rpc { + +class Actions final : public pw_rpc::nanopb::Actions::Service +{ + /* + * RPC Actions Service is a debugging interface for writting Attributes, emitting Events, or + * running Commands batchwisely. Each action will be execute one by one according to the + * delayed time in ms. + * + * An Action is a abstract type of Attribute, Command, Event + * type : this defines the action is either a Attribute, Command, or Event + * delayMs : this define the relative delayed time in ms after last action + * actionId : this defines the ID of Attribute, Command or Event + * arg1, arg2, arg3 : it has up to 3 optional arguments which could be mapped to Attribute/Command/Event aruments + * + * An Action Request is composed of a batch of Actions + * + * The usage of Actions Service: + * 1. Create an Action Request by protos.chip.rpc.ActionsWrite + * 2. Append Actions one by one to the action request + * 3. After all action added to the request, call rpcs.chip.rpc.Actions.Set to execute that + * + * e.g. In rpc_console: + * + * # Init a RPC Action request which is for endpoint 1 and Switch Cluster (0x003B) + * In [1]: request=protos.chip.rpc.ActionsWrite(endpoint_id=1, cluster_id=int("0x003B", 16)) + * + * # Add an action to write attribute id 0x1 (CurrentPosition) with data 2 after 1000 ms (meaning right away) + * In [2]: request.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.WRITE_ATTRIBUTE, delayMs=1000, + * actionId=1, arg1=2)) + * + * # Define the follow action to emit an event id 0x1 (InitialPress) with data 2 (NewPosition) after 1000 ms + * In [3]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.EMIT_EVENT, delayMs=1000, + * actionId=1, arg1=2)) + * + * # Define the follow action to emit an event id 0x2 (LongPress) with data 2 (NewPosition) after 2000 ms + * In [4]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.EMIT_EVENT, delayMs=2000, + * actionId=2, arg1=2)) + * + * # Define an action to write attribute id 0x1 (CurrentPosition) with data 0 after 2000 ms (meaning button bouncing back) + * In [5]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.WRITE_ATTRIBUTE, delayMs=2000, + * actionId=1, arg1=0)) + * + * # Define the follow action to emit an event id 0x4 (LongRelease) with data 2 (PreviousPosition) after 1000 ms + * In [6]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.EMIT_EVENT, delayMs=1000, + * actionId=4, arg1=2)) + * + * # Set the actions to device + * In [7]: rpcs.chip.rpc.Actions.Set(message, pw_rpc_timeout_s=10000) + * + */ +public: + enum class Type : uint8_t + { + Attribute = 0, + Command = 1, + Event = 2, + }; + + ::pw::Status Set(const chip_rpc_ActionsRequest & request, ::pw_protobuf_Empty & response) + + { + DeviceLayer::StackLock lock; + ChipLogProgress(NotSpecified, " request.endpoint_id=%d, request.cluster_id=%d", request.endpoint_id, request.cluster_id); + + for (int i = 0; i < request.actions_count; i++) + { + chip_rpc_Action action = request.actions[i]; + std::vector args; + if (action.has_arg1) + args.push_back(action.arg1); + if (action.has_arg2) + args.push_back(action.arg2); + if (action.has_arg3) + args.push_back(action.arg3); + + mActionsSubscribeCallback(request.endpoint_id, request.cluster_id, static_cast(action.type), action.delayMs, + action.actionId, args); + } + + return pw::OkStatus(); + } + + using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + + void SubscribeActions(RpcActionsSubscribeCallback subscriber) { mActionsSubscribeCallback = subscriber; }; + +private: + RpcActionsSubscribeCallback mActionsSubscribeCallback; +}; + +} // namespace rpc +} // namespace chip diff --git a/examples/common/pigweed/rpc_services/BooleanState.h b/examples/common/pigweed/rpc_services/BooleanState.h index bb4b524459d03d..2e0f15d6cb316d 100644 --- a/examples/common/pigweed/rpc_services/BooleanState.h +++ b/examples/common/pigweed/rpc_services/BooleanState.h @@ -28,7 +28,7 @@ namespace chip { namespace rpc { -class BooleanState final : public pw_rpc::nanopb::BooleanState::Service +class BooleanState : public pw_rpc::nanopb::BooleanState::Service { public: virtual ~BooleanState() = default; diff --git a/examples/common/pigweed/rpc_services/Locking.h b/examples/common/pigweed/rpc_services/Locking.h index 6d2e912858b47f..8f851592e8642b 100644 --- a/examples/common/pigweed/rpc_services/Locking.h +++ b/examples/common/pigweed/rpc_services/Locking.h @@ -27,7 +27,7 @@ namespace chip { namespace rpc { -class Locking final : public pw_rpc::nanopb::Locking::Service +class Locking : public pw_rpc::nanopb::Locking::Service { public: virtual ~Locking() = default; diff --git a/examples/contact-sensor-app/linux/README.md b/examples/contact-sensor-app/linux/README.md new file mode 100644 index 00000000000000..f99162f4fdee10 --- /dev/null +++ b/examples/contact-sensor-app/linux/README.md @@ -0,0 +1,144 @@ +# Matter Linux Contact Sensor Example + +An example showing the use of CHIP on the Linux. This document will describe how +to build and run Matter Linux Contact Sensor Example on Raspberry Pi. This +document is tested on **Ubuntu for Raspberry Pi Server 20.04 LTS (aarch64)** and +**Ubuntu for Raspberry Pi Desktop 20.10 (aarch64)** + +To cross-compile this example on an x64 host and run it on **NXP i.MX 8M Mini** +**EVK**, see the associated +[README document](../../../docs/guides/nxp/nxp_imx8m_linux_examples.md) for +details. + +
    + +- [Matter Linux Contact Sensor Example](#matter-linux-contact-sensor-example) + - [Building](#building) + - [Commandline Arguments](#commandline-arguments) + - [Running the Complete Example on Raspberry Pi 4](#running-the-complete-example-on-raspberry-pi-4) + - [Running RPC console](#running-rpc-console) + - [Device Tracing](#device-tracing) + +
    + +## Building + +- Install tool chain + + $ sudo apt-get install git gcc g++ python pkg-config libssl-dev libdbus-1-dev libglib2.0-dev ninja-build python3-venv python3-dev unzip + +- Build the example application: + + $ cd ~/connectedhomeip/examples/contact-sensor-app/linux + $ git submodule update --init + $ source third_party/connectedhomeip/scripts/activate.sh + $ gn gen out/debug + $ ninja -C out/debug + +- To delete generated executable, libraries and object files use: + + $ cd ~/connectedhomeip/examples/contact-sensor-app/linux + $ rm -rf out/ + +- Build the example with pigweed RPC + + $ cd ~/connectedhomeip/examples/contact-sensor-app/linux + $ git submodule update --init + $ source third_party/connectedhomeip/scripts/activate.sh + $ gn gen out/debug --args='import("//with_pw_rpc.gni")' + $ ninja -C out/debug + +## Commandline arguments + +- `--wifi` + + Enables WiFi management feature. Required for WiFi commissioning. + +- `--thread` + + Enables Thread management feature, requires ot-br-posix dbus daemon running. + Required for Thread commissioning. + +- `--ble-device ` + + Use specific bluetooth interface for BLE advertisement and connections. + + `interface id`: the number after `hci` when listing BLE interfaces by + `hciconfig` command, for example, `--ble-device 1` means using `hci1` + interface. Default: `0`. + +## Running the Complete Example on Raspberry Pi 4 + +> If you want to test Echo protocol, please enable Echo handler +> +> gn gen out/debug --args='chip_app_use_echo=true' +> ninja -C out/debug + +- Prerequisites + + 1. A Raspberry Pi 4 board + 2. A USB Bluetooth Dongle, Ubuntu desktop will send Bluetooth advertisement, + which will block CHIP from connecting via BLE. On Ubuntu server, you need + to install `pi-bluetooth` via APT. + 3. Ubuntu 20.04 or newer image for ARM64 platform. + +- Building + + Follow [Building](#building) section of this document. + +- Running + + - [Optional] Plug USB Bluetooth dongle + + - Plug USB Bluetooth dongle and find its bluetooth device number. The + number after `hci` is the bluetooth device number, `1` in this + example. + + $ hciconfig + hci1: Type: Primary Bus: USB + BD Address: 00:1A:7D:AA:BB:CC ACL MTU: 310:10 SCO MTU: 64:8 + UP RUNNING PSCAN ISCAN + RX bytes:20942 acl:1023 sco:0 events:1140 errors:0 + TX bytes:16559 acl:1011 sco:0 commands:121 errors:0 + + hci0: Type: Primary Bus: UART + BD Address: B8:27:EB:AA:BB:CC ACL MTU: 1021:8 SCO MTU: 64:1 + UP RUNNING PSCAN ISCAN + RX bytes:8609495 acl:14 sco:0 events:217484 errors:0 + TX bytes:92185 acl:20 sco:0 commands:5259 errors:0 + + - Run Linux Contact Sensor App + + $ cd ~/connectedhomeip/examples/contact-sensor-app/linux + $ sudo out/debug/chip-contact-sensor-app --ble-device [bluetooth device number] + # In this example, the device we want to use is hci1 + $ sudo out/debug/chip-contact-sensor-app --ble-device 1 + + - Test the device using ChipDeviceController on your laptop / + workstation etc. + +## Running RPC Console + +- As part of building the example with RPCs enabled the chip_rpc python + interactive console is installed into your venv. The python wheel files are + also created in the output folder: out/debug/chip_rpc_console_wheels. To + install the wheel files without rebuilding: + `pip3 install out/debug/chip_rpc_console_wheels/*.whl` + +- To use the chip-rpc console after it has been installed run: + `chip-console -s localhost:33000 -o //pw_log.out` + +- Then you can Get the contact sensor status using the RPCs: + `rpcs.chip.rpc.BooleanState.Get()` + +## Device Tracing + +Device tracing is available to analyze the device performance. To turn on +tracing, build with RPC enabled. See [Building with RPC enabled](#building). + +To obtain the tracing json file, run: + +``` + $ ./{PIGWEED_REPO}/pw_trace_tokenized/py/pw_trace_tokenized/get_trace.py -s localhost:33000 \ + -o {OUTPUT_FILE} -t {ELF_FILE} {PIGWEED_REPO}/pw_trace_tokenized/pw_trace_protos/trace_rpc.proto +``` diff --git a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h index 447d2c2ae5ccf6..8e5bb8f9842210 100644 --- a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h @@ -21,6 +21,10 @@ #include "../common/CHIPCommandBridge.h" #include +#define DFT_MODEL_COMMAND_DEFAULT_TIMEOUT 20 +#define DFT_STRINGIFY_HELPER(arg) #arg +#define DFT_STRINGIFY(arg) DFT_STRINGIFY_HELPER(arg) + class ModelCommand : public CHIPCommandBridge { public: @@ -30,6 +34,10 @@ class ModelCommand : public CHIPCommandBridge { AddArgument("node-id", 0, UINT64_MAX, &mNodeId); AddArgument("endpoint-id", 0, UINT16_MAX, &mEndPointId); + AddArgument( + "timeout", 0, UINT16_MAX, &mTimeout, + "Amount of time to allow the command to run for before considering it to have timed out. Defaults to " DFT_STRINGIFY( + DFT_MODEL_COMMAND_DEFAULT_TIMEOUT) " seconds."); } void Shutdown() override; @@ -38,11 +46,19 @@ class ModelCommand : public CHIPCommandBridge /////////// CHIPCommand Interface ///////// CHIP_ERROR RunCommand() override; - chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); } + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(DFT_MODEL_COMMAND_DEFAULT_TIMEOUT)); + } virtual CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endPointId) = 0; private: chip::NodeId mNodeId; chip::EndpointId mEndPointId; + chip::Optional mTimeout; }; + +#undef DFT_STRINGIFY +#undef DFT_STRINGIFY_HELPER +#undef DFT_MODEL_COMMAND_DEFAULT_TIMEOUT diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm index c8594a6f4fa87c..9723199ed007a4 100644 --- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm +++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm @@ -22,7 +22,7 @@ @implementation CHIPToolDeviceControllerDelegate - (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status { - NSLog(@"Pairing Status Update: %tu", status); + NSLog(@"Pairing Status Update: %ld", static_cast(status)); switch (status) { case MTRCommissioningStatusSuccess: ChipLogProgress(chipTool, "Secure Pairing Success"); diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index ea4e5db21a0b18..68db2eea271ec3 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -1237,7 +1237,7 @@ cluster GroupKeyManagement = 63 { } /** This cluster provides a mechanism for querying data about electrical power as measured by the server. */ -provisional cluster ElectricalPowerMeasurement = 144 { +cluster ElectricalPowerMeasurement = 144 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -1342,7 +1342,7 @@ provisional cluster ElectricalPowerMeasurement = 144 { } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ -provisional cluster ElectricalEnergyMeasurement = 145 { +cluster ElectricalEnergyMeasurement = 145 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -1639,7 +1639,7 @@ provisional cluster DeviceEnergyManagement = 152 { } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ -provisional cluster EnergyEvse = 153 { +cluster EnergyEvse = 153 { revision 2; enum EnergyTransferStoppedReasonEnum : enum8 { @@ -1817,7 +1817,7 @@ provisional cluster EnergyEvse = 153 { } /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ -provisional cluster PowerTopology = 156 { +cluster PowerTopology = 156 { revision 1; bitmap Feature : bitmap32 { @@ -1838,7 +1838,7 @@ provisional cluster PowerTopology = 156 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster EnergyEvseMode = 157 { +cluster EnergyEvseMode = 157 { revision 1; enum ModeTag : enum16 { diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index 79e175fb4a70c1..ddaa33483257b1 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -69,7 +69,6 @@ static_library("fabric-admin-utils") { sources += [ "commands/interactive/InteractiveCommands.cpp" ] deps += [ - "${chip_root}/examples/common/websocket-server", "${chip_root}/src/platform/logging:headers", "${editline_root}:editline", ] diff --git a/examples/fabric-admin/commands/clusters/JsonParser.h b/examples/fabric-admin/commands/clusters/JsonParser.h index 0871e767c21bd6..2a1cd62e97b028 100644 --- a/examples/fabric-admin/commands/clusters/JsonParser.h +++ b/examples/fabric-admin/commands/clusters/JsonParser.h @@ -18,7 +18,7 @@ #pragma once -#include "../common/CustomStringPrefix.h" +#include #include #include diff --git a/examples/fabric-admin/commands/clusters/ModelCommand.h b/examples/fabric-admin/commands/clusters/ModelCommand.h index c14d3c9952f3fc..185f6179db330f 100644 --- a/examples/fabric-admin/commands/clusters/ModelCommand.h +++ b/examples/fabric-admin/commands/clusters/ModelCommand.h @@ -20,7 +20,7 @@ #ifdef CONFIG_USE_LOCAL_STORAGE #include -#endif // CONFIG_USE_LOCAL_STORAGE +#endif #include "../common/CHIPCommand.h" #include diff --git a/examples/fabric-admin/commands/interactive/Commands.h b/examples/fabric-admin/commands/interactive/Commands.h index e324ddae2680ae..2b66a2d9c70f94 100644 --- a/examples/fabric-admin/commands/interactive/Commands.h +++ b/examples/fabric-admin/commands/interactive/Commands.h @@ -18,9 +18,9 @@ #pragma once -#include "commands/common/CHIPCommand.h" -#include "commands/common/Commands.h" -#include "commands/interactive/InteractiveCommands.h" +#include +#include +#include void registerCommandsInteractive(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { diff --git a/examples/fabric-admin/commands/interactive/InteractiveCommands.h b/examples/fabric-admin/commands/interactive/InteractiveCommands.h index 21c14a7a4c95ce..a0b490f3b668e5 100644 --- a/examples/fabric-admin/commands/interactive/InteractiveCommands.h +++ b/examples/fabric-admin/commands/interactive/InteractiveCommands.h @@ -18,11 +18,9 @@ #pragma once -#include "../clusters/DataModelLogger.h" -#include "../common/CHIPCommand.h" -#include "../common/Commands.h" - -#include +#include +#include +#include #include diff --git a/examples/fabric-admin/commands/pairing/Commands.h b/examples/fabric-admin/commands/pairing/Commands.h index 6fdfacef79e34f..af07536bfda052 100644 --- a/examples/fabric-admin/commands/pairing/Commands.h +++ b/examples/fabric-admin/commands/pairing/Commands.h @@ -18,15 +18,15 @@ #pragma once -#include "commands/common/Commands.h" -#include "commands/pairing/GetCommissionerNodeIdCommand.h" -#include "commands/pairing/GetCommissionerRootCertificateCommand.h" -#include "commands/pairing/IssueNOCChainCommand.h" -#include "commands/pairing/OpenCommissioningWindowCommand.h" -#include "commands/pairing/PairingCommand.h" +#include +#include +#include +#include +#include +#include +#include #include -#include #include class Unpair : public PairingCommand diff --git a/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h b/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h index 3234cfe456a956..10439830cb1345 100644 --- a/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h +++ b/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h @@ -18,8 +18,8 @@ #pragma once -#include "../common/CHIPCommand.h" -#include "../common/RemoteDataModelLogger.h" +#include +#include class GetCommissionerNodeIdCommand : public CHIPCommand { diff --git a/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h b/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h index 1d25efcc38224d..88afc9b6bace57 100644 --- a/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h +++ b/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h @@ -18,8 +18,8 @@ #pragma once -#include "../common/CHIPCommand.h" -#include "../common/RemoteDataModelLogger.h" +#include +#include #include "ToTLVCert.h" diff --git a/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h b/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h index 0103b26977136d..efed6738204008 100644 --- a/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h +++ b/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h @@ -18,8 +18,8 @@ #pragma once -#include "../common/CHIPCommand.h" -#include "../common/RemoteDataModelLogger.h" +#include +#include #include "ToTLVCert.h" diff --git a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h index 99b179d8753125..2c1d62f31c566b 100644 --- a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h +++ b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h @@ -18,8 +18,7 @@ #pragma once -#include "../common/CHIPCommand.h" - +#include #include #include diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 80775f0853d110..92754c2adaa69a 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -17,14 +17,14 @@ */ #include "PairingCommand.h" -#include "platform/PlatformManager.h" + #include #include #include #include #include +#include #include - #include #include @@ -436,7 +436,7 @@ void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioning info.icd.idleModeDuration, info.icd.activeModeDuration, info.icd.activeModeThreshold); } -void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) +void PairingCommand::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icdCounter) { char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; @@ -444,7 +444,7 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate); app::ICDClientInfo clientInfo; - clientInfo.peer_node = ScopedNodeId(nodeId, CurrentCommissioner().GetFabricIndex()); + clientInfo.peer_node = nodeId; clientInfo.monitored_subject = mICDMonitoredSubject.Value(); clientInfo.start_icd_counter = icdCounter; @@ -457,26 +457,26 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte if (err != CHIP_NO_ERROR) { CHIPCommand::sICDClientStorage.RemoveKey(clientInfo); - ChipLogError(NotSpecified, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", ChipLogValueX64(nodeId), - err.AsString()); + ChipLogError(NotSpecified, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", + ChipLogValueX64(nodeId.GetNodeId()), err.AsString()); SetCommandExitStatus(err); return; } mDeviceIsICD = true; - ChipLogProgress(NotSpecified, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId)); + ChipLogProgress(NotSpecified, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId.GetNodeId())); ChipLogProgress(NotSpecified, "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 " / Monitored Subject: " ChipLogFormatX64 " / Symmetric Key: %s / ICDCounter %u", - ChipLogValueX64(nodeId), ChipLogValueX64(mICDCheckInNodeId.Value()), + ChipLogValueX64(nodeId.GetNodeId()), ChipLogValueX64(mICDCheckInNodeId.Value()), ChipLogValueX64(mICDMonitoredSubject.Value()), icdSymmetricKeyHex, icdCounter); } -void PairingCommand::OnICDStayActiveComplete(NodeId deviceId, uint32_t promisedActiveDuration) +void PairingCommand::OnICDStayActiveComplete(ScopedNodeId deviceId, uint32_t promisedActiveDuration) { ChipLogProgress(NotSpecified, "ICD Stay Active Complete for device " ChipLogFormatX64 " / promisedActiveDuration: %u", - ChipLogValueX64(deviceId), promisedActiveDuration); + ChipLogValueX64(deviceId.GetNodeId()), promisedActiveDuration); } void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.h b/examples/fabric-admin/commands/pairing/PairingCommand.h index 4ff3903253be4e..331d177448aed5 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.h +++ b/examples/fabric-admin/commands/pairing/PairingCommand.h @@ -18,11 +18,10 @@ #pragma once -#include "../common/CHIPCommand.h" +#include +#include #include #include - -#include #include #include @@ -197,8 +196,8 @@ class PairingCommand : public CHIPCommand, void OnPairingDeleted(CHIP_ERROR error) override; void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; - void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; - void OnICDStayActiveComplete(NodeId deviceId, uint32_t promisedActiveDuration) override; + void OnICDRegistrationComplete(chip::ScopedNodeId deviceId, uint32_t icdCounter) override; + void OnICDStayActiveComplete(chip::ScopedNodeId deviceId, uint32_t promisedActiveDuration) override; /////////// DeviceDiscoveryDelegate Interface ///////// void OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) override; diff --git a/examples/fabric-admin/main.cpp b/examples/fabric-admin/main.cpp index cf1122bda1ec8a..a1002d83170d5b 100644 --- a/examples/fabric-admin/main.cpp +++ b/examples/fabric-admin/main.cpp @@ -16,11 +16,10 @@ * */ -#include "commands/common/Commands.h" - -#include "commands/clusters/SubscriptionsCommands.h" -#include "commands/interactive/Commands.h" -#include "commands/pairing/Commands.h" +#include +#include +#include +#include #include #include diff --git a/examples/fabric-bridge-app/linux/BUILD.gn b/examples/fabric-bridge-app/linux/BUILD.gn index 21c93344416b62..ea7e6e0b31b331 100644 --- a/examples/fabric-bridge-app/linux/BUILD.gn +++ b/examples/fabric-bridge-app/linux/BUILD.gn @@ -22,7 +22,9 @@ executable("fabric-bridge-app") { sources = [ "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h", "Device.cpp", + "DeviceManager.cpp", "include/Device.h", + "include/DeviceManager.h", "main.cpp", ] diff --git a/examples/fabric-bridge-app/linux/Device.cpp b/examples/fabric-bridge-app/linux/Device.cpp index 40cd8c007e8baa..4cf72a281113b6 100644 --- a/examples/fabric-bridge-app/linux/Device.cpp +++ b/examples/fabric-bridge-app/linux/Device.cpp @@ -46,11 +46,11 @@ void Device::SetReachable(bool aReachable) if (aReachable) { - ChipLogProgress(DeviceLayer, "Device[%s]: ONLINE", mName); + ChipLogProgress(NotSpecified, "Device[%s]: ONLINE", mName); } else { - ChipLogProgress(DeviceLayer, "Device[%s]: OFFLINE", mName); + ChipLogProgress(NotSpecified, "Device[%s]: OFFLINE", mName); } if (changed) @@ -63,7 +63,7 @@ void Device::SetName(const char * szName) { bool changed = (strncmp(mName, szName, sizeof(mName)) != 0); - ChipLogProgress(DeviceLayer, "Device[%s]: New Name=\"%s\"", mName, szName); + ChipLogProgress(NotSpecified, "Device[%s]: New Name=\"%s\"", mName, szName); chip::Platform::CopyString(mName, szName); diff --git a/examples/fabric-bridge-app/linux/DeviceManager.cpp b/examples/fabric-bridge-app/linux/DeviceManager.cpp new file mode 100644 index 00000000000000..a5ffe68445949b --- /dev/null +++ b/examples/fabric-bridge-app/linux/DeviceManager.cpp @@ -0,0 +1,130 @@ +/* + * + * 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 "DeviceManager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::Credentials; +using namespace chip::Inet; +using namespace chip::Transport; +using namespace chip::DeviceLayer; +using namespace chip::app::Clusters; + +namespace { +constexpr uint8_t kMaxRetries = 10; +} // namespace + +DeviceManager::DeviceManager() +{ + memset(mDevices, 0, sizeof(mDevices)); + mFirstDynamicEndpointId = static_cast( + static_cast(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1))) + 1); + mCurrentEndpointId = mFirstDynamicEndpointId; +} + +int DeviceManager::AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep, + const chip::Span & deviceTypeList, + const chip::Span & dataVersionStorage, chip::EndpointId parentEndpointId) +{ + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + if (nullptr == mDevices[index]) + { + mDevices[index] = dev; + CHIP_ERROR err; + int retryCount = 0; + while (retryCount < kMaxRetries) + { + DeviceLayer::StackLock lock; + dev->SetEndpointId(mCurrentEndpointId); + dev->SetParentEndpointId(parentEndpointId); + err = + emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, dataVersionStorage, deviceTypeList, parentEndpointId); + if (err == CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "Added device %s to dynamic endpoint %d (index=%d)", dev->GetName(), + mCurrentEndpointId, index); + return index; + } + if (err != CHIP_ERROR_ENDPOINT_EXISTS) + { + return -1; // Return error as endpoint addition failed due to an error other than endpoint already exists + } + // Increment the endpoint ID and handle wrap condition + if (++mCurrentEndpointId < mFirstDynamicEndpointId) + { + mCurrentEndpointId = mFirstDynamicEndpointId; + } + retryCount++; + } + ChipLogError(NotSpecified, "Failed to add dynamic endpoint after %d retries", kMaxRetries); + return -1; // Return error as all retries are exhausted + } + index++; + } + ChipLogProgress(NotSpecified, "Failed to add dynamic endpoint: No endpoints available!"); + return -1; +} + +int DeviceManager::RemoveDeviceEndpoint(Device * dev) +{ + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + if (mDevices[index] == dev) + { + DeviceLayer::StackLock lock; + // Silence complaints about unused ep when progress logging + // disabled. + [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); + mDevices[index] = nullptr; + ChipLogProgress(NotSpecified, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); + return index; + } + index++; + } + return -1; +} + +Device * DeviceManager::GetDevice(uint16_t index) const +{ + if (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + return mDevices[index]; + } + return nullptr; +} diff --git a/examples/fabric-bridge-app/linux/include/DeviceManager.h b/examples/fabric-bridge-app/linux/include/DeviceManager.h new file mode 100644 index 00000000000000..8e87c9059bcb78 --- /dev/null +++ b/examples/fabric-bridge-app/linux/include/DeviceManager.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "Device.h" + +class DeviceManager +{ +public: + DeviceManager(); + + /** + * @brief Adds a device to a dynamic endpoint. + * + * This function attempts to add a device to a dynamic endpoint. It tries to find an available + * endpoint slot and retries the addition process up to a specified maximum number of times if + * the endpoint already exists. If the addition is successful, it returns the index of the + * dynamic endpoint; otherwise, it returns -1. + * + * @param dev A pointer to the device to be added. + * @param ep A pointer to the endpoint type. + * @param deviceTypeList A span containing the list of device types. + * @param dataVersionStorage A span containing the data version storage. + * @param parentEndpointId The parent endpoint ID. Defaults to an invalid endpoint ID. + * @return int The index of the dynamic endpoint if successful, -1 otherwise. + */ + int AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep, const chip::Span & deviceTypeList, + const chip::Span & dataVersionStorage, + chip::EndpointId parentEndpointId = chip::kInvalidEndpointId); + + /** + * @brief Removes a device from a dynamic endpoint. + * + * This function attempts to remove a device from a dynamic endpoint by iterating through the + * available endpoints and checking if the device matches. If the device is found, it clears the + * dynamic endpoint, logs the removal, and returns the index of the removed endpoint. + * If the device is not found, it returns -1. + * + * @param dev A pointer to the device to be removed. + * @return int The index of the removed dynamic endpoint if successful, -1 otherwise. + */ + int RemoveDeviceEndpoint(Device * dev); + + Device * GetDevice(uint16_t index) const; + +private: + chip::EndpointId mCurrentEndpointId; + chip::EndpointId mFirstDynamicEndpointId; + Device * mDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1]; +}; diff --git a/examples/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index d2350cad37c717..600d4a2a376d55 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -17,302 +17,137 @@ */ #include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include #include "CommissionableInit.h" #include "Device.h" -#include +#include "DeviceManager.h" + +#include +#include -#include -#include #include +#include +#include using namespace chip; -using namespace chip::app; -using namespace chip::Credentials; -using namespace chip::Inet; -using namespace chip::Transport; -using namespace chip::DeviceLayer; -using namespace chip::app::Clusters; - -namespace { - -EndpointId gCurrentEndpointId; -EndpointId gFirstDynamicEndpointId; -Device * gDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1]; - -} // namespace - -// REVISION DEFINITIONS: -// ================================================================================= +#define POLL_INTERVAL_MS (100) #define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) #define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION (2u) #define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP (0u) -// --------------------------------------------------------------------------- +namespace { -int AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep, const Span & deviceTypeList, - const Span & dataVersionStorage, chip::EndpointId parentEndpointId = chip::kInvalidEndpointId) +bool KeyboardHit() { - uint8_t index = 0; - const int maxRetries = 10; // Set the maximum number of retries - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) - { - if (nullptr == gDevices[index]) - { - gDevices[index] = dev; - CHIP_ERROR err; - int retryCount = 0; - while (retryCount < maxRetries) - { - DeviceLayer::StackLock lock; - dev->SetEndpointId(gCurrentEndpointId); - dev->SetParentEndpointId(parentEndpointId); - err = - emberAfSetDynamicEndpoint(index, gCurrentEndpointId, ep, dataVersionStorage, deviceTypeList, parentEndpointId); - if (err == CHIP_NO_ERROR) - { - ChipLogProgress(DeviceLayer, "Added device %s to dynamic endpoint %d (index=%d)", dev->GetName(), - gCurrentEndpointId, index); - return index; - } - if (err != CHIP_ERROR_ENDPOINT_EXISTS) - { - return -1; // Return error as endpoint addition failed due to an error other than endpoint already exists - } - // Increment the endpoint ID and handle wrap condition - if (++gCurrentEndpointId < gFirstDynamicEndpointId) - { - gCurrentEndpointId = gFirstDynamicEndpointId; - } - retryCount++; - } - ChipLogError(DeviceLayer, "Failed to add dynamic endpoint after %d retries", maxRetries); - return -1; // Return error as all retries are exhausted - } - index++; - } - ChipLogProgress(DeviceLayer, "Failed to add dynamic endpoint: No endpoints available!"); - return -1; + int bytesWaiting; + ioctl(0, FIONREAD, &bytesWaiting); + return bytesWaiting > 0; } -int RemoveDeviceEndpoint(Device * dev) +void BridgePollingThread() { - uint8_t index = 0; - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + while (true) { - if (gDevices[index] == dev) + if (KeyboardHit()) { - DeviceLayer::StackLock lock; - // Silence complaints about unused ep when progress logging - // disabled. - [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); - gDevices[index] = nullptr; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); - return index; + int ch = getchar(); + if (ch == 'e') + { + ChipLogProgress(NotSpecified, "Exiting....."); + exit(0); + } + continue; } - index++; + + // Sleep to avoid tight loop reading commands + usleep(POLL_INTERVAL_MS * 1000); } - return -1; } -namespace { -void CallReportingCallback(intptr_t closure) -{ - auto path = reinterpret_cast(closure); - MatterReportingAttributeChangeCallback(*path); - Platform::Delete(path); -} +DeviceManager gDeviceManager; -void ScheduleReportingCallback(Device * dev, ClusterId cluster, AttributeId attribute) -{ - auto * path = Platform::New(dev->GetEndpointId(), cluster, attribute); - PlatformMgr().ScheduleWork(CallReportingCallback, reinterpret_cast(path)); -} -} // anonymous namespace +} // namespace -void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) +void ApplicationInit() { - if (itemChangedMask & Device::kChanged_Reachable) - { - ScheduleReportingCallback(dev, BridgedDeviceBasicInformation::Id, BridgedDeviceBasicInformation::Attributes::Reachable::Id); - } - - if (itemChangedMask & Device::kChanged_Name) - { - ScheduleReportingCallback(dev, BridgedDeviceBasicInformation::Id, BridgedDeviceBasicInformation::Attributes::NodeLabel::Id); - } + // Start a thread for bridge polling + std::thread pollingThread(BridgePollingThread); + pollingThread.detach(); } -Protocols::InteractionModel::Status HandleReadBridgedDeviceBasicAttribute(Device * dev, chip::AttributeId attributeId, - uint8_t * buffer, uint16_t maxReadLength) -{ - using namespace BridgedDeviceBasicInformation::Attributes; - - ChipLogProgress(DeviceLayer, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, maxReadLength); +void ApplicationShutdown() {} - if ((attributeId == Reachable::Id) && (maxReadLength == 1)) - { - *buffer = dev->IsReachable() ? 1 : 0; - } - else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) - { - MutableByteSpan zclNameSpan(buffer, maxReadLength); - MakeZclCharString(zclNameSpan, dev->GetName()); - } - else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) - { - uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; - memcpy(buffer, &rev, sizeof(rev)); - } - else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) - { - uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; - memcpy(buffer, &featureMap, sizeof(featureMap)); - } - else +int main(int argc, char * argv[]) +{ + if (ChipLinuxAppInit(argc, argv) != 0) { - return Protocols::InteractionModel::Status::Failure; + return -1; } - return Protocols::InteractionModel::Status::Success; + ChipLinuxAppMainLoop(); + + return 0; } +// External attribute read callback function Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, uint16_t maxReadLength) { - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + AttributeId attributeId = attributeMetadata->attributeId; - Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; - - if ((endpointIndex < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) && (gDevices[endpointIndex] != nullptr)) + Device * dev = gDeviceManager.GetDevice(endpointIndex); + if (dev != nullptr && clusterId == app::Clusters::BridgedDeviceBasicInformation::Id) { - Device * dev = gDevices[endpointIndex]; + using namespace app::Clusters::BridgedDeviceBasicInformation::Attributes; + ChipLogProgress(NotSpecified, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, + maxReadLength); - if (clusterId == BridgedDeviceBasicInformation::Id) + if ((attributeId == Reachable::Id) && (maxReadLength == 1)) + { + *buffer = dev->IsReachable() ? 1 : 0; + } + else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) + { + MutableByteSpan zclNameSpan(buffer, maxReadLength); + MakeZclCharString(zclNameSpan, dev->GetName()); + } + else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) + { + uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; + memcpy(buffer, &rev, sizeof(rev)); + } + else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) + { + uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; + memcpy(buffer, &featureMap, sizeof(featureMap)); + } + else { - ret = HandleReadBridgedDeviceBasicAttribute(dev, attributeMetadata->attributeId, buffer, maxReadLength); + return Protocols::InteractionModel::Status::Failure; } + return Protocols::InteractionModel::Status::Success; } - return ret; + return Protocols::InteractionModel::Status::Failure; } +// External attribute write callback function Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer) { - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; - if (endpointIndex < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + Device * dev = gDeviceManager.GetDevice(endpointIndex); + if (dev != nullptr && dev->IsReachable()) { - Device * dev = gDevices[endpointIndex]; - - if (dev->IsReachable()) - { - ChipLogProgress(DeviceLayer, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); - ret = Protocols::InteractionModel::Status::Success; - } + ChipLogProgress(NotSpecified, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); + ret = Protocols::InteractionModel::Status::Success; } return ret; } - -#define POLL_INTERVAL_MS (100) -uint8_t poll_prescale = 0; - -bool kbhit() -{ - int byteswaiting; - ioctl(0, FIONREAD, &byteswaiting); - return byteswaiting > 0; -} - -const int16_t oneDegree = 100; - -void * bridge_polling_thread(void * context) -{ - while (true) - { - if (kbhit()) - { - int ch = getchar(); - - // Commands used for the actions bridge test plan. - if (ch == 'e') - { - ChipLogProgress(DeviceLayer, "Exiting....."); - exit(0); - } - continue; - } - - // Sleep to avoid tight loop reading commands - usleep(POLL_INTERVAL_MS * 1000); - } - - return nullptr; -} - -void ApplicationInit() -{ - // Clear out the device database - memset(gDevices, 0, sizeof(gDevices)); - - // Set starting endpoint id where dynamic endpoints will be assigned, which - // will be the next consecutive endpoint id after the last fixed endpoint. - gFirstDynamicEndpointId = static_cast( - static_cast(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1))) + 1); - gCurrentEndpointId = gFirstDynamicEndpointId; - - { - pthread_t poll_thread; - int res = pthread_create(&poll_thread, nullptr, bridge_polling_thread, nullptr); - if (res) - { - printf("Error creating polling thread: %d\n", res); - exit(1); - } - } -} - -void ApplicationShutdown() {} - -int main(int argc, char * argv[]) -{ - if (ChipLinuxAppInit(argc, argv) != 0) - { - return -1; - } - - ChipLinuxAppMainLoop(); - - return 0; -} diff --git a/examples/kotlin-matter-controller/README.md b/examples/kotlin-matter-controller/README.md index c4e84cbd5982a4..71a954e711e0b5 100644 --- a/examples/kotlin-matter-controller/README.md +++ b/examples/kotlin-matter-controller/README.md @@ -109,7 +109,7 @@ the top Matter directory: ``` The Java executable file `kotlin-matter-controller` will be generated at -`out/android-x86-kotlin-matter-controller/bin/` +`out/linux-x64-kotlin-matter-controller/bin/` Run the kotlin-matter-controller diff --git a/examples/light-switch-app/infineon/cyw30739/README.md b/examples/light-switch-app/infineon/cyw30739/README.md index 530cfde2501498..70d650cfef97a3 100644 --- a/examples/light-switch-app/infineon/cyw30739/README.md +++ b/examples/light-switch-app/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/light-switch-app/infineon/cyw30739 out/cyw30739-light-switch \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode diff --git a/examples/light-switch-app/qpg/BUILD.gn b/examples/light-switch-app/qpg/BUILD.gn index 055cfd46f95abb..84ec9dd64173ac 100644 --- a/examples/light-switch-app/qpg/BUILD.gn +++ b/examples/light-switch-app/qpg/BUILD.gn @@ -137,7 +137,7 @@ qpg_executable("light_switch_app") { } } - ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld" + ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld" inputs = [ ldscript ] diff --git a/examples/light-switch-app/qpg/args.gni b/examples/light-switch-app/qpg/args.gni index 64db0987b3d7d6..9a69cd16959f6d 100644 --- a/examples/light-switch-app/qpg/args.gni +++ b/examples/light-switch-app/qpg/args.gni @@ -30,7 +30,7 @@ chip_enable_icd_lit = true chip_stack_lock_tracking = "none" matter_device_vid = "0xFFF1" -matter_device_pid = "0x8006" +matter_device_pid = "0x8004" pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" pw_assert_BACKEND = "$dir_pw_assert_log:check_backend" diff --git a/examples/light-switch-app/qpg/include/CHIPProjectConfig.h b/examples/light-switch-app/qpg/include/CHIPProjectConfig.h index b6d7572839ec75..09df64a412938e 100644 --- a/examples/light-switch-app/qpg/include/CHIPProjectConfig.h +++ b/examples/light-switch-app/qpg/include/CHIPProjectConfig.h @@ -40,9 +40,18 @@ * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION * * A uint32_t identifying the software version running on the device. + * First two bytes are reflecting the Matter standard + * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major + * version and the second nibble of the first byte has the minor number. The last byte holds the patch number. + * example for SDK v0.1.5 with Matter v1.2 standard: + * 0x01020105 */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003 // Can't be removed, needed for OTA file generation. +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105 +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106 +#endif #endif /** @@ -53,7 +62,11 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" // Can't be removed, needed for OTA file generation. +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5" +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6" +#endif #endif /** diff --git a/examples/light-switch-app/qpg/include/SwitchManager.h b/examples/light-switch-app/qpg/include/SwitchManager.h index 3f429f0c79a54e..41eedd10af4f13 100644 --- a/examples/light-switch-app/qpg/include/SwitchManager.h +++ b/examples/light-switch-app/qpg/include/SwitchManager.h @@ -54,8 +54,8 @@ class SwitchManager }; void Init(void); - static void GenericSwitchInitialPress(void); - static void GenericSwitchReleasePress(void); + static void GenericSwitchInitialPressHandler(AppEvent * aEvent); + static void GenericSwitchReleasePressHandler(AppEvent * aEvent); static void ToggleHandler(AppEvent * aEvent); static void LevelHandler(AppEvent * aEvent); static void ColorHandler(AppEvent * aEvent); diff --git a/examples/light-switch-app/qpg/src/AppTask.cpp b/examples/light-switch-app/qpg/src/AppTask.cpp index 318e61b1e875c8..4be2f4eeefbf39 100644 --- a/examples/light-switch-app/qpg/src/AppTask.cpp +++ b/examples/light-switch-app/qpg/src/AppTask.cpp @@ -297,13 +297,13 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed) case APP_FUNCTION2_SWITCH: { if (!btnPressed) { - ChipLogProgress(NotSpecified, "Switch initial press"); - SwitchMgr().GenericSwitchInitialPress(); + ChipLogProgress(NotSpecified, "Switch release press"); + button_event.Handler = SwitchMgr().GenericSwitchReleasePressHandler; } else { - ChipLogProgress(NotSpecified, "Switch release press"); - SwitchMgr().GenericSwitchReleasePress(); + ChipLogProgress(NotSpecified, "Switch initial press"); + button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler; } break; } @@ -516,11 +516,15 @@ void AppTask::UpdateLEDs(void) // If the system has ble connection(s) uptill the stage above, THEN blink // the LEDs at an even rate of 100ms. // - // Otherwise, blink the LED ON for a very short time. + // Otherwise, turn the LED OFF. if (sIsThreadProvisioned && sIsThreadEnabled) { qvIO_LedSet(SYSTEM_STATE_LED, true); } + else if (sIsThreadProvisioned && !sIsThreadEnabled) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); + } else if (sHaveBLEConnections) { qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); @@ -532,7 +536,7 @@ void AppTask::UpdateLEDs(void) else { // not commissioned yet - qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); + qvIO_LedSet(SYSTEM_STATE_LED, false); } } diff --git a/examples/light-switch-app/qpg/src/SwitchManager.cpp b/examples/light-switch-app/qpg/src/SwitchManager.cpp index 45d7079b578598..58b2f1d9bd8889 100644 --- a/examples/light-switch-app/qpg/src/SwitchManager.cpp +++ b/examples/light-switch-app/qpg/src/SwitchManager.cpp @@ -107,20 +107,40 @@ void SwitchManager::ColorHandler(AppEvent * aEvent) DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); } -void SwitchManager::GenericSwitchInitialPress(void) +void SwitchManager::GenericSwitchInitialPressHandler(AppEvent * aEvent) { // Press moves Position from 0 (idle) to 1 (press) uint8_t newPosition = 1; - SystemLayer().ScheduleLambda( - [newPosition] { chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); }); + if (aEvent->Type != AppEvent::kEventType_Button) + { + ChipLogError(NotSpecified, "Event type not supported!"); + return; + } + + ChipLogProgress(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition); + SystemLayer().ScheduleLambda([newPosition] { + chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); + // InitialPress event takes newPosition as event data + chip::app::Clusters::SwitchServer::Instance().OnInitialPress(GENERICSWITCH_ENDPOINT_ID, newPosition); + }); } -void SwitchManager::GenericSwitchReleasePress(void) +void SwitchManager::GenericSwitchReleasePressHandler(AppEvent * aEvent) { // Release moves Position from 1 (press) to 0 uint8_t newPosition = 0; - SystemLayer().ScheduleLambda( - [newPosition] { chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); }); + if (aEvent->Type != AppEvent::kEventType_Button) + { + ChipLogError(NotSpecified, "Event type not supported!"); + return; + } + + ChipLogProgress(NotSpecified, "GenericSwitchReleasePress new position %d", newPosition); + SystemLayer().ScheduleLambda([newPosition] { + chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); + // Short Release event takes newPosition as event data + chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, newPosition); + }); } diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index e3da4bf1d979f6..25937577420272 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -2404,6 +2404,8 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute supportedThreadFeatures; + callback attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -2441,19 +2443,21 @@ endpoint 0 { callback attribute networkInterfaces; callback attribute rebootCount; callback attribute upTime; + callback attribute totalOperationalHours; callback attribute bootReason; callback attribute activeHardwareFaults; callback attribute activeRadioFaults; callback attribute activeNetworkFaults; - ram attribute testEventTriggersEnabled default = 0; + callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; } server cluster SoftwareDiagnostics { @@ -2729,13 +2733,15 @@ endpoint 2 { } server cluster Switch { + emits event InitialPress; + emits event ShortRelease; ram attribute numberOfPositions default = 2; ram attribute currentPosition default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 1; + ram attribute featureMap default = 6; ram attribute clusterRevision default = 1; } } diff --git a/examples/light-switch-app/qpg/zap/switch.zap b/examples/light-switch-app/qpg/zap/switch.zap index 9a33d739328304..b04ff644b1192c 100644 --- a/examples/light-switch-app/qpg/zap/switch.zap +++ b/examples/light-switch-app/qpg/zap/switch.zap @@ -1622,6 +1622,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -1859,6 +1891,22 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 } ], "attributes": [ @@ -1874,8 +1922,8 @@ "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { @@ -1890,8 +1938,8 @@ "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { @@ -1910,6 +1958,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "BootReason", "code": 4, @@ -1981,10 +2045,10 @@ "side": "server", "type": "boolean", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "false", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2022,22 +2086,6 @@ "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, @@ -2082,8 +2130,8 @@ "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 } ], @@ -6045,7 +6093,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "6", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6067,6 +6115,22 @@ "maxInterval": 65534, "reportableChange": 0 } + ], + "events": [ + { + "name": "InitialPress", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShortRelease", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } ] } ] diff --git a/examples/lighting-app/infineon/cyw30739/README.md b/examples/lighting-app/infineon/cyw30739/README.md index 9dbfc23fe9e52f..b1ff7aa5304902 100644 --- a/examples/lighting-app/infineon/cyw30739/README.md +++ b/examples/lighting-app/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/lighting-app/infineon/cyw30739 out/cyw30739-light \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode @@ -190,19 +214,7 @@ Put the CYW30739 in to the recovery mode before running the flash script. [Openthread_border_router](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/openthread_border_router_pi.md) for more information on how to setup a border router on a raspberryPi. -- You can provision and control the Chip device using the python controller, - Chip tool standalone, Android or iOS app +- You can provision and control the device using the Python controller REPL, + chip-tool standalone, Android or iOS app [Python Controller](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) - - Here is an example with the Python controller: - - ```bash - $ chip-device-ctrl - chip-device-ctrl > connect -ble 3840 20202021 1234 - chip-device-ctrl > zcl NetworkCommissioning AddThreadNetwork 1234 0 0 operationalDataset=hex:0e080000000000000000000300000b35060004001fffe00208dead00beef00cafe0708fddead00beef000005108e11d8ea8ffaa875713699f59e8807e0030a4f70656e5468726561640102c2980410edc641eb63b100b87e90a9980959befc0c0402a0fff8 breadcrumb=0 timeoutMs=1000 - chip-device-ctrl > zcl NetworkCommissioning EnableNetwork 1234 0 0 networkID=hex:dead00beef00cafe breadcrumb=0 timeoutMs=1000 - chip-device-ctrl > close-ble - chip-device-ctrl > resolve 1234 - chip-device-ctrl > zcl OnOff Toggle 1234 1 0 - ``` diff --git a/examples/lighting-app/python/README.md b/examples/lighting-app/python/README.md index 8e34e59dea5847..a935a165c93e4c 100644 --- a/examples/lighting-app/python/README.md +++ b/examples/lighting-app/python/README.md @@ -32,17 +32,6 @@ cd examples/lighting-app/python python lighting.py ``` -Control the Python lighting matter device: +Control the Python lighting matter device using the Python controller REPL: -```shell -source ./out/python_env/bin/activate - -chip-device-ctrl - -chip-device-ctrl > connect -ble 3840 20202021 12344321 -chip-device-ctrl > zcl NetworkCommissioning AddOrUpdateWiFiNetwork 12344321 0 0 ssid=str:YOUR_SSID credentials=str:YOUR_PASSWORD breadcrumb=0 -chip-device-ctrl > zcl NetworkCommissioning ConnectNetwork 12344321 0 0 networkID=str:YOUR_SSID breadcrumb=0 -chip-device-ctrl > close-ble -chip-device-ctrl > resolve 5544332211 1 (pass appropriate fabric ID and node ID, you can get this from get-fabricid) -chip-device-ctrl > zcl OnOff Toggle 12344321 1 0 -``` +[Python Controller](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) diff --git a/examples/lighting-app/qpg/BUILD.gn b/examples/lighting-app/qpg/BUILD.gn index c835e0bf3cdaed..2677357a2f21e1 100644 --- a/examples/lighting-app/qpg/BUILD.gn +++ b/examples/lighting-app/qpg/BUILD.gn @@ -140,7 +140,7 @@ qpg_executable("lighting_app") { } } - ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld" + ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld" inputs = [ ldscript ] diff --git a/examples/lighting-app/qpg/include/AppTask.h b/examples/lighting-app/qpg/include/AppTask.h index 1021b7af7dbdcc..52023c2bde2125 100644 --- a/examples/lighting-app/qpg/include/AppTask.h +++ b/examples/lighting-app/qpg/include/AppTask.h @@ -63,6 +63,7 @@ class AppTask static void LightingActionEventHandler(AppEvent * aEvent); static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState); + static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static void UpdateLEDs(void); diff --git a/examples/lighting-app/qpg/include/CHIPProjectConfig.h b/examples/lighting-app/qpg/include/CHIPProjectConfig.h index 2e23b214716be1..f20fde352c199e 100644 --- a/examples/lighting-app/qpg/include/CHIPProjectConfig.h +++ b/examples/lighting-app/qpg/include/CHIPProjectConfig.h @@ -40,9 +40,18 @@ * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION * * A uint32_t identifying the software version running on the device. + * First two bytes are reflecting the Matter standard + * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major + * version and the second nibble of the first byte has the minor number. The last byte holds the patch number. + * example for SDK v0.1.5 with Matter v1.2 standard: + * 0x01020105 */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003 +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105 +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106 +#endif #endif /** @@ -53,8 +62,13 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5" +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6" +#endif #endif + /** * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE * diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 2bc0ffafec5d2a..d870ea24deeb13 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -28,7 +28,6 @@ #include "AppEvent.h" #include "AppTask.h" #include "ota.h" -#include "powercycle_counting.h" #include @@ -70,6 +69,7 @@ using namespace ::chip::DeviceLayer; #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 #define QPG_LIGHT_ENDPOINT_ID (1) +#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * 3600) // this value must be multiplication of 3600 static uint8_t countdown = 0; @@ -96,18 +96,19 @@ StaticTask_t appTaskStruct; Clusters::Identify::EffectIdentifierEnum sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; -// Define a custom attribute persister which makes actual write of the attribute value +// Define a custom attribute persister which makes actual write of the ColorX attribute value // to the non-volatile storage only when it has remained constant for 5 seconds. This is to reduce -// the flash wearout when the attribute changes frequently as a result of commands. +// the flash wearout when the attribute changes frequently as a result of MoveToLevel command. // DeferredAttribute object describes a deferred attribute, but also holds a buffer with a value to // be written, so it must live so long as the DeferredAttributePersistenceProvider object. // -DeferredAttribute gPersisters[] = { DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id, - Clusters::ColorControl::Attributes::CurrentX::Id)), - DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id, - Clusters::ColorControl::Attributes::CurrentY::Id)), - DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::LevelControl::Id, - Clusters::LevelControl::Attributes::CurrentLevel::Id)) +DeferredAttribute gPersisters[] = { + DeferredAttribute( + ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id, Clusters::ColorControl::Attributes::CurrentHue::Id)), + DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id, + Clusters::ColorControl::Attributes::CurrentSaturation::Id)), + DeferredAttribute( + ConcreteAttributePath(kLightEndpointId, Clusters::LevelControl::Id, Clusters::LevelControl::Attributes::CurrentLevel::Id)) }; @@ -342,6 +343,14 @@ CHIP_ERROR AppTask::Init() sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); UpdateLEDs(); + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, this); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } + return err; } @@ -438,6 +447,32 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState) sAppTask.PostEvent(&event); } +void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogProgress(NotSpecified, "HourlyTimer"); + + CHIP_ERROR err; + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, nullptr); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } +} + void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) { if (aEvent->Type != AppEvent::kEventType_Timer) @@ -670,11 +705,15 @@ void AppTask::UpdateLEDs(void) // If the system has ble connection(s) uptill the stage above, THEN blink // the LEDs at an even rate of 100ms. // - // Otherwise, blink the LED ON for a very short time. + // Otherwise, turn the LED OFF. if (sIsThreadProvisioned && sIsThreadEnabled) { qvIO_LedSet(SYSTEM_STATE_LED, true); } + else if (sIsThreadProvisioned && !sIsThreadEnabled) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); + } else if (sHaveBLEConnections) { qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); @@ -686,7 +725,7 @@ void AppTask::UpdateLEDs(void) else { // not commisioned yet - qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); + qvIO_LedSet(SYSTEM_STATE_LED, false); } } diff --git a/examples/lighting-app/qpg/src/ZclCallbacks.cpp b/examples/lighting-app/qpg/src/ZclCallbacks.cpp index e2255bd4e76684..319ea28f7ffa2d 100644 --- a/examples/lighting-app/qpg/src/ZclCallbacks.cpp +++ b/examples/lighting-app/qpg/src/ZclCallbacks.cpp @@ -160,8 +160,6 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & */ void emberAfOnOffClusterInitCallback(EndpointId endpoint) { - uint8_t levelValue; - XyColor_t xy; bool onOffValue = false; app::DataModel::Nullable currentLevel; Protocols::InteractionModel::Status status; @@ -181,20 +179,11 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint) return; } - levelValue = currentLevel.Value(); - - status = ColorControl::Attributes::CurrentY::Get(endpoint, &xy.y); - if (status != Protocols::InteractionModel::Status::Success) - { - return; - } - status = ColorControl::Attributes::CurrentX::Get(endpoint, &xy.x); - if (status != Protocols::InteractionModel::Status::Success) - { - return; - } - ChipLogProgress(Zcl, "restore level: %u", levelValue); - LightingMgr().InitiateAction(LightingManager::LEVEL_ACTION, 0, 1, &levelValue); - ChipLogProgress(Zcl, "restore XY color: %u|%u", xy.x, xy.y); - LightingMgr().InitiateAction(LightingManager::COLOR_ACTION_XY, 0, sizeof(xy), (uint8_t *) &xy); + HsvColor_t hsv; + status = ColorControl::Attributes::CurrentHue::Get(endpoint, &hsv.h); + assert(status == Protocols::InteractionModel::Status::Success); + status = ColorControl::Attributes::CurrentSaturation::Get(endpoint, &hsv.s); + assert(status == Protocols::InteractionModel::Status::Success); + ChipLogProgress(Zcl, "restore HSV color: %u|%u", hsv.h, hsv.s); + LightingMgr().InitiateAction(LightingManager::COLOR_ACTION_HSV, 0, sizeof(hsv), (uint8_t *) &hsv); } diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index 0fb3d8b9dcf7bc..72387fd4d25ad8 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -2035,6 +2035,8 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute supportedThreadFeatures; + callback attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; @@ -2070,6 +2072,7 @@ endpoint 0 { callback attribute networkInterfaces; callback attribute rebootCount; callback attribute upTime; + callback attribute totalOperationalHours; callback attribute bootReason; callback attribute activeHardwareFaults; callback attribute activeRadioFaults; @@ -2296,7 +2299,7 @@ endpoint 1 { 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; @@ -2343,11 +2346,11 @@ endpoint 1 { } server cluster ColorControl { - ram attribute currentHue default = 0x00; - ram attribute currentSaturation default = 0x00; + persist attribute currentHue default = 0x00; + persist attribute currentSaturation default = 0x00; ram attribute remainingTime default = 0x0000; - persist attribute currentX default = 0x616B; - persist attribute currentY default = 0x607D; + ram attribute currentX default = 0x616B; + ram attribute currentY default = 0x607D; ram attribute colorTemperatureMireds default = 0x00FA; ram attribute colorMode default = 0x01; ram attribute options default = 0x00; diff --git a/examples/lighting-app/qpg/zap/light.zap b/examples/lighting-app/qpg/zap/light.zap index 21dbe0235bc755..2c0a76acead00e 100644 --- a/examples/lighting-app/qpg/zap/light.zap +++ b/examples/lighting-app/qpg/zap/light.zap @@ -1542,6 +1542,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -1814,6 +1846,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "BootReason", "code": 4, @@ -4663,7 +4711,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "5", + "defaultValue": "6", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5262,7 +5310,7 @@ "side": "server", "type": "int8u", "included": 1, - "storageOption": "RAM", + "storageOption": "NVM", "singleton": 0, "bounded": 0, "defaultValue": "0x00", @@ -5278,7 +5326,7 @@ "side": "server", "type": "int8u", "included": 1, - "storageOption": "RAM", + "storageOption": "NVM", "singleton": 0, "bounded": 0, "defaultValue": "0x00", @@ -5310,7 +5358,7 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "NVM", + "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "0x616B", @@ -5326,7 +5374,7 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "NVM", + "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "0x607D", diff --git a/examples/lighting-app/silabs/src/AppTask.cpp b/examples/lighting-app/silabs/src/AppTask.cpp index 338d6d85e2ef51..4f74ca7f348e78 100644 --- a/examples/lighting-app/silabs/src/AppTask.cpp +++ b/examples/lighting-app/silabs/src/AppTask.cpp @@ -24,7 +24,6 @@ #include "LEDWidget.h" #include -#include #include #include #include diff --git a/examples/lighting-app/stm32/BUILD.gn b/examples/lighting-app/stm32/BUILD.gn index 6adecf2d04c1f5..3ac2fd365f11fa 100644 --- a/examples/lighting-app/stm32/BUILD.gn +++ b/examples/lighting-app/stm32/BUILD.gn @@ -54,24 +54,22 @@ if (stm32_board == "STM32WB5MM-DK") { } stm32_sdk("sdk") { - if (stm32_board == "STM32WB5MM-DK") { - sources = [ - "${examples_plat_dir}/config_files/STM32WB5/FreeRTOSConfig.h", - "${examples_plat_dir}/config_files/STM32WB5/matter_config.h", - "${stm32_project_dir}/include/STM32WB5/CHIPProjectConfig.h", - ] - } - include_dirs = [ "${chip_root}/src/platform/stm32", "${examples_plat_dir}", + "${stm32_project_dir}/include/STM32WB5", "${chip_root}/src/lib", ] if (stm32_board == "STM32WB5MM-DK") { + sources = [ + "${examples_plat_dir}/config_files/STM32WB5/FreeRTOSConfig.h", + "${examples_plat_dir}/config_files/STM32WB5/matter_config.h", + "${stm32_project_dir}/include/STM32WB5/CHIPProjectConfig.h", + ] + include_dirs += [ "${stm32_project_dir}/include/STM32WB5", - "${examples_plat_dir}/config_files/STM32WB5", "${chip_root}/src/include", ] } @@ -100,25 +98,29 @@ stm32_executable("lighting_app") { "${stm32_board_src}/STM32_WPAN/App/app_matter.c", "${stm32_board_src}/STM32_WPAN/App/app_thread.c", "${stm32_board_src}/STM32_WPAN/App/custom_stm.c", + + #"${stm32_board_src}/STM32_WPAN/Target/hw_ipcc.c", "${stm32_board_src}/Src/app_entry.cpp", "${stm32_board_src}/Src/main.cpp", + "${stm32_board_src}/Src/ota.cpp", "src/STM32WB5/AppTask.cpp", + "src/STM32WB5/IdentifierEffect.cpp", "src/STM32WB5/LightingManager.cpp", "src/STM32WB5/ZclCallbacks.cpp", ] + + deps = [ + ":sdk", + "${chip_root}/examples/lighting-app/lighting-common", + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/lib", + "${chip_root}/src/setup_payload", + ] } # Add the startup file to the target sources += [ "${examples_plat_dir}/startup_files/startup_${stm32_mcu}.s" ] - deps = [ - ":sdk", - "${chip_root}/examples/lighting-app/lighting-common", - "${chip_root}/examples/providers:device_info_provider", - "${chip_root}/src/lib", - "${chip_root}/src/setup_payload", - ] - defines += [ "DEBUG", "USE_HAL_DRIVER", diff --git a/examples/lighting-app/stm32/include/STM32WB5/AppTask.h b/examples/lighting-app/stm32/include/STM32WB5/AppTask.h index 5c0344cc8c687a..641233581872d3 100644 --- a/examples/lighting-app/stm32/include/STM32WB5/AppTask.h +++ b/examples/lighting-app/stm32/include/STM32WB5/AppTask.h @@ -26,6 +26,7 @@ #include "LightingManager.h" #include "app_entry.h" +#include #include #include #define APP_NAME "Lighting-app" @@ -55,9 +56,10 @@ class AppTask static void FunctionHandler(AppEvent * aEvent); static void LightingActionEventHandler(AppEvent * aEvent); static void TimerEventHandler(TimerHandle_t xTimer); - static void DelayNvmHandler(TimerHandle_t xTimer); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); +#if (OTA_SUPPORT == 0) static void UpdateLCD(void); +#endif static void UpdateNvmEventHandler(AppEvent * aEvent); enum Function_t diff --git a/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h b/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h index a911c565e95a1b..6540d718328090 100644 --- a/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h +++ b/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h @@ -23,16 +23,26 @@ */ #ifndef CHIPPROJECTCONFIG_H #define CHIPPROJECTCONFIG_H +#include "app_conf.h" // Use a default pairing code if one hasn't been provisioned in flash. -#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 -#endif #ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 #endif +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +// For convenience, Chip Security Test Mode can be enabled and the +// requirement for authentication in various protocols can be disabled. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 + /** * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID * @@ -73,6 +83,25 @@ */ #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 +/** + * CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY + * + * Enables the use of a hard-coded default Chip device id and credentials if no device id + * is found in Chip NV storage. + * + * This option is for testing only and should be disabled in production releases. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY 34 + +// For convenience, enable Chip Security Test Mode and disable the requirement for +// authentication in various protocols. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 +#define CHIP_CONFIG_REQUIRE_AUTH 1 + /** * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING * @@ -84,6 +113,15 @@ #define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" #endif +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + * + * A monothonic number identifying the software version running on the device. + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 1 +#endif + /** * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION * diff --git a/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h b/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h index aeb0ac1b8913da..e1ff4e30648486 100644 --- a/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h +++ b/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h @@ -76,7 +76,7 @@ extern uint32_t SystemCoreClock; #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_TICKLESS_IDLE 0 +#define configUSE_TICKLESS_IDLE 2 /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ /* Defaults to size_t for backward compatibility, but can be changed if lengths will always be less than the number of bytes in a size_t. */ @@ -172,19 +172,20 @@ standard names. */ /* USER CODE BEGIN Defines */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ // #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 /* required only for Keil but does not hurt otherwise */ -#define configGENERATE_RUN_TIME_STATS 1 +/*#define configGENERATE_RUN_TIME_STATS 1 -#if (configGENERATE_RUN_TIME_STATS == 1) +#if( configGENERATE_RUN_TIME_STATS == 1 ) -extern void RTOS_AppConfigureTimerForRuntimeStats(); + extern void RTOS_AppConfigureTimerForRuntimeStats(); -extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); + extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() -#define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() + #define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() #endif +*/ /* USER CODE END Defines */ diff --git a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp index d102f8a9dfd421..5841f15264bad4 100644 --- a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp +++ b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp @@ -24,12 +24,12 @@ #include "cmsis_os.h" #include "dbg_trace.h" #include "flash_wb.h" +#include "ota.h" #include "ssd1315.h" #include "stm32_lcd.h" #include "stm32_lpm.h" #include "stm32wb5mm_dk_lcd.h" -#include "stm_logging.h" #if HIGHWATERMARK #include "memory_buffer_alloc.h" #endif @@ -65,16 +65,12 @@ using chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr; AppTask AppTask::sAppTask; chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#define APP_FUNCTION_BUTTON BUTTON_USER1 -#define STM32ThreadDataSet "STM32DataSet" #define APP_EVENT_QUEUE_SIZE 10 #define NVM_TIMEOUT 1000 // timer to handle PB to save data in nvm or do a factory reset -#define DELAY_NVM 5000 // save data in nvm after commissioning with a delay of 5 sec #define STM32_LIGHT_ENDPOINT_ID 1 static QueueHandle_t sAppEventQueue; TimerHandle_t sPushButtonTimeoutTimer; -TimerHandle_t DelayNvmTimer; const osThreadAttr_t AppTask_attr = { .name = APPTASK_NAME, .attr_bits = APP_ATTR_BITS, .cb_mem = APP_CB_MEM, @@ -92,6 +88,8 @@ static bool sHaveFabric = false; static uint8_t NvmTimerCpt = 0; static uint8_t NvmButtonStateCpt = 0; +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + CHIP_ERROR AppTask::StartAppTask() { sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); @@ -134,15 +132,7 @@ CHIP_ERROR AppTask::Init() TimerEventHandler // timer callback handler ); - DelayNvmTimer = xTimerCreate("Delay_NVM", // Just a text name, not used by the RTOS kernel - DELAY_NVM, // == default timer period (mS) - pdFALSE, // timer reload - 0, // init timer - DelayNvmHandler // timer callback handler - ); - ThreadStackMgr().InitThreadStack(); - ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); PlatformMgr().AddEventHandler(MatterEventHandler, 0); @@ -174,6 +164,9 @@ CHIP_ERROR AppTask::Init() initParams.endpointNativeParams = static_cast(&nativeParams); chip::Server::GetInstance().Init(initParams); + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + ConfigurationMgr().LogDeviceConfig(); // Open commissioning after boot if no fabric was available @@ -186,23 +179,13 @@ CHIP_ERROR AppTask::Init() } else { // try to attach to the thread network - uint8_t datasetBytes[Thread::kSizeOperationalDataset]; - size_t datasetLength = 0; + sHaveFabric = true; +#if (CFG_LCD_SUPPORTED == 1) char Message[20]; snprintf(Message, sizeof(Message), "Fabric Found: %d", chip::Server::GetInstance().GetFabricTable().FabricCount()); - APP_BLE_Init_Dyn_3(); UTIL_LCD_DisplayStringAt(0, LINE(1), (uint8_t *) Message, LEFT_MODE); BSP_LCD_Refresh(0); - CHIP_ERROR error = KeyValueStoreMgr().Get(STM32ThreadDataSet, datasetBytes, sizeof(datasetBytes), &datasetLength); - if (error == CHIP_NO_ERROR) - { - ThreadStackMgr().SetThreadProvision(ByteSpan(datasetBytes, datasetLength)); - ThreadStackMgr().SetThreadEnabled(true); - } - else - { - APP_DBG("Thread network Data set was not found"); - } +#endif } err = PlatformMgr().StartEventLoopTask(); @@ -225,7 +208,6 @@ CHIP_ERROR AppTask::InitMatter() } else { - APP_DBG("Init CHIP stack"); err = PlatformMgr().InitChipStack(); if (err != CHIP_NO_ERROR) { @@ -248,14 +230,14 @@ void AppTask::AppTaskMain(void * pvParameter) #endif // endif HIGHWATERMARK if (err != CHIP_NO_ERROR) { - APP_DBG("App task init failled "); + APP_DBG("App task init failed "); } APP_DBG("App Task started"); while (true) { - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY); while (eventReceived == pdTRUE) { sAppTask.DispatchEvent(&event); @@ -309,7 +291,7 @@ void AppTask::ButtonEventHandler(Push_Button_st * Button) button_event.ButtonEvent.ButtonIdx = Button->Pushed_Button; button_event.ButtonEvent.Action = Button->State; - if (Button->Pushed_Button == APP_FUNCTION_BUTTON) + if (Button->Pushed_Button == BUTTON_USER1) { // Hand off to Functionality handler - depends on duration of press button_event.Handler = FunctionHandler; @@ -344,12 +326,16 @@ void AppTask::TimerEventHandler(TimerHandle_t xTimer) } else if ((NvmTimerCpt > NvmButtonStateCpt) && (NvmTimerCpt <= 2)) { - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = UpdateNvmEventHandler; xTimerStop(sPushButtonTimeoutTimer, 0); - sAppTask.mFunction = kFunction_SaveNvm; - sAppTask.PostEvent(&event); + if (sHaveFabric == true) + { + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + xTimerStop(sPushButtonTimeoutTimer, 0); + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); + } } } @@ -366,30 +352,40 @@ void AppTask::FunctionHandler(AppEvent * aEvent) void AppTask::ActionInitiated(LightingManager::Action_t aAction) { // Placeholder for light action +#if (CFG_LCD_SUPPORTED == 1) UTIL_LCD_ClearStringLine(2); +#endif if (aAction == LightingManager::ON_ACTION) { APP_DBG("Light goes on"); +#if (CFG_LCD_SUPPORTED == 1) char Message[11]; snprintf(Message, sizeof(Message), "LED ON %d", LightingMgr().GetLevel()); UTIL_LCD_DisplayStringAt(0, LINE(2), (uint8_t *) Message, CENTER_MODE); +#endif } else if (aAction == LightingManager::OFF_ACTION) { APP_DBG("Light goes off "); +#if (CFG_LCD_SUPPORTED == 1) UTIL_LCD_ClearStringLine(2); +#endif } else if (aAction == LightingManager::LEVEL_ACTION) { if (LightingMgr().IsTurnedOn()) { +#if (CFG_LCD_SUPPORTED == 1) char Message[11]; snprintf(Message, sizeof(Message), "LED ON %d", LightingMgr().GetLevel()); UTIL_LCD_DisplayStringAt(0, LINE(2), (uint8_t *) Message, CENTER_MODE); +#endif APP_DBG("Update level control %d", LightingMgr().GetLevel()); } } +#if (CFG_LCD_SUPPORTED == 1) BSP_LCD_Refresh(0); +#endif } void AppTask::ActionCompleted(LightingManager::Action_t aAction) @@ -459,15 +455,7 @@ void AppTask::UpdateClusterState(void) } } -void AppTask::DelayNvmHandler(TimerHandle_t xTimer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = UpdateNvmEventHandler; - sAppTask.mFunction = kFunction_SaveNvm; - sAppTask.PostEvent(&event); -} - +#if (CFG_LCD_SUPPORTED == 1) void AppTask::UpdateLCD(void) { if (sIsThreadProvisioned && sIsThreadEnabled) @@ -498,6 +486,7 @@ void AppTask::UpdateLCD(void) } BSP_LCD_Refresh(0); } +#endif void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) { @@ -505,13 +494,6 @@ void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) if (sAppTask.mFunction == kFunction_SaveNvm) { - if (sIsThreadProvisioned && sIsThreadEnabled) - { - chip::Thread::OperationalDataset dataset{}; - DeviceLayer::ThreadStackMgrImpl().GetThreadProvision(dataset); - ByteSpan datasetbyte = dataset.AsByteSpan(); - KeyValueStoreMgr().Put(STM32ThreadDataSet, datasetbyte.data(), datasetbyte.size()); - } err = NM_Dump(); if (err == 0) { @@ -520,8 +502,6 @@ void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) else { APP_DBG("Failed to SAVE NVM"); - // restart timer to save nvm later - xTimerStart(DelayNvmTimer, 0); } } else if (sAppTask.mFunction == kFunction_FactoryReset) @@ -537,32 +517,42 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) { case DeviceEventType::kServiceProvisioningChange: { sIsThreadProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kThreadConnectivityChange: { sIsThreadEnabled = (event->ThreadConnectivityChange.Result == kConnectivity_Established); +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kCHIPoBLEConnectionEstablished: { sHaveBLEConnections = true; APP_DBG("kCHIPoBLEConnectionEstablished"); +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kCHIPoBLEConnectionClosed: { sHaveBLEConnections = false; APP_DBG("kCHIPoBLEConnectionClosed"); +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif if (sFabricNeedSaved) { - APP_DBG("Start timer to save nvm after commissioning finish"); - // timer is used to avoid to much traffic on m0 side after the end of a commissioning - xTimerStart(DelayNvmTimer, 0); + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); sFabricNeedSaved = false; } break; @@ -574,18 +564,30 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) // check if ble is on, since before save in nvm we need to stop m0, Better to write in nvm when m0 is less busy if (sHaveBLEConnections == false) { - APP_DBG("Start timer to save nvm after commissioning finish"); - xTimerStart(DelayNvmTimer, 0); sFabricNeedSaved = false; // put to false to avoid save in nvm 2 times + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); } +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kFailSafeTimerExpired: { +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif sFailCommissioning = true; break; } + case DeviceEventType::kDnssdInitialized: +#if (OTA_SUPPORT == 1) + InitializeOTARequestor(); +#endif + break; default: break; } diff --git a/examples/lighting-app/stm32/src/STM32WB5/IdentifierEffect.cpp b/examples/lighting-app/stm32/src/STM32WB5/IdentifierEffect.cpp new file mode 100644 index 00000000000000..ebed8fd6c6e39c --- /dev/null +++ b/examples/lighting-app/stm32/src/STM32WB5/IdentifierEffect.cpp @@ -0,0 +1,66 @@ + + +#include "AppEvent.h" +#include "AppTask.h" +#include + +using namespace ::chip::app; +using namespace ::chip::DeviceLayer; + +Clusters::Identify::EffectIdentifierEnum sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; + +/********************************************************** + * Identify Callbacks + *********************************************************/ + +namespace { +void OnTriggerIdentifyEffectCompleted(chip::System::Layer * systemLayer, void * appState) +{ + sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; +} +} // namespace + +void OnTriggerIdentifyEffect(Identify * identify) +{ + sIdentifyEffect = identify->mCurrentEffectIdentifier; + + if (identify->mEffectVariant != Clusters::Identify::EffectVariantEnum::kDefault) + { + ChipLogDetail(AppServer, "Identify Effect Variant unsupported. Using default"); + } + + switch (sIdentifyEffect) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + case Clusters::Identify::EffectIdentifierEnum::kOkay: + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + SystemLayer().ScheduleLambda([identify] { + (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(5), OnTriggerIdentifyEffectCompleted, + identify); + }); + break; + case Clusters::Identify::EffectIdentifierEnum::kFinishEffect: + SystemLayer().ScheduleLambda([identify] { + (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); + (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(1), OnTriggerIdentifyEffectCompleted, + identify); + }); + break; + case Clusters::Identify::EffectIdentifierEnum::kStopEffect: + SystemLayer().ScheduleLambda( + [identify] { (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); }); + sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + } +} + +Identify gIdentify = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, + OnTriggerIdentifyEffect, +}; diff --git a/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp b/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp index 762ad402274cf6..02002c9250227c 100644 --- a/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp +++ b/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp @@ -1,7 +1,7 @@ +/* USER CODE BEGIN Header */ /* * - * Copyright (c) 2021 Project CHIP Authors - * Copyright (c) 2019 Google LLC. + * Copyright (c) 2020 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* USER CODE END Header */ #include "AppTask.h" #include "LightingManager.h" diff --git a/examples/lock-app/infineon/cyw30739/README.md b/examples/lock-app/infineon/cyw30739/README.md index 6623f77c88c1c4..2b7bd2094154df 100644 --- a/examples/lock-app/infineon/cyw30739/README.md +++ b/examples/lock-app/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/lock-app/infineon/cyw30739 out/cyw30739-lock \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode @@ -190,19 +214,7 @@ Put the CYW30739 in to the recovery mode before running the flash script. [Openthread_border_router](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/openthread_border_router_pi.md) for more information on how to setup a border router on a raspberryPi. -- You can provision and control the Chip device using the python controller, - Chip tool standalone, Android or iOS app +- You can provision and control the device using the Python controller REPL, + chip-tool standalone, Android or iOS app [Python Controller](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) - - Here is an example with the Python controller: - - ```bash - $ chip-device-ctrl - chip-device-ctrl > connect -ble 3840 20202021 1234 - chip-device-ctrl > zcl NetworkCommissioning AddThreadNetwork 1234 0 0 operationalDataset=hex:0e080000000000000000000300000b35060004001fffe00208dead00beef00cafe0708fddead00beef000005108e11d8ea8ffaa875713699f59e8807e0030a4f70656e5468726561640102c2980410edc641eb63b100b87e90a9980959befc0c0402a0fff8 breadcrumb=0 timeoutMs=1000 - chip-device-ctrl > zcl NetworkCommissioning EnableNetwork 1234 0 0 networkID=hex:dead00beef00cafe breadcrumb=0 timeoutMs=1000 - chip-device-ctrl > close-ble - chip-device-ctrl > resolve 1234 - chip-device-ctrl > zcl OnOff Toggle 1234 1 0 - ``` diff --git a/examples/lock-app/qpg/BUILD.gn b/examples/lock-app/qpg/BUILD.gn index 30794878fd1ae8..3db4d0cd1ee86d 100644 --- a/examples/lock-app/qpg/BUILD.gn +++ b/examples/lock-app/qpg/BUILD.gn @@ -54,6 +54,7 @@ qpg_executable("lock_app") { "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${examples_plat_dir}/app/main.cpp", "${examples_plat_dir}/ota/ota.cpp", + "${examples_plat_dir}/powercycle_counting.c", "src/AppTask.cpp", "src/BoltLockManager.cpp", "src/ZclCallbacks.cpp", @@ -83,7 +84,7 @@ qpg_executable("lock_app") { "${examples_plat_dir}/ota", ] - defines = [] + defines = [ "GP_APP_DIVERSITY_POWERCYCLECOUNTING" ] if (chip_enable_pw_rpc) { defines += [ @@ -137,7 +138,7 @@ qpg_executable("lock_app") { } } - ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld" + ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld" inputs = [ ldscript ] diff --git a/examples/lock-app/qpg/include/AppTask.h b/examples/lock-app/qpg/include/AppTask.h index b4ede0e6abde0d..a743a1c224850d 100644 --- a/examples/lock-app/qpg/include/AppTask.h +++ b/examples/lock-app/qpg/include/AppTask.h @@ -50,6 +50,7 @@ class AppTask void UpdateClusterState(); static void ButtonEventHandler(uint8_t btnIdx, bool btnPressed); + static void OpenCommissioning(intptr_t arg); private: friend AppTask & GetAppTask(void); @@ -68,6 +69,7 @@ class AppTask static void LockActionEventHandler(AppEvent * aEvent); static void JammedLockEventHandler(AppEvent * aEvent); static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState); + static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static void UpdateLEDs(void); diff --git a/examples/lock-app/qpg/include/CHIPProjectConfig.h b/examples/lock-app/qpg/include/CHIPProjectConfig.h index 826224654239ca..a35cfc0795697b 100644 --- a/examples/lock-app/qpg/include/CHIPProjectConfig.h +++ b/examples/lock-app/qpg/include/CHIPProjectConfig.h @@ -40,9 +40,18 @@ * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION * * A uint32_t identifying the software version running on the device. + * First two bytes are reflecting the Matter standard + * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major + * version and the second nibble of the first byte has the minor number. The last byte holds the patch number. + * example for SDK v0.1.5 with Matter v1.2 standard: + * 0x01020105 */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003 +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105 +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106 +#endif #endif /** @@ -53,8 +62,13 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5" +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6" +#endif #endif + /** * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE * diff --git a/examples/lock-app/qpg/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp index 7f9d922cc8558d..d2f3298db9b779 100644 --- a/examples/lock-app/qpg/src/AppTask.cpp +++ b/examples/lock-app/qpg/src/AppTask.cpp @@ -16,6 +16,11 @@ * limitations under the License. */ +#if !defined(GP_APP_DIVERSITY_POWERCYCLECOUNTING) +#error This application requires powercycle counting. +#endif + +#include "powercycle_counting.h" #include "qvIO.h" #include "AppConfig.h" @@ -59,6 +64,9 @@ using namespace ::chip::DeviceLayer; #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 #define QPG_LOCK_ENDPOINT_ID (1) +#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * 3600) // this value must be multiplication of 3600 + +#define NMBR_OF_RESETS_BLE_ADVERTISING (3) namespace { TaskHandle_t sAppTaskHandle; @@ -114,15 +122,26 @@ void OnTriggerIdentifyEffect(Identify * identify) switch (sIdentifyEffect) { case Clusters::Identify::EffectIdentifierEnum::kBlink: + ChipLogProgress(Zcl, "kBlink"); + qvIO_LedBlink(LOCK_STATE_LED, 100, 100); + break; case Clusters::Identify::EffectIdentifierEnum::kBreathe: + ChipLogProgress(Zcl, "kBreathe"); + qvIO_LedBlink(LOCK_STATE_LED, 500, 500); + break; case Clusters::Identify::EffectIdentifierEnum::kOkay: + ChipLogProgress(Zcl, "kOkay"); + qvIO_LedBlink(LOCK_STATE_LED, 1000, 1000); + break; case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + ChipLogProgress(Zcl, "kChannelChange"); SystemLayer().ScheduleLambda([identify] { (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(5), OnTriggerIdentifyEffectCompleted, identify); }); break; case Clusters::Identify::EffectIdentifierEnum::kFinishEffect: + ChipLogProgress(Zcl, "kFinishEffect"); SystemLayer().ScheduleLambda([identify] { (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(1), OnTriggerIdentifyEffectCompleted, @@ -130,9 +149,11 @@ void OnTriggerIdentifyEffect(Identify * identify) }); break; case Clusters::Identify::EffectIdentifierEnum::kStopEffect: + ChipLogProgress(Zcl, "kStopEffect"); SystemLayer().ScheduleLambda( [identify] { (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); }); sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; + qvIO_LedSet(LOCK_STATE_LED, false); break; default: ChipLogProgress(Zcl, "No identifier effect"); @@ -204,6 +225,21 @@ void AppTask::InitServer(intptr_t arg) chip::app::DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(extDiscTimeoutSecs); #endif } + +void AppTask::OpenCommissioning(intptr_t arg) +{ + // Enable BLE advertisements + + SystemLayer().ScheduleLambda([] { + CHIP_ERROR err; + err = chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + if (err == CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "BLE advertising started. Waiting for Pairing."); + } + }); +} + CHIP_ERROR AppTask::Init() { CHIP_ERROR err = CHIP_NO_ERROR; @@ -246,6 +282,14 @@ CHIP_ERROR AppTask::Init() sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); UpdateLEDs(); + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, this); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } + return err; } @@ -363,6 +407,32 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState) sAppTask.PostEvent(&event); } +void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogProgress(NotSpecified, "HourlyTimer"); + + CHIP_ERROR err; + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, nullptr); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } +} + void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) { if (aEvent->Type != AppEvent::kEventType_Timer) @@ -660,11 +730,15 @@ void AppTask::UpdateLEDs(void) // If the system has ble connection(s) uptill the stage above, THEN blink // the LEDs at an even rate of 100ms. // - // Otherwise, blink the LED ON for a very short time. + // Otherwise, turn the LED OFF. if (sIsThreadProvisioned && sIsThreadEnabled) { qvIO_LedSet(SYSTEM_STATE_LED, true); } + else if (sIsThreadProvisioned && !sIsThreadEnabled) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); + } else if (sHaveBLEConnections) { qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); @@ -676,7 +750,7 @@ void AppTask::UpdateLEDs(void) else { // not commisioned yet - qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); + qvIO_LedSet(SYSTEM_STATE_LED, false); } } @@ -718,3 +792,21 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) break; } } + +extern "C" { +void gpAppFramework_Reset_cbTriggerResetCountCompleted(void) +{ + uint8_t resetCount = gpAppFramework_Reset_GetResetCount(); + + ChipLogProgress(NotSpecified, "%d resets so far", resetCount); + if (resetCount >= NMBR_OF_RESETS_BLE_ADVERTISING) + { + // Open commissioning if no fabric was available + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + ChipLogProgress(NotSpecified, "No fabrics, starting commissioning."); + AppTask::OpenCommissioning((intptr_t) 0); + } + } +} +} diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index cf9816993e89b4..aa523a53539c13 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -2258,6 +2258,8 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute supportedThreadFeatures; + callback attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; @@ -2293,6 +2295,7 @@ endpoint 0 { callback attribute networkInterfaces; callback attribute rebootCount; callback attribute upTime; + callback attribute totalOperationalHours; callback attribute bootReason; callback attribute activeHardwareFaults; callback attribute activeRadioFaults; @@ -2480,7 +2483,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0x0001; + ram attribute featureMap default = 0x0000; ram attribute clusterRevision default = 2; } } @@ -2558,7 +2561,7 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0x181; - ram attribute clusterRevision default = 6; + ram attribute clusterRevision default = 7; handle command LockDoor; handle command UnlockDoor; diff --git a/examples/lock-app/qpg/zap/lock.zap b/examples/lock-app/qpg/zap/lock.zap index 9d13502644b3d0..d4116f8b9d7602 100644 --- a/examples/lock-app/qpg/zap/lock.zap +++ b/examples/lock-app/qpg/zap/lock.zap @@ -1542,6 +1542,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -1814,6 +1846,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "BootReason", "code": 4, @@ -4224,7 +4272,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0001", + "defaultValue": "0x0000", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5179,7 +5227,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "6", + "defaultValue": "7", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/lock-app/silabs/include/AppConfig.h b/examples/lock-app/silabs/include/AppConfig.h index 2045ce3ef4d947..2a98805fa0c8d3 100644 --- a/examples/lock-app/silabs/include/AppConfig.h +++ b/examples/lock-app/silabs/include/AppConfig.h @@ -31,6 +31,10 @@ // state to another. #define ACTUATOR_MOVEMENT_PERIOS_MS 10 +// Time the device will be left in the unlatched state before sending it back to the unlocked state. +// Left at 100 ms for testing purposes. +#define UNLATCH_TIME_MS 100 + #define ON_DEMO_BITMAP \ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, \ diff --git a/examples/lock-app/silabs/include/AppTask.h b/examples/lock-app/silabs/include/AppTask.h index b0040ac5bf6586..fb911e3ff02b5c 100644 --- a/examples/lock-app/silabs/include/AppTask.h +++ b/examples/lock-app/silabs/include/AppTask.h @@ -119,6 +119,13 @@ class AppTask : public BaseApplication */ static void UpdateClusterState(intptr_t context); + /** + * @brief Update Cluster State After Unlatch + * + * @param context current context + */ + static void UpdateClusterStateAfterUnlatch(intptr_t context); + /** * @brief Handle lock update event * diff --git a/examples/lock-app/silabs/include/LockManager.h b/examples/lock-app/silabs/include/LockManager.h index fb73d1d1218d23..7345782d695194 100644 --- a/examples/lock-app/silabs/include/LockManager.h +++ b/examples/lock-app/silabs/include/LockManager.h @@ -119,6 +119,7 @@ class LockManager { LOCK_ACTION = 0, UNLOCK_ACTION, + UNLATCH_ACTION, INVALID_ACTION } Action; @@ -128,7 +129,9 @@ class LockManager kState_LockInitiated = 0, kState_LockCompleted, kState_UnlockInitiated, + kState_UnlatchInitiated, kState_UnlockCompleted, + kState_UnlatchCompleted, } State; CHIP_ERROR Init(chip::app::DataModel::Nullable state, @@ -191,7 +194,30 @@ class LockManager bool ReadConfigValues(); + void UnlockAfterUnlatch(); + private: + struct UnlatchContext + { + chip::EndpointId mEndpointId; + Nullable mFabricIdx; + Nullable mNodeId; + Optional mPin; + OperationErrorEnum mErr; + + void Update(chip::EndpointId endpointId, const Nullable & fabricIdx, + const Nullable & nodeId, const Optional & pin, OperationErrorEnum & err) + { + mEndpointId = endpointId; + mFabricIdx = fabricIdx; + mNodeId = nodeId; + mPin = pin; + mErr = err; + } + }; + UnlatchContext mUnlatchContext; + chip::EndpointId mCurrentEndpointId; + friend LockManager & LockMgr(); State_t mState; diff --git a/examples/lock-app/silabs/src/AppTask.cpp b/examples/lock-app/silabs/src/AppTask.cpp index 6937dbb78e8aa5..4e4d05a810acb8 100644 --- a/examples/lock-app/silabs/src/AppTask.cpp +++ b/examples/lock-app/silabs/src/AppTask.cpp @@ -70,6 +70,45 @@ using namespace EFR32DoorLock::LockInitParams; namespace { LEDWidget sLockLED; +TimerHandle_t sUnlatchTimer; + +void UpdateClusterStateAfterUnlatch(intptr_t context) +{ + LockMgr().UnlockAfterUnlatch(); +} + +void UnlatchTimerCallback(TimerHandle_t xTimer) +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterStateAfterUnlatch, reinterpret_cast(nullptr)); +} + +void CancelUnlatchTimer(void) +{ + if (xTimerStop(sUnlatchTimer, pdMS_TO_TICKS(0)) == pdFAIL) + { + SILABS_LOG("sUnlatchTimer stop() failed"); + appError(APP_ERROR_STOP_TIMER_FAILED); + } +} + +void StartUnlatchTimer(uint32_t timeoutMs) +{ + if (xTimerIsTimerActive(sUnlatchTimer)) + { + SILABS_LOG("app timer already started!"); + CancelUnlatchTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ms if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerStart(sUnlatchTimer, pdMS_TO_TICKS(timeoutMs)) != pdPASS) + { + SILABS_LOG("sUnlatchTimer timer start() failed"); + appError(APP_ERROR_START_TIMER_FAILED); + } +} + } // namespace using namespace chip::TLV; @@ -180,6 +219,8 @@ CHIP_ERROR AppTask::Init() sLockLED.Init(LOCK_STATE_LED); sLockLED.Set(state.Value() == DlLockState::kUnlocked); + sUnlatchTimer = xTimerCreate("UnlatchTimer", pdMS_TO_TICKS(UNLATCH_TIME_MS), pdFALSE, (void *) 0, UnlatchTimerCallback); + // Update the LCD with the Stored value. Show QR Code if not provisioned #ifdef DISPLAY_ENABLED GetLCD().WriteDemoUI(state.Value() != DlLockState::kUnlocked); @@ -309,6 +350,10 @@ void AppTask::ActionInitiated(LockManager::Action_t aAction, int32_t aActor) sAppTask.GetLCD().WriteDemoUI(locked); #endif // DISPLAY_ENABLED } + else if (aAction == LockManager::UNLATCH_ACTION) + { + SILABS_LOG("Unlatch Action has been initiated"); + } if (aActor == AppEvent::kEventType_Button) { @@ -325,6 +370,11 @@ void AppTask::ActionCompleted(LockManager::Action_t aAction) { SILABS_LOG("Lock Action has been completed") } + else if (aAction == LockManager::UNLATCH_ACTION) + { + SILABS_LOG("Unlatch Action has been completed") + StartUnlatchTimer(UNLATCH_TIME_MS); + } else if (aAction == LockManager::UNLOCK_ACTION) { SILABS_LOG("Unlock Action has been completed") diff --git a/examples/lock-app/silabs/src/LockManager.cpp b/examples/lock-app/silabs/src/LockManager.cpp index 3c376a237ad81f..04527e53ac7ab1 100644 --- a/examples/lock-app/silabs/src/LockManager.cpp +++ b/examples/lock-app/silabs/src/LockManager.cpp @@ -186,22 +186,24 @@ bool LockManager::InitiateAction(int32_t aActor, Action_t aAction) State_t new_state; // Initiate Turn Lock/Unlock Action only when the previous one is complete. - if (mState == kState_LockCompleted && aAction == UNLOCK_ACTION) + if ((mState == kState_LockCompleted || mState == kState_UnlatchCompleted) && (aAction == UNLOCK_ACTION)) { action_initiated = true; - - new_state = kState_UnlockInitiated; + new_state = kState_UnlockInitiated; + } + else if ((mState == kState_LockCompleted || mState == kState_UnlockCompleted) && (aAction == UNLATCH_ACTION)) + { + action_initiated = true; + new_state = kState_UnlatchInitiated; } else if (mState == kState_UnlockCompleted && aAction == LOCK_ACTION) { action_initiated = true; - - new_state = kState_LockInitiated; + new_state = kState_LockInitiated; } if (action_initiated) { - StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); // Since the timer started successfully, update the state and trigger callback @@ -249,6 +251,23 @@ void LockManager::TimerEventHandler(void * timerCbArg) event.Handler = ActuatorMovementTimerEventHandler; AppTask::GetAppTask().PostEvent(&event); } +void LockManager::UnlockAfterUnlatch() +{ + // write the new lock value + bool succes = false; + if (mUnlatchContext.mEndpointId != kInvalidEndpointId) + { + succes = setLockState(mUnlatchContext.mEndpointId, mUnlatchContext.mFabricIdx, mUnlatchContext.mNodeId, + DlLockState::kUnlocked, mUnlatchContext.mPin, mUnlatchContext.mErr); + } + + if (!succes) + { + SILABS_LOG("Failed to update the lock state after Unlatch"); + } + + InitiateAction(AppEvent::kEventType_Lock, LockManager::UNLOCK_ACTION); +} void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) { @@ -261,6 +280,11 @@ void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) lock->mState = kState_LockCompleted; actionCompleted = LOCK_ACTION; } + else if (lock->mState == kState_UnlatchInitiated) + { + lock->mState = kState_UnlatchCompleted; + actionCompleted = UNLATCH_ACTION; + } else if (lock->mState == kState_UnlockInitiated) { lock->mState = kState_UnlockCompleted; @@ -285,6 +309,29 @@ bool LockManager::Lock(chip::EndpointId endpointId, const Nullable & fabricIdx, const Nullable & nodeId, const Optional & pin, OperationErrorEnum & err) { + if (DoorLockServer::Instance().SupportsUnbolt(endpointId)) + { + // TODO: Our current implementation does not support multiple endpoint. This needs to be fixed in the future. + if (endpointId != mUnlatchContext.mEndpointId) + { + // If we get a request to unlock on a different endpoint while the current endpoint is in the middle of an action, + // we return false for now. This needs to be fixed in the future. + if (mState != kState_UnlockCompleted && mState != kState_LockCompleted) + { + ChipLogError(Zcl, "Cannot unlock while unlatch on another endpoint is in progress on anotther endpoint"); + return false; + } + else + { + mUnlatchContext.Update(endpointId, fabricIdx, nodeId, pin, err); + return setLockState(endpointId, fabricIdx, nodeId, DlLockState::kUnlatched, pin, err); + } + } + else + { + return setLockState(endpointId, fabricIdx, nodeId, DlLockState::kUnlatched, pin, err); + } + } return setLockState(endpointId, fabricIdx, nodeId, DlLockState::kUnlocked, pin, err); } diff --git a/examples/lock-app/silabs/src/ZclCallbacks.cpp b/examples/lock-app/silabs/src/ZclCallbacks.cpp index 2aa0e9d0f6cef2..f7e333f3acb350 100644 --- a/examples/lock-app/silabs/src/ZclCallbacks.cpp +++ b/examples/lock-app/silabs/src/ZclCallbacks.cpp @@ -89,7 +89,14 @@ bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const bool status = LockMgr().Unlock(endpointId, fabricIdx, nodeId, pinCode, err); if (status == true) { - LockMgr().InitiateAction(AppEvent::kEventType_Lock, LockManager::UNLOCK_ACTION); + if (DoorLockServer::Instance().SupportsUnbolt(endpointId)) + { + LockMgr().InitiateAction(AppEvent::kEventType_Lock, LockManager::UNLATCH_ACTION); + } + else + { + LockMgr().InitiateAction(AppEvent::kEventType_Lock, LockManager::UNLOCK_ACTION); + } } return status; diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter index 40b3087bb836e3..bc4a43383fa2a9 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter @@ -1012,7 +1012,7 @@ cluster GroupKeyManagement = 63 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster MicrowaveOvenMode = 94 { +cluster MicrowaveOvenMode = 94 { revision 1; enum ModeTag : enum16 { @@ -1046,7 +1046,7 @@ provisional cluster MicrowaveOvenMode = 94 { } /** Attributes and commands for configuring the microwave oven control, and reporting cooking stats. */ -provisional cluster MicrowaveOvenControl = 95 { +cluster MicrowaveOvenControl = 95 { revision 1; // NOTE: Default/not specifically set bitmap Feature : bitmap32 { diff --git a/examples/network-manager-app/linux/main.cpp b/examples/network-manager-app/linux/main.cpp index 362ecb3100ad6a..ee6763a6d3d47d 100644 --- a/examples/network-manager-app/linux/main.cpp +++ b/examples/network-manager-app/linux/main.cpp @@ -16,13 +16,22 @@ */ #include +#include +#include +#include using namespace chip; using namespace chip::app; +using namespace chip::app::Clusters; void ApplicationInit() {} void ApplicationShutdown() {} +ByteSpan ByteSpanFromCharSpan(CharSpan span) +{ + return ByteSpan(Uint8::from_const_char(span.data()), span.size()); +} + int main(int argc, char * argv[]) { if (ChipLinuxAppInit(argc, argv) != 0) @@ -30,6 +39,9 @@ int main(int argc, char * argv[]) return -1; } + WiFiNetworkManagementServer::Instance().SetNetworkCredentials(ByteSpanFromCharSpan("MatterAP"_span), + ByteSpanFromCharSpan("Setec Astronomy"_span)); + ChipLinuxAppMainLoop(); return 0; } diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.matter b/examples/network-manager-app/network-manager-common/network-manager-app.matter index 8c935fbe9f9f08..935be20690a105 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.matter +++ b/examples/network-manager-app/network-manager-common/network-manager-app.matter @@ -1175,6 +1175,26 @@ cluster GroupKeyManagement = 63 { fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; } +/** Functionality to retrieve operational information about a managed Wi-Fi network. */ +cluster WiFiNetworkManagement = 1105 { + revision 1; + + readonly attribute nullable octet_string<32> ssid = 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; + + response struct NetworkPassphraseResponse = 1 { + octet_string<64> passphrase = 0; + } + + /** Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. */ + command access(invoke: administer) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -1280,7 +1300,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute attributeList; callback attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + callback attribute clusterRevision default = 0; } server cluster GeneralDiagnostics { @@ -1425,7 +1445,7 @@ endpoint 0 { } } endpoint 1 { - device type ma_network_infrastructure_manager = 4293984272, version 1; + device type ma_network_infrastructure_manager = 144, version 1; server cluster Descriptor { @@ -1440,6 +1460,19 @@ endpoint 1 { callback attribute featureMap; callback attribute clusterRevision; } + + server cluster WiFiNetworkManagement { + callback attribute ssid; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command NetworkPassphraseRequest; + handle command NetworkPassphraseResponse; + } } diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.zap b/examples/network-manager-app/network-manager-common/network-manager-app.zap index d144300c7dada7..46cb4b19598ca8 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.zap +++ b/examples/network-manager-app/network-manager-common/network-manager-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 100, + "featureLevel": 102, "creator": "zap", "keyValuePairs": [ { @@ -13,7 +13,7 @@ }, { "key": "manufacturerCodes", - "value": "0x1002" + "value": "0xFFF1" } ], "package": [ @@ -29,6 +29,7 @@ "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/app-templates.json", "type": "gen-templates-json", + "category": "matter", "version": "chip-v1" } ], @@ -1352,10 +1353,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "0", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -3016,14 +3017,14 @@ "id": 2, "name": "Anonymous Endpoint Type", "deviceTypeRef": { - "code": 4293984272, + "code": 144, "profileId": 259, "label": "MA-network-infrastructure-manager", "name": "MA-network-infrastructure-manager" }, "deviceTypes": [ { - "code": 4293984272, + "code": 144, "profileId": 259, "label": "MA-network-infrastructure-manager", "name": "MA-network-infrastructure-manager" @@ -3033,10 +3034,10 @@ 1 ], "deviceIdentifiers": [ - 4293984272 + 144 ], "deviceTypeName": "MA-network-infrastructure-manager", - "deviceTypeCode": 4293984272, + "deviceTypeCode": 144, "deviceTypeProfileId": 259, "clusters": [ { @@ -3208,6 +3209,146 @@ "reportableChange": 0 } ] + }, + { + "name": "Wi-Fi Network Management", + "code": 1105, + "mfgCode": null, + "define": "WIFI_NETWORK_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "NetworkPassphraseRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkPassphraseResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SSID", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] } ] } diff --git a/examples/persistent-storage/qpg/BUILD.gn b/examples/persistent-storage/qpg/BUILD.gn index 683a5ede278cff..546ec94cf2c9b9 100644 --- a/examples/persistent-storage/qpg/BUILD.gn +++ b/examples/persistent-storage/qpg/BUILD.gn @@ -58,7 +58,7 @@ qpg_executable("persistent_storage_app") { output_dir = root_out_dir - ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld" + ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld" inputs = [ ldscript ] diff --git a/examples/platform/esp32/Rpc.cpp b/examples/platform/esp32/Rpc.cpp index 61efb842f089b7..a3b61830b5a46a 100644 --- a/examples/platform/esp32/Rpc.cpp +++ b/examples/platform/esp32/Rpc.cpp @@ -52,6 +52,10 @@ #include "pigweed/rpc_services/Device.h" #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +#include "pigweed/rpc_services/Event.h" +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE #include "pigweed/rpc_services/Lighting.h" #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -275,6 +279,10 @@ static TaskHandle_t sRpcTaskHandle; StaticTask_t sRpcTaskBuffer; StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE]; +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +Actions actions_service; +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE Attributes attributes_service; #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -295,6 +303,10 @@ Descriptor descriptor_service; Esp32Device device_service; #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +Event event_service; +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE Lighting lighting_service; #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -313,6 +325,10 @@ Esp32WiFi wifi_service; void RegisterServices(pw::rpc::Server & server) { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + server.RegisterService(actions_service); +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE server.RegisterService(attributes_service); #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -333,6 +349,10 @@ void RegisterServices(pw::rpc::Server & server) server.RegisterService(device_service); #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + server.RegisterService(event_service); +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE server.RegisterService(lighting_service); #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -353,6 +373,13 @@ void RegisterServices(pw::rpc::Server & server) } // namespace +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +void SubscribeActions(RpcActionsSubscribeCallback subscriber) +{ + actions_service.SubscribeActions(subscriber); +} +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + void RunRpcService(void *) { Start(RegisterServices, &logger_mutex); diff --git a/examples/platform/esp32/Rpc.h b/examples/platform/esp32/Rpc.h index 9b73e5cafca96b..ff1a5f319ac975 100644 --- a/examples/platform/esp32/Rpc.h +++ b/examples/platform/esp32/Rpc.h @@ -20,6 +20,18 @@ namespace chip { namespace rpc { +enum class ActionType : uint8_t +{ + WRITE_ATTRIBUTE = 0x00, // Write an cluster Attribute + RUN_COMMAND = 0x01, // Run a cluster Command + EMIT_EVENT = 0x02, // Emit a cluster Events +}; + +using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + +void SubscribeActions(RpcActionsSubscribeCallback subscriber); + void Init(); } // namespace rpc diff --git a/examples/platform/infineon/cyw30739/BUILD.gn b/examples/platform/infineon/cyw30739/BUILD.gn index 0673c55c351de3..8ec7003633cd40 100644 --- a/examples/platform/infineon/cyw30739/BUILD.gn +++ b/examples/platform/infineon/cyw30739/BUILD.gn @@ -20,8 +20,10 @@ import("${cyw30739_sdk_build_root}/cyw30739_sdk.gni") static_library("platform") { sources = [ + "EventManagementTestEventTriggerHandler.h", "LEDWidget.h", "OTAConfig.h", + "SoftwareDiagnostics.h", "main.cpp", ] diff --git a/examples/platform/infineon/cyw30739/EventManagementTestEventTriggerHandler.cpp b/examples/platform/infineon/cyw30739/EventManagementTestEventTriggerHandler.cpp new file mode 100644 index 00000000000000..c5320f17f64bc4 --- /dev/null +++ b/examples/platform/infineon/cyw30739/EventManagementTestEventTriggerHandler.cpp @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "EventManagementTestEventTriggerHandler.h" + +#include "SoftwareDiagnostics.h" + +namespace chip { +namespace DeviceLayer { +namespace Infineon { +namespace CYW30739 { + +CHIP_ERROR EventManagementTestEventTriggerHandler::HandleEventTrigger(uint64_t eventTrigger) +{ + switch (eventTrigger) + { + case kFillUpEventLoggingBuffer: + return HandleFillUpEventLoggingBufferEventTriger(); + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } +} + +void EventManagementTestEventTriggerHandler::TriggerSoftwareFaultEvent(const char * faultRecordString) +{ + OnSoftwareFaultEventHandler(faultRecordString); +} + +} // namespace CYW30739 +} // namespace Infineon +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/infineon/cyw30739/EventManagementTestEventTriggerHandler.h b/examples/platform/infineon/cyw30739/EventManagementTestEventTriggerHandler.h new file mode 100644 index 00000000000000..b93109dae03dfa --- /dev/null +++ b/examples/platform/infineon/cyw30739/EventManagementTestEventTriggerHandler.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +namespace Infineon { +namespace CYW30739 { + +class EventManagementTestEventTriggerHandler : public app::GenericEventManagementTestEventTriggerHandler +{ +public: + static constexpr uint64_t kFillUpEventLoggingBuffer = 0xffff'ffff'1388'0000; + + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override; + +private: + virtual void TriggerSoftwareFaultEvent(const char * faultRecordString) override; +}; + +} // namespace CYW30739 +} // namespace Infineon +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/infineon/cyw30739/SoftwareDiagnostics.cpp b/examples/platform/infineon/cyw30739/SoftwareDiagnostics.cpp new file mode 100644 index 00000000000000..ae41f82d14d526 --- /dev/null +++ b/examples/platform/infineon/cyw30739/SoftwareDiagnostics.cpp @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SoftwareDiagnostics.h" + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Infineon { +namespace CYW30739 { + +using namespace chip::app::Clusters; + +void OnSoftwareFaultEventHandler(const char * faultRecordString) +{ +#ifdef MATTER_DM_PLUGIN_SOFTWARE_DIAGNOSTICS_SERVER + SoftwareDiagnostics::Events::SoftwareFault::Type softwareFault; + + /* Unable to access thread ID in the application layer. */ + softwareFault.id = 0; + + if (DeviceLayer::PlatformMgrImpl().IsCurrentTask()) + { + softwareFault.name.SetValue("Matter"_span); + } + else if (DeviceLayer::ThreadStackMgrImpl().IsCurrentTask()) + { + softwareFault.name.SetValue("Thread"_span); + } + else + { + softwareFault.name.SetValue("App"_span); + } + + softwareFault.faultRecording.SetValue(ByteSpan(Uint8::from_const_char(faultRecordString), strlen(faultRecordString))); + + SoftwareDiagnosticsServer::Instance().OnSoftwareFaultDetect(softwareFault); +#endif // MATTER_DM_PLUGIN_SOFTWARE_DIAGNOSTICS_SERVER +} + +} // namespace CYW30739 +} // namespace Infineon +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/infineon/cyw30739/SoftwareDiagnostics.h b/examples/platform/infineon/cyw30739/SoftwareDiagnostics.h new file mode 100644 index 00000000000000..b076d6e1bfe44c --- /dev/null +++ b/examples/platform/infineon/cyw30739/SoftwareDiagnostics.h @@ -0,0 +1,29 @@ +/* + * + * 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. + */ + +namespace chip { +namespace DeviceLayer { +namespace Infineon { +namespace CYW30739 { + +void OnSoftwareFaultEventHandler(const char * faultRecordString); + +} // namespace CYW30739 +} // namespace Infineon +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/infineon/cyw30739/cyw30739_example.gni b/examples/platform/infineon/cyw30739/cyw30739_example.gni index df8e50ee68bf2f..ff07ff6eb28633 100644 --- a/examples/platform/infineon/cyw30739/cyw30739_example.gni +++ b/examples/platform/infineon/cyw30739/cyw30739_example.gni @@ -24,8 +24,10 @@ template("cyw30739_example") { static_library(target_name) { sources = [ + "${cyw30739_example_dir}/EventManagementTestEventTriggerHandler.cpp", "${cyw30739_example_dir}/LEDWidget.cpp", "${cyw30739_example_dir}/OTAConfig.cpp", + "${cyw30739_example_dir}/SoftwareDiagnostics.cpp", "${cyw30739_example_dir}/matter_config.cpp", ] diff --git a/examples/platform/infineon/cyw30739/matter_config.cpp b/examples/platform/infineon/cyw30739/matter_config.cpp index 6b0b56730edecd..c30d55e55bc623 100644 --- a/examples/platform/infineon/cyw30739/matter_config.cpp +++ b/examples/platform/infineon/cyw30739/matter_config.cpp @@ -19,6 +19,7 @@ #include "matter_config.h" #include "AppTask.h" +#include "EventManagementTestEventTriggerHandler.h" #ifdef BOARD_ENABLE_DISPLAY #include "GUI.h" #endif @@ -44,14 +45,21 @@ #include #include #include -#include #include #include -#ifdef BOARD_ENABLE_OPTIGA -#include "wiced_optiga.h" -#endif #include +#ifdef BOARD_USE_OPTIGA +#include "wiced_optiga.h" +#ifdef USE_PROVISIONED_OPTIGA +#include +#else /* !USE_PROVISIONED_OPTIGA */ +#include +#endif /* USE_PROVISIONED_OPTIGA */ +#else /* !BOARD_USE_OPTIGA */ +#include +#endif /* BOARD_USE_OPTIGA */ + using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::Credentials; @@ -60,7 +68,15 @@ using namespace ::chip::Shell; using namespace ::chip::app; static DeviceInfoProviderImpl sExampleDeviceInfoProvider; +#ifdef BOARD_USE_OPTIGA +#ifdef USE_PROVISIONED_OPTIGA +static OptigaFactoryDataProvider sFactoryDataProvider; +#else /* !USE_PROVISIONED_OPTIGA */ +static UnprovisionedOptigaFactoryDataProvider sFactoryDataProvider; +#endif /* USE_PROVISIONED_OPTIGA */ +#else /* !BOARD_USE_OPTIGA */ static FactoryDataProvider sFactoryDataProvider; +#endif /* BOARD_USE_OPTIGA */ // NOTE! This key is for test/certification only and should not be available in production devices! uint8_t sTestEventTriggerEnableKey[chip::TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, @@ -135,7 +151,7 @@ void CYW30739MatterConfig::InitBoard(void) #ifdef BOARD_ENABLE_DISPLAY GUI_Init(); #endif -#ifdef BOARD_ENABLE_OPTIGA +#ifdef BOARD_USE_OPTIGA wiced_optiga_init(); #endif } @@ -186,13 +202,17 @@ void CYW30739MatterConfig::InitApp(void) LogAppInit(); ConfigurationMgr().LogDeviceConfig(); + sFactoryDataProvider.Init(); + // Print QR Code URL PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); /* Start CHIP datamodel server */ static chip::SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{}; static chip::OTATestEventTriggerHandler sOtaTestEventTriggerHandler{}; + static Infineon::CYW30739::EventManagementTestEventTriggerHandler sEventManagementTestEventTriggerHandler{}; VerifyOrDie(sTestEventTriggerDelegate.Init(chip::ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR); VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR); + VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sEventManagementTestEventTriggerHandler) == CHIP_NO_ERROR); // Create initParams with SDK example defaults here static chip::CommonCaseDeviceServerInitParams initParams; (void) initParams.InitializeStaticResourcesBeforeServerInit(); diff --git a/examples/platform/linux/Rpc.cpp b/examples/platform/linux/Rpc.cpp index da6b73b9135c13..6e20e2aecf61b9 100644 --- a/examples/platform/linux/Rpc.cpp +++ b/examples/platform/linux/Rpc.cpp @@ -20,8 +20,16 @@ #include "pw_rpc_system_server/rpc_server.h" #include "pw_rpc_system_server/socket.h" +#include #include +#include "Rpc.h" +#include + +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +#include "pigweed/rpc_services/Actions.h" +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE #include "pigweed/rpc_services/Attributes.h" #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -68,6 +76,10 @@ namespace chip { namespace rpc { namespace { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +Actions actions_service; +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE Attributes attributes_service; #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -94,6 +106,10 @@ pw::trace::TraceService trace_service(pw::trace::GetTokenizedTracer()); void RegisterServices(pw::rpc::Server & server) { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + server.RegisterService(actions_service); +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE server.RegisterService(attributes_service); #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -122,6 +138,13 @@ void RegisterServices(pw::rpc::Server & server) } // namespace +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +void SubscribeActions(RpcActionsSubscribeCallback subscriber) +{ + actions_service.SubscribeActions(subscriber); +} +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + void RunRpcService() { pw::rpc::system_server::Init(); diff --git a/examples/platform/linux/Rpc.h b/examples/platform/linux/Rpc.h index fbcfc6ed63f4f2..51f3f2e473bacb 100644 --- a/examples/platform/linux/Rpc.h +++ b/examples/platform/linux/Rpc.h @@ -18,9 +18,24 @@ #pragma once +#include +#include + namespace chip { namespace rpc { +enum class ActionType : uint8_t +{ + WRITE_ATTRIBUTE = 0x00, // Write an cluster Attribute + RUN_COMMAND = 0x01, // Run a cluster Command + EMIT_EVENT = 0x02, // Emit a cluster Events +}; + +using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + +void SubscribeActions(RpcActionsSubscribeCallback subscriber); + int Init(uint16_t rpcServerPort); } // namespace rpc diff --git a/examples/platform/nrfconnect/Rpc.cpp b/examples/platform/nrfconnect/Rpc.cpp index 8b47215d6a0680..510b0ac8ac4c64 100644 --- a/examples/platform/nrfconnect/Rpc.cpp +++ b/examples/platform/nrfconnect/Rpc.cpp @@ -28,6 +28,10 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +#include "pigweed/rpc_services/Actions.h" +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE #include "pigweed/rpc_services/Attributes.h" #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -48,6 +52,10 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); #include "pigweed/rpc_services/Device.h" #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +#include "pigweed/rpc_services/Event.h" +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE #include "pigweed/rpc_services/Lighting.h" #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -85,6 +93,10 @@ size_t pw_trace_GetTraceTimeTicksPerSecond() namespace chip { namespace rpc { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +Actions actions_service; +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE namespace { @@ -159,6 +171,10 @@ Descriptor descriptor_service; NrfDevice device_service; #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +Event event_service; +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE Lighting lighting_service; #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -181,6 +197,10 @@ pw::trace::TraceService trace_service(pw::trace::GetTokenizedTracer()); void RegisterServices(pw::rpc::Server & server) { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + server.RegisterService(actions_service); +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE server.RegisterService(attributes_service); #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -201,6 +221,10 @@ void RegisterServices(pw::rpc::Server & server) server.RegisterService(device_service); #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + server.RegisterService(event_service); +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE server.RegisterService(lighting_service); #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -225,6 +249,13 @@ void RegisterServices(pw::rpc::Server & server) } // namespace +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +void SubscribeActions(RpcActionsSubscribeCallback subscriber) +{ + actions_service.SubscribeActions(subscriber); +} +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + void RunRpcService(void *, void *, void *) { Start(RegisterServices, &logger_mutex); diff --git a/examples/platform/nrfconnect/Rpc.h b/examples/platform/nrfconnect/Rpc.h index f0aeaf45b61fba..40efcb0750ca2b 100644 --- a/examples/platform/nrfconnect/Rpc.h +++ b/examples/platform/nrfconnect/Rpc.h @@ -23,6 +23,18 @@ namespace chip { namespace rpc { +enum class ActionType : uint8_t +{ + WRITE_ATTRIBUTE = 0x00, // Write an cluster Attribute + RUN_COMMAND = 0x01, // Run a cluster Command + EMIT_EVENT = 0x02, // Emit a cluster Events +}; + +using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + +void SubscribeActions(RpcActionsSubscribeCallback subscriber); + class NrfButton; void RunRpcService(void *, void *, void *); diff --git a/examples/platform/qpg/app/main.cpp b/examples/platform/qpg/app/main.cpp index d7ba22f4adb232..647d248d14b95f 100644 --- a/examples/platform/qpg/app/main.cpp +++ b/examples/platform/qpg/app/main.cpp @@ -192,7 +192,7 @@ CHIP_ERROR CHIP_Init(void) qvIO_EnableSleep(true); #elif CHIP_DEVICE_CONFIG_THREAD_FTD ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); - qvIO_EnableSleep(true); + qvIO_EnableSleep(false); #else ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); qvIO_EnableSleep(false); diff --git a/examples/platform/qpg/powercycle_counting.c b/examples/platform/qpg/powercycle_counting.c index d9e1165a28ef7b..83177e7ca779d9 100644 --- a/examples/platform/qpg/powercycle_counting.c +++ b/examples/platform/qpg/powercycle_counting.c @@ -118,7 +118,8 @@ UInt8 gpAppFramework_Reset_GetResetCount(void) void gpAppFramework_Reset_Init(void) { - if (gpReset_GetResetReason() == gpReset_ResetReason_HW_Por) + if ((gpReset_GetResetReason() == gpReset_ResetReason_HW_Por) || + (gpReset_GetResetReason() == gpReset_ResetReason_UnSpecified)) // Use this reset reason for JLink resets { gpAppFramework_HardwareResetTriggered(); } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h index f439fd72f7393f..74903fa4d4d6dd 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h @@ -87,109 +87,10 @@ extern "C" { #define RX_1M 0x01 #define RX_2M 0x02 -/* freertos defines */ -#define CFG_SHCI_USER_EVT_PROCESS_NAME "SHCI_USER_EVT_PROCESS" -#define CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS (0) -#define CFG_SHCI_USER_EVT_PROCESS_CB_MEM (0) -#define CFG_SHCI_USER_EVT_PROCESS_CB_SIZE (0) -#define CFG_SHCI_USER_EVT_PROCESS_STACK_MEM (0) -#define CFG_SHCI_USER_EVT_PROCESS_PRIORITY osPriorityNormal -#define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 20) - -#define CFG_PUSH_BUTTON_EVT_PROCESS_NAME "PUSH_BUTTON_EVT_PROCESS" -#define CFG_PUSH_BUTTON_EVT_PROCESS_ATTR_BITS (0) -#define CFG_PUSH_BUTTON_EVT_PROCESS_CB_MEM (0) -#define CFG_PUSH_BUTTON_EVT_PROCESS_CB_SIZE (0) -#define CFG_PUSH_BUTTON_EVT_PROCESS_STACK_MEM (0) -#define CFG_PUSH_BUTTON_EVT_PROCESS_PRIORITY osPriorityNormal -#define CFG_PUSH_BUTTON_EVT_PROCESS_STACK_SIZE (128 * 4) - -#define CFG_SEND_COAP_NAME "SEND_COAP_EVT_PROCESS" - -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_NAME "SWITCH_PROTCOL_EVT_PROCESS" -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_ATTR_BITS (0) -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_CB_MEM (0) -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_CB_SIZE (0) -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_STACK_MEM (0) -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_PRIORITY osPriorityNormal -#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_STACK_SIZE (128 * 8) - -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_NAME "THREAD_MSG_M0_TO_M4_PROCESS" -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_ATTR_BITS (0) -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_MEM (0) -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_SIZE (0) -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_MEM (0) -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_PRIORITY osPriorityNormal -#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_SIZE (128 * 8) - -#define CFG_THREAD_CLI_PROCESS_NAME "THREAD_CLI_PROCESS" -#define CFG_THREAD_CLI_PROCESS_ATTR_BITS (0) -#define CFG_THREAD_CLI_PROCESS_CB_MEM (0) -#define CFG_THREAD_CLI_PROCESS_CB_SIZE (0) -#define CFG_THREAD_CLI_PROCESS_STACK_MEM (0) -#define CFG_THREAD_CLI_PROCESS_PRIORITY osPriorityNormal -#define CFG_THREAD_CLI_PROCESS_STACK_SIZE (128 * 8) - -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_NAME "THREAD_SEND_COAP_MSG_PROCESS" -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_ATTR_BITS (0) -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_CB_MEM (0) -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_CB_SIZE (0) -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_STACK_MEM (0) -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_PRIORITY osPriorityNormal -#define CFG_THREAD_SEND_COAP_MSG_PROCESS_STACk_SIZE (128 * 8) - -#define CFG_THREAD_SET_SED_MODE_PROCESS_NAME "THREAD_SET_SED_MODE_PROCESS" -#define CFG_THREAD_SET_SED_MODE_PROCESS_ATTR_BITS (0) -#define CFG_THREAD_SET_SED_MODE_PROCESS_CB_MEM (0) -#define CFG_THREAD_SET_SED_MODE_PROCESS_CB_SIZE (0) -#define CFG_THREAD_SET_SED_MODE_PROCESS_STACK_MEM (0) -#define CFG_THREAD_SET_SED_MODE_PROCESS_PRIORITY osPriorityNormal -#define CFG_THREAD_SET_SED_MODE_PROCESS_STACk_SIZE (128 * 8) - -#define CFG_HCI_USER_EVT_PROCESS_NAME "HCI_USER_EVT_PROCESS" -#define CFG_HCI_USER_EVT_PROCESS_ATTR_BITS (0) -#define CFG_HCI_USER_EVT_PROCESS_CB_MEM (0) -#define CFG_HCI_USER_EVT_PROCESS_CB_SIZE (0) -#define CFG_HCI_USER_EVT_PROCESS_STACK_MEM (0) -#define CFG_HCI_USER_EVT_PROCESS_PRIORITY osPriorityNormal -#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 40) - -#define CFG_ADV_UPDATE_PROCESS_NAME "ADV_UPDATE_PROCESS" -#define CFG_ADV_UPDATE_PROCESS_ATTR_BITS (0) -#define CFG_ADV_UPDATE_PROCESS_CB_MEM (0) -#define CFG_ADV_UPDATE_PROCESS_CB_SIZE (0) -#define CFG_ADV_UPDATE_PROCESS_STACK_MEM (0) -#define CFG_ADV_UPDATE_PROCESS_PRIORITY osPriorityNormal -#define CFG_ADV_UPDATE_PROCESS_STACK_SIZE (128 * 20) - -#define CFG_P2P_SERVER_PROCESS_NAME "P2P_SERVER_PROCESS" -#define CFG_P2P_SERVER_PROCESS_ATTR_BITS (0) -#define CFG_P2P_SERVER_PROCESS_CB_MEM (0) -#define CFG_P2P_SERVER_PROCESS_CB_SIZE (0) -#define CFG_P2P_SERVER_PROCESS_STACK_MEM (0) -#define CFG_P2P_SERVER_PROCESS_PRIORITY osPriorityNormal -#define CFG_P2P_SERVER_PROCESS_STACK_SIZE (128 * 20) - -#define LED_PROCESS_NAME "LED_CUBE_PROCESS" -#define LED_PROCESS_ATTR_BITS (0) -#define LED_PROCESS_CB_MEM (0) -#define LED_PROCESS_CB_SIZE (0) -#define LED_PROCESS_STACK_MEM (0) -#define LED_PROCESS_PRIORITY osPriorityNormal -#define LED_PROCESS_STACK_SIZE (128 * 10) - -#define APPTASK_NAME "APPTASK" -#define APP_ATTR_BITS (0) -#define APP_CB_MEM (0) -#define APP_CB_SIZE (0) -#define APP_STACK_MEM (0) -#define APP_PRIORITY osPriorityNormal -#define APP_STACK_SIZE (1024 * 6) - /** * Identity root key used to derive LTK and CSRK */ -#define CFG_BLE_IRK \ +#define CFG_BLE_IR \ { \ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 \ } @@ -197,7 +98,7 @@ extern "C" { /** * Encryption root key used to derive LTK and CSRK */ -#define CFG_BLE_ERK \ +#define CFG_BLE_ER \ { \ 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21 \ } @@ -236,11 +137,11 @@ extern "C" { #define CONN_P(x) ((int) ((x) / 1.25f)) /* L2CAP Connection Update request parameters used for test only with smart Phone */ -#define L2CAP_REQUEST_NEW_CONN_PARAM 1 +#define L2CAP_REQUEST_NEW_CONN_PARAM 0 #define L2CAP_INTERVAL_MIN CONN_P(1000) /* 1s */ #define L2CAP_INTERVAL_MAX CONN_P(1000) /* 1s */ -#define L2CAP_SLAVE_LATENCY 0x0000 +#define L2CAP_PERIPHERAL_LATENCY 0x0000 #define L2CAP_TIMEOUT_MULTIPLIER 0x1F4 /****************************************************************************** @@ -301,12 +202,12 @@ extern "C" { #define CFG_BLE_DATA_LENGTH_EXTENSION 1 /** - * Sleep clock accuracy in Slave mode (ppm value) + * Sleep clock accuracy in Peripheral mode (ppm value) */ -#define CFG_BLE_SLAVE_SCA 500 +#define CFG_BLE_PERIPHERAL_SCA 500 /** - * Sleep clock accuracy in Master mode + * Sleep clock accuracy in Central mode * 0 : 251 ppm to 500 ppm * 1 : 151 ppm to 250 ppm * 2 : 101 ppm to 150 ppm @@ -316,14 +217,14 @@ extern "C" { * 6 : 21 ppm to 30 ppm * 7 : 0 ppm to 20 ppm */ -#define CFG_BLE_MASTER_SCA 0 +#define CFG_BLE_CENTRAL_SCA 0 /** * Source for the 32 kHz slow speed clock * 1 : internal RO * 0 : external crystal ( no calibration ) */ -#define CFG_BLE_LSE_SOURCE 0 +#define CFG_BLE_LS_SOURCE 0 /** * Start up time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 us (~2.44 us) @@ -331,7 +232,7 @@ extern "C" { #define CFG_BLE_HSE_STARTUP_TIME 0x148 /** - * Maximum duration of the connection event when the device is in Slave mode in units of 625/256 us (~2.44 us) + * Maximum duration of the connection event when the device is in Peripheral mode in units of 625/256 us (~2.44 us) */ #define CFG_BLE_MAX_CONN_EVENT_LENGTH (0xFFFFFFFF) @@ -512,6 +413,7 @@ extern "C" { /** tick timer value in us */ #define CFG_TS_TICK_VAL DIVR((CFG_RTCCLK_DIV * 1000000), LSE_VALUE) +#define CFG_TS_TICK_VAL_PS DIVR(((uint64_t) CFG_RTCCLK_DIV * 1e12), (uint64_t) LSE_VALUE) typedef enum { @@ -631,6 +533,16 @@ typedef enum #endif /* CFG_FULL_LOW_POWER */ /* USER CODE END Defines */ +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_NAME "CONN_INT_UPD_REQ" +#define CFG_CONN_INT_UPD_REQ_PROCESS_ATTR_BITS (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_SIZE (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_PRIORITY osPriorityNormal +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_SIZE (128 * 8) +#endif + /****************************************************************************** * LOW POWER ******************************************************************************/ @@ -648,12 +560,124 @@ typedef enum /* USER CODE END CFG_LPM_Id_t */ } CFG_LPM_Id_t; +/****************************************************************************** + * FreeRTOS + ******************************************************************************/ +/* USER CODE BEGIN FreeRTOS */ + +#define CFG_SHCI_USER_EVT_PROCESS_NAME "SHCI_USER_EVT_PROCESS" +#define CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS (0) +#define CFG_SHCI_USER_EVT_PROCESS_CB_MEM (0) +#define CFG_SHCI_USER_EVT_PROCESS_CB_SIZE (0) +#define CFG_SHCI_USER_EVT_PROCESS_STACK_MEM (0) +#define CFG_SHCI_USER_EVT_PROCESS_PRIORITY osPriorityNone +#define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 20) + +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_NAME "THREAD_MSG_M0_TO_M4_PROCESS" +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_ATTR_BITS (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_MEM (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_SIZE (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_MEM (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_PRIORITY osPriorityLow +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_THREAD_CLI_PROCESS_NAME "THREAD_CLI_PROCESS" +#define CFG_THREAD_CLI_PROCESS_ATTR_BITS (0) +#define CFG_THREAD_CLI_PROCESS_CB_MEM (0) +#define CFG_THREAD_CLI_PROCESS_CB_SIZE (0) +#define CFG_THREAD_CLI_PROCESS_STACK_MEM (0) +#define CFG_THREAD_CLI_PROCESS_PRIORITY osPriorityNormal +#define CFG_THREAD_CLI_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_HCI_USER_EVT_PROCESS_NAME "HCI_USER_EVT_PROCESS" +#define CFG_HCI_USER_EVT_PROCESS_ATTR_BITS (0) +#define CFG_HCI_USER_EVT_PROCESS_CB_MEM (0) +#define CFG_HCI_USER_EVT_PROCESS_CB_SIZE (0) +#define CFG_HCI_USER_EVT_PROCESS_STACK_MEM (0) +#define CFG_HCI_USER_EVT_PROCESS_PRIORITY osPriorityNone +#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 40) + +#define CFG_ADV_CANCEL_PROCESS_NAME "ADV_CANCEL_PROCESS" +#define CFG_ADV_CANCEL_PROCESS_ATTR_BITS (0) +#define CFG_ADV_CANCEL_PROCESS_CB_MEM (0) +#define CFG_ADV_CANCEL_PROCESS_CB_SIZE (0) +#define CFG_ADV_CANCEL_PROCESS_STACK_MEM (0) +#define CFG_ADV_CANCEL_PROCESS_PRIORITY osPriorityNormal +#define CFG_ADV_CANCEL_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_P2PS_SEND_NOTIF_PROCESS_NAME "P2PS_SEND_NOTIF_PROCESS" +#define CFG_P2PS_SEND_NOTIF_PROCESS_ATTR_BITS (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_CB_MEM (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_CB_SIZE (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_STACK_MEM (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_PRIORITY osPriorityNormal +#define CFG_P2PS_SEND_NOTIF_PROCESS_STACK_SIZE (128 * 8) + +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_NAME "CONN_INT_UPD_REQ" +#define CFG_CONN_INT_UPD_REQ_PROCESS_ATTR_BITS (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_SIZE (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_PRIORITY osPriorityNormal +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_SIZE (128 * 8) +#endif + +#define APPTASK_NAME "APPTASK" +#define APP_ATTR_BITS (0) +#define APP_CB_MEM (0) +#define APP_CB_SIZE (0) +#define APP_STACK_MEM (0) +#define APP_PRIORITY osPriorityNormal +#define APP_STACK_SIZE (1024 * 6) + +#define CFG_PUSH_BUTTON_EVT_PROCESS_NAME "PUSH_BUTTON_EVT_PROCESS" +#define CFG_PUSH_BUTTON_EVT_PROCESS_ATTR_BITS (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_CB_MEM (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_CB_SIZE (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_STACK_MEM (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_PRIORITY osPriorityNormal +#define CFG_PUSH_BUTTON_EVT_PROCESS_STACK_SIZE (128 * 4) +/* USER CODE END FreeRTOS_Defines */ + /****************************************************************************** * OTP manager ******************************************************************************/ #define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE -#define CFG_OTP_END_ADDRESS OTP_AREA_END_ADDR +#define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR + +/****************************************************************************** + * OTA support + ******************************************************************************/ +#define OTA_SUPPORT 0 + +/****************************************************************************** + * LCD support + ******************************************************************************/ +#define CFG_LCD_SUPPORTED 1 + +#if ((OTA_SUPPORT == 1) || (CFG_FULL_LOW_POWER == 1)) +/****************************************************************************** + * LCD support + ******************************************************************************/ +#undef CFG_LCD_SUPPORTED +#define CFG_LCD_SUPPORTED 0 +#endif + +/****************************************************************************** + * versions + ******************************************************************************/ +#define X_CUBE_MATTER_VERSION "1.0.3" +#define PRODUCT_NAME "Dimmable Light" +#define VENDOR_NAME "STMicroelectronics" +#define HARDWARE_VERSION "STM32WB5MM-DK" +#define MATTER_SDK_VERSION "github CSA" + +/****************************************************************************** + * Matter Factory data + ******************************************************************************/ +#define CONFIG_STM32_FACTORY_DATA_ENABLE 0 typedef enum { diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_debug.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_debug.h new file mode 100644 index 00000000000000..6ea86e05ffa9f8 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_debug.h @@ -0,0 +1,67 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_debug.h + * @author MCD Application Team + * @brief Header for app_debug.c module + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_DEBUG_H +#define APP_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported variables --------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Exported macros ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions ---------------------------------------------*/ +void APPD_Init(void); +void APPD_EnableCPU2(void); +/* USER CODE BEGIN EF */ + +/* USER CODE END EF */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*APP_DEBUG_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h index 9d0378c18792c1..ff90bc72025585 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h @@ -48,7 +48,6 @@ void APP_ENTRY_ProcessMsgM0ToM4(void); void APP_ENTRY_Init_CFG_CLI_UART(void); void APP_ENTRY_TL_THREAD_INIT(void); void APP_ENTRY_PBSetReceiveCallback(PushButtonCallback aCallback); -void APP_ENTRY_LedBlink(uint8_t LedStatus); #ifdef __cplusplus } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h deleted file mode 100644 index 24f4cfc6253572..00000000000000 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h +++ /dev/null @@ -1,181 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file flash_driver.h - * @author MCD Application Team - * @brief Dual core Flash driver interface - ****************************************************************************** - * @attention - * - * Copyright (c) 2020-2021 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef FLASH_DRIVER_H -#define FLASH_DRIVER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -typedef enum -{ - SINGLE_FLASH_OPERATION_DONE, - SINGLE_FLASH_OPERATION_NOT_EXECUTED, -} SingleFlashOperationStatus_t; - -typedef enum -{ - WAITED_SEM_BUSY, - WAITED_SEM_FREE, -} WaitedSemStatus_t; - -typedef enum -{ - WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU1, - WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU2, -} WaitedSemId_t; - -typedef enum -{ - ReadyToWrite, - NotReadyToWrite, - -} StatusReadyToWrite; -/* Exported functions ------------------------------------------------------- */ - -/** - * @brief Implements the Dual core algorithm to erase multiple sectors in flash with CPU1 - * It calls for each sector to be erased the API FD_EraseSingleSector() - * - * @param FirstSector: The first sector to be erased - * This parameter must be a value between 0 and (SFSA - 1) - * @param NbrOfSectors: The number of sectors to erase - * This parameter must be a value between 1 and (SFSA - FirstSector) - * @retval Number of sectors not erased: - * Depending on the implementation of FD_WaitForSemAvailable(), - * it may still have some sectors not erased when the timing protection has been - * enabled by either CPU1 or CPU2. When the value returned is not 0, the application - * should wait until both timing protection before retrying to erase the last missing sectors. - * - * In addition, When the returned value is not 0: - * - The Sem2 is NOT released - * - The FLASH is NOT locked - * - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF) is NOT called - * It is expected that the user will call one more time this function to finish the process - */ -uint32_t FD_EraseSectors(uint32_t FirstSector, uint32_t NbrOfSectors); - -/** - * @brief Implements the Dual core algorithm to write multiple 64bits data in flash with CPU1 - * The user shall first make sure the location to be written has been first erase. - * Otherwise, the API will loop for ever as it will be not able to write in flash - * The only value that can be written even though the destination is not erased is 0. - * It calls for each 64bits to be written the API FD_WriteSingleData() - * - * @param DestAddress: Address of the flash to write the first data. It shall be 64bits aligned - * @param pSrcBuffer: Address of the buffer holding the 64bits data to be written in flash - * @param NbrOfData: Number of 64bits data to be written - * @retval Number of 64bits data not written: - * Depending on the implementation of FD_WaitForSemAvailable(), - * it may still have 64bits data not written when the timing protection has been - * enabled by either CPU1 or CPU2. When the value returned is not 0, the application - * should wait until both timing protection before retrying to write the last missing 64bits data. - * - * In addition, When the returned value is not 0: - * - The Sem2 is NOT released - * - The FLASH is NOT locked - * It is expected that the user will call one more time this function to finish the process - */ -uint32_t FD_WriteData(uint32_t DestAddress, uint64_t * pSrcBuffer, uint32_t NbrOfData); - -/** - * @brief Implements the Dual core algorithm to erase one sector in flash with CPU1 - * - * It expects the following point before calling this API: - * - The Sem2 is taken - * - The FLASH is unlocked - * - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON) has been called - * It expects the following point to be done when no more sectors need to be erased - * - The Sem2 is released - * - The FLASH is locked - * - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF) is called - * - * The two point above are implemented in FD_EraseSectors() - * This API needs to be used instead of FD_EraseSectors() in case a provided library is taking - * care of these two points and request only a single operation. - * - * @param FirstSector: The sector to be erased - * This parameter must be a value between 0 and (SFSA - 1) - * @retval: SINGLE_FLASH_OPERATION_DONE -> The data has been written - * SINGLE_FLASH_OPERATION_NOT_EXECUTED -> The data has not been written due to timing protection - * from either CPU1 or CPU2. On a failure status, the user should check - * both timing protection before retrying. - */ -SingleFlashOperationStatus_t FD_EraseSingleSector(uint32_t SectorNumber); - -/** - * @brief Implements the Dual core algorithm to write one 64bits data in flash with CPU1 - * The user shall first make sure the location to be written has been first erase. - * Otherwise, the API will loop for ever as it will be not able to write in flash - * The only value that can be written even though the destination is not erased is 0. - * - * It expects the following point before calling this API: - * - The Sem2 is taken - * - The FLASH is unlocked - * It expects the following point to be done when no more sectors need to be erased - * - The Sem2 is released - * - The FLASH is locked - * - * The two point above are implemented in FD_WriteData() - * This API needs to be used instead of FD_WriteData() in case a provided library is taking - * care of these two points and request only a single operation. - * - * @param DestAddress: Address of the flash to write the data. It shall be 64bits aligned - * @param Data: 64bits Data to be written - * @retval: SINGLE_FLASH_OPERATION_DONE -> The data has been written - * SINGLE_FLASH_OPERATION_NOT_EXECUTED -> The data has not been written due to timing protection - * from either CPU1 or CPU2. On a failure status, the user should check - * both timing protection before retrying. - */ -SingleFlashOperationStatus_t FD_WriteSingleData(uint32_t DestAddress, uint64_t Data); - -/** - * By default, this function is implemented weakly in flash_driver.c to return WAITED_SEM_BUSY. - * When the semaphore is busy, this will result in either FD_WriteSingleData() or FD_EraseSingleSector() - * to loop until the semaphore is free. - * - * This function may be implemented so that when using either an OS or the UTIL_SEQ_WaitEvt() API from the sequencer, - * it could possible to run other tasks or enter idle mode until the waited semaphore is free. - * This function shall not take the waited semaphore but just return when it is free. - * - * @param WaitedSemId: The semaphore ID this function should not return until it is free - * @retval: WAITED_SEM_BUSY -> The function returned before waiting for the semaphore to be free. This will exit the loop - * from either FD_EraseSingleSector() or FD_WriteSingleData() and the number of actions left to - * be processed are reported to the user - * WAITED_SEM_FREE -> The semaphore has been checked as free. Both FD_EraseSingleSector() and FD_WriteSingleData() - * try again to process one more time the flash. - */ -WaitedSemStatus_t FD_WaitForSemAvailable(WaitedSemId_t WaitedSemId); - -#ifdef __cplusplus -} -#endif - -#endif /*FLASH_DRIVER_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h index 5a866b3edf7fbe..010881188f6feb 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h @@ -40,6 +40,7 @@ typedef enum NVM_BLOCK_SIZE_OVERFLOW, NVM_ERROR_BLOCK_ALIGN, NVM_FLASH_CORRUPTION, + NVM_PARAM_ERROR, NVM_BUFFER_TOO_SMALL } NVM_StatusTypeDef; @@ -57,19 +58,13 @@ typedef enum * @brief Copy Flash to RAM NVM */ -void NM_Init(void); +NVM_StatusTypeDef NM_Init(void); /** * @brief Copy RAM NVM to Flash */ NVM_StatusTypeDef NM_Dump(void); -/** - * @brief check the nvm if it s corrupted or not - * @retval return NVM_OK if nvm is empty or NVM_FLASH_CORRUPTION if it s not empty - */ -NVM_StatusTypeDef NM_Check_Validity(void); - /** * @brief Get KeyName in RAM NVM and return the value of Key in KeyValue * @@ -86,7 +81,6 @@ NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t * * @param KeyValue: Address of the buffer * @param KeyName: Name of Key needed - * @param KeyAddr: TODO DELETED this param * @param KeySize: size of KeyValue * @param read_by_size: return size of KeyValue found * @retval return state of function @@ -103,11 +97,16 @@ NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySi NVM_StatusTypeDef NM_DeleteKey(const char * Keyname, NVM_Sector sector); /** - * @brief Erase all persistent and reboot program + * @brief Get the address of the OT NVM buffer + * @param Addr: return the Address of the OT buffer + * @retval return state of function */ +NVM_StatusTypeDef NM_GetOtNVMAddr(uint32_t * NVMAddr); +/** + * @brief Erase all persistent and reboot program + */ void NM_ResetFactory(void); -void NM_FullErase(void); #ifdef __cplusplus } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h index 109084d298637f..4614e33b58a817 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h @@ -20,6 +20,7 @@ #ifndef __HW_CONF_H #define __HW_CONF_H +#include "FreeRTOSConfig.h" /****************************************************************************** * Semaphores * THIS SHALL NO BE CHANGED AS THESE SEMAPHORES ARE USED AS WELL ON THE CM0+ @@ -81,7 +82,7 @@ * wakeup timer. * This setting is the preemptpriority part of the NVIC. */ -#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO 3 +#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1) /* FreeRTOS requirement */ /** * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h index 6ea2f076e6a8ae..ca1b5ffa4bea36 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h @@ -35,7 +35,7 @@ #include "x_nucleo_epd.h" #endif #ifdef USE_STM32WB5M_DK -#include "./../../../../../Drivers/BSP/STM32WB5MM-DK/stm32wb5mm_dk.h" +#include "stm32wb5mm_dk.h" #endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/ota.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/ota.h new file mode 100644 index 00000000000000..dbce1040104dd4 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/ota.h @@ -0,0 +1,50 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef OTA_H +#define OTA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/*! Attribute structure */ +typedef struct +{ + uint16_t vendorId; /*! VendorId info from image header */ + uint16_t productId; /*! ProductId info from image header */ + uint32_t softwareVersion; /*! Software version of the binary */ + uint32_t minApplicableVersion; /*! Minimum running software version to be compatible with the OTA image */ + uint32_t maxApplicableVersion; /*! Maximum running software version to be compatible with the OTA image */ +} Ota_ImageHeader_t; + +void InitializeOTARequestor(void); +bool OtaHeaderValidation(Ota_ImageHeader_t imageHeader); +void TriggerOTAQuery(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* OTA_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/s25fl128s_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/s25fl128s_conf.h new file mode 100644 index 00000000000000..009853e8989420 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/s25fl128s_conf.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file s25fl128s_conf_template.h + * @author MCD Application Team + * @brief This file contains the configurations of the S25FL128S QSPI memory. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef S25FL128S_CONF_H +#define S25FL128S_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup S25FL128S + * @brief This file provides a set of definitions for the Spansion + * S25FL128S memory configuration. + * @{ + */ + +/** @addtogroup S25FL128S_Exported_Constants + * @{ + */ + +#define CONF_S25FL128S_READ_ENHANCE 0 /* MMP performance enhance read enable/disable */ +#define CONF_QSPI_DUMMY_CLOCK 8U + +/* Dummy cycles for STR read mode */ +#define S25FL128S_DUMMY_CYCLES_READ_QUAD 8U +#define S25FL128S_DUMMY_CYCLES_READ 8U +#define S25FL128S_DUMMY_CYCLES_READ_DUAL_INOUT 4U +#define S25FL128S_DUMMY_CYCLES_READ_QUAD_INOUT 6U + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* S25FL128S_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_factorydata.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_factorydata.h new file mode 100644 index 00000000000000..ddf384fa03e2e3 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_factorydata.h @@ -0,0 +1,78 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file flash_wb.h + * @author MCD Application Team + * @brief Header file for flash_wb.c + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32_FACTORYDATA_H +#define STM32_FACTORYDATA_H + +/* Includes ------------------------------------------------------------------*/ +#include "utilities_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PRIVATE_KEY_LEN 32 +#define PUBLIC_KEY_LEN 65 +typedef enum +{ + DATAFACTORY_OK, + DATAFACTORY_DATA_NOT_FOUND, + DATAFACTORY_BUFFER_TOO_SMALL, + DATAFACTORY_PARAM_ERROR, + +} FACTORYDATA_StatusTypeDef; + +typedef enum +{ + /* DeviceAttestationCredentialsProvider */ + TAG_ID_CERTIFICATION_DECLARATION = 1, + TAG_ID_FIRMWARE_INFORMATION = 2, + TAG_ID_DEVICE_ATTESTATION_CERTIFICATE = 3, + TAG_ID_PRODUCT_ATTESTATION_INTERMEDIATE_CERTIFICATE = 4, + TAG_ID_DEVICE_ATTESTATION_PRIVATE_KEY = 5, + TAG_ID_DEVICE_ATTESTATION_PUBLIC_KEY = 6, + /* CommissionableDataProvider */ + TAG_ID_SETUP_DISCRIMINATOR = 11, + TAG_ID_SPAKE2_ITERATION_COUNT = 12, + TAG_ID_SPAKE2_SALT = 13, + TAG_ID_SPAKE2_VERIFIER = 14, + TAG_ID_SPAKE2_SETUP_PASSCODE = 15, + /* DeviceInstanceInfoProvider */ + TAG_ID_VENDOR_NAME = 21, + TAG_ID_VENDOR_ID = 22, + TAG_ID_PRODUCT_NAME = 23, + TAG_ID_PRODUCT_ID = 24, + TAG_ID_SERIAL_NUMBER = 25, + TAG_ID_MANUFACTURING_DATE = 26, + TAG_ID_HARDWARE_VERSION = 27, + TAG_ID_HARDWARE_VERSION_STRING = 28, + TAG_ID_ROTATING_DEVICE_ID = 29, + /* Platform specific */ + TAG_ID_ENABLE_KEY = 41, + +} FACTORYDATA_TagId; + +FACTORYDATA_StatusTypeDef FACTORYDATA_GetValue(FACTORYDATA_TagId tag, uint8_t * data, uint32_t size, uint32_t * out_datalength); + +#ifdef __cplusplus +} +#endif +#endif /*STM32_FACTORYDATA_H*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_qspi.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_qspi.h new file mode 100644 index 00000000000000..f525f6e1c7ed65 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_qspi.h @@ -0,0 +1,213 @@ +/** + ****************************************************************************** + * @file stm32wb5mm_dk_qspi.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32wb5mm_dk_qspi.c driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WB5MM_DK_QSPI_H +#define STM32WB5MM_DK_QSPI_H + +#ifdef __cplusplus +extern "C" { +#endif +/* Includes ------------------------------------------------------------------*/ +#include "../Components/s25fl128s/s25fl128s.h" +#include "stm32wb5mm_dk_conf.h" +#include "stm32wb5mm_dk_errno.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WB5MM_DK + * @{ + */ + +/** @addtogroup STM32WB5MM_DK_QSPI + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Types Exported Types + * @{ + */ +#define BSP_QSPI_Info_t S25FL128S_Info_t +#define BSP_QSPI_Interface_t S25FL128S_Interface_t +#define BSP_QSPI_Transfer_t S25FL128S_Transfer_t +#define BSP_QSPI_DualFlash_t S25FL128S_DualFlash_t +#define BSP_QSPI_Erase_t S25FL128S_Erase_t + +typedef enum +{ + QSPI_ACCESS_NONE = 0, /*!< Instance not initialized, */ + QSPI_ACCESS_INDIRECT, /*!< Instance use indirect mode access */ + QSPI_ACCESS_MMP /*!< Instance use Memory Mapped Mode read */ +} BSP_QSPI_Access_t; + +typedef struct +{ + BSP_QSPI_Access_t IsInitialized; /*!< Instance access Flash method */ + BSP_QSPI_Interface_t InterfaceMode; /*!< Flash Interface mode of Instance */ + BSP_QSPI_Transfer_t TransferRate; /*!< Flash Transfer mode of Instance */ + uint32_t DualFlashMode; /*!< Flash dual mode */ + uint32_t IsMspCallbacksValid; +} BSP_QSPI_Ctx_t; + +typedef struct +{ + BSP_QSPI_Interface_t InterfaceMode; /*!< Current Flash Interface mode */ + BSP_QSPI_Transfer_t TransferRate; /*!< Current Flash Transfer mode */ + BSP_QSPI_DualFlash_t DualFlashMode; /*!< Dual Flash mode */ +} BSP_QSPI_Init_t; + +typedef struct +{ + uint32_t FlashSize; + uint32_t ClockPrescaler; + uint32_t SampleShifting; + uint32_t DualFlashMode; +} MX_QSPI_Init_t; +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +typedef struct +{ + void (*pMspInitCb)(pQSPI_CallbackTypeDef); + void (*pMspDeInitCb)(pQSPI_CallbackTypeDef); +} BSP_QSPI_Cb_t; +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Constants Exported Constants + * @{ + */ +/* QSPI instances number */ +#define QSPI_INSTANCES_NUMBER 1U + +/* Definition for QSPI modes */ +#define BSP_QSPI_SPI_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_MODE /* 1 Cmd Line, 1 Address Line and 1 Data Line */ +#define BSP_QSPI_SPI_1I2O_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_1I2O_MODE /* 1 Cmd Line, 1 Address Line and 2 Data Lines */ +#define BSP_QSPI_SPI_2IO_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_2IO_MODE /* 1 Cmd Line, 2 Address Lines and 2 Data Lines */ +#define BSP_QSPI_SPI_1I4O_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_1I4O_MODE /* 1 Cmd Line, 1 Address Line and 4 Data Lines */ +#define BSP_QSPI_SPI_4IO_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_4IO_MODE /* 1 Cmd Line, 4 Address Lines and 4 Data Lines */ +#define BSP_QSPI_QPI_MODE (BSP_QSPI_Interface_t) S25FL128S_QPI_MODE /* 4 Cmd Lines, 4 Address Lines and 4 Data Lines */ + +/* Definition for QSPI transfer rates */ +#define BSP_QSPI_STR_TRANSFER (BSP_QSPI_Transfer_t) S25FL128S_STR_TRANSFER /* Single Transfer Rate */ + +/* Definition for QSPI dual flash mode */ +#define BSP_QSPI_DUALFLASH_DISABLE (BSP_QSPI_DualFlash_t) S25FL128S_DUALFLASH_DISABLE /* Single flash mode */ + +/* QSPI erase types */ +#define BSP_QSPI_ERASE_4K (BSP_QSPI_Erase_t) S25FL128S_ERASE_4K +#define BSP_QSPI_ERASE_64K (BSP_QSPI_Erase_t) S25FL128S_ERASE_64K +#define BSP_QSPI_ERASE_CHIP (BSP_QSPI_Erase_t) S25FL128S_ERASE_CHIP + +/* QSPI block sizes */ +#define BSP_QSPI_BLOCK_4K S25FL128S_SECTOR_4K +#define BSP_QSPI_BLOCK_64K S25FL128S_BLOCK_64K + +/* Definition for QSPI clock resources */ +#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() +#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() +#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() + +#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() +#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() + +/* Definition for QSPI Pins */ +#define QSPI_CS_PIN GPIO_PIN_3 +#define QSPI_CS_GPIO_PORT GPIOD +#define QSPI_CLK_PIN GPIO_PIN_3 +#define QSPI_CLK_GPIO_PORT GPIOA +#define QSPI_D0_PIN GPIO_PIN_9 +#define QSPI_D0_GPIO_PORT GPIOB +#define QSPI_D1_PIN GPIO_PIN_5 +#define QSPI_D1_GPIO_PORT GPIOD +#define QSPI_D2_PIN GPIO_PIN_6 +#define QSPI_D2_GPIO_PORT GPIOD +#define QSPI_D3_PIN GPIO_PIN_7 +#define QSPI_D3_GPIO_PORT GPIOD + +/* S25FL128S memory */ +/* Size of the flash */ +#define QSPI_FLASH_SIZE 26 +#define QSPI_PAGE_SIZE 256 + +/** + * @} + */ + +/** @addtogroup STM32WB5MM_DK_QSPI_Exported_Variables + * @{ + */ +extern QSPI_HandleTypeDef hqspi; +extern BSP_QSPI_Ctx_t QSPI_Ctx[QSPI_INSTANCES_NUMBER]; +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup STM32WB5MM_DK_QSPI_Exported_Functions + * @{ + */ +int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t * Init); +int32_t BSP_QSPI_DeInit(uint32_t Instance); +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +int32_t BSP_QSPI_RegisterMspCallbacks(uint32_t Instance, BSP_QSPI_Cb_t * CallBacks); +int32_t BSP_QSPI_RegisterDefaultMspCallbacks(uint32_t Instance); +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ +int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t * pData, uint32_t ReadAddr, uint32_t Size); +int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t * pData, uint32_t WriteAddr, uint32_t Size); +int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize); +int32_t BSP_QSPI_EraseChip(uint32_t Instance); +int32_t BSP_QSPI_GetStatus(uint32_t Instance); +int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t * pInfo); +int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance); +int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance); +int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t * Id); + +/* These functions can be modified in case the current settings + need to be changed for specific application needs */ +HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef * hQspi, MX_QSPI_Init_t * Config); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WB5MM_DK_QSPI_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h index fbba7c4af75667..b5b6fe06460491 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h @@ -37,20 +37,21 @@ void BusFault_Handler(void); void UsageFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); -void PendSV_Handler(void); -void SysTick_Handler(void); void IPCC_C1_RX_IRQHandler(void); void IPCC_C1_TX_IRQHandler(void); -void EXTI4_IRQHandler(void); -void EXTI0_IRQHandler(void); -void EXTI1_IRQHandler(void); +#if (CFG_HW_USART1_ENABLED == 1) void USART1_IRQHandler(void); -void DMA2_Channel4_IRQHandler(void); +#endif +#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1) +void CFG_HW_USART1_DMA_TX_IRQHandler(void); +#endif +#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1) void CFG_HW_USART1_DMA_TX_IRQHandler(void); +#endif void RTC_WKUP_IRQHandler(void); +#if (CFG_HW_LPUART1_ENABLED == 1) void LPUART1_IRQHandler(void); -void DMA1_Channel4_IRQHandler(void); -void QUADSPI_IRQHandler(void); +#endif #ifdef __cplusplus } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_ext_flash.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_ext_flash.h new file mode 100644 index 00000000000000..f4bf139e2a3c37 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_ext_flash.h @@ -0,0 +1,73 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm_ext_flash.h + * @author MCD Application Team + * @brief Header file for stm_ext_flash.c + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM_EXT_FLASH_H +#define STM_EXT_FLASH_H + +/* Includes ------------------------------------------------------------------*/ +#include "utilities_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXTERNAL_FLASH_ADDRESS 0x90000000U +#define OTA_MAX_SIZE 0x100000 // 1 Mbytes + +typedef enum +{ + STM_EXT_FLASH_OK, + STM_EXT_FLASH_INIT_FAILED, + STM_EXT_FLASH_WRITE_FAILED, + STM_EXT_FLASH_READ_FAILED, + STM_EXT_FLASH_DELETE_FAILED, + STM_EXT_FLASH_INVALID_PARAM, + STM_EXT_FLASH_SIZE_FULL +} STM_OTA_StatusTypeDef; + +/* Exported variables ------------------------------------------------------- */ +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief init ota fw + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_Init(void); + +/** + * @brief Delete old image in external flash + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_Delete_Image(uint32_t Address, uint32_t Length); + +/** + * @brief Write chunk of data in external flash + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_WriteChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length); + +/** + * @brief Read chunk of data in external flash + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_ReadChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length); + +#ifdef __cplusplus +} +#endif + +#endif /*STM_EXT_FLASH_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h index 21400abd1df463..e34783ebc1307b 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h @@ -66,6 +66,6 @@ typedef uint8_t appliLogLevel_t; void logApplication(appliLogLevel_t aLogLevel, appliLogRegion_t aLogRegion, const char * aFormat, ...); #ifdef __cplusplus -} /* extern "C" */ +} #endif #endif /* STM_LOGGING_H_ */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c index 4200191a38a0e9..7863775d427146 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c @@ -161,11 +161,6 @@ typedef struct { BleGlobalContext_t BleApplicationContext_legacy; APP_BLE_ConnStatus_t Device_Connection_Status; - /** - * ID of the Advertising Timeout - */ - uint8_t Advertising_mgr_timer_Id; - uint8_t SwitchOffGPIO_timer_Id; } BleApplicationContext_t; /* USER CODE BEGIN PTD */ @@ -174,8 +169,8 @@ typedef struct /* Private defines -----------------------------------------------------------*/ #define APPBLE_GAP_DEVICE_NAME_LENGTH 7 -#define FAST_ADV_TIMEOUT (30 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 30s */ -#define INITIAL_ADV_TIMEOUT (60 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 60s */ +#define FAST_ADV_TIMEOUT (30 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 30s */ +#define INITIAL_ADV_TIMEOUT (1 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 60s */ #define BD_ADDR_SIZE_LOCAL 6 @@ -188,20 +183,6 @@ typedef struct /* USER CODE END PM */ -osMutexId_t MtxHciId; -osSemaphoreId_t SemHciId; -osThreadId_t HciUserEvtProcessId; -// FreeeRTOS sw timer -TimerHandle_t sbleWorkaroundAdvTimeoutTimer; - -const osThreadAttr_t HciUserEvtProcess_attr = { .name = CFG_HCI_USER_EVT_PROCESS_NAME, - .attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS, - .cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM, - .cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE, - .stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM, - .priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY, - .stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE }; - /* Private variables ---------------------------------------------------------*/ PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer; @@ -213,17 +194,17 @@ static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] = { static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL]; /** - * Identity root key used to derive LTK and CSRK + * Identity root key used to derive IRK and DHK(Legacy) */ -static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IRK; +static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IR; /** - * Encryption root key used to derive LTK and CSRK + * Encryption root key used to derive LTK(Legacy) and CSRK */ -static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ERK; +static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ER; -PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext; -PLACE_IN_SECTION("BLE_APP_CONTEXT") static uint16_t AdvIntervalMin, AdvIntervalMax; +static BleApplicationContext_t BleApplicationContext; +static uint16_t AdvIntervalMin, AdvIntervalMax; MATTER_App_Notification_evt_t handleNotification; @@ -245,18 +226,45 @@ uint8_t manuf_data[15] = { /* USER CODE END PV */ +/* Global variables ----------------------------------------------------------*/ +osMutexId_t MtxHciId; +osSemaphoreId_t SemHciId; +osThreadId_t HciUserEvtProcessId; +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +osThreadId_t ConnIntUpdateReqProcessId; +#endif + +const osThreadAttr_t HciUserEvtProcess_attr = { .name = CFG_HCI_USER_EVT_PROCESS_NAME, + .attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS, + .cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM, + .cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE, + .stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM, + .priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY, + .stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE }; + +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +const osThreadAttr_t ConnIntUpdateReqProcess_attr = { .name = CFG_CONN_INT_UPD_REQ_PROCESS_NAME, + .attr_bits = CFG_CONN_INT_UPD_REQ_PROCESS_ATTR_BITS, + .cb_mem = CFG_CONN_INT_UPD_REQ_PROCESS_CB_MEM, + .cb_size = CFG_CONN_INT_UPD_REQ_PROCESS_CB_SIZE, + .stack_mem = CFG_CONN_INT_UPD_REQ_PROCESS_STACK_MEM, + .priority = CFG_CONN_INT_UPD_REQ_PROCESS_PRIORITY, + .stack_size = CFG_CONN_INT_UPD_REQ_PROCESS_STACK_SIZE }; +#endif + /* Private function prototypes -----------------------------------------------*/ static void BLE_UserEvtRx(void * pPayload); static void BLE_StatusNot(HCI_TL_CmdStatus_t status); static void Ble_Tl_Init(void); static void Ble_Hci_Gap_Gatt_Init(void); static const uint8_t * BleGetBdAddress(void); +static void HciUserEvtProcess(void * argument); static void Switch_OFF_GPIO(void); #if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +static void ConnIntUpdateReqProcess(void * argument); static void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle); #endif -static void HciUserEvtProcess(void * argument); -void BleAdvWorkaroundTimeoutHandler(TimerHandle_t xTimer); + /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -267,6 +275,7 @@ void APP_BLE_Init_Dyn_1(void) /* USER CODE BEGIN APP_BLE_Init_1 */ /* USER CODE END APP_BLE_Init_1 */ + SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { { { 0, 0, 0 } }, /**< Header unused */ { 0, /** pBleBufferAddress not used */ 0, /** BleBufferSize not used */ @@ -278,9 +287,9 @@ void APP_BLE_Init_Dyn_1(void) CFG_BLE_PREPARE_WRITE_LIST_SIZE, CFG_BLE_MBLOCK_COUNT, CFG_BLE_MAX_ATT_MTU, - CFG_BLE_SLAVE_SCA, - CFG_BLE_MASTER_SCA, - CFG_BLE_LSE_SOURCE, + CFG_BLE_PERIPHERAL_SCA, + CFG_BLE_CENTRAL_SCA, + CFG_BLE_LS_SOURCE, CFG_BLE_MAX_CONN_EVENT_LENGTH, CFG_BLE_HSE_STARTUP_TIME, CFG_BLE_VITERBI_MODE, @@ -300,8 +309,6 @@ void APP_BLE_Init_Dyn_1(void) */ UTIL_LPM_SetOffMode(1 << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE); - MtxHciId = osMutexNew(NULL); - SemHciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ /** * Register the hci transport layer to handle BLE User Asynchronous Events */ @@ -327,27 +334,26 @@ void APP_BLE_Init_Dyn_1(void) */ BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE; BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF; + /** * Initialization of ADV - Ad Manufacturer Element - Support OTA Bit Mask */ - #if (RADIO_ACTIVITY_EVENT != 0) aci_hal_set_radio_activity_mask(0x0006); #endif #if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) + ConnIntUpdateReqProcessId = osThreadNew(ConnIntUpdateReqProcess, NULL, &ConnIntUpdateReqProcess_attr); + index_con_int = 0; mutex = 1; #endif /** - * Initialize P2P Server Application + * Initialize Matter Application */ APP_MATTER_Init(); - /** - * Create timer to handle the Led Switch OFF - */ - HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.SwitchOffGPIO_timer_Id), hw_ts_SingleShot, Switch_OFF_GPIO); + return; } void APP_BLE_Init_Dyn_2(void) @@ -361,26 +367,16 @@ void APP_BLE_Init_Dyn_2(void) AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN; AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX; + /** + * Start to Advertise to be connected by P2P Client + */ +#if (CFG_LPM_SUPPORTED == 1) + APP_BLE_Adv_Request(APP_BLE_LP_ADV); +#endif /* USER CODE BEGIN APP_BLE_Init_2 */ /* USER CODE END APP_BLE_Init_2 */ -} - -void APP_BLE_Init_Dyn_3(void) -{ - - sbleWorkaroundAdvTimeoutTimer = xTimerCreate("BleAdvWorkaroundTimer", // Just a text name, not used by the RTOS kernel - pdMS_TO_TICKS(2000), // == default timer period (mS) - 0, // no timer reload (==one-shot) - NULL, // init timer id = ble obj context - BleAdvWorkaroundTimeoutHandler // timer callback handler - ); - if (xTimerStart(sbleWorkaroundAdvTimeoutTimer, 0) != pdPASS) - { - /* The timer could not be set into the Active - state. */ - } - APP_BLE_Adv_Request(APP_BLE_FAST_ADV); + return; } SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void * pckt) @@ -437,8 +433,6 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void * pckt) */ connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data; - // HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id); - APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\n", connection_complete_event->Connection_Handle); if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING) @@ -486,15 +480,13 @@ APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void) return BleApplicationContext.Device_Connection_Status; } +/* USER CODE BEGIN FD*/ +void APP_BLE_Key_Button1_Action(void) {} + void APP_BLE_Key_Button2_Action(void) { #if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) - if (BleApplicationContext.Device_Connection_Status != APP_BLE_FAST_ADV && - BleApplicationContext.Device_Connection_Status != APP_BLE_IDLE) - { - BLE_SVC_L2CAP_Conn_Update(BleApplicationContext.BleApplicationContext_legacy.connectionHandle); - } - return; + osThreadFlagsSet(ConnIntUpdateReqProcessId, 1); #endif } @@ -502,9 +494,7 @@ void APP_BLE_Key_Button3_Action(void) {} void APP_BLE_Stop(void) { - /* Stop Advertising Timer */ - // HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id); - // HW_TS_Delete(BleApplicationContext.Advertising_mgr_timer_Id); + /* BLE STOP Procedure */ aci_hal_stack_reset(); } @@ -518,6 +508,8 @@ static void Ble_Tl_Init(void) { HCI_TL_HciInitConf_t Hci_Tl_Init_Conf; + MtxHciId = osMutexNew(NULL); + SemHciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t *) &BleCmdBuffer; Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot; hci_init(BLE_UserEvtRx, (void *) &Hci_Tl_Init_Conf); @@ -549,13 +541,13 @@ static void Ble_Hci_Gap_Gatt_Init(void) aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, (uint8_t *) bd_addr); /* BLE MAC in ADV Packet */ - // manuf_data[ sizeof(manuf_data)-6] = bd_addr[5]; - // manuf_data[ sizeof(manuf_data)-5] = bd_addr[4]; - // manuf_data[ sizeof(manuf_data)-4] = bd_addr[3]; - // manuf_data[ sizeof(manuf_data)-3] = bd_addr[2]; - // manuf_data[ sizeof(manuf_data)-2] = bd_addr[1]; - // manuf_data[ sizeof(manuf_data)-1] = bd_addr[0]; - // + // manuf_data[ sizeof(manuf_data)-6] = bd_addr[5]; + // manuf_data[ sizeof(manuf_data)-5] = bd_addr[4]; + // manuf_data[ sizeof(manuf_data)-4] = bd_addr[3]; + // manuf_data[ sizeof(manuf_data)-3] = bd_addr[2]; + // manuf_data[ sizeof(manuf_data)-2] = bd_addr[1]; + // manuf_data[ sizeof(manuf_data)-1] = bd_addr[0]; + /** * Static random Address * The two upper bits shall be set to 1 @@ -567,7 +559,7 @@ static void Ble_Hci_Gap_Gatt_Init(void) aci_hal_write_config_data(CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t *) srd_bd_addr); /** - * Write Identity root key used to derive LTK and CSRK + * Write Identity root key used to derive IRK and DHK(Legacy) */ aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t *) BLE_CFG_IR_VALUE); @@ -642,7 +634,7 @@ static void Ble_Hci_Gap_Gatt_Init(void) } aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode, - BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode, 1, 0, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode, 0, 0, BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin, BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax, BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin, @@ -700,7 +692,6 @@ void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status) /* Update Advertising data */ ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t *) manuf_data); - APP_DBG_MSG("check set discoverable , result: %d \n", ret); if (ret == BLE_STATUS_SUCCESS) { if (New_Status == APP_BLE_FAST_ADV) @@ -709,14 +700,14 @@ void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status) } else { - APP_DBG_MSG("Successfully Start Low Power Advertising \n"); + APP_DBG_MSG("\n\rSuccessfully Start Low Power Advertising \n\r"); } } else { if (New_Status == APP_BLE_FAST_ADV) { - APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n", ret); + APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n\r", ret); } else { @@ -785,15 +776,9 @@ const uint8_t * BleGetBdAddress(void) *SPECIFIC FUNCTIONS FOR P2P SERVER * *************************************************************/ -void BleAdvWorkaroundTimeoutHandler(TimerHandle_t xTimer) -{ - APP_BLE_Adv_Cancel(); -} - void APP_BLE_Adv_Cancel(void) { /* USER CODE BEGIN Adv_Cancel_1 */ - // BSP_LED_Off(LED_GREEN); /* USER CODE END Adv_Cancel_1 */ if (BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_SERVER) @@ -825,7 +810,6 @@ void APP_BLE_Adv_Cancel(void) static void Switch_OFF_GPIO() { /* USER CODE BEGIN Switch_OFF_GPIO */ - // BSP_LED_Off(LED_GREEN); /* USER CODE END Switch_OFF_GPIO */ } @@ -841,12 +825,12 @@ void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle) index_con_int = (index_con_int + 1) % SIZE_TAB_CONN_INT; uint16_t interval_min = CONN_P(tab_conn_interval[index_con_int]); uint16_t interval_max = CONN_P(tab_conn_interval[index_con_int]); - uint16_t slave_latency = L2CAP_SLAVE_LATENCY; + uint16_t peripheral_latency = L2CAP_PERIPHERAL_LATENCY; uint16_t timeout_multiplier = L2CAP_TIMEOUT_MULTIPLIER; tBleStatus result; result = aci_l2cap_connection_parameter_update_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, - interval_min, interval_max, slave_latency, timeout_multiplier); + interval_min, interval_max, peripheral_latency, timeout_multiplier); if (result == BLE_STATUS_SUCCESS) { APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Successfully \r\n\r"); @@ -861,16 +845,21 @@ void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle) /* USER CODE END BLE_SVC_L2CAP_Conn_Update_2 */ return; } -#endif - -/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */ -/* USER CODE END FD_SPECIFIC_FUNCTIONS */ -/************************************************************* - * - * WRAP FUNCTIONS - * - *************************************************************/ +static void ConnIntUpdateReqProcess(void * argument) +{ + UNUSED(argument); + for (;;) + { + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + if (BleApplicationContext.Device_Connection_Status != APP_BLE_FAST_ADV && + BleApplicationContext.Device_Connection_Status != APP_BLE_IDLE) + { + BLE_SVC_L2CAP_Conn_Update(BleApplicationContext.BleApplicationContext_legacy.connectionHandle); + } + } +} +#endif static void HciUserEvtProcess(void * argument) { @@ -883,39 +872,56 @@ static void HciUserEvtProcess(void * argument) } } +/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */ + +/* USER CODE END FD_SPECIFIC_FUNCTIONS */ +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ void hci_notify_asynch_evt(void * pdata) { + UNUSED(pdata); + osThreadFlagsSet(HciUserEvtProcessId, 1); + return; } void hci_cmd_resp_release(uint32_t flag) { + UNUSED(flag); + osSemaphoreRelease(SemHciId); + return; } void hci_cmd_resp_wait(uint32_t timeout) { + UNUSED(timeout); + osSemaphoreAcquire(SemHciId, osWaitForever); + return; } static void BLE_UserEvtRx(void * pPayload) { SVCCTL_UserEvtFlowStatus_t svctl_return_status; - tHCI_UserEvtRxParam * pParam; + tHCI_UserEvtRxParam * p_param; - pParam = (tHCI_UserEvtRxParam *) pPayload; + p_param = (tHCI_UserEvtRxParam *) pPayload; - svctl_return_status = SVCCTL_UserEvtRx((void *) &(pParam->pckt->evtserial)); + svctl_return_status = SVCCTL_UserEvtRx((void *) &(p_param->pckt->evtserial)); if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; + p_param->status = HCI_TL_UserEventFlow_Enable; } else { - pParam->status = HCI_TL_UserEventFlow_Disable; + p_param->status = HCI_TL_UserEventFlow_Disable; } } @@ -929,7 +935,6 @@ static void BLE_StatusNot(HCI_TL_CmdStatus_t status) * This is to prevent a new command is sent while one is already pending */ osMutexAcquire(MtxHciId, osWaitForever); - break; case HCI_TL_CmdAvailable: @@ -938,7 +943,6 @@ static void BLE_StatusNot(HCI_TL_CmdStatus_t status) * This is to prevent a new command is sent while one is already pending */ osMutexRelease(MtxHciId); - break; default: diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h index cb0b80a25628f6..1197ff8ecd27b8 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h @@ -35,6 +35,7 @@ extern "C" { /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ + typedef enum { APP_BLE_IDLE, @@ -68,8 +69,6 @@ typedef enum /* Exported functions ---------------------------------------------*/ void APP_BLE_Init_Dyn_1(void); void APP_BLE_Init_Dyn_2(void); -void APP_BLE_Init_Dyn_3(void); - APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void); /* USER CODE BEGIN EF */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c index f917b8542fc4bf..dd58d369187e1e 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c @@ -44,15 +44,8 @@ /* Private defines -----------------------------------------------------------*/ #define C_SIZE_CMD_STRING 256U +#define THREAD_LINK_POLL_PERIOD (5 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 5s */ #define MO_NOTIF_QUEUE_SIZE 10 - -/* USER CODE BEGIN PD */ - -/* USER CODE END PD */ - -static osSemaphoreId_t TransferToM0Semaphore; -static osMutexId_t MtxThreadId; - /* FreeRtos stacks attributes */ const osThreadAttr_t ThreadMsgM0ToM4Process_attr = { .name = CFG_THREAD_MSG_M0_TO_M4_PROCESS_NAME, .attr_bits = CFG_THREAD_MSG_M0_TO_M4_PROCESS_ATTR_BITS, @@ -62,15 +55,13 @@ const osThreadAttr_t ThreadMsgM0ToM4Process_attr = { .name = CFG_THREAD_MS .priority = CFG_THREAD_MSG_M0_TO_M4_PROCESS_PRIORITY, .stack_size = CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_SIZE }; -const osThreadAttr_t ThreadCliProcess_attr = { .name = CFG_THREAD_CLI_PROCESS_NAME, - .attr_bits = CFG_THREAD_CLI_PROCESS_ATTR_BITS, - .cb_mem = CFG_THREAD_CLI_PROCESS_CB_MEM, - .cb_size = CFG_THREAD_CLI_PROCESS_CB_SIZE, - .stack_mem = CFG_THREAD_CLI_PROCESS_STACK_MEM, - .priority = CFG_THREAD_CLI_PROCESS_PRIORITY, - .stack_size = CFG_THREAD_CLI_PROCESS_STACK_SIZE }; +static osSemaphoreId_t OtCmdProcessSem; +static osSemaphoreId_t OtCmdAckSem; + +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ -static volatile int FlagReceiveAckFromM0 = 0; /* Private macros ------------------------------------------------------------*/ /* USER CODE BEGIN PM */ @@ -78,38 +69,21 @@ static volatile int FlagReceiveAckFromM0 = 0; /* Private function prototypes -----------------------------------------------*/ static void APP_THREAD_CheckWirelessFirmwareInfo(void); +static void APP_THREAD_StateNotif(uint32_t NotifFlags, void * pContext); +static void APP_THREAD_DeviceConfig(void); static void APP_THREAD_TraceError(const char * pMess, uint32_t ErrCode); -#if (CFG_FULL_LOW_POWER == 0) -static void Send_CLI_To_M0(void); -#endif /* (CFG_FULL_LOW_POWER == 0) */ -static void Send_CLI_Ack_For_OT(void); -static void HostTxCb(void); static void Wait_Getting_Ack_From_M0(void); static void Receive_Ack_From_M0(void); static void Receive_Notification_From_M0(void); + +/* FreeRTos wrapper functions */ static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument); -static void Ot_Cmd_Transfer_Common(void); -#if (CFG_FULL_LOW_POWER == 0) -static void APP_THREAD_FreeRTOSSendCLIToM0Task(void * argument); -#endif /* (CFG_FULL_LOW_POWER == 0) */ -#if (CFG_FULL_LOW_POWER == 0) -static void RxCpltCallback(void); -#endif /* (CFG_FULL_LOW_POWER == 0) */ /* USER CODE BEGIN PFP */ + /* USER CODE END PFP */ /* Private variables ---------------------------------------------------------*/ -#if (CFG_FULL_LOW_POWER == 0) -static uint8_t aRxBuffer[C_SIZE_CMD_STRING]; -#endif /* (CFG_FULL_LOW_POWER == 0) */ - -#if (CFG_FULL_LOW_POWER == 0) -static uint8_t CommandString[C_SIZE_CMD_STRING]; -#endif /* (CFG_FULL_LOW_POWER == 0) */ -static __IO uint16_t indexReceiveChar = 0; -static __IO uint16_t CptReceiveCmdFromUser = 0; - static TL_CmdPacket_t * p_thread_otcmdbuffer; static TL_EvtPacket_t * p_thread_notif_M0_to_M4; PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_TH_Config_t ThreadConfigBuffer; @@ -119,18 +93,20 @@ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ThreadCliCmdBuffer; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ThreadCliNotBuffer; extern uint8_t g_ot_notification_allowed; -/* USER CODE BEGIN PV */ static QueueHandle_t MoNotifQueue; static osThreadId_t OsTaskMsgM0ToM4Id; /* Task managing the M0 to M4 messaging */ -#if (CFG_FULL_LOW_POWER == 0) -static osThreadId_t OsTaskCliId; /* Task used to manage CLI command */ -#endif /* (CFG_FULL_LOW_POWER == 0) */ -/* Debug */ +/* USER CODE BEGIN PV */ + /* USER CODE END PV */ /* Functions Definition ------------------------------------------------------*/ -void APP_THREAD_Init(void) +/** + * @brief Main entry point for the Thread Application + * @param none + * @retval None + */ +void APP_THREAD_Init_Dyn_1(void) { /* USER CODE BEGIN APP_THREAD_INIT_1 */ /* Do not allow stop mode before Thread is initialized */ @@ -153,32 +129,40 @@ void APP_THREAD_Init(void) /* Init config buffer and call TL_THREAD_Init */ APP_THREAD_TL_THREAD_INIT(); - /* Configure UART for sending CLI command from M4 */ - // APP_THREAD_Init_UART_CLI(); Conflict with qspi gpio /* Send Thread start system cmd to M0 */ ThreadInitStatus = SHCI_C2_THREAD_Init(); /* Prevent unused argument(s) compilation warning */ UNUSED(ThreadInitStatus); - /* Semaphore */ - TransferToM0Semaphore = osSemaphoreNew(1, 0, NULL); - /* Initialize the mutex */ - MtxThreadId = osMutexNew(NULL); + /* Create the different FreeRTOS tasks requested to run this Thread application*/ + OsTaskMsgM0ToM4Id = osThreadNew(APP_THREAD_FreeRTOSProcessMsgM0ToM4Task, NULL, &ThreadMsgM0ToM4Process_attr); + + /* Create binary semaphores for OT command handling */ + OtCmdProcessSem = osSemaphoreNew(1, 1, NULL); + OtCmdAckSem = osSemaphoreNew(1, 0, NULL); + /* USER CODE BEGIN APP_THREAD_INIT_FREERTOS */ MoNotifQueue = xQueueCreate(MO_NOTIF_QUEUE_SIZE, sizeof(uint8_t)); if (MoNotifQueue == NULL) { APP_DBG("Failed to allocate M0 notification queue"); } + /* USER CODE END APP_THREAD_INIT_FREERTOS */ +} - /* Create the different FreeRTOS tasks requested to run this Thread application*/ - OsTaskMsgM0ToM4Id = osThreadNew(APP_THREAD_FreeRTOSProcessMsgM0ToM4Task, NULL, &ThreadMsgM0ToM4Process_attr); +void APP_THREAD_Init_Dyn_2(void) +{ + /* Initialize and configure the Thread device*/ +#if (CFG_LPM_SUPPORTED == 1) + APP_THREAD_DeviceConfig(); - /* USER CODE BEGIN APP_THREAD_INIT_FREERTOS */ - /* USER CODE END APP_THREAD_INIT_FREERTOS */ - /* USER CODE BEGIN APP_THREAD_INIT_2 */ - /* USER CODE END APP_THREAD_INIT_2 */ + /* Allow the 800_15_4 IP to enter in low power mode */ + SHCI_C2_RADIO_AllowLowPower(THREAD_IP, TRUE); + + /* Allow stop mode after Thread initialization*/ + UTIL_LPM_SetStopMode(1 << CFG_LPM_APP_THREAD, UTIL_LPM_ENABLE); +#endif } /** @@ -215,10 +199,13 @@ void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode) case ERR_THREAD_ERASE_PERSISTENT_INFO: APP_THREAD_TraceError("ERROR : ERR_THREAD_ERASE_PERSISTENT_INFO ", ErrCode); break; + case ERR_THREAD_SET_NETWORK_KEY: + APP_THREAD_TraceError("ERROR : ERR_THREAD_SET_NETWORK_KEY ", ErrCode); + break; case ERR_THREAD_CHECK_WIRELESS: APP_THREAD_TraceError("ERROR : ERR_THREAD_CHECK_WIRELESS ", ErrCode); break; - /* USER CODE BEGIN APP_THREAD_Error_2 */ + /* USER CODE BEGIN APP_THREAD_Error_2 */ case ERR_THREAD_COAP_START: APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_START ", ErrCode); break; @@ -243,164 +230,101 @@ void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode) case ERR_TIMER_START: APP_THREAD_TraceError("ERROR : ERR_TIMER_START ", ErrCode); break; - /* USER CODE END APP_THREAD_Error_2 */ + /* USER CODE END APP_THREAD_Error_2 */ default: APP_THREAD_TraceError("ERROR Unknown ", 0); break; } } -/** - * @brief Perform initialization of CLI UART interface. - * @param None - * @retval None - */ -void APP_THREAD_Init_UART_CLI(void) -{ -#if (CFG_FULL_LOW_POWER == 0) - OsTaskCliId = osThreadNew(APP_THREAD_FreeRTOSSendCLIToM0Task, NULL, &ThreadCliProcess_attr); -#endif /* (CFG_FULL_LOW_POWER == 0) */ - -#if (CFG_FULL_LOW_POWER == 0) - HW_UART_Init(CFG_CLI_UART); - HW_UART_Receive_IT(CFG_CLI_UART, aRxBuffer, 1, RxCpltCallback); -#endif /* (CFG_FULL_LOW_POWER == 0) */ -} - -/** - * @brief Perform initialization of TL for THREAD. - * @param None - * @retval None - */ -void APP_THREAD_TL_THREAD_INIT(void) -{ - ThreadConfigBuffer.p_ThreadOtCmdRspBuffer = (uint8_t *) &ThreadOtCmdBuffer; - ThreadConfigBuffer.p_ThreadNotAckBuffer = (uint8_t *) ThreadNotifRspEvtBuffer; - ThreadConfigBuffer.p_ThreadCliRspBuffer = (uint8_t *) &ThreadCliCmdBuffer; - ThreadConfigBuffer.p_ThreadCliNotBuffer = (uint8_t *) &ThreadCliNotBuffer; - - TL_THREAD_Init(&ThreadConfigBuffer); -} - -/** - * @brief This function is used to transfer the Ot commands from the - * M4 to the M0. - * - * @param None - * @return None - */ -void Ot_Cmd_Transfer(void) -{ - Ot_Cmd_Transfer_Common(); -} - -/** - * @brief This function is used to transfer the Ot commands from the - * M4 to the M0 with Notification M0 to M4 allowed. +/************************************************************* * - * @param None - * @return None - */ -void Ot_Cmd_TransferWithNotif(void) -{ - /* Flag to specify to UTIL_SEQ_EvtIdle that M0 to M4 notifications are allowed */ - g_ot_notification_allowed = 1U; - - Ot_Cmd_Transfer_Common(); -} - -/** - * @brief This function is called when acknowledge from OT command is received from the M0+. + * LOCAL FUNCTIONS * - * @param Otbuffer : a pointer to TL_EvtPacket_t - * @return None - */ -void TL_OT_CmdEvtReceived(TL_EvtPacket_t * Otbuffer) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(Otbuffer); - - Receive_Ack_From_M0(); - - /* Does not allow OpenThread M0 to M4 notification */ - g_ot_notification_allowed = 0U; -} + *************************************************************/ /** - * @brief This function is called when notification from M0+ is received. - * - * @param Notbuffer : a pointer to TL_EvtPacket_t - * @return None - */ -void TL_THREAD_NotReceived(TL_EvtPacket_t * Notbuffer) -{ - p_thread_notif_M0_to_M4 = Notbuffer; - - Receive_Notification_From_M0(); -} - /** - * @brief This function is called when notification on CLI TL Channel from M0+ is received. - * - * @param Notbuffer : a pointer to TL_EvtPacket_t - * @return None + * @brief Thread initialization. + * @param None + * @retval None */ -void TL_THREAD_CliNotReceived(TL_EvtPacket_t * Notbuffer) +static void APP_THREAD_DeviceConfig(void) { - TL_CmdPacket_t * l_CliBuffer = (TL_CmdPacket_t *) Notbuffer; - uint8_t l_size = l_CliBuffer->cmdserial.cmd.plen; - - /* WORKAROUND: if string to output is "> " then respond directly to M0 and do not output it */ - if (strcmp((const char *) l_CliBuffer->cmdserial.cmd.payload, "> ") != 0) + otError error = OT_ERROR_NONE; + otLinkModeConfig OT_LinkMode = { 0 }; + /* Set the pool period to 5 sec. It means that when the device will enter + * in 'sleepy end device' mode, it will send an ACK_Request every 5 sec. + * This message will act as keep alive message. + */ + error = otLinkSetPollPeriod(NULL, THREAD_LINK_POLL_PERIOD); + /* Set the sleepy end device mode */ + OT_LinkMode.mRxOnWhenIdle = 0; + OT_LinkMode.mDeviceType = 0; + OT_LinkMode.mNetworkData = 1U; + + error = otThreadSetLinkMode(NULL, OT_LinkMode); + if (error != OT_ERROR_NONE) { - /* Write to CLI UART */ - HW_UART_Transmit_IT(CFG_CLI_UART, l_CliBuffer->cmdserial.cmd.payload, l_size, HostTxCb); + APP_THREAD_Error(ERR_THREAD_LINK_MODE, error); } - else + error = otIp6SetEnabled(NULL, true); + if (error != OT_ERROR_NONE) + { + APP_THREAD_Error(ERR_THREAD_IPV6_ENABLE, error); + } + error = otThreadSetEnabled(NULL, true); + if (error != OT_ERROR_NONE) { - Send_CLI_Ack_For_OT(); + APP_THREAD_Error(ERR_THREAD_START, error); } } - -/** - * @brief This function is called before sending any ot command to the M0 - * core. The purpose of this function is to be able to check if - * there are no notifications coming from the M0 core which are - * pending before sending a new ot command. - * @param None +/* @brief Thread notification when the state changes. + * @param aFlags : Define the item that has been modified + * aContext: Context * @retval None */ -void Pre_OtCmdProcessing(void) +static void APP_THREAD_StateNotif(uint32_t NotifFlags, void * pContext) { - osMutexAcquire(MtxThreadId, osWaitForever); -} - -void APP_THREAD_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer) -{ - p_thread_otcmdbuffer = p_buffer; -} + /* Prevent unused argument(s) compilation warning */ + UNUSED(pContext); -Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdPayloadBuffer(void) -{ - return (Thread_OT_Cmd_Request_t *) p_thread_otcmdbuffer->cmdserial.cmd.payload; -} + /* USER CODE BEGIN APP_THREAD_STATENOTIF */ -Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdRspPayloadBuffer(void) -{ - return (Thread_OT_Cmd_Request_t *) ((TL_EvtPacket_t *) p_thread_otcmdbuffer)->evtserial.evt.payload; -} + /* USER CODE END APP_THREAD_STATENOTIF */ -Thread_OT_Cmd_Request_t * THREAD_Get_NotificationPayloadBuffer(void) -{ - return (Thread_OT_Cmd_Request_t *) (p_thread_notif_M0_to_M4)->evtserial.evt.payload; + if ((NotifFlags & (uint32_t) OT_CHANGED_THREAD_ROLE) == (uint32_t) OT_CHANGED_THREAD_ROLE) + { + switch (otThreadGetDeviceRole(NULL)) + { + case OT_DEVICE_ROLE_DISABLED: + /* USER CODE BEGIN OT_DEVICE_ROLE_DISABLED */ + /* USER CODE END OT_DEVICE_ROLE_DISABLED */ + break; + case OT_DEVICE_ROLE_DETACHED: + /* USER CODE BEGIN OT_DEVICE_ROLE_DETACHED */ + /* USER CODE END OT_DEVICE_ROLE_DETACHED */ + break; + case OT_DEVICE_ROLE_CHILD: + /* USER CODE BEGIN OT_DEVICE_ROLE_CHILD */ + /* USER CODE END OT_DEVICE_ROLE_CHILD */ + break; + case OT_DEVICE_ROLE_ROUTER: + /* USER CODE BEGIN OT_DEVICE_ROLE_ROUTER */ + /* USER CODE END OT_DEVICE_ROLE_ROUTER */ + break; + case OT_DEVICE_ROLE_LEADER: + /* USER CODE BEGIN OT_DEVICE_ROLE_LEADER */ + /* USER CODE END OT_DEVICE_ROLE_LEADER */ + break; + default: + /* USER CODE BEGIN DEFAULT */ + /* USER CODE END DEFAULT */ + break; + } + } } -/************************************************************* - * - * LOCAL FUNCTIONS - * - *************************************************************/ - /** * @brief Warn the user that an error has occurred.In this case, * the LEDs on the Board will start blinking. @@ -438,30 +362,16 @@ static void APP_THREAD_CheckWirelessFirmwareInfo(void) else { APP_DBG("**********************************************************"); - APP_DBG("WIRELESS COPROCESSOR FW:"); - /* Print version */ - APP_DBG("VERSION ID = %d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub); + APP_DBG("PRODUCT NAME : " PRODUCT_NAME); + APP_DBG("VENDOR NAME : " VENDOR_NAME); + APP_DBG("HARDWARE : " HARDWARE_VERSION); + APP_DBG("SOFTWARE : X-CUBE-MATTER release revision " X_CUBE_MATTER_VERSION); + APP_DBG("Embedded SW components :"); + APP_DBG("- Matter SDK version : " MATTER_SDK_VERSION); + APP_DBG("- STM32WB Cube Firmware Version : %d.%d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, + p_wireless_info->VersionSub, p_wireless_info->VersionBranch); + APP_DBG("**********************************************************"); - switch (p_wireless_info->StackType) - { - case INFO_STACK_TYPE_THREAD_FTD: - APP_DBG("FW Type : Thread FTD"); - break; - case INFO_STACK_TYPE_THREAD_MTD: - APP_DBG("FW Type : Thread MTD"); - break; - case INFO_STACK_TYPE_BLE_THREAD_FTD_DYAMIC: - APP_DBG("FW Type : Dynamic Concurrent Mode BLE/Thread"); - break; - // case INFO_STACK_TYPE_BLE_THREAD_FOR_MATTER: - // APP_DBG("FW Type : Dynamic Concurrent Mode BLE/Thread for Matter ") - // ; - // break; - default: - /* No Thread device supported ! */ - APP_THREAD_Error((uint32_t) ERR_THREAD_CHECK_WIRELESS, (uint32_t) ERR_INTERFACE_FATAL); - break; - } APP_DBG("**********************************************************"); } } @@ -478,7 +388,6 @@ static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument) for (;;) { /* USER CODE BEGIN APP_THREAD_FREERTOS_PROCESS_MSG_M0_TO_M4_1 */ - /* USER END END APP_THREAD_FREERTOS_PROCESS_MSG_M0_TO_M4_1 */ xQueueReceive(MoNotifQueue, &NotUsed, portMAX_DELAY); @@ -496,25 +405,8 @@ static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument) } } -#if (CFG_FULL_LOW_POWER == 0) -static void APP_THREAD_FreeRTOSSendCLIToM0Task(void * argument) -{ - UNUSED(argument); - for (;;) - { - /* USER CODE BEGIN APP_THREAD_FREERTOS_SEND_CLI_TO_M0_1 */ - - /* USER END END APP_THREAD_FREERTOS_SEND_CLI_TO_M0_1 */ - osThreadFlagsWait(1, osFlagsWaitAll, osWaitForever); - Send_CLI_To_M0(); - /* USER CODE BEGIN APP_THREAD_FREERTOS_SEND_CLI_TO_M0_2 */ - - /* USER END END APP_THREAD_FREERTOS_SEND_CLI_TO_M0_2 */ - } -} -#endif /* (CFG_FULL_LOW_POWER == 0) */ - /* USER CODE BEGIN FREERTOS_WRAPPER_FUNCTIONS */ + /* USER CODE END FREERTOS_WRAPPER_FUNCTIONS */ /* USER CODE BEGIN FD_LOCAL_FUNCTIONS */ @@ -526,6 +418,27 @@ static void APP_THREAD_FreeRTOSSendCLIToM0Task(void * argument) * WRAP FUNCTIONS * *************************************************************/ + +void APP_THREAD_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer) +{ + p_thread_otcmdbuffer = p_buffer; +} + +Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdPayloadBuffer(void) +{ + return (Thread_OT_Cmd_Request_t *) p_thread_otcmdbuffer->cmdserial.cmd.payload; +} + +Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdRspPayloadBuffer(void) +{ + return (Thread_OT_Cmd_Request_t *) ((TL_EvtPacket_t *) p_thread_otcmdbuffer)->evtserial.evt.payload; +} + +Thread_OT_Cmd_Request_t * THREAD_Get_NotificationPayloadBuffer(void) +{ + return (Thread_OT_Cmd_Request_t *) (p_thread_notif_M0_to_M4)->evtserial.evt.payload; +} + static void Ot_Cmd_Transfer_Common(void) { /* OpenThread OT command cmdcode range 0x280 .. 0x3DF = 352 */ @@ -542,122 +455,159 @@ static void Ot_Cmd_Transfer_Common(void) } /** - * @brief This function waits for getting an acknowledgment from the M0. + * @brief This function is used to transfer the Ot commands from the + * M4 to the M0. * - * @param None - * @retval None + * @param None + * @return None */ -static void Wait_Getting_Ack_From_M0(void) +void Ot_Cmd_Transfer(void) { - while (FlagReceiveAckFromM0 == 0) - { - } - FlagReceiveAckFromM0 = 0; - osMutexRelease(MtxThreadId); - // osSemaphoreAcquire( TransferToM0Semaphore, osWaitForever ); + Ot_Cmd_Transfer_Common(); } /** - * @brief Receive an acknowledgment from the M0+ core. - * Each command send by the M4 to the M0 are acknowledged. - * This function is called under interrupt. - * @param None - * @retval None + * @brief This function is used to transfer the Ot commands from the + * M4 to the M0 with Notification M0 to M4 allowed. + * + * @param None + * @return None */ -static void Receive_Ack_From_M0(void) +void Ot_Cmd_TransferWithNotif(void) { - FlagReceiveAckFromM0 = 1; - // osSemaphoreRelease( TransferToM0Semaphore); + /* Flag to specify to UTIL_SEQ_EvtIdle that M0 to M4 notifications are allowed */ + g_ot_notification_allowed = 1U; + + Ot_Cmd_Transfer_Common(); } /** - * @brief Receive a notification from the M0+ through the IPCC. - * This function is called under interrupt. + * @brief Perform initialization of TL for THREAD. * @param None * @retval None */ -static void Receive_Notification_From_M0(void) +void APP_THREAD_TL_THREAD_INIT(void) { - /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as - it will get set to pdTRUE inside the interrupt safe API function if a - context switch is required. */ - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - - uint8_t NotUsed = 0; - xQueueSendToFrontFromISR(MoNotifQueue, &NotUsed, &xHigherPriorityTaskWoken); + ThreadConfigBuffer.p_ThreadOtCmdRspBuffer = (uint8_t *) &ThreadOtCmdBuffer; + ThreadConfigBuffer.p_ThreadNotAckBuffer = (uint8_t *) ThreadNotifRspEvtBuffer; + ThreadConfigBuffer.p_ThreadCliRspBuffer = (uint8_t *) &ThreadCliCmdBuffer; + ThreadConfigBuffer.p_ThreadCliNotBuffer = (uint8_t *) &ThreadCliNotBuffer; - /* Pass the xHigherPriorityTaskWoken value into portEND_SWITCHING_ISR(). If - xHigherPriorityTaskWoken was set to pdTRUE inside xSemaphoreGiveFromISR() - then calling portEND_SWITCHING_ISR() will request a context switch. If - xHigherPriorityTaskWoken is still pdFALSE then calling - portEND_SWITCHING_ISR() will have no effect */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); + TL_THREAD_Init(&ThreadConfigBuffer); } -#if (CFG_FULL_LOW_POWER == 0) -static void RxCpltCallback(void) +/** + * @brief This function is called when notification on CLI TL Channel from M0+ is received. + * + * @param Notbuffer : a pointer to TL_EvtPacket_t + * @return None + */ +void TL_THREAD_CliNotReceived(TL_EvtPacket_t * Notbuffer) { - /* Filling buffer and wait for '\r' char */ - if (indexReceiveChar < C_SIZE_CMD_STRING) - { - CommandString[indexReceiveChar++] = aRxBuffer[0]; - if (aRxBuffer[0] == '\r') - { - CptReceiveCmdFromUser = 1U; + TL_CmdPacket_t * l_CliBuffer = (TL_CmdPacket_t *) Notbuffer; + uint8_t l_size = l_CliBuffer->cmdserial.cmd.plen; - /* UART task scheduling*/ - osThreadFlagsSet(OsTaskCliId, 1); - } + /* WORKAROUND: if string to output is "> " then respond directly to M0 and do not output it */ + if (strcmp((const char *) l_CliBuffer->cmdserial.cmd.payload, "> ") != 0) + { + /* Do nothing CLI is not enable */ + } + else + { + /* Notify M0 that characters have been sent to UART */ + TL_THREAD_CliSendAck(); } +} + +/** + * @brief This function is called when acknowledge from OT command is received from the M0+. + * + * @param Otbuffer : a pointer to TL_EvtPacket_t + * @return None + */ +void TL_OT_CmdEvtReceived(TL_EvtPacket_t * Otbuffer) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Otbuffer); - /* Once a character has been sent, put back the device in reception mode */ - HW_UART_Receive_IT(CFG_CLI_UART, aRxBuffer, 1U, RxCpltCallback); + Receive_Ack_From_M0(); + + /* Does not allow OpenThread M0 to M4 notification */ + g_ot_notification_allowed = 0U; } -#endif /* (CFG_FULL_LOW_POWER == 0) */ -#if (CFG_FULL_LOW_POWER == 0) /** - * @brief Process sends receive CLI command to M0. - * @param None - * @retval None + * @brief This function is called when notification from M0+ is received. + * + * @param Notbuffer : a pointer to TL_EvtPacket_t + * @return None */ -static void Send_CLI_To_M0(void) +void TL_THREAD_NotReceived(TL_EvtPacket_t * Notbuffer) { - memset(ThreadCliCmdBuffer.cmdserial.cmd.payload, 0x0U, 255U); - memcpy(ThreadCliCmdBuffer.cmdserial.cmd.payload, CommandString, indexReceiveChar); - ThreadCliCmdBuffer.cmdserial.cmd.plen = indexReceiveChar; - ThreadCliCmdBuffer.cmdserial.cmd.cmdcode = 0x0; + p_thread_notif_M0_to_M4 = Notbuffer; - /* Clear receive buffer, character counter and command complete */ - CptReceiveCmdFromUser = 0; - indexReceiveChar = 0; - memset(CommandString, 0, C_SIZE_CMD_STRING); + Receive_Notification_From_M0(); +} - TL_CLI_SendCmd(); +/** + * @brief This function is called before sending any ot command to the M0 + * core. The purpose of this function is to be able to check if + * there are no notifications coming from the M0 core which are + * pending before sending a new ot command. + * @param None + * @retval None + */ +void Pre_OtCmdProcessing(void) +{ + osSemaphoreAcquire(OtCmdProcessSem, osWaitForever); } -#endif /* (CFG_FULL_LOW_POWER == 0) */ /** - * @brief Send notification for CLI TL Channel. + * @brief This function waits for getting an acknowledgment from the M0. + * * @param None * @retval None */ -static void Send_CLI_Ack_For_OT(void) +static void Wait_Getting_Ack_From_M0(void) { + osSemaphoreAcquire(OtCmdAckSem, osWaitForever); + osSemaphoreRelease(OtCmdProcessSem); +} - /* Notify M0 that characters have been sent to UART */ - TL_THREAD_CliSendAck(); +/** + * @brief Receive an acknowledgment from the M0+ core. + * Each command send by the M4 to the M0 are acknowledged. + * This function is called under interrupt. + * @param None + * @retval None + */ +static void Receive_Ack_From_M0(void) +{ + osSemaphoreRelease(OtCmdAckSem); } /** - * @brief End of transfer callback for CLI UART sending. - * - * @param Notbuffer : a pointer to TL_EvtPacket_t - * @return None + * @brief Receive a notification from the M0+ through the IPCC. + * This function is called under interrupt. + * @param None + * @retval None */ -static void HostTxCb(void) +static void Receive_Notification_From_M0(void) { - Send_CLI_Ack_For_OT(); + /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as + it will get set to pdTRUE inside the interrupt safe API function if a + context switch is required. */ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + uint8_t NotUsed = 0; + xQueueSendToFrontFromISR(MoNotifQueue, &NotUsed, &xHigherPriorityTaskWoken); + + /* Pass the xHigherPriorityTaskWoken value into portEND_SWITCHING_ISR(). If + xHigherPriorityTaskWoken was set to pdTRUE inside xSemaphoreGiveFromISR() + then calling portEND_SWITCHING_ISR() will request a context switch. If + xHigherPriorityTaskWoken is still pdFALSE then calling + portEND_SWITCHING_ISR() will have no effect */ + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } /* USER CODE BEGIN FD_WRAP_FUNCTIONS */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h index 512b3bcd544538..b4b31bfd25ad1c 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h @@ -110,16 +110,12 @@ typedef enum /* USER CODE END EM */ /* Exported functions ------------------------------------------------------- */ -void APP_THREAD_Init(void); +void APP_THREAD_Init_Dyn_1(void); +void APP_THREAD_Init_Dyn_2(void); void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode); void APP_THREAD_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer); void APP_THREAD_ProcessMsgM0ToM4(void); -void APP_THREAD_Init_UART_CLI(void); void APP_THREAD_TL_THREAD_INIT(void); -void APP_THREAD_SEND_MSG(void); -/* **** */ -void APP_THREAD_Stop(void); -void APP_THREAD_CleanCallbacks(void); /* USER CODE BEGIN EF */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c index a4e4a492cbc360..9a7479e48d9302 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c @@ -1,6 +1,6 @@ /** ****************************************************************************** - * @file custom_stm.c + * @file matter_stm.c * @author MCD Application Team * @brief matter Service using gatt(Custom STM) ****************************************************************************** @@ -234,6 +234,11 @@ static SVCCTL_EvtAckStatus_t Matter_Event_Handler(void * Event) Notification.DataTransfered.Length = attribute_modified->Attr_Data_Length; Notification.DataTransfered.pPayload = attribute_modified->Attr_Data; Notification.ConnectionHandle = attribute_modified->Connection_Handle; + if (Notification.DataTransfered.Length == 0) + { + /* Exit the function because of bad packet */ + break; + } APP_MATTER_Notification(&Notification); } } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h index a4627c05ae9223..17240d11e36cbe 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h @@ -28,7 +28,7 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ /* USER CODE BEGIN Includes */ -#include + /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_debug.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_debug.c new file mode 100644 index 00000000000000..49c95488297abf --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_debug.c @@ -0,0 +1,345 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_debug.c + * @author MCD Application Team + * @brief Debug capabilities source file for STM32WPAN Middleware + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "app_common.h" + +#include "app_debug.h" +#include "dbg_trace.h" +#include "shci.h" +#include "tl.h" +#include "utilities_common.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ +typedef PACKED_STRUCT +{ + GPIO_TypeDef * port; + uint16_t pin; + uint8_t enable; + uint8_t reserved; +} +APPD_GpioConfig_t; +/* USER CODE END PTD */ + +/* Private defines -----------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +#define GPIO_NBR_OF_RF_SIGNALS 9 +#define GPIO_CFG_NBR_OF_FEATURES 43 +#define NBR_OF_TRACES_CONFIG_PARAMETERS 4 +#define NBR_OF_GENERAL_CONFIG_PARAMETERS 4 + +/** + * THIS SHALL BE SET TO A VALUE DIFFERENT FROM 0 ONLY ON REQUEST FROM ST SUPPORT + */ +#define BLE_DTB_CFG 0 + +/** + * System Debug Options flags to be configured with: + * - SHCI_C2_DEBUG_OPTIONS_IPCORE_LP + * - SHCI_C2_DEBUG_OPTIONS_IPCORE_NO_LP + * - SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN + * - SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_DIS + * which are used to set following configuration bits: + * - bit 0: 0: IP BLE core in LP mode 1: IP BLE core in run mode (no LP supported) + * - bit 1: 0: CPU2 STOP mode Enable 1: CPU2 STOP mode Disable + * - bit [2-7]: bits reserved ( shall be set to 0) + */ +#define SYS_DBG_CFG1 (SHCI_C2_DEBUG_OPTIONS_IPCORE_LP | SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN) +/* USER CODE END PD */ + +/* Private macros ------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig = { 0, 0, 0, 0 }; +PLACE_IN_SECTION("MB_MEM2") +ALIGN(4) static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig = { BLE_DTB_CFG, SYS_DBG_CFG1, { 0, 0 } }; + +#ifdef CFG_DEBUG_TRACE_UART +#if (CFG_HW_LPUART1_ENABLED == 1) +extern void MX_LPUART1_UART_Init(void); +#endif +#if (CFG_HW_USART1_ENABLED == 1) +extern void MX_USART1_UART_Init(void); +#endif +#endif + +/** + * THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT + * It provides timing information on the CPU2 activity. + * All configuration of (port, pin) is supported for each features and can be selected by the user + * depending on the availability + */ +static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] = { + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_ISR - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_STACK_TICK - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_CMD_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_ACL_DATA_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* SYS_CMD_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* RNG_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVM_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_GENERAL - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_EVT_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_ACL_DATA_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_SYS_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_SYS_EVT_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_CLI_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_OT_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_OT_ACK_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_CLI_ACK_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_MEM_MANAGER_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_TRACES_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* HARD_FAULT - Set on Entry / Reset on Exit */ + /* From v1.1.1 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IP_CORE_LP_STATUS - Set on Entry / Reset on Exit */ + /* From v1.2.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* TIMER_SERVER_CALLBACK - Toggle on Entry */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* PES_ACTIVITY - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */ + /* From v1.3.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_NO_DELAY - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_STACK_STORE_NVM_CB - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_WRITE_ONGOING - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_WRITE_COMPLETE - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_CLEANUP - Set on Entry / Reset on Exit */ + /* From v1.4.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_START - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, + /* FLASH_EOP - Set on Entry / Reset on Exit */ /* The FLASH_EOP Debug GPIO trace is not supported since v1.5.0 */ + /* From v1.5.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* FLASH_WRITE - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* FLASH_ERASE - Set on Entry / Reset on Exit */ + /* From v1.6.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_RESCHEDULE_EVENT - Set on Entry / Reset on Exit */ + /* From v1.8.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_LLD_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_LLD_ACK_TX - Set on Entry / Reset on Exit */ + /* From v1.9.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_ASYNCH_EVENT_NACKED - Set on Entry / Reset on Exit */ + /* From v1.17.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_SFTIMER_IRQ */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_COMPC_WRAP */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_SWITCH_RADIO */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_PROG_SFTIMER */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_RADIO_GRANTED_TO_15_4 */ +}; + +/** + * THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT + * This table is relevant only for BLE + * It provides timing information on BLE RF activity. + * New signals may be allocated at any location when requested by ST + * The GPIO allocated to each signal depend on the BLE_DTB_CFG value and cannot be changed + */ +#if (BLE_DTB_CFG == 7) +static const APPD_GpioConfig_t aRfConfigList[GPIO_NBR_OF_RF_SIGNALS] = { + { GPIOB, LL_GPIO_PIN_2, 0, 0 }, /* DTB10 - Tx/Rx SPI */ + { GPIOB, LL_GPIO_PIN_7, 0, 0 }, /* DTB11 - Tx/Tx SPI Clk */ + { GPIOA, LL_GPIO_PIN_8, 0, 0 }, /* DTB12 - Tx/Rx Ready & SPI Select */ + { GPIOA, LL_GPIO_PIN_9, 0, 0 }, /* DTB13 - Tx/Rx Start */ + { GPIOA, LL_GPIO_PIN_10, 0, 0 }, /* DTB14 - FSM0 */ + { GPIOA, LL_GPIO_PIN_11, 0, 0 }, /* DTB15 - FSM1 */ + { GPIOB, LL_GPIO_PIN_8, 0, 0 }, /* DTB16 - FSM2 */ + { GPIOB, LL_GPIO_PIN_11, 0, 0 }, /* DTB17 - FSM3 */ + { GPIOB, LL_GPIO_PIN_10, 0, 0 }, /* DTB18 - FSM4 */ +}; +#endif +/* USER CODE END PV */ + +/* Global variables ----------------------------------------------------------*/ +/* USER CODE BEGIN GV */ +/* USER CODE END GV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ +static void APPD_SetCPU2GpioConfig(void); +static void APPD_BleDtbCfg(void); +/* USER CODE END PFP */ + +/* Functions Definition ------------------------------------------------------*/ +void APPD_Init(void) +{ + /* USER CODE BEGIN APPD_Init */ + APPD_SetCPU2GpioConfig(); + APPD_BleDtbCfg(); + + /* USER CODE END APPD_Init */ + return; +} + +void APPD_EnableCPU2(void) +{ + /* USER CODE BEGIN APPD_EnableCPU2 */ + SHCI_C2_DEBUG_Init_Cmd_Packet_t DebugCmdPacket = { { { 0, 0, 0 } }, /**< Does not need to be initialized */ + { (uint8_t *) aGpioConfigList, (uint8_t *) &APPD_TracesConfig, + (uint8_t *) &APPD_GeneralConfig, GPIO_CFG_NBR_OF_FEATURES, + NBR_OF_TRACES_CONFIG_PARAMETERS, NBR_OF_GENERAL_CONFIG_PARAMETERS } }; + + /**< Traces channel initialization */ + TL_TRACES_Init(); + + /** GPIO DEBUG Initialization */ + SHCI_C2_DEBUG_Init(&DebugCmdPacket); + + /* USER CODE END APPD_EnableCPU2 */ + return; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static void APPD_SetCPU2GpioConfig(void) +{ + /* USER CODE BEGIN APPD_SetCPU2GpioConfig */ + GPIO_InitTypeDef gpio_config = { 0 }; + uint8_t local_loop; + uint16_t gpioa_pin_list; + uint16_t gpiob_pin_list; + uint16_t gpioc_pin_list; + + gpioa_pin_list = 0; + gpiob_pin_list = 0; + gpioc_pin_list = 0; + + for (local_loop = 0; local_loop < GPIO_CFG_NBR_OF_FEATURES; local_loop++) + { + if (aGpioConfigList[local_loop].enable != 0) + { + switch ((uint32_t) aGpioConfigList[local_loop].port) + { + case (uint32_t) GPIOA: + gpioa_pin_list |= aGpioConfigList[local_loop].pin; + break; + + case (uint32_t) GPIOB: + gpiob_pin_list |= aGpioConfigList[local_loop].pin; + break; + + case (uint32_t) GPIOC: + gpioc_pin_list |= aGpioConfigList[local_loop].pin; + break; + + default: + break; + } + } + } + + gpio_config.Pull = GPIO_NOPULL; + gpio_config.Mode = GPIO_MODE_OUTPUT_PP; + gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + if (gpioa_pin_list != 0) + { + gpio_config.Pin = gpioa_pin_list; + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_C2GPIOA_CLK_ENABLE(); + HAL_GPIO_Init(GPIOA, &gpio_config); + HAL_GPIO_WritePin(GPIOA, gpioa_pin_list, GPIO_PIN_RESET); + } + + if (gpiob_pin_list != 0) + { + gpio_config.Pin = gpiob_pin_list; + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_C2GPIOB_CLK_ENABLE(); + HAL_GPIO_Init(GPIOB, &gpio_config); + HAL_GPIO_WritePin(GPIOB, gpiob_pin_list, GPIO_PIN_RESET); + } + + if (gpioc_pin_list != 0) + { + gpio_config.Pin = gpioc_pin_list; + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_C2GPIOC_CLK_ENABLE(); + HAL_GPIO_Init(GPIOC, &gpio_config); + HAL_GPIO_WritePin(GPIOC, gpioc_pin_list, GPIO_PIN_RESET); + } + + /* USER CODE END APPD_SetCPU2GpioConfig */ + return; +} + +static void APPD_BleDtbCfg(void) +{ +/* USER CODE BEGIN APPD_BleDtbCfg */ +#if (BLE_DTB_CFG != 0) + GPIO_InitTypeDef gpio_config = { 0 }; + uint8_t local_loop; + uint16_t gpioa_pin_list; + uint16_t gpiob_pin_list; + + gpioa_pin_list = 0; + gpiob_pin_list = 0; + + for (local_loop = 0; local_loop < GPIO_NBR_OF_RF_SIGNALS; local_loop++) + { + if (aRfConfigList[local_loop].enable != 0) + { + switch ((uint32_t) aRfConfigList[local_loop].port) + { + case (uint32_t) GPIOA: + gpioa_pin_list |= aRfConfigList[local_loop].pin; + break; + + case (uint32_t) GPIOB: + gpiob_pin_list |= aRfConfigList[local_loop].pin; + break; + + default: + break; + } + } + } + + gpio_config.Pull = GPIO_NOPULL; + gpio_config.Mode = GPIO_MODE_AF_PP; + gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_config.Alternate = GPIO_AF6_RF_DTB7; + + if (gpioa_pin_list != 0) + { + gpio_config.Pin = gpioa_pin_list; + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_C2GPIOA_CLK_ENABLE(); + HAL_GPIO_Init(GPIOA, &gpio_config); + } + + if (gpiob_pin_list != 0) + { + gpio_config.Pin = gpiob_pin_list; + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_C2GPIOB_CLK_ENABLE(); + HAL_GPIO_Init(GPIOB, &gpio_config); + } +#endif + + /* USER CODE END APPD_BleDtbCfg */ + return; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp index f631165467e749..cf0cb741c54f10 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp @@ -19,12 +19,15 @@ /* Includes ------------------------------------------------------------------*/ #include "app_entry.h" +#include "AppTask.h" #include "app_ble.h" #include "app_common.h" #include "app_conf.h" +#include "app_debug.h" #include "app_thread.h" #include "cmsis_os.h" #include "dbg_trace.h" +#include "flash_wb.h" #include "hw_conf.h" #include "main.h" #include "shci.h" @@ -33,9 +36,9 @@ #include "stm32_lcd.h" #include "stm32_lpm.h" #include "stm32wb5mm_dk_lcd.h" +#include "stm_ext_flash.h" #include "stm_logging.h" -#include "AppTask.h" /* Private includes -----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -48,7 +51,7 @@ /* Private defines -----------------------------------------------------------*/ /* POOL_SIZE = 2(TL_PacketHeader_t) + 258 (3(TL_EVT_HDR_SIZE) + 255(Payload size)) */ -#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4 * DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4)) +#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4U * DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4U)) /* USER CODE BEGIN PD */ /* USER CODE END PD */ @@ -70,17 +73,11 @@ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255]; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255]; uint8_t g_ot_notification_allowed = 0U; -/* Global variables ----------------------------------------------------------*/ -/* Global function prototypes -----------------------------------------------*/ -#if (CFG_DEBUG_TRACE != 0) -size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize); -#endif - -/* USER CODE BEGIN GFP */ +/* Global variables ----------------------------------------------------------*/ +osMutexId_t MtxShciId; osSemaphoreId_t SemShciId; -osSemaphoreId_t SemShciUserEvtProcessId; -osThreadId_t OsShciUserEvtProcessId; +osThreadId_t ShciUserEvtProcessId; osThreadId_t OsPushButtonProcessId; const osThreadAttr_t ShciUserEvtProcess_attr = { .name = CFG_SHCI_USER_EVT_PROCESS_NAME, @@ -99,6 +96,13 @@ const osThreadAttr_t PushButtonProcess_attr = { .name = CFG_PUSH_BUTTON_EV .stack_size = CFG_PUSH_BUTTON_EVT_PROCESS_STACK_SIZE, .priority = CFG_PUSH_BUTTON_EVT_PROCESS_PRIORITY }; +/* Global function prototypes -----------------------------------------------*/ +#if (CFG_DEBUG_TRACE != 0) +size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize); +#endif + +/* USER CODE BEGIN GFP */ + /* USER CODE END GFP */ /* Private functions prototypes-----------------------------------------------*/ @@ -108,6 +112,9 @@ static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status); static void APPE_SysUserEvtRx(void * pPayload); static void APPE_SysEvtReadyProcessing(void); static void APPE_SysEvtError(SCHI_SystemErrCode_t ErrorCode); +static void ShciUserEvtProcess(void * argument); +static void PushButtonEvtProcess(void * argument); + static void appe_Tl_Init(void); /* USER CODE BEGIN PFP */ static void Led_Init(void); @@ -115,12 +122,8 @@ static void Button_Init(void); #if (CFG_HW_EXTPA_ENABLED == 1) static void ExtPA_Init(void); #endif -static void ShciUserEvtProcess(void * argument); -static void PushButtonEvtProcess(void * argument); /* USER CODE END PFP */ -static void displayConcurrentMode(void); - // Callback function to handle pushbutton to apptask PushButtonCallback PbCb = NULL; @@ -128,7 +131,6 @@ void APP_ENTRY_PBSetReceiveCallback(PushButtonCallback aCallback) { PbCb = aCallback; } - /* Functions Definition ------------------------------------------------------*/ void APPE_Init(void) { @@ -142,8 +144,12 @@ void APPE_Init(void) /* initialize debugger module if supported and debug trace if activated */ Init_Debug(); - /* Display Dynamic concurrent mode (BLE and Thread) */ - displayConcurrentMode(); + // Init qspi and external flash + STM_EXT_FLASH_Init(); + // Init nvm + NM_Init(); + + APPD_Init(); /** * The Standby mode should not be entered before the initialization is over @@ -151,12 +157,7 @@ void APPE_Init(void) */ UTIL_LPM_SetOffMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE); - /** init freertos semaphore */ - SemShciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ - SemShciUserEvtProcessId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ - OsShciUserEvtProcessId = osThreadNew(ShciUserEvtProcess, NULL, &ShciUserEvtProcess_attr); - OsPushButtonProcessId = osThreadNew(PushButtonEvtProcess, NULL, &PushButtonProcess_attr); - + OsPushButtonProcessId = osThreadNew(PushButtonEvtProcess, NULL, &PushButtonProcess_attr); Led_Init(); Button_Init(); @@ -164,6 +165,7 @@ void APPE_Init(void) /* Initialize all transport layers and start CPU2 which will send back a ready event to CPU1 */ appe_Tl_Init(); +#if (CFG_LCD_SUPPORTED == 1) BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE); /* Set LCD Foreground Layer */ UTIL_LCD_SetFuncDriver(&LCD_Driver); /* SetFunc before setting device */ @@ -177,9 +179,9 @@ void APPE_Init(void) UTIL_LCD_SetBackColor(SSD1315_COLOR_BLACK); BSP_LCD_Clear(0, SSD1315_COLOR_BLACK); BSP_LCD_Refresh(0); - UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *) "Matter LightingApp", CENTER_MODE); + UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *) APP_NAME, CENTER_MODE); BSP_LCD_Refresh(0); - +#endif /** * From now, the application is waiting for the ready event ( VS_HCI_C2_Ready ) * received on the system channel before starting the Stack @@ -194,11 +196,6 @@ void APPE_Init(void) return; } -static void displayConcurrentMode() -{ - APP_DBG("Matter Over Thread Lighting-App starting..."); -} - /************************************************************* * * LOCAL FUNCTIONS @@ -292,6 +289,12 @@ static void appe_Tl_Init(void) /**< Reference table initialization */ TL_Init(); + MtxShciId = osMutexNew(NULL); + SemShciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ + + /** FreeRTOS system task creation */ + ShciUserEvtProcessId = osThreadNew(ShciUserEvtProcess, NULL, &ShciUserEvtProcess_attr); + /**< System channel initialization */ SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t *) &SystemCmdBuffer; SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot; @@ -311,7 +314,19 @@ static void appe_Tl_Init(void) static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status) { - UNUSED(status); + switch (status) + { + case SHCI_TL_CmdBusy: + osMutexAcquire(MtxShciId, osWaitForever); + break; + + case SHCI_TL_CmdAvailable: + osMutexRelease(MtxShciId); + break; + + default: + break; + } return; } @@ -321,7 +336,7 @@ static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status) * - a ready event (subevtcode = SHCI_SUB_EVT_CODE_READY) * - reported by the FUS (sysevt_ready_rsp == FUS_FW_RUNNING) * The buffer shall not be released - * ( eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable ) + * (eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable ) * When the status is not filled, the buffer is released by default */ static void APPE_SysUserEvtRx(void * pPayload) @@ -373,31 +388,64 @@ static void APPE_SysEvtError(SCHI_SystemErrCode_t ErrorCode) static void APPE_SysEvtReadyProcessing(void) { /* Traces channel initialization */ - TL_TRACES_Init(); + APPD_EnableCPU2(); + /* Configuration to CPU2 */ + SHCI_C2_CONFIG_Cmd_Param_t config_param = { 0 }; + uint32_t Ot_NVMAddr = 0; /* In the Context of Dynamic Concurrent mode, the Init and start of each stack must be split and executed * in the following order : - * APP_BLE_Init : BLE Stack Init until it's ready to start ADV + * APP_BLE_Init_Dyn_1() : BLE Stack Init until it's ready to start ADV * APP_THREAD_Init_Dyn_1() : Thread Stack Init until it's ready to be configured (default channel, PID, etc...) + * APP_BLE_Init_Dyn_2() : Start ADV + * APP_THREAD_Init_Dyn_2() : Thread Stack configuration (default channel, PID, etc...) to be able to start scanning + * or joining a Thread Network */ APP_DBG("1- Initialisation of BLE Stack..."); APP_BLE_Init_Dyn_1(); + /* Set the address that will be used by OT stack for NVM data management */ + if (NM_GetOtNVMAddr(&Ot_NVMAddr) == NVM_OK) + { + config_param.ThreadNvmRamAddress = Ot_NVMAddr; + (void) SHCI_C2_Config(&config_param); + } + APP_DBG("2- Initialisation of OpenThread Stack. FW info :"); - APP_THREAD_Init(); + APP_THREAD_Init_Dyn_1(); APP_BLE_Init_Dyn_2(); - + APP_THREAD_Init_Dyn_2(); APP_DBG("Start init matter"); GetAppTask().StartAppTask(); - #if (CFG_LPM_SUPPORTED == 1) /* Thread stack is initialized, low power mode can be enabled */ UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE); UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE); #endif - return; } +/************************************************************* + * + * FREERTOS WRAPPER FUNCTIONS + * + *************************************************************/ +static void ShciUserEvtProcess(void * argument) +{ + UNUSED(argument); + for (;;) + { + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_1 */ + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + shci_user_evt_proc(); + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_2 */ + } +} + +/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */ static void Led_Init(void) { #if (CFG_LED_SUPPORTED == 1U) @@ -413,12 +461,14 @@ static void Led_Init(void) static void Button_Init(void) { -#if (CFG_BUTTON_SUPPORTED == 1U) +#if ((CFG_BUTTON_SUPPORTED == 1U) || (CFG_HW_EXTPA_ENABLED == 1)) /** * Button Initialization */ BSP_PB_Init(BUTTON_USER1, BUTTON_MODE_EXTI); + BSP_PB_Init(BUTTON_USER2, BUTTON_MODE_EXTI); + #endif return; @@ -457,15 +507,24 @@ static void ExtPA_Init(void) static void PushButtonEvtProcess(void * argument) { UNUSED(argument); + uint32_t ButtonPressed = 0; + for (;;) { /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */ - /* USER CODE END SHCI_USER_EVT_PROCESS_1 */ - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + ButtonPressed = osThreadFlagsWait(3, osFlagsWaitAny, osWaitForever); Push_Button_st Message; - Message.Pushed_Button = BUTTON_USER1; - Message.State = 1; + if (1 == ButtonPressed) + { + Message.Pushed_Button = BUTTON_USER1; + Message.State = 1; + } + if (2 == ButtonPressed) + { + Message.Pushed_Button = BUTTON_USER2; + Message.State = 2; + } PbCb(&Message); // call matter callback to handle push button /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ @@ -473,27 +532,10 @@ static void PushButtonEvtProcess(void * argument) } } -static void ShciUserEvtProcess(void * argument) -{ - UNUSED(argument); - for (;;) - { - /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */ - - /* USER CODE END SHCI_USER_EVT_PROCESS_1 */ - // osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - osSemaphoreAcquire(SemShciUserEvtProcessId, osWaitForever); - shci_user_evt_proc(); - /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ - - /* USER CODE END SHCI_USER_EVT_PROCESS_2 */ - } -} - void shci_notify_asynch_evt(void * pdata) { UNUSED(pdata); - osSemaphoreRelease(SemShciUserEvtProcessId); + osThreadFlagsSet(ShciUserEvtProcessId, 1); return; } @@ -506,8 +548,7 @@ void shci_cmd_resp_release(uint32_t flag) void shci_cmd_resp_wait(uint32_t timeout) { - UNUSED(timeout); - osSemaphoreAcquire(SemShciId, osWaitForever); + osSemaphoreAcquire(SemShciId, pdMS_TO_TICKS(timeout)); return; } @@ -569,7 +610,7 @@ void BSP_PB_Callback(Button_TypeDef Button) case BUTTON_USER2: APP_DBG("BUTTON 2 PUSHED !"); - /* Set "Switch Protocol" Task */ + osThreadFlagsSet(OsPushButtonProcessId, 2); break; default: @@ -578,6 +619,7 @@ void BSP_PB_Callback(Button_TypeDef Button) return; } + #ifdef __cplusplus } #endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c index db25dccdf97cf0..3adaf861b574a3 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c @@ -1,4 +1,3 @@ - /* USER CODE BEGIN Header */ /** ****************************************************************************** diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c deleted file mode 100644 index fcf4534a327003..00000000000000 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c +++ /dev/null @@ -1,322 +0,0 @@ -/** - ****************************************************************************** - * @file : flash_driver.c - * @author : MCD Application Team - * @brief : Dual core Flash driver - ****************************************************************************** - * @attention - * - * Copyright (c) 2019-2021 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "flash_driver.h" -#include "app_common.h" -#include "main.h" -#include "shci.h" -#include "utilities_conf.h" - -/* Private typedef -----------------------------------------------------------*/ -typedef enum -{ - SEM_LOCK_SUCCESSFUL, - SEM_LOCK_BUSY, -} SemStatus_t; - -typedef enum -{ - FLASH_ERASE, - FLASH_WRITE, -} FlashOperationType_t; - -/* Private defines -----------------------------------------------------------*/ -/* Private macros ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Global variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static SingleFlashOperationStatus_t ProcessSingleFlashOperation(FlashOperationType_t FlashOperationType, - uint32_t SectorNumberOrDestAddress, uint64_t Data); -/* Public functions ----------------------------------------------------------*/ -uint32_t FD_EraseSectors(uint32_t FirstSector, uint32_t NbrOfSectors) -{ - uint32_t loop_flash; - uint32_t return_value; - SingleFlashOperationStatus_t single_flash_operation_status; - - single_flash_operation_status = SINGLE_FLASH_OPERATION_DONE; - - /** - * Take the semaphore to take ownership of the Flash IP - */ - while (LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID)) - ; - - HAL_FLASH_Unlock(); - - /** - * Notify the CPU2 that some flash erase activity may be executed - * On reception of this command, the CPU2 enables the BLE timing protection versus flash erase processing - * The Erase flash activity will be executed only when the BLE RF is idle for at least 25ms - * The CPU2 will prevent all flash activity (write or erase) in all cases when the BL RF Idle is shorter than 25ms. - */ - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); - - for (loop_flash = 0; (loop_flash < NbrOfSectors) && (single_flash_operation_status == SINGLE_FLASH_OPERATION_DONE); - loop_flash++) - { - single_flash_operation_status = FD_EraseSingleSector(FirstSector + loop_flash); - } - - if (single_flash_operation_status != SINGLE_FLASH_OPERATION_DONE) - { - return_value = NbrOfSectors - loop_flash + 1; - } - else - { - /** - * Notify the CPU2 there will be no request anymore to erase the flash - * On reception of this command, the CPU2 will disables the BLE timing protection versus flash erase processing - * The protection is active until next end of radio event. - */ - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF); - - HAL_FLASH_Lock(); - - /** - * Release the ownership of the Flash IP - */ - LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0); - - return_value = 0; - } - - return return_value; -} - -uint32_t FD_WriteData(uint32_t DestAddress, uint64_t * pSrcBuffer, uint32_t NbrOfData) -{ - uint32_t loop_flash; - uint32_t return_value; - SingleFlashOperationStatus_t single_flash_operation_status; - - single_flash_operation_status = SINGLE_FLASH_OPERATION_DONE; - - /** - * Take the semaphore to take ownership of the Flash IP - */ - while (LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID)) - ; - - HAL_FLASH_Unlock(); - - for (loop_flash = 0; (loop_flash < NbrOfData) && (single_flash_operation_status == SINGLE_FLASH_OPERATION_DONE); loop_flash++) - { - single_flash_operation_status = FD_WriteSingleData(DestAddress + (8 * loop_flash), *(pSrcBuffer + loop_flash)); - } - - if (single_flash_operation_status != SINGLE_FLASH_OPERATION_DONE) - { - return_value = NbrOfData - loop_flash + 1; - } - else - { - HAL_FLASH_Lock(); - - /** - * Release the ownership of the Flash IP - */ - LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0); - - return_value = 0; - } - - return return_value; -} - -SingleFlashOperationStatus_t FD_EraseSingleSector(uint32_t SectorNumber) -{ - SingleFlashOperationStatus_t return_value; - - /* The last parameter is unused in that case and set to 0 */ - return_value = ProcessSingleFlashOperation(FLASH_ERASE, SectorNumber, 0); - - return return_value; -} - -SingleFlashOperationStatus_t FD_WriteSingleData(uint32_t DestAddress, uint64_t Data) -{ - SingleFlashOperationStatus_t return_value; - - return_value = ProcessSingleFlashOperation(FLASH_WRITE, DestAddress, Data); - - return return_value; -} - -/************************************************************* - * - * LOCAL FUNCTIONS - * - *************************************************************/ -static SingleFlashOperationStatus_t ProcessSingleFlashOperation(FlashOperationType_t FlashOperationType, - uint32_t SectorNumberOrDestAddress, uint64_t Data) -{ - SemStatus_t cpu1_sem_status; - SemStatus_t cpu2_sem_status; - WaitedSemStatus_t waited_sem_status; - SingleFlashOperationStatus_t return_status; - - uint32_t page_error; - FLASH_EraseInitTypeDef p_erase_init; - - waited_sem_status = WAITED_SEM_FREE; - - p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; - p_erase_init.NbPages = 1; - p_erase_init.Page = SectorNumberOrDestAddress; - - do - { - /** - * When the PESD bit mechanism is used by CPU2 to protect its timing, the PESD bit should be polled here. - * If the PESD is set, the CPU1 will be stalled when reading literals from an ISR that may occur after - * the flash processing has been requested but suspended due to the PESD bit. - * - * Note: This code is required only when the PESD mechanism is used to protect the CPU2 timing. - * However, keeping that code make it compatible with the two mechanisms. - */ - while (LL_FLASH_IsActiveFlag_OperationSuspended()) - ; - - UTILS_ENTER_CRITICAL_SECTION(); - - /** - * Depending on the application implementation, in case a multitasking is possible with an OS, - * it should be checked here if another task in the application disallowed flash processing to protect - * some latency in critical code execution - * When flash processing is ongoing, the CPU cannot access the flash anymore. - * Trying to access the flash during that time stalls the CPU. - * The only way for CPU1 to disallow flash processing is to take CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID. - */ - cpu1_sem_status = (SemStatus_t) LL_HSEM_GetStatus(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID); - if (cpu1_sem_status == SEM_LOCK_SUCCESSFUL) - { - /** - * Check now if the CPU2 disallows flash processing to protect its timing. - * If the semaphore is locked, the CPU2 does not allow flash processing - * - * Note: By default, the CPU2 uses the PESD mechanism to protect its timing, - * therefore, it is useless to get/release the semaphore. - * - * However, keeping that code make it compatible with the two mechanisms. - * The protection by semaphore is enabled on CPU2 side with the command SHCI_C2_SetFlashActivityControl() - * - */ - cpu2_sem_status = (SemStatus_t) LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID); - if (cpu2_sem_status == SEM_LOCK_SUCCESSFUL) - { - /** - * When CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is taken, it is allowed to only erase one sector or - * write one single 64bits data - * When either several sectors need to be erased or several 64bits data need to be written, - * the application shall first exit from the critical section and try again. - */ - if (FlashOperationType == FLASH_ERASE) - { - HAL_FLASHEx_Erase(&p_erase_init, &page_error); - } - else - { - HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, SectorNumberOrDestAddress, Data); - } - /** - * Release the semaphore to give the opportunity to CPU2 to protect its timing versus the next flash operation - * by taking this semaphore. - * Note that the CPU2 is polling on this semaphore so CPU1 shall release it as fast as possible. - * This is why this code is protected by a critical section. - */ - LL_HSEM_ReleaseLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0); - } - } - - UTILS_EXIT_CRITICAL_SECTION(); - - if (cpu1_sem_status != SEM_LOCK_SUCCESSFUL) - { - /** - * To avoid looping in ProcessSingleFlashOperation(), FD_WaitForSemAvailable() should implement a mechanism to - * continue only when CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID is free - */ - waited_sem_status = FD_WaitForSemAvailable(WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU1); - } - else if (cpu2_sem_status != SEM_LOCK_SUCCESSFUL) - { - /** - * To avoid looping in ProcessSingleFlashOperation(), FD_WaitForSemAvailable() should implement a mechanism to - * continue only when CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is free - */ - waited_sem_status = FD_WaitForSemAvailable(WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU2); - } - } while (((cpu2_sem_status != SEM_LOCK_SUCCESSFUL) || (cpu1_sem_status != SEM_LOCK_SUCCESSFUL)) && - (waited_sem_status != WAITED_SEM_BUSY)); - - /** - * In most BLE application, the flash should not be blocked by the CPU2 longer than FLASH_TIMEOUT_VALUE (1000ms) - * However, it could be that for some marginal application, this time is longer. - * In that case either HAL_FLASHEx_Erase() or HAL_FLASH_Program() will exit with FLASH_TIMEOUT_VALUE value. - * This is not a failing case and there is no other way than waiting the operation to be completed. - * If for any reason this test is never passed, this means there is a failure in the system and there is no other - * way to recover than applying a device reset. - * - * Note: This code is required only when the PESD mechanism is used to protect the CPU2 timing. - * However, keeping that code make it compatible with the two mechanisms. - */ - while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY)) - ; - - if (waited_sem_status != WAITED_SEM_BUSY) - { - /** - * The flash processing has been done. It has not been checked whether it has been successful or not. - * The only commitment is that it is possible to request a new flash processing - */ - return_status = SINGLE_FLASH_OPERATION_DONE; - } - else - { - /** - * The flash processing has not been executed due to timing protection from either the CPU1 or the CPU2. - * This status is reported up to the user that should retry after checking that each CPU do not - * protect its timing anymore. - */ - return_status = SINGLE_FLASH_OPERATION_NOT_EXECUTED; - } - - return return_status; -} - -/************************************************************* - * - * WEAK FUNCTIONS - * - *************************************************************/ -__WEAK WaitedSemStatus_t FD_WaitForSemAvailable(WaitedSemId_t WaitedSemId) -{ - /** - * The timing protection is enabled by either CPU1 or CPU2. It should be decided here if the driver shall - * keep trying to erase/write the flash until successful or if it shall exit and report to the user that the action - * has not been executed. - * WAITED_SEM_BUSY returns to the user - * WAITED_SEM_FREE keep looping in the driver until the action is executed. This will result in the current stack looping - * until this is done. In a bare metal implementation, only the code within interrupt handler can be executed. With an OS, - * only task with higher priority can be processed - * - */ - return WAITED_SEM_BUSY; -} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c index 4c24d6f71c9103..6fb60c16f87609 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c @@ -19,29 +19,36 @@ /* Includes ------------------------------------------------------------------*/ #include "flash_wb.h" -#include "flash_driver.h" +#include "stm_ext_flash.h" + +#if (OTA_SUPPORT == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +#include "mapping_fwimg.h" +#include "mapping_sbsfu.h" +#elif defined(__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __CC_ARM || __ARMCC_VERSION */ +#endif #include #include #include /* Private defines -----------------------------------------------------------*/ -#define MATTER_KEY_NAME_MAX_LENGTH (15 * 2) // ADD Max key name string size is 30 "keyType...;KeyName..." -// ^ STM32STORE_MAX_KEY_SIZE +#if (OTA_SUPPORT == 1) +#define NVM_MATTER_ADDR_INIT_SECURE BACKUP_END + 1 // start after back up slot +#else +#define NVM_MATTER_ADDR_INIT_SECURE EXTERNAL_FLASH_ADDRESS +#endif +// #define NVM_MATTER_ADDR_INIT_SECURE EXTERNAL_FLASH_ADDRESS + OTA_MAX_SIZE // start after back up slot +#define MATTER_KEY_NAME_MAX_LENGTH (16 * 2) // ADD Max key name string size is 32 "keyType...;KeyName..." #define NVM_OFFSET_KEY 512 -#define NVM_END_FLASH #define NVM_BLOCK_SIZE NVM_OFFSET_KEY -#define FLASH_START 0x08000000 #define DEFAULT_VALUE 0xFF -#define NB_SECTOR 3 -#define NVM_MATTER_ADDR_INIT_SECURE 0x08082000 -#define NVM_MATTER_ADDR_INIT_SECURE_PTR ((void * const) NVM_MATTER_ADDR_INIT_SECURE) -#define SECTOR_SIZE_SECURE 4096 * 2 +#define SECTOR_SIZE_SECURE 4096 * 5 #define NVM_MATTER_ADDR_INIT_NO_SECURE NVM_MATTER_ADDR_INIT_SECURE + SECTOR_SIZE_SECURE -#define NVM_MATTER_ADDR_INIT_NOSECURE_PTR ((void * const) NVM_MATTER_ADDR_INIT_NO_SECURE) #define SECTOR_SIZE_NO_SECURE 4096 #define NVM_SIZE_FLASH (SECTOR_SIZE_SECURE + SECTOR_SIZE_NO_SECURE) -#define NVM_MAX_KEY NVM_SIZE_FLASH / NVM_OFFSET_KEY typedef struct { @@ -63,7 +70,6 @@ const NVM_Sector_Struct sector_no_secure = { .id_sector = SECTOR_NO_SECURE, //*SIMULATE TO EXAMPLE* const NVM_Sector_Struct sector_secure = { .id_sector = SECTOR_SECURE, .ram_ptr = ram_nvm, .sector_size = SECTOR_SIZE_SECURE }; -uint8_t CheckSanity = 0; /* Global variables ----------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ @@ -72,28 +78,17 @@ static uint8_t flash_update(const NVM_Sector_Struct select_sector, uint8_t * Key static NVM_StatusTypeDef flash_replace(const NVM_Sector_Struct select_sector, uint8_t * PtKeyfind, uint8_t * KeyName, uint8_t * KeyValue, size_t KeySize); static NVM_StatusTypeDef flash_write(uint8_t * PtKeyFree, uint8_t * key, uint8_t * value, size_t value_size); -static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName); +static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName, size_t nvm_size); static NVM_StatusTypeDef delete_key(const NVM_Sector_Struct select_sector, uint8_t * PtkeyFind); /* Public functions ----------------------------------------------------------*/ -void NM_Init(void) -{ - // Copy Nvm flash to ram, it used one time for boot - // copy no secure nvm to no secure ram - memcpy(sector_no_secure.ram_ptr, NVM_MATTER_ADDR_INIT_NOSECURE_PTR, sector_no_secure.sector_size); - - // copy secure nvm to secure ram *SIMULATE TO EXAMPLE* - memcpy(sector_secure.ram_ptr, NVM_MATTER_ADDR_INIT_SECURE_PTR, sector_secure.sector_size); -} - -NVM_StatusTypeDef NM_Check_Validity(void) +NVM_StatusTypeDef NM_Init(void) { NVM_StatusTypeDef err = NVM_OK; - if (CheckSanity != 0) - { - err = NVM_FLASH_CORRUPTION; - } + + memset(ram_nvm, DEFAULT_VALUE, sizeof(ram_nvm)); + err = STM_EXT_FLASH_ReadChunk(NVM_MATTER_ADDR_INIT_SECURE, ram_nvm, sizeof(ram_nvm)); return err; } @@ -101,24 +96,15 @@ NVM_StatusTypeDef NM_Dump(void) { NVM_StatusTypeDef err = NVM_DELETE_FAILED; - err = FD_EraseSectors((NVM_MATTER_ADDR_INIT_SECURE - FLASH_START) / (NVM_SIZE_FLASH / NB_SECTOR), NB_SECTOR); - if (err == 0) + if (STM_EXT_FLASH_Delete_Image(NVM_MATTER_ADDR_INIT_SECURE, sizeof(ram_nvm)) == STM_EXT_FLASH_OK) { - err = FD_WriteData(NVM_MATTER_ADDR_INIT_SECURE, (uint64_t *) ram_nvm, (uint32_t) (NVM_SIZE_FLASH / sizeof(uint64_t))); - if (err != 0) + if (STM_EXT_FLASH_WriteChunk(NVM_MATTER_ADDR_INIT_SECURE, ram_nvm, sizeof(ram_nvm)) == STM_EXT_FLASH_OK) { - err = NVM_WRITE_FAILED; + err = NVM_OK; } else { - if (memcmp(ram_nvm, (void *) NVM_MATTER_ADDR_INIT_SECURE, (size_t) NVM_SIZE_FLASH)) - { - err = NVM_WRITE_FAILED; - } - else - { - err = NVM_OK; - } + err = NVM_WRITE_FAILED; } } return err; @@ -127,6 +113,10 @@ NVM_StatusTypeDef NM_Dump(void) NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t KeySize, size_t * read_by_size, NVM_Sector sector) { + if ((KeyValue == NULL) || (read_by_size == NULL)) + { + return NVM_PARAM_ERROR; + } NVM_Sector_Struct select_nvm = { 0 }; switch (sector) { @@ -142,7 +132,7 @@ NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t return NVM_WRITE_FAILED; } - uint8_t * key_search = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName); + uint8_t * key_search = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName, select_nvm.sector_size); if (key_search != NULL) { // copy Keyname's value in KeyValue and copy the size of KeyValue in read_by_size @@ -151,9 +141,23 @@ NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t return NVM_KEY_NOT_FOUND; } +NVM_StatusTypeDef NM_GetOtNVMAddr(uint32_t * NVMAddr) +{ + if (NVMAddr == NULL) + { + return NVM_PARAM_ERROR; + } + *NVMAddr = (uint32_t) ram_nvm + SECTOR_SIZE_SECURE; + return NVM_OK; +} + NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySize, NVM_Sector sector) { + if ((KeyValue == NULL) || (KeyName == NULL)) + { + return NVM_PARAM_ERROR; + } NVM_Sector_Struct select_nvm = { 0 }; void * Ptkey = NULL; @@ -176,7 +180,7 @@ NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySi return NVM_BLOCK_SIZE_OVERFLOW; } // call function to search the pointer of key if it exist else return null - Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName); + Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName, select_nvm.sector_size); if (Ptkey == NULL) { @@ -192,9 +196,13 @@ NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySi return NVM_WRITE_FAILED; } -uint8_t NM_DeleteKey(const char * Keyname, NVM_Sector sector) +NVM_StatusTypeDef NM_DeleteKey(const char * Keyname, NVM_Sector sector) { + if (Keyname == NULL) + { + return NVM_PARAM_ERROR; + } NVM_Sector_Struct select_nvm = { 0 }; switch (sector) { @@ -209,7 +217,7 @@ uint8_t NM_DeleteKey(const char * Keyname, NVM_Sector sector) default: return NVM_WRITE_FAILED; } - uint8_t * Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) Keyname); + uint8_t * Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) Keyname, select_nvm.sector_size); if (Ptkey != NULL) { return delete_key(select_nvm, Ptkey); @@ -221,7 +229,7 @@ void NM_ResetFactory(void) { while (1) { - FD_EraseSectors((NVM_MATTER_ADDR_INIT_SECURE - FLASH_START) / (NVM_SIZE_FLASH / NB_SECTOR), NB_SECTOR); + STM_EXT_FLASH_Delete_Image(NVM_MATTER_ADDR_INIT_SECURE, sizeof(ram_nvm)); NVIC_SystemReset(); } } @@ -232,24 +240,29 @@ void NM_ResetFactory(void) * *************************************************************/ -static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName) +static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName, size_t nvm_size) { uint8_t * i = PtPage; size_t read_by_size = 0; - while ((i >= PtPage) || (i < (PtPage + NVM_SIZE_FLASH))) + while ((i >= PtPage) || (i < (PtPage + nvm_size))) { if (*i != DEFAULT_VALUE) { - if (strcmp((char *) KeyName, (char *) i) == 0) + if (strcmp(KeyName, (uint8_t *) i) == 0) { return i; } read_by_size = *(size_t *) ((uint8_t *) i + MATTER_KEY_NAME_MAX_LENGTH); + // ensure that the size of the data being read does not exceed the remaining size of the buffer + if (read_by_size + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH > nvm_size - (i - PtPage)) + { + return NULL; + } i += read_by_size + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH; // Flash is corrupted - if ((i < PtPage) || (i > (PtPage + NVM_SIZE_FLASH))) + if ((i < PtPage) || (i > (PtPage + nvm_size))) { NM_ResetFactory(); } @@ -327,14 +340,14 @@ static NVM_StatusTypeDef delete_key(const NVM_Sector_Struct select_sector, uint8 size_key = *(size_t *) ((uint8_t *) PtkeyFind + MATTER_KEY_NAME_MAX_LENGTH); PtKeyNext = PtkeyFind + size_key + MATTER_KEY_NAME_MAX_LENGTH + sizeof(size_key); PtKeyCpy = PtkeyFind; - while ((*PtKeyNext != 0xFF) && (PtKeyNext < (ram_nvm + NVM_SIZE_FLASH))) + while ((*PtKeyNext != 0xFF) && (PtKeyNext < (select_sector.ram_ptr + select_sector.sector_size))) { size_key = *(size_t *) ((uint8_t *) PtKeyNext + MATTER_KEY_NAME_MAX_LENGTH); memcpy(PtKeyCpy, PtKeyNext, size_key + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH); PtKeyCpy += size_key + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH; PtKeyNext += size_key + MATTER_KEY_NAME_MAX_LENGTH + sizeof(size_key); } - memset(PtKeyCpy, DEFAULT_VALUE, (ram_nvm + NVM_SIZE_FLASH - PtKeyCpy)); + memset(PtKeyCpy, DEFAULT_VALUE, (select_sector.ram_ptr + select_sector.sector_size - PtKeyCpy)); return NVM_OK; } return NVM_DELETE_FAILED; diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp index a48e8b88dc6101..06481af913c99c 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp @@ -45,9 +45,7 @@ #include "app_thread.h" #include "cmsis_os.h" #include "dbg_trace.h" -#include "flash_wb.h" #include "stm32_lpm.h" - /* Private typedef -----------------------------------------------------------*/ /* Private defines -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ @@ -96,6 +94,7 @@ int main(void) * The OPTVERR flag is wrongly set at power on * It shall be cleared before using any HAL_FLASH_xxx() api */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); /** @@ -126,9 +125,7 @@ int main(void) MX_GPIO_Init(); /* IPCC initialisation */ MX_IPCC_Init(); - NM_Init(); freertos_mbedtls_init(); - APPE_Init(); GetAppTask().InitMatter(); osKernelStart(); diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/ota.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/ota.cpp new file mode 100644 index 00000000000000..7af8c69807fbf7 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/ota.cpp @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/***************************************************************************** + * Includes Definitions + *****************************************************************************/ + +#if (OTA_SUPPORT == 1) +#include "ota.h" +#include + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::DeviceLayer; + +/***************************************************************************** + * Static Data Definitions + *****************************************************************************/ + +DefaultOTARequestor gRequestorCore; +DefaultOTARequestorStorage gRequestorStorage; +DefaultOTARequestorDriver gRequestorUser; +BDXDownloader gDownloader; +OTAImageProcessorImpl gImageProcessor; +FactoryDataProvider gFactoryDataProvider; +chip::ota::DefaultOTARequestorUserConsent gUserConsentProvider; +static chip::ota::UserConsentState gUserConsentState = chip::ota::UserConsentState::kGranted; + +/***************************************************************************** + * Application Function Definitions + *****************************************************************************/ + +bool OtaHeaderValidation(Ota_ImageHeader_t imageHeader) +{ + + uint16_t vendorId = 0; + uint16_t productId = 0; + + if (gFactoryDataProvider.GetVendorId(vendorId) != CHIP_NO_ERROR) + { + return false; + } + if (gFactoryDataProvider.GetProductId(productId) != CHIP_NO_ERROR) + { + return false; + } + + // Check that the image matches vendor and product ID and that the version is higher than what we currently have + if (imageHeader.vendorId != vendorId || imageHeader.productId != productId || + imageHeader.softwareVersion <= CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION) + { + return false; + } + + return true; +} + +void InitializeOTARequestor(void) +{ + ChipLogProgress(DeviceLayer, "Initialising OTA Requestor"); + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&gRequestorCore); + + gRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + gRequestorCore.Init(chip::Server::GetInstance(), gRequestorStorage, gRequestorUser, gDownloader); + gImageProcessor.SetOTADownloader(&gDownloader); + gDownloader.SetImageProcessorDelegate(&gImageProcessor); + gRequestorUser.Init(&gRequestorCore, &gImageProcessor); + gUserConsentProvider.SetUserConsentState(gUserConsentState); + // Test to trigger ota. this function can be trigger by a Push Button + TriggerOTAQuery(); +} + +void TriggerOTAQuery(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + OTARequestorInterface * requestor = GetRequestorInstance(); + + if (requestor != nullptr) + { + err = requestor->TriggerImmediateQuery(kUndefinedFabricIndex); + + if (CHIP_NO_ERROR != err) + { + ChipLogError(DeviceLayer, "Failed trigger OTA query: %" CHIP_ERROR_FORMAT, err.Format()); + } + } + else + { + ChipLogProgress(DeviceLayer, "No OTA requestor instance, can't query OTA"); + } +} +#endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c index ee2d71467514b5..f355df04fb803d 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c @@ -33,7 +33,7 @@ uint8_t * OTP_Read(uint8_t id) { uint8_t * p_id; - p_id = (uint8_t *) (CFG_OTP_END_ADDRESS - 7); + p_id = (uint8_t *) (CFG_OTP_END_ADRESS - 7); while (((*(p_id + 7)) != id) && (p_id != (uint8_t *) CFG_OTP_BASE_ADDRESS)) { diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_factorydata.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_factorydata.c new file mode 100644 index 00000000000000..3ad44445b11908 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_factorydata.c @@ -0,0 +1,132 @@ +/** + ****************************************************************************** + * @file stm32_factorydata.c + * @author MCD Application Team + * @brief Middleware between matter factory data and external flash , + * to manage factory data needed for Matter + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_factorydata.h" +#include "stm_ext_flash.h" + +/* Private defines -----------------------------------------------------------*/ +#define HEADER_SIZE 8 +#define FACTORY_DATA_START_ADDR 0x901C0000U +#define FACTORY_DATA_END_ADDR 0x901CFFFFU +#define DATA_MAX_LENGTH 603 + +/* Private variables ---------------------------------------------------------*/ +typedef struct +{ + uint32_t tag_id; + uint32_t data_length; +} header; + +/* Private functions prototypes-----------------------------------------------*/ +static FACTORYDATA_StatusTypeDef Get_TagLocation(FACTORYDATA_TagId tag, uint32_t * out_Location, uint32_t * out_length); + +/************************************************************* + * + * PUBLIC FUNCTIONS + * + *************************************************************/ + +FACTORYDATA_StatusTypeDef FACTORYDATA_GetValue(FACTORYDATA_TagId tag, uint8_t * data, uint32_t size, uint32_t * out_datalength) +{ + + FACTORYDATA_StatusTypeDef err = DATAFACTORY_DATA_NOT_FOUND; + uint32_t Location; + uint32_t datalength; + + if ((data == NULL) || (out_datalength == NULL)) + { + return DATAFACTORY_PARAM_ERROR; + } + + // search for tag location + err = Get_TagLocation(tag, &Location, &datalength); + if (err != DATAFACTORY_OK) + { + return err; + } + else + { + if (datalength > size) + { + return DATAFACTORY_BUFFER_TOO_SMALL; + } + // Read data + err = STM_EXT_FLASH_ReadChunk(Location, data, datalength); + if (err == DATAFACTORY_OK) + { + *out_datalength = datalength; + } + } + + return err; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ + +static FACTORYDATA_StatusTypeDef Get_TagLocation(FACTORYDATA_TagId tag, uint32_t * out_Location, uint32_t * out_length) +{ + FACTORYDATA_StatusTypeDef err = DATAFACTORY_OK; + header Header_tag; + uint8_t Header_data[HEADER_SIZE]; + uint32_t location_tmp = FACTORY_DATA_START_ADDR; + + // read all header until find the right tag + do + { + memset(Header_data, 0, HEADER_SIZE); + err = STM_EXT_FLASH_ReadChunk(location_tmp, Header_data, HEADER_SIZE); + if (err != DATAFACTORY_OK) + { + return DATAFACTORY_PARAM_ERROR; + } + + // retrieve header with tag_id and data_length + Header_tag.tag_id = Header_data[0] + ((Header_data[1]) << 8) + ((Header_data[2]) << 16) + ((Header_data[3]) << 24); + Header_tag.data_length = Header_data[4] + ((Header_data[5]) << 8) + ((Header_data[6]) << 16) + ((Header_data[7]) << 24); + + // check if the length is valid + if ((Header_tag.data_length > 0) && (Header_tag.data_length < DATA_MAX_LENGTH)) + { + if (Header_tag.tag_id == tag) + { + *out_Location = location_tmp + HEADER_SIZE; + *out_length = Header_tag.data_length; + break; + } + // move to the next data + location_tmp += Header_tag.data_length + HEADER_SIZE; + } + else + { + return DATAFACTORY_PARAM_ERROR; + } + } while (location_tmp < FACTORY_DATA_END_ADDR); + + if (location_tmp > FACTORY_DATA_END_ADDR) + { + err = DATAFACTORY_DATA_NOT_FOUND; + } + + return err; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wb5mm_dk_qspi.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wb5mm_dk_qspi.c new file mode 100644 index 00000000000000..6925269ea304a1 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wb5mm_dk_qspi.c @@ -0,0 +1,922 @@ +/** + ****************************************************************************** + * @file stm32wb5mm_dk_qspi.c + * @author MCD Application Team + * @brief This file includes a standard driver for the S25FL128S QSPI + * memory mounted on STM32WB5MM-DK board. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) This driver is used to drive the S25FL128S QSPI external + memory mounted on STM32WB5MM-DK board. + + (#) This driver needs a specific component driver (S25FL128S) to be included with. + + (#) Initialization steps: + (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This + function includes the MSP layer hardware resources initialization and the + QSPI interface with the external memory. + + (#) QSPI memory operations + (++) QSPI memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_QSPI_Read()/BSP_QSPI_Write(). + (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. + (see the QSPI memory data sheet) + (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by + specifying the block address. You can perform an erase operation of the whole + chip by calling the function BSP_QSPI_Erase_Chip(). + (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. + (see the QSPI memory data sheet) + (++) The function BSP_QSPI_EnableMemoryMappedMode enables the QSPI memory mapped mode. + (++) The function BSP_QSPI_DisableMemoryMappedMode disables the QSPI memory mapped mode. + (++) The function BSP_QSPI_ReadID() returns 3 bytes memory IDs: Manufacturer ID, + Memory type, Memory density. + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wb5mm_dk_qspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WB5MM_DK + * @{ + */ + +/** @defgroup STM32WB5MM_DK_QSPI STM32WB5MM_DK QSPI + * @{ + */ + +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Variables Exported Variables + * @{ + */ +QSPI_HandleTypeDef hqspi; +BSP_QSPI_Ctx_t QSPI_Ctx[QSPI_INSTANCES_NUMBER]; +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STM32WB5MM_DK_QSPI_Private_Functions Private Functions + * @{ + */ +static void QSPI_MspInit(QSPI_HandleTypeDef * hQspi); +static void QSPI_MspDeInit(QSPI_HandleTypeDef * hSspi); +static int32_t QSPI_ResetMemory(uint32_t Instance); +static int32_t QSPI_DummyCyclesCfg(uint32_t Instance); + +/** + * @} + */ + +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the QSPI interface. + * @param Instance QSPI Instance + * @param Init QSPI Init structure + * @retval BSP status + */ +int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t * Init) +{ + int32_t ret = BSP_ERROR_NONE; + BSP_QSPI_Info_t pInfo; + MX_QSPI_Init_t qspi_init; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if instance is already initialized */ + if (QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_NONE) + { +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) + /* Register the QSPI MSP Callbacks */ + if (QSPI_Ctx[Instance].IsMspCallbacksValid == 0UL) + { + if (BSP_QSPI_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#else + /* Msp QSPI initialization */ + QSPI_MspInit(&hqspi); +#endif /* USE_HAL_QSPI_REGISTER_CALLBACKS == 1 */ + + if (ret == BSP_ERROR_NONE) + { + /* STM32 QSPI interface initialization */ + (void) S25FL128S_GetFlashInfo(&pInfo); + qspi_init.ClockPrescaler = 4; + qspi_init.DualFlashMode = S25FL128S_DUALFLASH_DISABLE; + qspi_init.FlashSize = (uint32_t) POSITION_VAL((uint32_t) pInfo.FlashSize) - 1U; + qspi_init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + + if (MX_QSPI_Init(&hqspi, &qspi_init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } /* QSPI memory reset */ + else if (QSPI_ResetMemory(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Force Flash enter 4 Byte address mode */ + else if (S25FL128S_AutoPollingMemReady(&hqspi, Init->InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (S25FL128S_Enter4BytesAddressMode(&hqspi, Init->InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Configuration of the dummy cycles on QSPI memory side */ + else if (QSPI_DummyCyclesCfg(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + QSPI_Ctx[Instance].InterfaceMode = Init->InterfaceMode; + } + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief De-Initializes the QSPI interface. + * @param Instance QSPI Instance + * @retval BSP status + */ +int32_t BSP_QSPI_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_MMP) + { + if (BSP_QSPI_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + if (ret == BSP_ERROR_NONE) + { + /* Set default QSPI_Ctx values */ + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_NONE; + QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE; + QSPI_Ctx[Instance].TransferRate = BSP_QSPI_STR_TRANSFER; + QSPI_Ctx[Instance].DualFlashMode = 0; + +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) + QSPI_MspDeInit(&hqspi); +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) */ + + /* Call the DeInit function to reset the driver */ + if (HAL_QSPI_DeInit(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Initializes the QSPI interface. + * @param hQspi QSPI handle + * @param Config QSPI configuration structure + * @retval BSP status + */ +__weak HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef * hQspi, MX_QSPI_Init_t * Config) +{ + /* QSPI initialization */ + /* QSPI freq = SYSCLK /(1 + ClockPrescaler) Mhz */ + hQspi->Instance = QUADSPI; + hQspi->Init.ClockPrescaler = Config->ClockPrescaler; + hQspi->Init.FifoThreshold = 1; + hQspi->Init.SampleShifting = Config->SampleShifting; + hQspi->Init.FlashSize = Config->FlashSize; + hQspi->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_8_CYCLE; + hQspi->Init.ClockMode = QSPI_CLOCK_MODE_0; + + return HAL_QSPI_Init(hQspi); +} + +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +/** + * @brief Default BSP QSPI Msp Callbacks + * @param Instance QSPI Instance + * @retval BSP status + */ +int32_t BSP_QSPI_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, QSPI_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, QSPI_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsMspCallbacksValid = 1U; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP QSPI Msp Callback registering + * @param Instance QSPI Instance + * @param CallBacks pointer to MspInit/MspDeInit callbacks functions + * @retval BSP status + */ +int32_t BSP_QSPI_RegisterMspCallbacks(uint32_t Instance, BSP_QSPI_Cb_t * CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsMspCallbacksValid = 1U; + } + } + + /* Return BSP status */ + return ret; +} +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Reads an amount of data from the QSPI memory. + * @param Instance QSPI instance + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval BSP status + */ +int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t * pData, uint32_t ReadAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER) + { + if (S25FL128S_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, pData, ReadAddr, Size) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes an amount of data to the QSPI memory. + * @param Instance QSPI instance + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @retval BSP status + */ +int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t * pData, uint32_t WriteAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t end_addr, current_size, current_addr; + uint8_t * write_data; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Calculation of the size between the write address and the end of the page */ + current_size = S25FL128S_PAGE_SIZE - (WriteAddr % S25FL128S_PAGE_SIZE); + + /* Check if the size of the data is less than the remaining place in the page */ + if (current_size > Size) + { + current_size = Size; + } + + /* Initialize the address variables */ + current_addr = WriteAddr; + end_addr = WriteAddr + Size; + write_data = pData; + + /* Perform the write page by page */ + do + { + /* Check if Flash busy ? */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Enable write operations */ + else if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Issue page program command */ + else if (S25FL128S_PageProgram(&hqspi, QSPI_Ctx[Instance].InterfaceMode, write_data, current_addr, current_size) != + S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Configure automatic polling mode to wait for end of program */ + else if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update the address and size variables for next page programming */ + current_addr += current_size; + write_data += current_size; + current_size = ((current_addr + S25FL128S_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : S25FL128S_PAGE_SIZE; + } + } while ((current_addr < end_addr) && (ret == BSP_ERROR_NONE)); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the specified block of the QSPI memory. + * S25FL128S support 4K, 64K size block erase commands. + * @param Instance QSPI instance + * @param BlockAddress Block address to erase + * @param BlockSize Erase Block size + * @retval BSP status + */ +int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Enable write operations */ + else if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Issue Block Erase command */ + if (S25FL128S_BlockErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode, BlockAddress, BlockSize) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the entire QSPI memory. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_EraseChip(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Enable write operations */ + else if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Issue Chip erase command */ + if (S25FL128S_ChipErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads current status of the QSPI memory. + * If WIP != 0 then return busy. + * @param Instance QSPI instance + * @retval QSPI memory status: whether busy or not + */ +int32_t BSP_QSPI_GetStatus(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t reg; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (S25FL128S_ReadStatusRegister(&hqspi, QSPI_Ctx[Instance].InterfaceMode, ®) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Check the value of the register */ + if ((reg & S25FL128S_SR1_WIP) != 0U) + { + ret = BSP_ERROR_BUSY; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Return the configuration of the QSPI memory. + * @param Instance QSPI instance + * @param pInfo pointer on the configuration structure + * @retval BSP status + */ +int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t * pInfo) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + (void) S25FL128S_GetFlashInfo(pInfo); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Configure the QSPI in memory-mapped mode + * Only 1 Instance can running MMP mode. And it will lock system at this mode. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER) + { + if (S25FL128S_EnableMemoryMappedModeSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP; + } + } + else + { + /* Update QSPI context if all operations are well done */ + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Exit form memory-mapped mode + * Only 1 Instance can run MMP mode. And it will lock system at this mode. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance) +{ + uint8_t Dummy; + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].IsInitialized != QSPI_ACCESS_MMP) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } /* Abort MMP back to indirect mode */ + else if (HAL_QSPI_Abort(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Force QSPI interface Sampling Shift to half cycle */ + hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + + if (HAL_QSPI_Init(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Dummy read for exit from Performance Enhance mode */ + else if (S25FL128S_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, &Dummy, 0, 1) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; + } + } + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Get flash ID, 3 Bytes + * Manufacturer ID, Memory type, Memory density + * @param Instance QSPI instance + * @param Id QSPI Identifier + * @retval BSP status + */ +int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t * Id) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (S25FL128S_ReadID(&hqspi, QSPI_Ctx[Instance].InterfaceMode, Id) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @} + */ + +/** @defgroup STM32WB5MM_DK_QSPI_Private_Functions Private Functions + * @{ + */ + +/** + * @brief QSPI MSP Initialization + * @param hQspi : QSPI handle + * This function configures the hardware resources used in this example: + * - Peripheral's clock enable + * - Peripheral's GPIO Configuration + * - NVIC configuration for QSPI interrupt + * @retval None + */ +static void QSPI_MspInit(QSPI_HandleTypeDef * hQspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hQspi); + GPIO_InitTypeDef gpio_init_structure; + + /*##-1- Enable peripherals and GPIO Clocks #################################*/ + /* Enable the QuadSPI memory interface clock */ + QSPI_CLK_ENABLE(); + /* Reset the QuadSPI memory interface */ + QSPI_FORCE_RESET(); + QSPI_RELEASE_RESET(); + /* Enable GPIO clocks */ + QSPI_CS_GPIO_CLK_ENABLE(); + QSPI_CLK_GPIO_CLK_ENABLE(); + QSPI_D0_GPIO_CLK_ENABLE(); + QSPI_D1_GPIO_CLK_ENABLE(); + QSPI_D2_GPIO_CLK_ENABLE(); + QSPI_D3_GPIO_CLK_ENABLE(); + + /*##-2- Configure peripheral GPIO ##########################################*/ + /* QSPI CS GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure); + + /* QSPI CLK GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CLK_PIN; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure); + + /* QSPI D0 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D0_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure); + + /* QSPI D1 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D1_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure); + + /* QSPI D2 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D2_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure); + + /* QSPI D3 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D3_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure); + + /*##-3- Configure the NVIC for QSPI #########################################*/ + /* NVIC configuration for QSPI interrupt */ + HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0); + HAL_NVIC_EnableIRQ(QUADSPI_IRQn); +} + +/** + * @brief QSPI MSP De-Initialization + * @param hQspi QSPI handle + * This function frees the hardware resources used in this example: + * - Disable the Peripheral's clock + * - Revert GPIO and NVIC configuration to their default state + * @retval None + */ +static void QSPI_MspDeInit(QSPI_HandleTypeDef * hQspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hQspi); + + /*##-2- Disable peripherals and GPIO Clocks ################################*/ + /* De-Configure QSPI pins */ + /* De-Configure QSPI pins */ + HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN); + HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN); + HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN); + HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN); + HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN); + HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN); + + /*##-3- Reset peripherals ##################################################*/ + /* Reset the QuadSPI memory interface */ + QSPI_FORCE_RESET(); + QSPI_RELEASE_RESET(); + + /* Disable the QuadSPI memory interface clock */ + QSPI_CLK_DISABLE(); +} + +/** + * @brief This function reset the QSPI Flash memory. + * For SPI reset to avoid system come from unknown status. + * Flash accept 1-1-1, 1-1-2, 1-2-2 commands after reset. + * @param Instance QSPI instance + * @retval BSP status + */ +static int32_t QSPI_ResetMemory(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Wait Flash ready */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Send RESET ENABLE command in SPI mode (1-1-1) */ + else if (S25FL128S_ResetEnable(&hqspi, BSP_QSPI_SPI_MODE) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Send RESET memory command in SPI mode (1-1-1) */ + else if (S25FL128S_ResetMemory(&hqspi, BSP_QSPI_SPI_MODE) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; /* After reset S/W setting to indirect access */ + QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE; /* After reset H/W back to SPI mode by default */ + QSPI_Ctx[Instance].TransferRate = BSP_QSPI_STR_TRANSFER; /* After reset S/W setting to STR mode */ + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function configures the dummy cycles on memory side. + * Dummy cycle bit locate in Configuration Register[7:6] + * @param Instance QSPI instance + * @retval BSP status + */ +static int32_t QSPI_DummyCyclesCfg(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + QSPI_CommandTypeDef s_command; + uint8_t reg[2]; + + /* Initialize the read configuration register command */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.Instruction = S25FL128S_READ_CONFIGURATION_REG1_CMD; + s_command.AddressMode = QSPI_ADDRESS_NONE; + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = QSPI_DATA_1_LINE; + s_command.DummyCycles = 0; + s_command.NbData = 1; + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&hqspi, ®[1], HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Initialize the read status register1 command */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.Instruction = S25FL128S_READ_STATUS_REG1_CMD; + s_command.AddressMode = QSPI_ADDRESS_NONE; + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = QSPI_DATA_1_LINE; + s_command.DummyCycles = 0; + s_command.NbData = 1; + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&hqspi, ®[0], HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Enable write operations */ + if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Update configuration register (with new Latency Code) */ + s_command.Instruction = S25FL128S_WRITE_STATUS_CMD_REG_CMD; + s_command.NbData = 2; + MODIFY_REG(reg[1], S25FL128S_CR1_LC_MASK, S25FL128S_CR1_LC1); + + /* Configure the write volatile configuration register command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Transmission of the data Status Register 1 */ + if (HAL_QSPI_Transmit(&hqspi, reg, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c index b5fa5b234e778f..1ff1746dcd5ef1 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c @@ -29,16 +29,7 @@ extern DMA_HandleTypeDef hdma_usart1_tx; /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ -void Error_Handler(void) -{ - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - while (1) - { - HAL_Delay(100); - } - /* USER CODE END Error_Handler_Debug */ -} + /* USER CODE END TD */ /* Private define ------------------------------------------------------------*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c index aa13c0fb6ada54..bf28e5b4c3dff8 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c @@ -74,14 +74,6 @@ void MemManage_Handler(void) /* USER CODE END W1_MemoryManagement_IRQn 0 */ } } -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -/*void SVC_Handler(void) -{ -}*/ /** * @brief This function handles Debug Monitor exception. @@ -90,25 +82,6 @@ void MemManage_Handler(void) */ void DebugMon_Handler(void) {} -/** - * @brief This function handles PendSVC exception. - * @param None - * @retval None - */ -/*void PendSV_Handler(void) -{ -}*/ - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -/*void SysTick_Handler(void) -{ - HAL_IncTick(); -}*/ - void IPCC_C1_TX_IRQHandler(void) { HW_IPCC_Tx_Handler(); @@ -142,7 +115,6 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) * @param None * @retval None */ - void EXTI15_10_IRQHandler(void) { BSP_PB_IRQHandler(BUTTON_USER1); diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_ext_flash.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_ext_flash.c new file mode 100644 index 00000000000000..feb8e92041175e --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_ext_flash.c @@ -0,0 +1,257 @@ +/** + ****************************************************************************** + * @file stm_ota.c + * @author MCD Application Team + * @brief Write new image in external flash + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm_ext_flash.h" +#include "cmsis_os.h" +#include "stm32wb5mm_dk_qspi.h" + +/* Private defines -----------------------------------------------------------*/ +#define ERASE_BLOC_SIZE 0x10000U /*!< 64 Kbytes */ + +/* Private macros ------------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +osSemaphoreId_t SemExtFlashId; + +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static STM_OTA_StatusTypeDef check_addr(uint32_t Address, uint32_t Length); +static void QSPI_Pin_LP(void); +static void QSPI_Pin_WakeUP(void); +/* Public functions ----------------------------------------------------------*/ + +STM_OTA_StatusTypeDef STM_EXT_FLASH_Init(void) +{ + BSP_QSPI_Init_t init; + + SemExtFlashId = osSemaphoreNew(1, 1, NULL); /*< Create the semaphore and make it available at initialization */ + + init.TransferRate = BSP_QSPI_STR_TRANSFER; + init.DualFlashMode = BSP_QSPI_DUALFLASH_DISABLE; + init.InterfaceMode = S25FL128S_QPI_MODE; + if (BSP_QSPI_Init(0, &init) != BSP_ERROR_NONE) + { + return STM_EXT_FLASH_INIT_FAILED; + } + else + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + return STM_EXT_FLASH_OK; + } +} + +STM_OTA_StatusTypeDef STM_EXT_FLASH_Delete_Image(uint32_t Address, uint32_t Length) +{ + uint32_t loop_flash; + + // check if the address is in the external flash and if the length is < flash size + if (check_addr(Address, Length) != STM_EXT_FLASH_OK) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + + /* Do nothing if Length equal to 0 */ + if (Length == 0U) + { + return STM_EXT_FLASH_OK; + } + + /* flash address to erase is the offset from begin of external flash */ + Address -= EXTERNAL_FLASH_ADDRESS; + + osSemaphoreAcquire(SemExtFlashId, osWaitForever); +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_WakeUP(); +#endif + /* Loop on 64KBytes block */ + for (loop_flash = 0U; loop_flash < (((Length - 1U) / ERASE_BLOC_SIZE) + 1U); loop_flash++) + { + if (BSP_QSPI_EraseBlock(0, Address, BSP_QSPI_ERASE_64K) != BSP_ERROR_NONE) + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_DELETE_FAILED; + } + + /* next 64KBytes block */ + Address += ERASE_BLOC_SIZE; + } +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_OK; +} + +STM_OTA_StatusTypeDef STM_EXT_FLASH_WriteChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length) +{ + int32_t error = 0; + if (pSrcBuffer == NULL) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + // check if the address is in the external flash and if the length is < flash size + if (check_addr(DestAddress, Length) != STM_EXT_FLASH_OK) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + /* Do nothing if Length equal to 0 */ + if (Length == 0U) + { + return STM_EXT_FLASH_OK; + } + osSemaphoreAcquire(SemExtFlashId, osWaitForever); +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_WakeUP(); +#endif + error = BSP_QSPI_Write(0, pSrcBuffer, DestAddress - EXTERNAL_FLASH_ADDRESS, Length); + if (error != BSP_ERROR_NONE) + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_WRITE_FAILED; + } + else + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_OK; + } +} + +STM_OTA_StatusTypeDef STM_EXT_FLASH_ReadChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length) +{ + int32_t error = 0; + if (pSrcBuffer == NULL) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + // check if the address is in the external flash and if the length is < flash size + if (check_addr(DestAddress, Length) != STM_EXT_FLASH_OK) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + + /* Do nothing if Length equal to 0 */ + if (Length == 0U) + { + return STM_EXT_FLASH_OK; + } + osSemaphoreAcquire(SemExtFlashId, osWaitForever); +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_WakeUP(); +#endif + error = BSP_QSPI_Read(0, pSrcBuffer, DestAddress - EXTERNAL_FLASH_ADDRESS, Length); + if (error != BSP_ERROR_NONE) + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_READ_FAILED; + } + else + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_OK; + } +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static STM_OTA_StatusTypeDef check_addr(uint32_t Address, uint32_t Length) +{ + // check if the address is in the external flash and if the length is < flash size + if ((Address < EXTERNAL_FLASH_ADDRESS) || (S25FL128S_FLASH_SIZE < Length) || + (Address + Length > EXTERNAL_FLASH_ADDRESS + S25FL128S_FLASH_SIZE)) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + else + { + return STM_EXT_FLASH_OK; + } +} + +static void QSPI_Pin_WakeUP(void) +{ + + GPIO_InitTypeDef gpio_init_structure; + + /*##-1- Configure peripheral GPIO ##########################################*/ + /* QSPI CS GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure); + + /* QSPI CLK GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CLK_PIN; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure); + + /* QSPI D0 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D0_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure); + + /* QSPI D1 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D1_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure); + + /* QSPI D2 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D2_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure); + + /* QSPI D3 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D3_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure); +} + +static void QSPI_Pin_LP(void) +{ + /*##-1- Disable peripherals ################################*/ + /* De-Configure QSPI pins */ + HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN); + HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN); + HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN); + HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN); + HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN); + HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN); +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c index 910a401c70eef5..bfe1ed754c2c82 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c @@ -1,4 +1,3 @@ - /** ****************************************************************************** * @file stm_logging.c diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c index 7231d53efafcb2..319074d8d26eac 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c @@ -35,7 +35,7 @@ register char * stack_ptr asm("sp"); _sbrk Increase program data space. Malloc and related functions depend on this **/ -caddr_t _sbrk(int incr) +void * _sbrk(int incr) { extern char end asm("end"); static char * heap_end; @@ -48,10 +48,10 @@ caddr_t _sbrk(int incr) if (heap_end + incr > stack_ptr) { errno = ENOMEM; - return (caddr_t) -1; + return (void *) -1; } heap_end += incr; - return (caddr_t) prev_heap_end; + return (void *) prev_heap_end; } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c index 533cc4f0aa9671..86bc4defd7edc4 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c @@ -124,7 +124,55 @@ /** * @} */ - +#if (OTA_SUPPORT == 1) +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2 + CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept + at address 0x00 which correspond to automatic remap of boot address selected */ +#define USER_VECT_TAB_ADDRESS +#if defined(USER_VECT_TAB_ADDRESS) +#ifdef CORE_CM0PLUS +/*!< Uncomment this line for user vector table remap in Sram else user remap + will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS \ + SRAM2_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x100. */ +#define VECT_TAB_OFFSET \ + 0x00008000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x100. */ +#else +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x100. */ +#define VECT_TAB_OFFSET \ + 0x00020000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x100. */ +#endif +#else +/*!< Uncomment this line for user vector table remap in Sram else user remap + will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS \ + SRAM1_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#endif +#endif +#endif +#endif /** @addtogroup STM32WBxx_System_Private_Macros * @{ */ @@ -137,12 +185,12 @@ * @{ */ /* The SystemCoreClock variable is updated in three ways: - 1) by calling CMSIS function SystemCoreClockUpdate() - 2) by calling HAL API function HAL_RCC_GetHCLKFreq() - 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency - Note: If you use this function to configure the system clock; then there - is no need to call the 2 first functions listed above, since SystemCoreClock - variable is updated automatically. + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. */ uint32_t SystemCoreClock = 4000000UL; /*CPU1: M4 on MSI clock after startup (4MHz)*/ @@ -177,6 +225,18 @@ const uint32_t SmpsPrescalerTable[4UL][6UL] = { { 1UL, 3UL, 2UL, 2UL, 1UL, 2UL } /** @addtogroup STM32WBxx_System_Private_Functions * @{ */ +#if (OTA_SUPPORT == 1) +#if defined(__ICCARM__) +extern uint32_t __vector_table; +#define INTVECT_START ((uint32_t) &__vector_table) +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +extern void * __Vectors; +#define INTVECT_START ((uint32_t) &__Vectors) +#elif defined(__GNUC__) +extern void * g_pfnVectors; +#define INTVECT_START ((uint32_t) &g_pfnVectors) +#endif +#endif /** * @brief Setup the microcontroller system. @@ -187,10 +247,46 @@ void SystemInit(void) { OTP_ID0_t * p_otp; +#if (OTA_SUPPORT == 1) +#if defined(USER_VECT_TAB_ADDRESS) + /* Configure the Vector Table location add offset address ------------------*/ + /* Reuse information from map file */ + SCB->VTOR = INTVECT_START; /* Vector Table Relocation in Internal FLASH */ +#endif +#endif /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */ #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00070000U; + + /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */ + RCC->CR &= (uint32_t) 0xFAF6FEFBU; + + /*!< Reset LSI1 and LSI2 bits */ + RCC->CSR &= (uint32_t) 0xFFFFFFFAU; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t) 0xFFFFFFFEU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x22041000U; + +#if defined(STM32WB55xx) || defined(STM32WB5Mxx) + /* Reset PLLSAI1CFGR register */ + RCC->PLLSAI1CFGR = 0x22041000U; +#endif + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000; /** * Read HSE_Tuning from OTP @@ -296,7 +392,7 @@ void SystemCoreClockUpdate(void) case 0x0C: /* PLL used as system clock source */ /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN - SYSCLK = PLL_VCO / PLLR + SYSCLK = PLL_VCO / PLLR */ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL; diff --git a/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h b/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h index aeb0ac1b8913da..e1ff4e30648486 100644 --- a/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h +++ b/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h @@ -76,7 +76,7 @@ extern uint32_t SystemCoreClock; #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_TICKLESS_IDLE 0 +#define configUSE_TICKLESS_IDLE 2 /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ /* Defaults to size_t for backward compatibility, but can be changed if lengths will always be less than the number of bytes in a size_t. */ @@ -172,19 +172,20 @@ standard names. */ /* USER CODE BEGIN Defines */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ // #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 /* required only for Keil but does not hurt otherwise */ -#define configGENERATE_RUN_TIME_STATS 1 +/*#define configGENERATE_RUN_TIME_STATS 1 -#if (configGENERATE_RUN_TIME_STATS == 1) +#if( configGENERATE_RUN_TIME_STATS == 1 ) -extern void RTOS_AppConfigureTimerForRuntimeStats(); + extern void RTOS_AppConfigureTimerForRuntimeStats(); -extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); + extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() -#define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() + #define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() #endif +*/ /* USER CODE END Defines */ diff --git a/examples/platform/stm32/config_files/STM32WB5/matter_config.h b/examples/platform/stm32/config_files/STM32WB5/matter_config.h index e89e44b64fda3b..987b9273e3af5d 100644 --- a/examples/platform/stm32/config_files/STM32WB5/matter_config.h +++ b/examples/platform/stm32/config_files/STM32WB5/matter_config.h @@ -1,19 +1,29 @@ -/** - ****************************************************************************** - * @file matter_config.h - * @author MCD Application Team - * @brief config file for mbedtls - ****************************************************************************** - * @attention - * - * Copyright (c) 2019-2021 STMicroelectronics. - * All rights reserved. +/* + * Copyright (c) 2020, The OpenThread Authors. + * All rights reserved. * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - ****************************************************************************** + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #pragma once @@ -67,10 +77,7 @@ extern "C" { #define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED #define MBEDTLS_MD_C - #define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - #define MBEDTLS_OID_C #define MBEDTLS_PEM_PARSE_C #define MBEDTLS_PEM_WRITE_C @@ -114,9 +121,9 @@ extern "C" { #define MBEDTLS_ENTROPY_MAX_SOURCES 2 /**< Maximum number of sources supported */ #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE -#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maximum fragment length in bytes */ #else -#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maximum fragment length in bytes */ #endif #define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 @@ -134,6 +141,7 @@ extern "C" { #include "mbedtls/check_config.h" #include "mbedtls/config_psa.h" +int mbedtls_ssl_safer_memcmp(const void * a, const void * b, size_t n); #ifdef __cplusplus } #endif diff --git a/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld b/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld index 56292a5b88ac1b..81e0246bd94d76 100644 --- a/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld +++ b/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld @@ -1,198 +1,198 @@ -/* -****************************************************************************** -** -** File : LinkerScript.ld -** -** Author : STM32CubeIDE -** -** Abstract : Linker script for STM32WB5MMG Device -** 1024Kbytes FLASH -** 256Kbytes RAM -** -** Set heap size, stack size and stack location according -** to application requirements. -** -** Set memory bank area and size if external memory is used. -** -** Target : STMicroelectronics STM32 -** -** Distribution: The file is distributed as is without any warranty -** of any kind. -** -***************************************************************************** -** @attention -** -** Copyright (c) 2020 STMicroelectronics. -** All rights reserved. -** -** This software is licensed under terms that can be found in the LICENSE file -** in the root directory of this software component. -** If no LICENSE file comes with this software, it is provided AS-IS. -** -***************************************************************************** -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = 0x20026EC4; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x400 ; /* required amount of heap */ -_Min_Stack_Size = 0x1000 ; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ -FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 520K -NVM_MATTER : ORIGIN = 0x08082000, LENGTH = 0x3000 -RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x26EC4 -RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K -} - -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into FLASH */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - -_nvm_matter_init_base = LOADADDR(.nvm_matter); -_nvm_matter_init_length = SIZEOF(.nvm_matter); - - .nvm_matter : - { - . = ALIGN(4); - _nvm_matter_start = .; /* create a global symbol at nvm_matter start */ - *(.nvm_matter) /* .nvm_matter sections */ - *(.nvm_matter*) /* .nvm_matter* sections */ - . = ALIGN(4); - _nvm_matter_end = .; /* define a global symbols at end of nvm_matter */ - - } >NVM_MATTER - - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - *(.RamFunc) /* .RamFunc sections */ - *(.RamFunc*) /* .RamFunc* sections */ - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM1 AT> FLASH - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss section */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM1 - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM1 - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } - MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED - MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED - MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED - - - - - - -} - - - - +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32WB5MMG Device +** 1024Kbytes FLASH +** 256Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2020 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20026EC4; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x400 ; /* required amount of heap */ +_Min_Stack_Size = 0x1000 ; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 520K +NVM_MATTER : ORIGIN = 0x08082000, LENGTH = 0x3000 +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x26EC4 +RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + +_nvm_matter_init_base = LOADADDR(.nvm_matter); +_nvm_matter_init_length = SIZEOF(.nvm_matter); + + .nvm_matter : + { + . = ALIGN(4); + _nvm_matter_start = .; /* create a global symbol at nvm_matter start */ + *(.nvm_matter) /* .nvm_matter sections */ + *(.nvm_matter*) /* .nvm_matter* sections */ + . = ALIGN(4); + _nvm_matter_end = .; /* define a global symbols at end of nvm_matter */ + + } >NVM_MATTER + + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM1 AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM1 + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM1 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } + MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED + + + + + + +} + + + + diff --git a/examples/platform/tizen/TizenServiceAppMain.cpp b/examples/platform/tizen/TizenServiceAppMain.cpp index 778c36960c608b..aed9734ce1aa2f 100644 --- a/examples/platform/tizen/TizenServiceAppMain.cpp +++ b/examples/platform/tizen/TizenServiceAppMain.cpp @@ -18,7 +18,9 @@ #include "TizenServiceAppMain.h" +#include #include +#include #include #include @@ -29,13 +31,13 @@ namespace { bool service_app_create(void * data) { auto app = reinterpret_cast(data); - return app->AppCreated(); + return app->AppCreate(); } void service_app_terminate(void * data) { auto app = reinterpret_cast(data); - app->AppTerminated(); + app->AppTerminate(); } void service_app_control(app_control_h app_control, void * data) @@ -68,15 +70,17 @@ void TizenServiceAppMain::Exit() service_app_exit(); } -bool TizenServiceAppMain::AppCreated() +bool TizenServiceAppMain::AppCreate() { - ChipLogProgress(NotSpecified, "Tizen app created"); + ChipLogProgress(NotSpecified, "Tizen app create"); return true; } -void TizenServiceAppMain::AppTerminated() +void TizenServiceAppMain::AppTerminate() { - ChipLogProgress(NotSpecified, "Tizen app terminated"); + ChipLogProgress(NotSpecified, "Tizen app terminate"); + chip::Server::GetInstance().GenerateShutDownEvent(); + chip::DeviceLayer::PlatformMgr().StopEventLoopTask(); } static void TizenMainLoopWrapper() diff --git a/examples/platform/tizen/TizenServiceAppMain.h b/examples/platform/tizen/TizenServiceAppMain.h index 20f889e94a8b63..316a6b6a1f7a36 100644 --- a/examples/platform/tizen/TizenServiceAppMain.h +++ b/examples/platform/tizen/TizenServiceAppMain.h @@ -35,8 +35,8 @@ class TizenServiceAppMain app_error_e RunMainLoop(); void Exit(); - virtual bool AppCreated(); - virtual void AppTerminated(); + virtual bool AppCreate(); + virtual void AppTerminate(); virtual void AppControl(app_control_h app_control); private: diff --git a/examples/shell/qpg/BUILD.gn b/examples/shell/qpg/BUILD.gn index d325be35e1dd2c..ec477e194bbf12 100644 --- a/examples/shell/qpg/BUILD.gn +++ b/examples/shell/qpg/BUILD.gn @@ -66,7 +66,7 @@ qpg_executable("shell_app") { defines = [] - ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld" + ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld" inputs = [ ldscript ] diff --git a/examples/shell/qpg/args.gni b/examples/shell/qpg/args.gni index cc3d97a0432e43..478e91d9cb05a6 100644 --- a/examples/shell/qpg/args.gni +++ b/examples/shell/qpg/args.gni @@ -29,7 +29,6 @@ chip_stack_lock_tracking = "none" matter_device_vid = "0xFFF1" matter_device_pid = "0x8006" -matter_device_software_version = "0x0001" -matter_device_software_version_string = "1.0" +matter_ota_test_image = false chip_openthread_ftd = false diff --git a/examples/thermostat/infineon/cyw30739/README.md b/examples/thermostat/infineon/cyw30739/README.md index 44052add4d0ed4..6d37d24eb920ef 100644 --- a/examples/thermostat/infineon/cyw30739/README.md +++ b/examples/thermostat/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode diff --git a/examples/thermostat/qpg/BUILD.gn b/examples/thermostat/qpg/BUILD.gn index 9989e349fc6c86..11a0317a6abc0f 100644 --- a/examples/thermostat/qpg/BUILD.gn +++ b/examples/thermostat/qpg/BUILD.gn @@ -136,7 +136,7 @@ qpg_executable("thermostat") { } } - ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld" + ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld" inputs = [ ldscript ] diff --git a/examples/thermostat/qpg/args.gni b/examples/thermostat/qpg/args.gni index d5dcdfe217c635..693375e4388593 100644 --- a/examples/thermostat/qpg/args.gni +++ b/examples/thermostat/qpg/args.gni @@ -29,7 +29,7 @@ chip_enable_icd_server = true chip_stack_lock_tracking = "none" matter_device_vid = "0xFFF1" -matter_device_pid = "0x8006" +matter_device_pid = "0x8003" pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" pw_assert_BACKEND = "$dir_pw_assert_log:check_backend" diff --git a/examples/thermostat/qpg/include/CHIPProjectConfig.h b/examples/thermostat/qpg/include/CHIPProjectConfig.h index afab6cdbd8ee89..5a134c1b0addd8 100644 --- a/examples/thermostat/qpg/include/CHIPProjectConfig.h +++ b/examples/thermostat/qpg/include/CHIPProjectConfig.h @@ -40,9 +40,18 @@ * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION * * A uint32_t identifying the software version running on the device. + * First two bytes are reflecting the Matter standard + * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major + * version and the second nibble of the first byte has the minor number. The last byte holds the patch number. + * example for SDK v0.1.5 with Matter v1.2 standard: + * 0x01020105 */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003 // Can't be removed, needed for OTA file generation. +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105 +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106 +#endif #endif /** @@ -53,7 +62,11 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" // Can't be removed, needed for OTA file generation. +#ifndef OTA_TEST_IMAGE +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5" +#else +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6" +#endif #endif /** diff --git a/examples/thermostat/qpg/src/AppTask.cpp b/examples/thermostat/qpg/src/AppTask.cpp index 7297541df32d4e..5bd1e9cc29ad9a 100644 --- a/examples/thermostat/qpg/src/AppTask.cpp +++ b/examples/thermostat/qpg/src/AppTask.cpp @@ -460,11 +460,15 @@ void AppTask::UpdateLEDs(void) // If the system has ble connection(s) uptill the stage above, THEN blink // the LEDs at an even rate of 100ms. // - // Otherwise, blink the LED ON for a very short time. + // Otherwise, turn the LED OFF. if (sIsThreadProvisioned && sIsThreadEnabled) { qvIO_LedSet(SYSTEM_STATE_LED, true); } + else if (sIsThreadProvisioned && !sIsThreadEnabled) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); + } else if (sHaveBLEConnections) { qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); @@ -476,7 +480,7 @@ void AppTask::UpdateLEDs(void) else { // not commissioned yet - qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); + qvIO_LedSet(SYSTEM_STATE_LED, false); } } diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter index 26053604ec2daa..b47ca948e6c72f 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter @@ -2027,6 +2027,8 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute supportedThreadFeatures; + callback attribute threadVersion; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap index 2b61c6bdc90c24..a7f0c9cded77f6 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap @@ -1502,6 +1502,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index a4a8d09396ae53..199ec7761be0c8 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -197,7 +197,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, launchResponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, launchResponse); } break; } @@ -211,7 +211,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, navigateTargetResponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, navigateTargetResponse); } break; } @@ -225,7 +225,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, playbackResponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, playbackResponse); } break; } @@ -244,7 +244,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, getSetupPINresponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, getSetupPINresponse); } break; } diff --git a/examples/tv-app/android/java/MyUserPrompter-JNI.cpp b/examples/tv-app/android/java/MyUserPrompter-JNI.cpp index 6d586d99c1c67f..4eb0abe25645da 100644 --- a/examples/tv-app/android/java/MyUserPrompter-JNI.cpp +++ b/examples/tv-app/android/java/MyUserPrompter-JNI.cpp @@ -227,6 +227,15 @@ bool JNIMyUserPrompter::DisplaysPasscodeAndQRCode() return false; } +/** + * Called to prompt the user for consent to allow the app commissioneeName/vendorId/productId to be installed. + * For example "[commissioneeName] is requesting permission to install app to this TV, approve?" + */ +void JNIMyUserPrompter::PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) +{ + ChipLogError(Zcl, "JNIMyUserPrompter::PromptForAppInstallOKPermission Needs Implementation"); +} + /** * Called to display the given setup passcode to the user, * for commissioning the given commissioneeName with the given vendorId and productId, diff --git a/examples/tv-app/android/java/MyUserPrompter-JNI.h b/examples/tv-app/android/java/MyUserPrompter-JNI.h index 408346326a6fd6..3d2e7f14afb75e 100644 --- a/examples/tv-app/android/java/MyUserPrompter-JNI.h +++ b/examples/tv-app/android/java/MyUserPrompter-JNI.h @@ -29,6 +29,7 @@ class JNIMyUserPrompter : public UserPrompter void PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override; void PromptForCommissionPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName, uint16_t pairingHint, const char * pairingInstruction) override; + void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override; void HidePromptsOnCancel(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override; bool DisplaysPasscodeAndQRCode() override; void PromptWithCommissionerPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName, uint32_t passcode, diff --git a/examples/tv-app/linux/README.md b/examples/tv-app/linux/README.md index 5cd2bcfc48b5ed..2fc85a9a8f25c8 100644 --- a/examples/tv-app/linux/README.md +++ b/examples/tv-app/linux/README.md @@ -107,6 +107,11 @@ id): $ app add 9050 (vendor id 9050) $ app remove 1 +You can also install or uninstall the app by using commands: + + $ app install 65521 32768 + $ app uninstall 65521 32768 + As an app platform, local apps can be used to facilitate commissioning using their AccountLogin clusters. The dummy apps have hardcoded setup codes - on a real device, these apps would communicate with a cloud service to obtain the diff --git a/examples/tv-app/tv-common/include/AppTv.h b/examples/tv-app/tv-common/include/AppTv.h index bd056ae6813a5f..34f5bd8dc4c958 100644 --- a/examples/tv-app/tv-common/include/AppTv.h +++ b/examples/tv-app/tv-common/include/AppTv.h @@ -91,6 +91,11 @@ class DLL_EXPORT ContentAppImpl : public ContentApp KeypadInputDelegate * GetKeypadInputDelegate() override { return &mKeypadInputDelegate; }; MediaPlaybackDelegate * GetMediaPlaybackDelegate() override { return &mMediaPlaybackDelegate; }; TargetNavigatorDelegate * GetTargetNavigatorDelegate() override { return &mTargetNavigatorDelegate; }; + bool MatchesPidVid(uint16_t productId, uint16_t vendorId) + { + return vendorId == mApplicationBasicDelegate.HandleGetVendorId() && + productId == mApplicationBasicDelegate.HandleGetProductId(); + } protected: ApplicationBasicManager mApplicationBasicDelegate; @@ -138,15 +143,13 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory uint16_t productId) override; void AddAdminVendorId(uint16_t vendorId); + // Add the app to the list of mContentApps + void InstallContentApp(uint16_t vendorId, uint16_t productId); + // Remove the app from the list of mContentApps + bool UninstallContentApp(uint16_t vendorId, uint16_t productId); protected: - ContentAppImpl mContentApps[APP_LIBRARY_SIZE] = { - ContentAppImpl("Vendor1", 1, "exampleid", 11, "Version1", "34567890"), - ContentAppImpl("Vendor2", 65521, "exampleString", 32768, "Version2", "20202021"), - ContentAppImpl("Vendor3", 9050, "App3", 22, "Version3", "20202021"), - ContentAppImpl("TestSuiteVendor", 1111, "applicationId", 22, "v2", "20202021") - }; - + std::vector> mContentApps; std::vector mAdminVendorIds{}; }; diff --git a/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp b/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp index ee85cf099ff380..b39e84ad40f89a 100644 --- a/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp +++ b/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp @@ -243,6 +243,55 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv) return CHIP_NO_ERROR; } + else if (strcmp(argv[0], "install") == 0) + { + if (argc < 2) + { + return PrintAllCommands(); + } + char * eptr; + + uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10); + uint16_t pid = 0; + if (argc >= 3) + { + pid = (uint16_t) strtol(argv[2], &eptr, 10); + } + ContentAppFactoryImpl * factory = GetContentAppFactoryImpl(); + factory->InstallContentApp(vid, pid); + + ChipLogProgress(DeviceLayer, "installed an app"); + + return CHIP_NO_ERROR; + } + else if (strcmp(argv[0], "uninstall") == 0) + { + if (argc < 2) + { + return PrintAllCommands(); + } + char * eptr; + + uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10); + uint16_t pid = 0; + if (argc >= 3) + { + pid = (uint16_t) strtol(argv[2], &eptr, 10); + } + ContentAppFactoryImpl * factory = GetContentAppFactoryImpl(); + bool isAppUninstalled = factory->UninstallContentApp(vid, pid); + + if (isAppUninstalled) + { + ChipLogProgress(DeviceLayer, "uninstalled an app"); + } + else + { + ChipLogProgress(DeviceLayer, "app not found."); + } + + return CHIP_NO_ERROR; + } else if (strcmp(argv[0], "add") == 0) { if (argc < 2) diff --git a/examples/tv-app/tv-common/src/AppTv.cpp b/examples/tv-app/tv-common/src/AppTv.cpp index 2bed28e34d5fb8..9987b4cdd67d6e 100644 --- a/examples/tv-app/tv-common/src/AppTv.cpp +++ b/examples/tv-app/tv-common/src/AppTv.cpp @@ -98,6 +98,12 @@ class MyUserPrompter : public UserPrompter // tv should override this with a dialog prompt inline void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) override { return; } + + // tv should override this with a dialog prompt + inline void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override + { + return; + } }; MyUserPrompter gMyUserPrompter; @@ -146,6 +152,16 @@ class MyPasscodeService : public PasscodeService }; MyPasscodeService gMyPasscodeService; +class MyAppInstallationService : public AppInstallationService +{ + bool LookupTargetContentApp(uint16_t vendorId, uint16_t productId) override + { + return ContentAppPlatform::GetInstance().LoadContentAppByClient(vendorId, productId) != nullptr; + } +}; + +MyAppInstallationService gMyAppInstallationService; + class MyPostCommissioningListener : public PostCommissioningListener { void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr, @@ -527,19 +543,23 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend { ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: LoadContentAppByAppId catalogVendorId=%d applicationId=%s ", vendorApp.catalogVendorId, vendorApp.applicationId); + int index = 0; - for (size_t i = 0; i < ArraySize(mContentApps); ++i) + for (auto & contentApp : mContentApps) { - auto & app = mContentApps[i]; - ChipLogProgress(DeviceLayer, " Looking next=%s ", app.GetApplicationBasicDelegate()->GetCatalogVendorApp()->applicationId); - if (app.GetApplicationBasicDelegate()->GetCatalogVendorApp()->Matches(vendorApp)) + auto app = contentApp.get(); + + ChipLogProgress(DeviceLayer, " Looking next=%s ", app->GetApplicationBasicDelegate()->GetCatalogVendorApp()->applicationId); + if (app->GetApplicationBasicDelegate()->GetCatalogVendorApp()->Matches(vendorApp)) { - ContentAppPlatform::GetInstance().AddContentApp(&app, &contentAppEndpoint, Span(gDataVersions[i]), + ContentAppPlatform::GetInstance().AddContentApp(app, &contentAppEndpoint, Span(gDataVersions[index]), Span(gContentAppDeviceType)); - return &app; + return app; } + index++; } + ChipLogProgress(DeviceLayer, "LoadContentAppByAppId NOT FOUND catalogVendorId=%d applicationId=%s ", vendorApp.catalogVendorId, vendorApp.applicationId); @@ -551,6 +571,62 @@ void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId) mAdminVendorIds.push_back(vendorId); } +void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t productId) +{ + ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: InstallContentApp vendorId=%d productId=%d ", vendorId, productId); + if (vendorId == 1 && productId == 11) + { + mContentApps.emplace_back( + std::make_unique("Vendor1", vendorId, "exampleid", productId, "Version1", "34567890")); + } + else if (vendorId == 65521 && productId == 32768) + { + mContentApps.emplace_back( + std::make_unique("Vendor2", vendorId, "exampleString", productId, "Version2", "20202021")); + } + else if (vendorId == 9050 && productId == 22) + { + mContentApps.emplace_back(std::make_unique("Vendor3", vendorId, "App3", productId, "Version3", "20202021")); + } + else if (vendorId == 1111 && productId == 22) + { + mContentApps.emplace_back( + std::make_unique("TestSuiteVendor", vendorId, "applicationId", productId, "v2", "20202021")); + } + else + { + mContentApps.emplace_back( + std::make_unique("NewAppVendor", vendorId, "newAppApplicationId", productId, "v2", "20202021")); + } +} + +bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t productId) +{ + ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: UninstallContentApp vendorId=%d productId=%d ", vendorId, productId); + + int index = 0; + for (auto & contentApp : mContentApps) + { + + auto app = contentApp.get(); + + ChipLogProgress(DeviceLayer, "Looking next vid=%d pid=%d", app->GetApplicationBasicDelegate()->HandleGetVendorId(), + app->GetApplicationBasicDelegate()->HandleGetProductId()); + + if (app->MatchesPidVid(productId, vendorId)) + { + ChipLogProgress(DeviceLayer, "Found an app vid=%d pid=%d. Uninstalling it.", + app->GetApplicationBasicDelegate()->HandleGetVendorId(), + app->GetApplicationBasicDelegate()->HandleGetProductId()); + mContentApps.erase(mContentApps.begin() + index); + return true; + } + + index++; + } + return false; +} + Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId) { for (size_t i = 0; i < mAdminVendorIds.size(); ++i) @@ -607,6 +683,10 @@ CHIP_ERROR AppTvInit() #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED ContentAppPlatform::GetInstance().SetupAppPlatform(); ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory); + gFactory.InstallContentApp((uint16_t) 1, (uint16_t) 11); + gFactory.InstallContentApp((uint16_t) 65521, (uint16_t) 32768); + gFactory.InstallContentApp((uint16_t) 9050, (uint16_t) 22); + gFactory.InstallContentApp((uint16_t) 1111, (uint16_t) 22); uint16_t value; if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR) { @@ -623,6 +703,7 @@ CHIP_ERROR AppTvInit() if (cdc != nullptr) { cdc->SetPasscodeService(&gMyPasscodeService); + cdc->SetAppInstallationService(&gMyAppInstallationService); cdc->SetUserPrompter(&gMyUserPrompter); cdc->SetPostCommissioningListener(&gMyPostCommissioningListener); } diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/MatterCastingPlayer-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/MatterCastingPlayer-JNI.cpp index d0409c6a27945c..b2597c883406d8 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/MatterCastingPlayer-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/MatterCastingPlayer-JNI.cpp @@ -120,9 +120,8 @@ JNI_METHOD(jobject, verifyOrEstablishConnection) matter::casting::core::ConnectionCallbacks connectionCallbacks; connectionCallbacks.mOnConnectionComplete = connectCallback; - // TODO: Verify why commissioningWindowTimeoutSec is a "unsigned long long int" type. Seems too big. - castingPlayer->VerifyOrEstablishConnection(connectionCallbacks, - static_cast(commissioningWindowTimeoutSec), idOptions); + castingPlayer->VerifyOrEstablishConnection(connectionCallbacks, static_cast(commissioningWindowTimeoutSec), + idOptions); return support::convertMatterErrorFromCppToJava(CHIP_NO_ERROR); } diff --git a/examples/tv-casting-app/linux/simple-app-helper.cpp b/examples/tv-casting-app/linux/simple-app-helper.cpp index 49f006aa9cf4ab..beef624eea5ff8 100644 --- a/examples/tv-casting-app/linux/simple-app-helper.cpp +++ b/examples/tv-casting-app/linux/simple-app-helper.cpp @@ -33,6 +33,11 @@ // VendorId of the Endpoint on the CastingPlayer that the CastingApp desires to interact with after connection const uint16_t kDesiredEndpointVendorId = 65521; +// EndpointId of the Endpoint on the CastingPlayer that the CastingApp desires to interact with after connection using the +// Commissioner-Generated passcode commissioning flow +const uint8_t kDesiredEndpointId = 1; +// Indicates that the Commissioner-Generated passcode commissioning flow is in progress. +bool gCommissionerGeneratedPasscodeFlowRunning = false; DiscoveryDelegateImpl * DiscoveryDelegateImpl::_discoveryDelegateImpl = nullptr; bool gAwaitingCommissionerPasscodeInput = false; @@ -244,6 +249,16 @@ CHIP_ERROR InitCommissionableDataProvider(LinuxCommissionableDataProvider & prov options.payload.discriminator.GetLongValue()); } +void LogEndpointsDetails(const std::vector> & endpoints) +{ + ChipLogProgress(AppServer, "simple-app-helper.cpp::LogEndpointsDetails() Number of Endpoints: %d", + static_cast(endpoints.size())); + for (const auto & endpoint : endpoints) + { + endpoint->LogDetail(); + } +} + void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * castingPlayer) { ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler()"); @@ -256,16 +271,39 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca "simple-app-helper.cpp::ConnectionHandler(): Failed to connect to CastingPlayer (ID: %s) with err %" CHIP_ERROR_FORMAT, targetCastingPlayer->GetId(), err.Format())); - ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler(): Successfully connected to CastingPlayer (ID: %s)", - castingPlayer->GetId()); - ChipLogProgress(AppServer, - "simple-app-helper.cpp::ConnectionHandler(): Triggering demo interactions with CastingPlayer (ID: %s)", - castingPlayer->GetId()); + if (gCommissionerGeneratedPasscodeFlowRunning) + { + ChipLogProgress(AppServer, + "simple-app-helper.cpp::ConnectionHandler(): Successfully connected to CastingPlayer (ID: %s) using " + "Commissioner-Generated passcode", + castingPlayer->GetId()); + ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler(): Desired Endpoint ID for demo interactions: 1"); + } + else + { + ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler(): Successfully connected to CastingPlayer (ID: %s)", + castingPlayer->GetId()); + ChipLogProgress(AppServer, + "simple-app-helper.cpp::ConnectionHandler(): Desired Endpoint Vendor ID for demo interactions: %d", + kDesiredEndpointVendorId); + } + ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler(): Getting endpoints avaiable for demo interactions"); std::vector> endpoints = castingPlayer->GetEndpoints(); + LogEndpointsDetails(endpoints); + // Find the desired Endpoint and auto-trigger some Matter Casting demo interactions auto it = std::find_if(endpoints.begin(), endpoints.end(), [](const matter::casting::memory::Strong & endpoint) { + if (gCommissionerGeneratedPasscodeFlowRunning) + { + // For the example Commissioner-Generated passcode commissioning flow, run demo interactions with + // the Endpoint with ID 1. For this flow, we commissioned with the Target Content Application + // with Vendor ID 1111. Since this target content application does not report its Endpoint's + // Vendor IDs, we find the desired endpoint based on the Endpoint ID. See + // connectedhomeip/examples/tv-app/tv-common/include/AppTv.h. + return endpoint->GetId() == kDesiredEndpointId; + } return endpoint->GetVendorId() == kDesiredEndpointVendorId; }); if (it != endpoints.end()) @@ -273,6 +311,11 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca // The desired endpoint is endpoints[index] unsigned index = (unsigned int) std::distance(endpoints.begin(), it); + ChipLogProgress( + AppServer, + "simple-app-helper.cpp::ConnectionHandler(): Triggering demo interactions with CastingPlayer (ID: %s). Endpoint ID: %d", + castingPlayer->GetId(), endpoints[index]->GetId()); + // demonstrate invoking a command InvokeContentLauncherLaunchURL(endpoints[index]); @@ -286,8 +329,8 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca { ChipLogError( AppServer, - "simple-app-helper.cpp::ConnectionHandler():Desired Endpoint Vendor Id (%d) not found on the CastingPlayer (ID: %s)", - kDesiredEndpointVendorId, castingPlayer->GetId()); + "simple-app-helper.cpp::ConnectionHandler():Desired Endpoint Vendor ID not found on the CastingPlayer (ID: %s)", + castingPlayer->GetId()); } } @@ -350,9 +393,14 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) ChipLogError(AppServer, "Invalid casting player index provided: %lu", index)); targetCastingPlayer = castingPlayers.at(index); + gCommissionerGeneratedPasscodeFlowRunning = false; matter::casting::core::IdentificationDeclarationOptions idOptions; + chip::Protocols::UserDirectedCommissioning::TargetAppInfo targetAppInfo; + targetAppInfo.vendorId = kDesiredEndpointVendorId; + if (argc == 3) { + if (strcmp(argv[2], "commissioner-generated-passcode") == 0) { // Attempt Commissioner-Generated Passcode (commissioner-generated-passcode) commissioning flow only if the @@ -364,6 +412,14 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) "Commissioner-Generated Passcode commissioning flow", index); idOptions.mCommissionerPasscode = true; + + // For the example Commissioner-Generated passcode commissioning flow, override the default Target Content + // Application Vendor ID, which is configured on the tv-app. This Target Content Application Vendor ID (1111), + // does not implement the AccountLogin cluster, which would otherwise auto commission using the + // Commissionee-Generated passcode upon recieving the IdentificationDeclaration Message. See + // connectedhomeip/examples/tv-app/tv-common/include/AppTv.h. + targetAppInfo.vendorId = 1111; + gCommissionerGeneratedPasscodeFlowRunning = true; } else { @@ -374,9 +430,8 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) } } } - chip::Protocols::UserDirectedCommissioning::TargetAppInfo targetAppInfo; - targetAppInfo.vendorId = kDesiredEndpointVendorId; - CHIP_ERROR result = idOptions.addTargetAppInfo(targetAppInfo); + + CHIP_ERROR result = idOptions.addTargetAppInfo(targetAppInfo); if (result != CHIP_NO_ERROR) { ChipLogError(AppServer, "CommandHandler() request, failed to add targetAppInfo: %" CHIP_ERROR_FORMAT, result.Format()); @@ -430,11 +485,8 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) err.Format()); } - matter::casting::core::ConnectionCallbacks connectionCallbacks; - connectionCallbacks.mOnConnectionComplete = ConnectionHandler; - // Continue Connecting to the target CastingPlayer with the user entered Commissioner-generated Passcode. - targetCastingPlayer->ContinueConnecting(connectionCallbacks, matter::casting::core::kCommissioningWindowTimeoutSec); + targetCastingPlayer->ContinueConnecting(); } else { diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp b/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp index 1210af574603f4..dafa11f2381fed 100644 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp +++ b/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp @@ -82,6 +82,11 @@ void ModelCommand::Shutdown() mOnDeviceConnectionFailureCallback.Cancel(); } +void ModelCommand::ClearICDEntry(const chip::ScopedNodeId & nodeId) +{ + ChipLogError(chipTool, "ClearICDEntry is not implemented in tv-casting-app"); +} + bool ModelCommand::IsPeerLIT() { // Does not support tv-casting-app diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp index b3075be95304d8..ff204923da5d40 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp @@ -29,9 +29,7 @@ namespace core { CastingPlayer * CastingPlayer::mTargetCastingPlayer = nullptr; -// TODO: Verify why commissioningWindowTimeoutSec is a "unsigned long long int" type. Seems too big. -void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks, - unsigned long long int commissioningWindowTimeoutSec, +void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks, uint16_t commissioningWindowTimeoutSec, IdentificationDeclarationOptions idOptions) { ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() called"); @@ -72,6 +70,25 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa "CastingPlayer::VerifyOrEstablishConnection() CommissionerDeclarationCallback not provided in ConnectionCallbacks"); } + ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() verifying User Directed Commissioning (UDC) state"); + mIdOptions.LogDetail(); + if (!GetSupportsCommissionerGeneratedPasscode() && mIdOptions.mCommissionerPasscode) + { + ChipLogError(AppServer, + "CastingPlayer::VerifyOrEstablishConnection() the target CastingPlayer doesn't support Commissioner-Generated " + "passcode yet IdentificationDeclarationOptions.mCommissionerPasscode is set to true"); + SuccessOrExit(err = CHIP_ERROR_INVALID_ARGUMENT); + } + if (!matter::casting::core::CommissionerDeclarationHandler::GetInstance()->HasCommissionerDeclarationCallback() && + mIdOptions.mCommissionerPasscode) + { + ChipLogError( + AppServer, + "CastingPlayer::VerifyOrEstablishConnection() the CommissionerDeclarationHandler CommissionerDeclaration message " + "callback has not been set, yet IdentificationDeclarationOptions.mCommissionerPasscode is set to true"); + SuccessOrExit(err = CHIP_ERROR_INVALID_ARGUMENT); + } + // If *this* CastingPlayer was previously connected to, its nodeId, fabricIndex and other attributes should be present // in the CastingStore cache. If that is the case, AND, the cached data contains the endpoint desired by the client, if any, // as per IdentificationDeclarationOptions.mTargetAppInfos, simply Find or Re-establish the CASE session and return early. @@ -138,28 +155,11 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa } else { - ChipLogProgress(AppServer, - "CastingPlayer::VerifyOrEstablishConnection() verifying User Directed Commissioning (UDC) state"); - mIdOptions.LogDetail(); - SuccessOrExit(err = support::ChipDeviceEventHandler::SetUdcStatus(true)); - - if (!GetSupportsCommissionerGeneratedPasscode() && mIdOptions.mCommissionerPasscode) - { - ChipLogError( - AppServer, - "CastingPlayer::VerifyOrEstablishConnection() the target CastingPlayer doesn't support Commissioner-Generated " - "passcode yet IdentificationDeclarationOptions.mCommissionerPasscode is set to true"); - SuccessOrExit(err = CHIP_ERROR_INVALID_ARGUMENT); - } - if (!matter::casting::core::CommissionerDeclarationHandler::GetInstance()->HasCommissionerDeclarationCallback() && - mIdOptions.mCommissionerPasscode) - { - ChipLogError(AppServer, - "CastingPlayer::VerifyOrEstablishConnection() the CommissionerDeclaration message callback has not been " - "set yet IdentificationDeclarationOptions.mCommissionerPasscode is set to true"); - SuccessOrExit(err = CHIP_ERROR_INVALID_ARGUMENT); - } - + // We need to call OpenBasicCommissioningWindow() for both Commissionee-Generated passcode commissioning flow and + // Commissioner-Generated passcode commissioning flow. Per the Matter spec (UserDirectedCommissioning), even if the + // Commissionee sends an IdentificationDeclaration with CommissionerPasscode set to true, the Commissioner will first + // attempt to use AccountLogin in order to obtain Passcode using rotatingID. If no Passcode is obtained, Commissioner + // displays a Passcode. ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() calling OpenBasicCommissioningWindow()"); SuccessOrExit(err = chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow( chip::System::Clock::Seconds16(mCommissioningWindowTimeoutSec))); @@ -178,33 +178,19 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa } } -void CastingPlayer::ContinueConnecting(ConnectionCallbacks connectionCallbacks, - unsigned long long int commissioningWindowTimeoutSec) +void CastingPlayer::ContinueConnecting() { ChipLogProgress(AppServer, "CastingPlayer::ContinueConnecting()"); CHIP_ERROR err = CHIP_NO_ERROR; - SuccessOrExit(err = support::ChipDeviceEventHandler::SetUdcStatus(true)); - VerifyOrExit( - connectionCallbacks.mOnConnectionComplete != nullptr, - ChipLogError(AppServer, "CastingPlayer::ContinueConnecting() ConnectionCallbacks.mOnConnectionComplete was not provided")); - mConnectionState = CASTING_PLAYER_CONNECTING; - mOnCompleted = connectionCallbacks.mOnConnectionComplete; - mCommissioningWindowTimeoutSec = commissioningWindowTimeoutSec; - mTargetCastingPlayer = this; - - // Register the handler for Commissioner's CommissionerDeclaration messages. The CommissionerDeclaration messages provide - // information indicating the Commissioner's pre-commissioning state. - if (connectionCallbacks.mCommissionerDeclarationCallback != nullptr) - { - matter::casting::core::CommissionerDeclarationHandler::GetInstance()->SetCommissionerDeclarationCallback( - connectionCallbacks.mCommissionerDeclarationCallback); - } - else + // Verify that mOnCompleted is not nullptr. + VerifyOrExit(mOnCompleted != nullptr, ChipLogError(AppServer, "CastingPlayer::ContinueConnecting() mOnCompleted == nullptr")); + if (!matter::casting::core::CommissionerDeclarationHandler::GetInstance()->HasCommissionerDeclarationCallback()) { - ChipLogProgress( - AppServer, - "CastingPlayer::VerifyOrEstablishConnection() CommissionerDeclarationCallback not provided in ConnectionCallbacks"); + ChipLogProgress(AppServer, + "CastingPlayer::ContinueConnecting() CommissionerDeclaration message callback has not been set."); } + mConnectionState = CASTING_PLAYER_CONNECTING; + mTargetCastingPlayer = this; ChipLogProgress(AppServer, "CastingPlayer::ContinueConnecting() calling OpenBasicCommissioningWindow()"); SuccessOrExit(err = chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow( @@ -272,6 +258,8 @@ CHIP_ERROR CastingPlayer::SendUserDirectedCommissioningRequest() chip::Protocols::UserDirectedCommissioning::IdentificationDeclaration id = mIdOptions.buildIdentificationDeclarationMessage(); + ReturnErrorOnFailure(support::ChipDeviceEventHandler::SetUdcStatus(true)); + ReturnErrorOnFailure(chip::Server::GetInstance().SendUserDirectedCommissioningRequest( chip::Transport::PeerAddress::UDP(*ipAddressToUse, mAttributes.port, mAttributes.interfaceId), id)); @@ -401,6 +389,26 @@ void CastingPlayer::LogDetail() const } } +CastingPlayer::CastingPlayer(const CastingPlayer & other) : + std::enable_shared_from_this(other), mEndpoints(other.mEndpoints), mConnectionState(other.mConnectionState), + mAttributes(other.mAttributes), mIdOptions(other.mIdOptions), + mCommissioningWindowTimeoutSec(other.mCommissioningWindowTimeoutSec), mOnCompleted(other.mOnCompleted) +{} + +CastingPlayer & CastingPlayer::operator=(const CastingPlayer & other) +{ + if (this != &other) + { + mAttributes = other.mAttributes; + mEndpoints = other.mEndpoints; + mConnectionState = other.mConnectionState; + mIdOptions = other.mIdOptions; + mCommissioningWindowTimeoutSec = other.mCommissioningWindowTimeoutSec; + mOnCompleted = other.mOnCompleted; + } + return *this; +} + ConnectionContext::ConnectionContext(void * clientContext, core::CastingPlayer * targetCastingPlayer, chip::OnDeviceConnected onDeviceConnectedFn, chip::OnDeviceConnectionFailure onDeviceConnectionFailureFn) diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h index 14a55e045fcb83..d5bbcd46006920 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h @@ -38,8 +38,8 @@ namespace core { const int kPortMaxLength = 5; // port is uint16_t // +1 for the : between the hostname and the port. -const int kIdMaxLength = chip::Dnssd::kHostNameMaxLength + kPortMaxLength + 1; -const unsigned long long int kCommissioningWindowTimeoutSec = 3 * 60; // 3 minutes +const int kIdMaxLength = chip::Dnssd::kHostNameMaxLength + kPortMaxLength + 1; +const uint16_t kCommissioningWindowTimeoutSec = 3 * 60; // 3 minutes /** * @brief Describes an Endpoint that the client wants to connect to @@ -111,46 +111,81 @@ class CastingPlayer : public std::enable_shared_from_this return (compareResult == 0) ? 1 : 0; } + /** + * @brief Define the copy constructor + */ + CastingPlayer(const CastingPlayer & other); + + /** + * @brief Define the assignment operator + */ + CastingPlayer & operator=(const CastingPlayer & other); + /** * @return true if this CastingPlayer is connected to the CastingApp */ bool IsConnected() const { return mConnectionState == CASTING_PLAYER_CONNECTED; } /** - * @brief Verifies that a connection exists with this CastingPlayer, or triggers a new session - * request. If the CastingApp does not have the nodeId and fabricIndex of this CastingPlayer cached on disk, - * this will execute the User Directed Commissioning (UDC) process. + * @brief Verifies that a connection exists with this CastingPlayer, or triggers a new commissioning session request. If the + * CastingApp does not have the nodeId and fabricIndex of this CastingPlayer cached on disk, this will execute the User Directed + * Commissioning (UDC) process by sending an IdentificationDeclaration message to the Commissioner. For certain UDC features, + * where a Commissioner reply is expected, this API needs to be followed up with the ContinueConnecting() API defiend below. See + * the Matter UDC specification or parameter class definitions for details on features not included in the description below. + * + * @param connectionCallbacks contains the ConnectCallback (Required) and CommissionerDeclarationCallback (Optional) defiend in + * ConnectCallbacks.h. + * + * ConnectCallback: The callback called when the connection process has ended, regardless of whether it was successful or not. + * + * CommissionerDeclarationCallback: The callback called when the Commissionee receives a CommissionerDeclaration message from + * the Commissioner. This callback is needed to support UDC features where a reply from the Commissioner is expected. It + * provides information indicating the Commissioner’s pre-commissioning state. + * + * For example: During Commissioner-Generated passcode commissioning, the Commissioner replies with a CommissionerDeclaration + * message with PasscodeDialogDisplayed and CommissionerPasscode set to true. Given these Commissioner state details, the client + * is expected to perform some actions, detailed in the ContinueConnecting() API below, and then call the ContinueConnecting() + * API to complete the process. * - * @param connectionCallbacks contains the ConnectCallback and CommissionerDeclarationCallback (Optional). * @param commissioningWindowTimeoutSec (Optional) time (in sec) to keep the commissioning window open, if commissioning is * required. Needs to be >= kCommissioningWindowTimeoutSec. + * * @param idOptions (Optional) Parameters in the IdentificationDeclaration message sent by the Commissionee to the Commissioner. * These parameters specify the information relating to the requested commissioning session. + * + * For example: To invoke the Commissioner-Generated passcode commissioning flow, the client would call this API with + * IdentificationDeclarationOptions containing CommissionerPasscode set to true. See IdentificationDeclarationOptions.h for a + * complete list of optional parameters. + * * Furthermore, attributes (such as VendorId) describe the TargetApp that the client wants to interact with after commissioning. * If this value is passed in, VerifyOrEstablishConnection() will force UDC, in case the desired * TargetApp is not found in the on-device CastingStore. */ void VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks, - unsigned long long int commissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec, - IdentificationDeclarationOptions idOptions = IdentificationDeclarationOptions()); + uint16_t commissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec, + IdentificationDeclarationOptions idOptions = IdentificationDeclarationOptions()); /** - * @brief Continues the UDC process during the Commissioner-Generated passcode commissioning flow by sending a second - * IdentificationDeclaration to Commissioner containing CommissionerPasscode and CommissionerPasscodeReady set to true. At this - * point it is assumed that the following have occurred: - * 1. Client has handled the Commissioner's CommissionerDecelration message with PasscodeDialogDisplayed and - * CommissionerPasscode set to true. - * 2. Client prompted user to input Passcode from Commissioner. - * 3. Client has updated the commissioning session's PAKE verifier using the user input Passcode by updating the CastingApps + * @brief This is a continuation of the Commissioner-Generated passcode commissioning flow started via the + * VerifyOrEstablishConnection() API above. It continues the UDC process by sending a second IdentificationDeclaration message + * to Commissioner containing CommissionerPasscode and CommissionerPasscodeReady set to true. At this point it is assumed that + * the following have occurred: + * + * 1. Client (Commissionee) has sent the first IdentificationDeclaration message, via VerifyOrEstablishConnection(), to the + * Commissioner containing CommissionerPasscode set to true. + * 2. Commissioner generated and displayed a passcode. + * 3. The Commissioner replied with a CommissionerDecelration message with PasscodeDialogDisplayed and CommissionerPasscode set + * to true. + * 3. Client has handled the Commissioner's CommissionerDecelration message. + * 4. Client prompted user to input Passcode from Commissioner. + * 5. Client has updated the commissioning session's PAKE verifier using the user input Passcode by updating the CastingApps * CommissionableDataProvider * (matter::casting::core::CastingApp::GetInstance()->UpdateCommissionableDataProvider(CommissionableDataProvider)). * - * @param connectionCallbacks contains the ConnectCallback and CommissionerDeclarationCallback (Optional). - * @param commissioningWindowTimeoutSec (Optional) time (in sec) to keep the commissioning window open, if commissioning is - * required. Needs to be >= kCommissioningWindowTimeoutSec. + * The same connectionCallbacks and commissioningWindowTimeoutSec parameters passed into VerifyOrEstablishConnection() will be + * used. */ - void ContinueConnecting(ConnectionCallbacks connectionCallbacks, - unsigned long long int commissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec); + void ContinueConnecting(); /** * @brief Sets the internal connection state of this CastingPlayer to "disconnected" @@ -220,8 +255,8 @@ class CastingPlayer : public std::enable_shared_from_this CastingPlayerAttributes mAttributes; IdentificationDeclarationOptions mIdOptions; static CastingPlayer * mTargetCastingPlayer; - unsigned long long int mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec; - ConnectCallback mOnCompleted = {}; + uint16_t mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec; + ConnectCallback mOnCompleted = {}; /** * @brief resets this CastingPlayer's state and calls mOnCompleted with the CHIP_ERROR. Also, after calling mOnCompleted, it diff --git a/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp b/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp index bb9ecc3c4c57d9..22e7d49cdb7a5d 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp @@ -38,7 +38,7 @@ CommissionerDeclarationHandler * CommissionerDeclarationHandler::GetInstance() } // TODO: In the following PRs. Implement setHandler() for CommissionerDeclaration messages and expose messages to higher layers for -// Linux(DONE), Android(pending) and iOS(pending). +// Linux, Android and iOS. void CommissionerDeclarationHandler::OnCommissionerDeclarationMessage( const chip::Transport::PeerAddress & source, chip::Protocols::UserDirectedCommissioning::CommissionerDeclaration cd) { diff --git a/examples/tv-casting-app/tv-casting-common/core/Endpoint.h b/examples/tv-casting-app/tv-casting-common/core/Endpoint.h index 4da8cd56210b07..fc18267cf466be 100644 --- a/examples/tv-casting-app/tv-casting-common/core/Endpoint.h +++ b/examples/tv-casting-app/tv-casting-common/core/Endpoint.h @@ -145,6 +145,12 @@ class Endpoint : public std::enable_shared_from_this } return nullptr; } + + void LogDetail() const + { + ChipLogProgress(AppServer, "Endpoint::LogDetail() Endpoint ID: %d, Vendor ID: %d, Product ID: %d", mAttributes.mId, + mAttributes.mVendorId, mAttributes.mProductId); + } }; }; // namespace core diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 9a59e96c18355c..3458a0819286da 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -52 : [NXP] Update K32W0 SDK to 2.6.14 \ No newline at end of file +54 : [Telink] Update Docker image (Zephyr update) diff --git a/integrations/docker/images/stage-2/chip-build-telink/Dockerfile b/integrations/docker/images/stage-2/chip-build-telink/Dockerfile index 1333a4bfaaa286..e3b806eec091c0 100644 --- a/integrations/docker/images/stage-2/chip-build-telink/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-telink/Dockerfile @@ -12,7 +12,7 @@ RUN set -x \ && : # last line # Setup Zephyr -ARG ZEPHYR_REVISION=68deadeb5c20b82d68700e720d4580e8003bf1d8 +ARG ZEPHYR_REVISION=0e8032dfef7e02498f34ba0b5d5d2df71a62adb1 WORKDIR /opt/telink/zephyrproject RUN set -x \ && python3 -m pip install -U --no-cache-dir west \ diff --git a/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile b/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile index ff63e5c1940a01..8c38d19c1b3ed8 100644 --- a/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile +++ b/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile @@ -84,6 +84,7 @@ RUN set -x \ # Add extra libraries to the root image && guestfish --rw -a $TIZEN_IOT_IMAGE_ROOT -m /dev/sda copy-in \ $TIZEN_SDK_TOOLCHAIN/arm-tizen-linux-gnueabi/lib/libasan.so.* \ + $TIZEN_SDK_TOOLCHAIN/arm-tizen-linux-gnueabi/lib/libatomic.so.* \ $TIZEN_SDK_TOOLCHAIN/arm-tizen-linux-gnueabi/lib/libubsan.so.* \ $TIZEN_SDK_SYSROOT/usr/lib/libbluetooth-api.so.* \ $TIZEN_SDK_SYSROOT/usr/lib/libcapi-network-bluetooth.so.* \ diff --git a/ruff.toml b/ruff.toml index fec7608d707987..a33a97ef467d3c 100644 --- a/ruff.toml +++ b/ruff.toml @@ -15,5 +15,5 @@ line-length = 132 [lint] select = ["E4", "E7", "E9", "F"] ignore = [ - "E721" # We use is for good reasons + "E721" # We use it for good reasons ] diff --git a/scripts/build/build_examples.py b/scripts/build/build_examples.py index a52c9aa6f3e131..e1f37fca797d7f 100755 --- a/scripts/build/build_examples.py +++ b/scripts/build/build_examples.py @@ -83,14 +83,17 @@ def ValidateTargetNames(context, parameter, values): default=[], multiple=True, callback=ValidateTargetNames, - help='Build target(s)' -) + help='Build target(s)') +@click.option( + '--enable-link-map-file', + default=False, + is_flag=True, + help='Enable generation of link map files.') @click.option( '--enable-flashbundle', default=False, is_flag=True, - help='Also generate the flashbundles for the app.' -) + help='Also generate the flashbundles for the app.') @click.option( '--repo', default='.', @@ -132,7 +135,7 @@ def ValidateTargetNames(context, parameter, values): 'Set pigweed command launcher. E.g.: "--pw-command-launcher=ccache" ' 'for using ccache when building examples.')) @click.pass_context -def main(context, log_level, target, repo, +def main(context, log_level, target, enable_link_map_file, repo, out_prefix, pregen_dir, clean, dry_run, dry_run_output, enable_flashbundle, no_log_timestamps, pw_command_launcher): # Ensures somewhat pretty logging of what is going on @@ -160,6 +163,7 @@ def main(context, log_level, target, repo, context.obj = build.Context( repository_path=repo, output_prefix=out_prefix, runner=runner) context.obj.SetupBuilders(targets=requested_targets, options=BuilderOptions( + enable_link_map_file=enable_link_map_file, enable_flashbundle=enable_flashbundle, pw_command_launcher=pw_command_launcher, pregen_dir=pregen_dir, diff --git a/scripts/build/builders/ameba.py b/scripts/build/builders/ameba.py index 677b47bbd43a01..802ce1f73cbe62 100644 --- a/scripts/build/builders/ameba.py +++ b/scripts/build/builders/ameba.py @@ -15,7 +15,7 @@ import os from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class AmebaBoard(Enum): @@ -89,18 +89,19 @@ def _build(self): title='Building ' + self.identifier) def build_outputs(self): - return { - self.app.AppNamePrefix + '.axf': - os.path.join(self.output_dir, 'asdk', 'target_image2.axf'), - self.app.AppNamePrefix + '.map': + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'target_image2.axf'), + self.app.AppNamePrefix + '.axf') + if self.options.enable_link_map_file: + yield BuilderOutput( os.path.join(self.output_dir, 'asdk', 'target_image2.map'), - 'km0_boot_all.bin': - os.path.join(self.output_dir, 'asdk', - 'bootloader', 'km0_boot_all.bin'), - 'km4_boot_all.bin': - os.path.join(self.output_dir, 'asdk', - 'bootloader', 'km4_boot_all.bin'), - 'km0_km4_image2.bin': - os.path.join(self.output_dir, 'asdk', - 'image', 'km0_km4_image2.bin'), - } + self.app.AppNamePrefix + '.map') + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'bootloader', 'km0_boot_all.bin'), + 'km0_boot_all.bin') + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'bootloader', 'km4_boot_all.bin'), + 'km4_boot_all.bin') + yield BuilderOutput( + os.path.join(self.output_dir, 'asdk', 'image', 'km0_km4_image2.bin'), + 'km0_km4_image2.bin') diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index bd2c90c28136d6..94d3a566a63877 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -16,7 +16,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class AndroidBoard(Enum): @@ -366,6 +366,9 @@ def generate(self): if self.options.pw_command_launcher: gn_args["pw_command_launcher"] = self.options.pw_command_launcher + if self.options.enable_link_map_file: + gn_args["chip_generate_link_map_file"] = True + if exampleName == "chip-test": gn_args["chip_build_tests"] = True if self.profile != AndroidProfile.DEBUG: @@ -569,85 +572,61 @@ def _build(self): def build_outputs(self): if self.board.IsIde(): - outputs = { - self.app.AppName() - + "-debug.apk": os.path.join( + yield BuilderOutput( + os.path.join( self.root, "examples/android", self.app.AppName(), - "app/build/outputs/apk/debug/app-debug.apk", - ) - } + "app/build/outputs/apk/debug/app-debug.apk"), + self.app.AppName() + "-debug.apk") elif self.app.ExampleName() is not None: if self.app == AndroidApp.TV_SERVER: - outputs = { - "tv-sever-platform-app-debug.apk": os.path.join( - self.output_dir, "platform-app", "outputs", "apk", "debug", "platform-app-debug.apk" - ), - "tv-sever-content-app-debug.apk": os.path.join( - self.output_dir, "content-app", "outputs", "apk", "debug", "content-app-debug.apk" - ) - } + yield BuilderOutput( + os.path.join(self.output_dir, "platform-app", + "outputs", "apk", "debug", "platform-app-debug.apk"), + "tv-sever-platform-app-debug.apk") + yield BuilderOutput( + os.path.join(self.output_dir, "content-app", + "outputs", "apk", "debug", "content-app-debug.apk"), + "tv-sever-content-app-debug.apk") elif self.app == AndroidApp.VIRTUAL_DEVICE_APP: - outputs = { - self.app.AppName() + "app-debug.apk": os.path.join( - self.output_dir, "VirtualDeviceApp", "app", "outputs", "apk", "debug", "app-debug.apk" - ) - } + yield BuilderOutput( + os.path.join(self.output_dir, "VirtualDeviceApp", "app", + "outputs", "apk", "debug", "app-debug.apk"), + self.app.AppName() + "app-debug.apk") else: - outputs = { - self.app.AppName() + "app-debug.apk": os.path.join( - self.output_dir, "outputs", "apk", "debug", "app-debug.apk" - ) - } + yield BuilderOutput( + os.path.join(self.output_dir, + "outputs", "apk", "debug", "app-debug.apk"), + self.app.AppName() + "app-debug.apk") else: - outputs = { - self.app.AppName() + "app-debug.apk": os.path.join( - self.output_dir, "outputs", "apk", "debug", "app-debug.apk" - ), - "CHIPController.jar": os.path.join( - self.output_dir, "lib", "src/controller/java/CHIPController.jar" - ), - "CHIPInteractionModel.jar": os.path.join( - self.output_dir, "lib", "src/controller/java/CHIPInteractionModel.jar" - ), - "libMatterTlv.jar": os.path.join( - self.output_dir, "lib", "src/controller/java/libMatterTlv.jar" - ), - "AndroidPlatform.jar": os.path.join( - self.output_dir, "lib", "src/platform/android/AndroidPlatform.jar" - ), - "OnboardingPayload.jar": os.path.join( - self.output_dir, - "lib", - "src/controller/java/OnboardingPayload.jar", - ), - "CHIPClusters.jar": os.path.join( - self.output_dir, - "lib", - "src/controller/java/CHIPClusters.jar", - ), - "CHIPClusterID.jar": os.path.join( - self.output_dir, - "lib", - "src/controller/java/CHIPClusterID.jar", - ), - "jni/%s/libCHIPController.so" - % self.board.AbiName(): os.path.join( - self.output_dir, - "lib", - "jni", - self.board.AbiName(), - "libCHIPController.so", - ), - "jni/%s/libc++_shared.so" - % self.board.AbiName(): os.path.join( - self.output_dir, - "lib", - "jni", - self.board.AbiName(), - "libc++_shared.so", - ), - } - - return outputs + yield BuilderOutput( + os.path.join(self.output_dir, "outputs", "apk", "debug", "app-debug.apk"), + self.app.AppName() + "app-debug.apk") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPController.jar"), + "CHIPController.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPInteractionModel.jar"), + "CHIPInteractionModel.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "libMatterTlv.jar"), + "libMatterTlv.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "platform", "android", "AndroidPlatform.jar"), + "AndroidPlatform.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "OnboardingPayload.jar"), + "OnboardingPayload.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPClusters.jar"), + "CHIPClusters.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "src", "controller", "java", "CHIPClusterID.jar"), + "CHIPClusterID.jar") + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "jni", self.board.AbiName(), "libCHIPController.so"), + "jni/%s/libCHIPController.so" % self.board.AbiName()) + yield BuilderOutput( + os.path.join(self.output_dir, "lib", "jni", self.board.AbiName(), "libc++_shared.so"), + "jni/%s/libc++_shared.so" % self.board.AbiName()) diff --git a/scripts/build/builders/asr.py b/scripts/build/builders/asr.py index d7351a1daec289..a901147cf1e7a7 100644 --- a/scripts/build/builders/asr.py +++ b/scripts/build/builders/asr.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -178,13 +179,9 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = { - '%s.out' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix()), - '%s.out.map' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix()), - } - - return items + extensions = ["out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/bouffalolab.py b/scripts/build/builders/bouffalolab.py index 1b661bff045c07..a8adfbb2a32b74 100644 --- a/scripts/build/builders/bouffalolab.py +++ b/scripts/build/builders/bouffalolab.py @@ -16,6 +16,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -226,16 +227,12 @@ def GnBuildArgs(self): return self.argsOpt def build_outputs(self): - items = { - '%s.out' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix(self.chip_name)), - '%s.out.map' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix(self.chip_name)), - } - - return items + extensions = ["out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix(self.chip_name)}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) def PostBuildCommand(self): diff --git a/scripts/build/builders/builder.py b/scripts/build/builders/builder.py index dc420fce5e6b41..2895300e12388e 100644 --- a/scripts/build/builders/builder.py +++ b/scripts/build/builders/builder.py @@ -22,6 +22,9 @@ @dataclass class BuilderOptions: + # Generate a link map file + enable_link_map_file: bool = False + # Enable flashbundle generation stage enable_flashbundle: bool = False @@ -32,6 +35,12 @@ class BuilderOptions: pregen_dir: str = None +@dataclass +class BuilderOutput: + source: str # Source file generated by the build + target: str # Target file to be copied to + + class Builder(ABC): """Generic builder base class for CHIP. @@ -59,63 +68,61 @@ def _build(self): """Perform an actual build""" raise NotImplementedError() - def _generate_flashbundle(self): - """Perform an actual generating of flashbundle + def _bundle(self): + """Perform an actual generating of flashbundle. - May do nothing (and builder can choose not to implement this) if the - app does not need special steps for generating flashbundle. (e.g. the - example apps on Linux platform can run the ELF files directly.) + May do nothing (and builder can choose not to implement this) if + the app does not need special steps for generating flashbundle (e.g. + on Linux platform, the output ELF files can be used directly). """ pass @abstractmethod def build_outputs(self): - """Return a list of relevant output files after a build. + """Return a list of relevant BuilderOutput objects after a build. - May use build output data (e.g. manifests), so this should be invoked - only after a build has succeeded. + May use build output data (e.g. manifests), so this should be + invoked only after a build has succeeded. """ raise NotImplementedError() - def flashbundle(self): - """Return the files in flashbundle. + def bundle_outputs(self): + """Return the BuilderOutput objects in flashbundle. - Return an empty dict (and builder can choose not to implement this) if the - app does not need special files as flashbundle. (e.g. the example apps on - Linux platform can run the ELF files directly.) + Return an empty list (and builder can choose not to implement this) + if the app does not need special files as flashbundle. - May use data from do_generate_flashbundle, so this should be invoked only - after do_generate_flashbundle has succeeded. + May use data from _bundle(), so this should be invoked only after + _bundle() has succeeded. """ - return {} + return [] def outputs(self): - artifacts = self.build_outputs() + outputs = list(self.build_outputs()) if self.options.enable_flashbundle: - artifacts.update(self.flashbundle()) - return artifacts + outputs.extend(self.bundle_outputs()) + return outputs def build(self): self._build() if self.options.enable_flashbundle: - self._generate_flashbundle() + self._bundle() def _Execute(self, cmdarray, title=None): self._runner.Run(cmdarray, title=title) def CompressArtifacts(self, target_file: str): with tarfile.open(target_file, "w:gz") as tar: - for target_name, source_name in self.outputs().items(): - logging.info( - f'Adding {source_name} into {target_file}/{target_name}') - tar.add(source_name, target_name) + for output in self.outputs(): + logging.info('Adding %s into %s(%s)', + output.source, target_file, output.target) + tar.add(output.source, output.target) def CopyArtifacts(self, target_dir: str): - for target_name, source_name in self.outputs().items(): - target_full_name = os.path.join(target_dir, target_name) - - logging.info('Copying %s into %s', source_name, target_name) + for output in self.outputs(): + logging.info(f'Copying {output.source} into {output.target}') + target_full_name = os.path.join(target_dir, output.target) target_dir_full_name = os.path.dirname(target_full_name) if not os.path.exists(target_dir_full_name): @@ -123,5 +130,5 @@ def CopyArtifacts(self, target_dir: str): target_dir_full_name) os.makedirs(target_dir_full_name) - shutil.copyfile(source_name, target_full_name) - shutil.copymode(source_name, target_full_name) + shutil.copyfile(output.source, target_full_name) + shutil.copymode(output.source, target_full_name) diff --git a/scripts/build/builders/cc32xx.py b/scripts/build/builders/cc32xx.py index f54b7531eecc81..2563cab948ce0b 100644 --- a/scripts/build/builders/cc32xx.py +++ b/scripts/build/builders/cc32xx.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -62,17 +63,14 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} if (self.app == cc32xxApp.LOCK): - extensions = [".out", ".bin", ".out.map"] + extensions = ["out", "bin"] elif (self.app == cc32xxApp.AIR_PURIFIER): - extensions = [".out", ".bin", ".out.map"] - + extensions = ["out", "bin"] else: raise Exception('Unknown app type: %r' % self.app) - - for extension in extensions: - name = '%s%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/cyw30739.py b/scripts/build/builders/cyw30739.py index 4c03edca3151ef..243c78bc524b82 100644 --- a/scripts/build/builders/cyw30739.py +++ b/scripts/build/builders/cyw30739.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -102,8 +103,9 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} - for extension in ["elf", "elf.map"]: - name = "%s-%s.%s" % (self.app.AppNamePrefix(), self.board.GnArgName(), extension) - items[name] = os.path.join(self.output_dir, name) - return items + extensions = ["elf"] + if self.options.enable_link_map_file: + extensions.append("elf.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}-{self.board.GnArgName()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 1144cfc8c54a16..b0ad37be4774a9 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -17,6 +17,7 @@ import subprocess from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -263,26 +264,27 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = {} - for extension in ["out", "out.map", "hex"]: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) + extensions = ["out", "hex"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) if self.app == Efr32App.UNIT_TEST: # Include test runner python wheels for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_nl_test_runner_wheels')): for file in files: - items["chip_nl_test_runner_wheels/" + - file] = os.path.join(root, file) + yield BuilderOutput( + os.path.join(root, file), + os.path.join("chip_nl_test_runner_wheels", file)) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: - for line in f.readlines(): - name = line.strip() - items['flashbundle/%s' % - name] = os.path.join(self.output_dir, name) - - return items + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput( + os.path.join(self.output_dir, name), + os.path.join("flashbundle", name)) def generate(self): cmd = [ @@ -298,6 +300,9 @@ def generate(self): if self.options.pw_command_launcher: extra_args.append('pw_command_launcher="%s"' % self.options.pw_command_launcher) + if self.options.enable_link_map_file: + extra_args.append('chip_generate_link_map_file=true') + if self.options.pregen_dir: extra_args.append('chip_code_pre_generated_directory="%s"' % self.options.pregen_dir) diff --git a/scripts/build/builders/esp32.py b/scripts/build/builders/esp32.py index 468a92072c9fd9..3528a5873050e4 100644 --- a/scripts/build/builders/esp32.py +++ b/scripts/build/builders/esp32.py @@ -17,7 +17,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class Esp32Board(Enum): @@ -248,26 +248,21 @@ def _build(self): def build_outputs(self): if self.app == Esp32App.TESTS: # Include the runnable image names as artifacts - result = dict() with open(os.path.join(self.output_dir, 'test_images.txt'), 'rt') as f: - for name in f.readlines(): - name = name.strip() - result[name] = os.path.join(self.output_dir, name) - - return result + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, name), name) + return - return { - self.app.AppNamePrefix + '.elf': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), - self.app.AppNamePrefix + '.map': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.map'), - } + extensions = ["elf"] + if self.options.enable_link_map_file: + extensions.append("map") + for ext in extensions: + name = f"{self.app.AppNamePrefix}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) - def flashbundle(self): + def bundle_outputs(self): if not self.app.FlashBundleName: - return {} - - with open(os.path.join(self.output_dir, self.app.FlashBundleName), 'r') as fp: - return { - line.strip(): os.path.join(self.output_dir, line.strip()) for line in fp.readlines() if line.strip() - } + return + with open(os.path.join(self.output_dir, self.app.FlashBundleName)) as f: + for line in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, line), line) diff --git a/scripts/build/builders/genio.py b/scripts/build/builders/genio.py index 822f198fd798da..ed7a8518f7d128 100755 --- a/scripts/build/builders/genio.py +++ b/scripts/build/builders/genio.py @@ -1,6 +1,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -48,9 +49,9 @@ def __init__(self, self.app = app def build_outputs(self): - items = {} - for extension in ['out', 'out.map', 'bin']: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + extensions = ['out', 'bin'] + if self.options.enable_link_map_file: + extensions.append('out.map') + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/gn.py b/scripts/build/builders/gn.py index 75f6bb02c4231e..d2b09f393c1597 100644 --- a/scripts/build/builders/gn.py +++ b/scripts/build/builders/gn.py @@ -64,6 +64,9 @@ def generate(self): if self.options.pw_command_launcher: extra_args.append('pw_command_launcher="%s"' % self.options.pw_command_launcher) + if self.options.enable_link_map_file: + extra_args.append('chip_generate_link_map_file=true') + if self.options.pregen_dir: extra_args.append('chip_code_pre_generated_directory="%s"' % self.options.pregen_dir) diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 667cd39d47da99..822375fdd65c05 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -17,6 +17,7 @@ from platform import uname from typing import Optional +from .builder import BuilderOutput from .gn import GnBuilder @@ -564,19 +565,13 @@ def PostBuildCommand(self): self.createJavaExecutable("kotlin-matter-controller") def build_outputs(self): - outputs = {} - for name in self.app.OutputNames(): + if not self.options.enable_link_map_file and name.endswith(".map"): + continue path = os.path.join(self.output_dir, name) if os.path.isdir(path): for root, dirs, files in os.walk(path): for file in files: - outputs.update({ - file: os.path.join(root, file) - }) + yield BuilderOutput(os.path.join(root, file), file) else: - outputs.update({ - name: os.path.join(self.output_dir, name) - }) - - return outputs + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/imx.py b/scripts/build/builders/imx.py index e748144edc21a1..0d10557b8c5396 100644 --- a/scripts/build/builders/imx.py +++ b/scripts/build/builders/imx.py @@ -17,6 +17,7 @@ import shlex from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -180,19 +181,13 @@ def SysRootPath(self, name): return os.environ[name] def build_outputs(self): - outputs = {} - for name in self.app.OutputNames(): + if not self.options.enable_link_map_file and name.endswith(".map"): + continue path = os.path.join(self.output_dir, name) if os.path.isdir(path): for root, dirs, files in os.walk(path): for file in files: - outputs.update({ - file: os.path.join(root, file) - }) + yield BuilderOutput(os.path.join(root, file), file) else: - outputs.update({ - name: os.path.join(self.output_dir, name) - }) - - return outputs + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/infineon.py b/scripts/build/builders/infineon.py index 1cf7e0dd9b900d..8578fba45434a3 100644 --- a/scripts/build/builders/infineon.py +++ b/scripts/build/builders/infineon.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -102,19 +103,14 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = { - '%s.out' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix()), - '%s.out.map' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix()), - } - - return items - - def flashbundle(self): - with open(os.path.join(self.output_dir, self.app.FlashBundleName()), 'r') as fp: - return { - line.strip(): os.path.join(self.output_dir, line.strip()) for line in fp.readlines() if line.strip() - } + extensions = ['out'] + if self.options.enable_link_map_file: + extensions.append('out.map') + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) + + def bundle_outputs(self): + with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: + for line in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, line), line) diff --git a/scripts/build/builders/mbed.py b/scripts/build/builders/mbed.py index fd2aa00ebd2f35..6dc47d0aa4aa27 100644 --- a/scripts/build/builders/mbed.py +++ b/scripts/build/builders/mbed.py @@ -16,7 +16,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class MbedApp(Enum): @@ -147,12 +147,9 @@ def _build(self): title='Building ' + self.identifier) def build_outputs(self): - return { - self.app.AppNamePrefix + '.elf': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), - self.app.AppNamePrefix + '.hex': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.hex'), - self.app.AppNamePrefix + '.map': - os.path.join(self.output_dir, - self.app.AppNamePrefix + '.elf.map'), - } + extensions = ['elf', 'hex'] + if self.options.enable_link_map_file: + extensions.append('elf.map') + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/mw320.py b/scripts/build/builders/mw320.py index 66b739321d8759..7fdf7578385eec 100755 --- a/scripts/build/builders/mw320.py +++ b/scripts/build/builders/mw320.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -49,9 +50,9 @@ def __init__(self, self.app = app def build_outputs(self): - items = {} - for extension in [".bin", ".out", ".out.map"]: - name = '%s%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + extensions = ["bin", "out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/nrf.py b/scripts/build/builders/nrf.py index 9bc4f9596efc26..d584490589c662 100644 --- a/scripts/build/builders/nrf.py +++ b/scripts/build/builders/nrf.py @@ -17,7 +17,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class NrfApp(Enum): @@ -225,23 +225,24 @@ def _build(self): self._Execute(['ctest', '--build-nocmake', '-V', '--output-on-failure', '--test-dir', self.output_dir], title='Run Tests ' + self.identifier) - def _generate_flashbundle(self): + def _bundle(self): logging.info(f'Generating flashbundle at {self.output_dir}') self._Execute(['ninja', '-C', self.output_dir, 'flashing_script'], title='Generating flashable files of ' + self.identifier) def build_outputs(self): - return { - '%s.elf' % self.app.AppNamePrefix(): os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), - '%s.map' % self.app.AppNamePrefix(): os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), - } - - def flashbundle(self): + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + '%s.elf' % self.app.AppNamePrefix()) + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + '%s.map' % self.app.AppNamePrefix()) + + def bundle_outputs(self): if self.app == NrfApp.UNIT_TESTS: - return dict() - - with open(os.path.join(self.output_dir, self.app.FlashBundleName()), 'r') as fp: - return { - line.strip(): os.path.join(self.output_dir, line.strip()) for line in fp.readlines() if line.strip() - } + return + with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: + for line in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput(os.path.join(self.output_dir, line), line) diff --git a/scripts/build/builders/nuttx.py b/scripts/build/builders/nuttx.py index ae198ca71f07ac..39bb2e78918667 100644 --- a/scripts/build/builders/nuttx.py +++ b/scripts/build/builders/nuttx.py @@ -16,6 +16,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import Builder @@ -86,13 +87,9 @@ def _build(self): def build_outputs(self): logging.info('Compiling outputs NuttX at %s', self.output_dir) - items = { - '%s.out' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix(self.chip_name)), - '%s.out.map' % self.app.AppNamePrefix(self.chip_name): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix(self.chip_name)), - } - - return items + extensions = ["out"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix(self.chip_name)}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 9f0dcfddd7bbde..4bd4f0ae451875 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -129,7 +130,10 @@ def generate(self): def build_outputs(self): name = 'chip-%s-%s' % (self.board.Name(), self.app.NameSuffix()) - return { - '%s.elf' % name: os.path.join(self.output_dir, name), - '%s.map' % name: os.path.join(self.output_dir, '%s.map' % name) - } + yield BuilderOutput( + os.path.join(self.output_dir, name), + f'{name}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, f'{name}.map'), + f'{name}.map') diff --git a/scripts/build/builders/openiotsdk.py b/scripts/build/builders/openiotsdk.py index 89aad6a59e9a16..c0ea5facb92f70 100644 --- a/scripts/build/builders/openiotsdk.py +++ b/scripts/build/builders/openiotsdk.py @@ -16,7 +16,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class OpenIotSdkApp(Enum): @@ -90,10 +90,9 @@ def _build(self): title='Building ' + self.identifier) def build_outputs(self): - return { - self.app.AppNamePrefix + '.elf': - os.path.join(self.output_dir, self.app.AppNamePrefix + '.elf'), - self.app.AppNamePrefix + '.map': - os.path.join(self.output_dir, - self.app.AppNamePrefix + '.map'), - } + extensions = ["elf"] + if self.options.enable_link_map_file: + extensions.append("map") + for ext in extensions: + name = f"{self.app.AppNamePrefix}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/qpg.py b/scripts/build/builders/qpg.py index e641b6f58df4ec..330f4e3b74977d 100644 --- a/scripts/build/builders/qpg.py +++ b/scripts/build/builders/qpg.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -88,6 +89,16 @@ def GnArgName(self): raise Exception('Unknown board #: %r' % self) +class QpgFlavour(Enum): + EXT_FLASH = 1 + + def GnFlavourName(self): + if self == QpgFlavour.EXT_FLASH: + return '_ext_flash' + else: + raise Exception('Unknown flavour #: %r' % self) + + class QpgBuilder(GnBuilder): def __init__(self, @@ -95,6 +106,7 @@ def __init__(self, runner, app: QpgApp = QpgApp.LIGHT, board: QpgBoard = QpgBoard.QPG6105, + flavour: QpgFlavour = QpgFlavour.EXT_FLASH, enable_rpcs: bool = False, update_image: bool = False): super(QpgBuilder, self).__init__( @@ -102,28 +114,29 @@ def __init__(self, runner=runner) self.app = app self.board = board + self.flavour = flavour self.enable_rpcs = enable_rpcs self.update_image = update_image def GnBuildArgs(self): - args = ['qpg_target_ic=\"%s\"' % self.board.GnArgName()] + args = ['qpg_target_ic=\"%s\" qpg_flavour=\"%s\"' % (self.board.GnArgName(), self.flavour.GnFlavourName())] if self.enable_rpcs: args.append('import("//with_pw_rpc.gni")') if self.update_image: - args.append('matter_device_software_version_string=\"1.1_OTA_TEST\" matter_device_software_version=4') + args.append('matter_ota_test_image=true') return args def build_outputs(self): - items = {} - for extension in ["out", "out.map", "out.hex"]: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) + extensions = ["out", "out.hex"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: - for line in f.readlines(): - name = line.strip() - items['flashbundle/%s' % - name] = os.path.join(self.output_dir, name) - - return items + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput( + os.path.join(self.output_dir, name), + os.path.join('flashbundle', name)) diff --git a/scripts/build/builders/rw61x.py b/scripts/build/builders/rw61x.py index 546c6549e2aab9..b0c67dcbac68b1 100644 --- a/scripts/build/builders/rw61x.py +++ b/scripts/build/builders/rw61x.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -117,8 +118,10 @@ def generate(self): super(RW61XBuilder, self).generate() def build_outputs(self): - name = '%s' % self.app.NameSuffix() - return { - '%s.elf' % name: os.path.join(self.output_dir, name), - '%s.map' % name: os.path.join(self.output_dir, '%s.map' % name) - } + yield BuilderOutput( + os.path.join(self.output_dir, self.app.NameSuffix()), + f'{self.app.NameSuffix()}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, f'{self.app.NameSuffix()}.map'), + f'{self.app.NameSuffix()}.map') diff --git a/scripts/build/builders/stm32.py b/scripts/build/builders/stm32.py index 1613ecbbe42f39..ae9d4f7b65c702 100644 --- a/scripts/build/builders/stm32.py +++ b/scripts/build/builders/stm32.py @@ -15,6 +15,7 @@ import os from enum import Enum, auto +from .builder import BuilderOutput from .gn import GnBuilder @@ -78,16 +79,16 @@ def GnBuildArgs(self): return self.extra_gn_options def build_outputs(self): - items = {} - for extension in ["out", "out.map", "out.hex"]: - name = '%s.%s' % (self.app.AppNamePrefix(), extension) - items[name] = os.path.join(self.output_dir, name) + extensions = ["out", "out.hex"] + if self.options.enable_link_map_file: + extensions.append("out.map") + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: - for line in f.readlines(): - name = line.strip() - items['flashbundle/%s' % - name] = os.path.join(self.output_dir, name) - - return items + for name in filter(None, [x.strip() for x in f.readlines()]): + yield BuilderOutput( + os.path.join(self.output_dir, name), + os.path.join('flashbundle', name)) diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index 9b63635250dcf2..c53e0b6321cd76 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -17,7 +17,7 @@ import shlex from enum import Enum, auto -from .builder import Builder +from .builder import Builder, BuilderOutput class TelinkApp(Enum): @@ -229,15 +229,10 @@ def _build(self): self._Execute(['bash', '-c', cmd], title='Building ' + self.identifier) def build_outputs(self): - return { - '%s.elf' % - self.app.AppNamePrefix(): os.path.join( - self.output_dir, - 'zephyr', - 'zephyr.elf'), - '%s.map' % - self.app.AppNamePrefix(): os.path.join( - self.output_dir, - 'zephyr', - 'zephyr.map'), - } + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + '%s.elf' % self.app.AppNamePrefix()) + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + '%s.map' % self.app.AppNamePrefix()) diff --git a/scripts/build/builders/ti.py b/scripts/build/builders/ti.py index 5decd75cc058e0..f0691f541b3157 100644 --- a/scripts/build/builders/ti.py +++ b/scripts/build/builders/ti.py @@ -16,6 +16,7 @@ from enum import Enum, auto from typing import Optional +from .builder import BuilderOutput from .gn import GnBuilder @@ -104,6 +105,9 @@ def GnBuildArgs(self): args = [ 'ti_sysconfig_root="%s"' % os.environ['TI_SYSCONFIG_ROOT'], 'ti_simplelink_board="%s"' % self.board.BoardName(), + # FIXME: It seems that TI SDK expects link map file to be present. + # In order to make it optional, SDK fix is needed. + 'chip_generate_link_map_file=true', ] if self.openthread_ftd: @@ -115,22 +119,18 @@ def GnBuildArgs(self): return args def build_outputs(self): - items = {} - if (self.board == TIBoard.LP_EM_CC1354P10_6): - if (self.app == TIApp.LOCK - or self.app == TIApp.LIGHTING - or self.app == TIApp.PUMP - or self.app == TIApp.PUMP_CONTROLLER): - extensions = [".out", ".out.map", "-mcuboot.hex"] - + if self.board == TIBoard.LP_EM_CC1354P10_6: + if self.app in [TIApp.LOCK, + TIApp.LIGHTING, + TIApp.PUMP, + TIApp.PUMP_CONTROLLER]: + suffixes = [".out", "-mcuboot.hex"] else: - extensions = [".out", ".out.map"] - + suffixes = [".out"] else: - extensions = [".out", ".out.map"] - - for extension in extensions: - name = '%s%s' % (self.app.AppNamePrefix(self.board), extension) - items[name] = os.path.join(self.output_dir, name) - - return items + suffixes = [".out"] + if self.options.enable_link_map_file: + suffixes.append(".out.map") + for suffix in suffixes: + name = f"{self.app.AppNamePrefix(self.board)}{suffix}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) diff --git a/scripts/build/builders/tizen.py b/scripts/build/builders/tizen.py index 6b5cdd90ec77f0..97124328c5dd1e 100644 --- a/scripts/build/builders/tizen.py +++ b/scripts/build/builders/tizen.py @@ -18,6 +18,7 @@ from enum import Enum from xml.etree import ElementTree as ET +from .builder import BuilderOutput from .gn import GnBuilder Board = namedtuple('Board', ['target_cpu']) @@ -147,23 +148,23 @@ def GnBuildArgs(self): 'tizen_sdk_sysroot="%s"' % os.environ['TIZEN_SDK_SYSROOT'], ] - def _generate_flashbundle(self): + def _bundle(self): if self.app.is_tpk: logging.info('Packaging %s', self.output_dir) cmd = ['ninja', '-C', self.output_dir, self.app.value.name + ':tpk'] self._Execute(cmd, title='Packaging ' + self.identifier) def build_outputs(self): - return { - output: os.path.join(self.output_dir, output) - for output in self.app.value.outputs - } - - def flashbundle(self): + for name in self.app.value.outputs: + if not self.options.enable_link_map_file and name.endswith(".map"): + continue + yield BuilderOutput( + os.path.join(self.output_dir, name), + name) + + def bundle_outputs(self): if not self.app.is_tpk: - return {} - return { - self.app.package: os.path.join(self.output_dir, - self.app.package_name, 'out', - self.app.package), - } + return + source = os.path.join(self.output_dir, self.app.package_name, + 'out', self.app.package) + yield BuilderOutput(source, self.app.package) diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index e876bae22094c6..037ed829a15a11 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -97,6 +97,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/window-covering.xml"; load "../src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml"; diff --git a/scripts/setup/requirements.infineon.txt b/scripts/setup/requirements.infineon.txt index bba66165a7654c..0a79ce1f3bfa63 100644 --- a/scripts/setup/requirements.infineon.txt +++ b/scripts/setup/requirements.infineon.txt @@ -1 +1,2 @@ leb128 +zcbor diff --git a/scripts/setup/requirements.nxp.txt b/scripts/setup/requirements.nxp.txt index 6db976c85da690..a78e1f0fc6230d 100644 --- a/scripts/setup/requirements.nxp.txt +++ b/scripts/setup/requirements.nxp.txt @@ -1,3 +1,4 @@ +crc>=7.0.0 jsonschema>=4.17.0 pycrypto>=2.6.1 pycryptodome>=3.20.0 diff --git a/scripts/setup/requirements.qpg.txt b/scripts/setup/requirements.qpg.txt index 3216862564e024..6670c1063d462d 100644 --- a/scripts/setup/requirements.qpg.txt +++ b/scripts/setup/requirements.qpg.txt @@ -1 +1,3 @@ -pylzma \ No newline at end of file +pylzma +intelhex +ecdsa \ No newline at end of file diff --git a/scripts/spec_xml/generate_spec_xml.py b/scripts/spec_xml/generate_spec_xml.py index b947b997665251..bb33c13533991d 100755 --- a/scripts/spec_xml/generate_spec_xml.py +++ b/scripts/spec_xml/generate_spec_xml.py @@ -20,6 +20,8 @@ import re import subprocess import sys +import xml.etree.ElementTree as ElementTree +from pathlib import Path import click @@ -36,6 +38,20 @@ def get_xml_path(filename, output_dir): return os.path.abspath(os.path.join(output_dir, xml)) +def make_asciidoc(target: str, include_in_progress: bool, spec_dir: str, dry_run: bool) -> str: + cmd = ['make', 'PRINT_FILENAMES=1'] + if include_in_progress: + cmd.append('INCLUDE_IN_PROGRESS=1') + cmd.append(target) + if dry_run: + print(cmd) + return '' + else: + ret = subprocess.check_output(cmd, cwd=spec_dir).decode('UTF-8').rstrip() + print(ret) + return ret + + @click.command() @click.option( '--scraper', @@ -56,16 +72,21 @@ def get_xml_path(filename, output_dir): default=False, is_flag=True, help='Flag for dry run') -def main(scraper, spec_root, output_dir, dry_run): +@click.option( + '--include-in-progress', + default=True, + type=bool, + help='Include in-progress items from spec') +def main(scraper, spec_root, output_dir, dry_run, include_in_progress): # Clusters need to be scraped first because the cluster directory is passed to the device type directory - scrape_clusters(scraper, spec_root, output_dir, dry_run) - scrape_device_types(scraper, spec_root, output_dir, dry_run) + scrape_clusters(scraper, spec_root, output_dir, dry_run, include_in_progress) + scrape_device_types(scraper, spec_root, output_dir, dry_run, include_in_progress) if not dry_run: dump_versions(scraper, spec_root, output_dir) dump_cluster_ids(output_dir) -def scrape_clusters(scraper, spec_root, output_dir, dry_run): +def scrape_clusters(scraper, spec_root, output_dir, dry_run, include_in_progress): src_dir = os.path.abspath(os.path.join(spec_root, 'src')) sdm_clusters_dir = os.path.abspath( os.path.join(src_dir, 'service_device_management')) @@ -74,22 +95,25 @@ def scrape_clusters(scraper, spec_root, output_dir, dry_run): media_clusters_dir = os.path.abspath( os.path.join(app_clusters_dir, 'media')) clusters_output_dir = os.path.abspath(os.path.join(output_dir, 'clusters')) - dm_clusters_list = ['ACL-Cluster.adoc', 'Binding-Cluster.adoc', 'bridge-clusters.adoc', - 'Descriptor-Cluster.adoc', 'Group-Key-Management-Cluster.adoc', 'ICDManagement.adoc', - 'Label-Cluster.adoc'] - sdm_exclude_list = ['AdminAssistedCommissioningFlows.adoc', 'BulkDataExchange.adoc', 'CommissioningFlows.adoc', - 'DeviceCommissioningFlows.adoc', 'DistributedComplianceLedger.adoc', 'OTAFileFormat.adoc'] - app_exclude_list = ['appliances.adoc', 'closures.adoc', 'general.adoc', - 'hvac.adoc', 'lighting.adoc', 'meas_and_sense.adoc', 'robots.adoc'] - media_exclude_list = ['media.adoc', 'VideoPlayerArchitecture.adoc'] if not os.path.exists(clusters_output_dir): os.makedirs(clusters_output_dir) + print('Generating main spec to get file include list - this make take a few minutes') + main_out = make_asciidoc('pdf', include_in_progress, spec_root, dry_run) + print('Generating cluster spec to get file include list - this make take a few minutes') + cluster_out = make_asciidoc('pdf-appclusters-book', include_in_progress, spec_root, dry_run) + def scrape_cluster(filename: str) -> None: + base = Path(filename).stem + if base not in main_out and base not in cluster_out: + print(f'skipping file: {base} as it is not compiled into the asciidoc') + return xml_path = get_xml_path(filename, clusters_output_dir) cmd = [scraper, 'cluster', '-i', filename, '-o', - xml_path, '-nd', '--define', 'in-progress'] + xml_path, '-nd'] + if include_in_progress: + cmd.extend(['--define', 'in-progress']) if dry_run: print(cmd) else: @@ -97,19 +121,28 @@ def scrape_cluster(filename: str) -> None: def scrape_all_clusters(dir: str, exclude_list: list[str] = []) -> None: for filename in glob.glob(f'{dir}/*.adoc'): - if os.path.basename(filename) in exclude_list: - continue scrape_cluster(filename) - scrape_all_clusters(sdm_clusters_dir, sdm_exclude_list) - scrape_all_clusters(app_clusters_dir, app_exclude_list) - scrape_all_clusters(media_clusters_dir, media_exclude_list) - for f in dm_clusters_list: - filename = f'{dm_clusters_dir}/{f}' - scrape_cluster(filename) - - -def scrape_device_types(scraper, spec_root, output_dir, dry_run): + scrape_all_clusters(dm_clusters_dir) + scrape_all_clusters(sdm_clusters_dir) + scrape_all_clusters(app_clusters_dir) + scrape_all_clusters(media_clusters_dir) + + for xml_path in glob.glob(f'{clusters_output_dir}/*.xml'): + tree = ElementTree.parse(f'{xml_path}') + root = tree.getroot() + cluster = next(root.iter('cluster')) + # If there's no cluster ID table, this isn't a cluster + try: + next(cluster.iter('clusterIds')) + except StopIteration: + # If there's no cluster ID table, this isn't a cluster just some kind of intro adoc + print(f'Removing file {xml_path} as it does not include any cluster definitions') + os.remove(xml_path) + continue + + +def scrape_device_types(scraper, spec_root, output_dir, dry_run, include_in_progress): device_type_dir = os.path.abspath( os.path.join(spec_root, 'src', 'device_types')) device_types_output_dir = os.path.abspath( @@ -119,9 +152,16 @@ def scrape_device_types(scraper, spec_root, output_dir, dry_run): if not os.path.exists(device_types_output_dir): os.makedirs(device_types_output_dir) + print('Generating device type library to get file include list - this make take a few minutes') + device_type_output = make_asciidoc('pdf-devicelibrary-book', include_in_progress, spec_root, dry_run) + def scrape_device_type(filename: str) -> None: + base = Path(filename).stem + if base not in device_type_output: + print(f'skipping file: {filename} as it is not compiled into the asciidoc') + return xml_path = get_xml_path(filename, device_types_output_dir) - cmd = [scraper, 'devicetype', '-c', clusters_output_dir, + cmd = [scraper, 'devicetype', '-c', '-cls', clusters_output_dir, '-nd', '-i', filename, '-o', xml_path] if dry_run: print(cmd) @@ -187,7 +227,8 @@ def dump_cluster_ids(output_dir): json_file = os.path.join(clusters_output_dir, 'cluster_ids.json') with open(json_file, "w") as outfile: - json.dump(json_dict, outfile, indent=2) + json.dump(json_dict, outfile, indent=4) + outfile.write('\n') if __name__ == '__main__': diff --git a/scripts/tests/run_tv_casting_test.py b/scripts/tests/run_tv_casting_test.py index c2492c5cb8818d..074d4592d59afe 100644 --- a/scripts/tests/run_tv_casting_test.py +++ b/scripts/tests/run_tv_casting_test.py @@ -16,6 +16,7 @@ import logging import os +import re import subprocess import sys import tempfile @@ -31,11 +32,14 @@ TV_APP_MAX_START_WAIT_SEC = 2 # The maximum amount of time to commission the Linux tv-casting-app and the tv-app before timeout. -COMMISSIONING_STAGE_MAX_WAIT_SEC = 10 +COMMISSIONING_STAGE_MAX_WAIT_SEC = 15 # The maximum amount of time to test that the launchURL is sent from the Linux tv-casting-app and received on the tv-app before timeout. TEST_LAUNCHURL_MAX_WAIT_SEC = 10 +# The maximum amount of time to verify the subscription state in the Linux tv-casting-app output before timeout. +VERIFY_SUBSCRIPTION_STATE_MAX_WAIT_SEC = 10 + # File names of logs for the Linux tv-casting-app and the Linux tv-app. LINUX_TV_APP_LOGS = 'Linux-tv-app-logs.txt' LINUX_TV_CASTING_APP_LOGS = 'Linux-tv-casting-app-logs.txt' @@ -46,6 +50,10 @@ PRODUCT_ID = 0x8001 # Test product id DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # Device type library 10.3: Casting Video Player +# Values to verify the subscription state against from the `ReportDataMessage` in the Linux tv-casting-app output. +CLUSTER_MEDIA_PLAYBACK = '0x506' # Application Cluster Spec 6.10.3 Cluster ID: Media Playback +ATTRIBUTE_CURRENT_PLAYBACK_STATE = '0x0000_0000' # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback + class ProcessManager: """A context manager for managing subprocesses. @@ -68,10 +76,30 @@ def __exit__(self, exception_type, exception_value, traceback): self.process.wait() +class LogValueExtractor: + """A utility class for extracting values from log lines. + + This class provides a centralized way to extract values from log lines and manage the error handling and logging process. + """ + + def __init__(self, casting_state: str, log_paths: List[str]): + self.casting_state = casting_state + self.log_paths = log_paths + + def extract_from(self, line: str, value_name: str): + if value_name in line: + try: + return extract_value_from_string(line, value_name, self.casting_state, self.log_paths) + except ValueError: + logging.error(f'Failed to extract `{value_name}` value from line: {line}') + handle_casting_failure(self.casting_state, self.log_paths) + return None + + def dump_temporary_logs_to_console(log_file_path: str): """Dump log file to the console; log file will be removed once the function exits.""" """Write the entire content of `log_file_path` to the console.""" - print('\nDumping logs from: ', log_file_path) + print(f'\nDumping logs from: {log_file_path}') with open(log_file_path, 'r') as file: for line in file: @@ -80,36 +108,74 @@ def dump_temporary_logs_to_console(log_file_path: str): def handle_casting_failure(casting_state: str, log_file_paths: List[str]): """Log '{casting_state} failed!' as error, dump log files to console, exit on error.""" - logging.error(casting_state + ' failed!') + logging.error(f'{casting_state} failed!') for log_file_path in log_file_paths: try: dump_temporary_logs_to_console(log_file_path) except Exception as e: - logging.exception(f"Failed to dump {log_file_path}: {e}") + logging.exception(f'Failed to dump {log_file_path}: {e}') sys.exit(1) -def extract_value_from_string(line: str) -> str: +def extract_value_from_string(line: str, value_name: str, casting_state: str, log_paths) -> str: """Extract and return value from given input string. - The string is expected to be in the following format as it is received - from the Linux tv-casting-app output: - \x1b[0;34m[1713741926895] [7276:9521344] [DIS] Vendor ID: 65521\x1b[0m - The integer value to be extracted here is 65521. - Or: - \x1b[0;34m[1714583616179] [7029:2386956] [SVR] device Name: Test TV casting app\x1b[0m - The substring to be extracted here is 'Test TV casting app'. + Some string examples as they are received from the Linux tv-casting-app and/or tv-app output: + 1. On 'darwin' machines: + \x1b[0;34m[1715206773402] [20056:2842184] [DMG] Cluster = 0x506,\x1b[0m + The substring to be extracted here is '0x506'. + + Or: + \x1b[0;32m[1714582264602] [77989:2286038] [SVR] Discovered Commissioner #0\x1b[0m + The integer value to be extracted here is '0'. + + Or: + \x1b[0;34m[1713741926895] [7276:9521344] [DIS] Vendor ID: 65521\x1b[0m + The integer value to be extracted here is '65521'. + + Or: + \x1b[0;34m[1714583616179] [7029:2386956] [SVR] device Name: Test TV casting app\x1b[0m + The substring to be extracted here is 'Test TV casting app'. + + 2. On 'linux' machines: + [1716224960.316809][6906:6906] CHIP:DMG: \t\t\t\t\tCluster = 0x506,\n + [1716224958.576320][6906:6906] CHIP:SVR: Discovered Commissioner #0 + [1716224958.576407][6906:6906] CHIP:DIS: \tVendor ID: 65521\n + [1716224959.580746][6906:6906] CHIP:SVR: \tdevice Name: Test TV casting app\n """ - value = line.split(':')[-1].strip().replace('\x1b[0m', '') + log_line_pattern = '' + if sys.platform == 'darwin': + log_line_pattern = r'\x1b\[0;\d+m\[\d+\] \[\d+:\d+\] \[[A-Z]{1,3}\] (.+)\x1b\[0m' + elif sys.platform == 'linux': + log_line_pattern = r'\[\d+\.\d+\]\[\d+:\d+\] [A-Z]{1,4}:[A-Z]{1,3}: (.+)' - return value + log_line_match = re.search(log_line_pattern, line) + + if log_line_match: + log_text_of_interest = log_line_match.group(1) + + if '=' in log_text_of_interest: + delimiter = '=' + elif '#' in log_text_of_interest: + delimiter = '#' + else: + delimiter = ':' + + return log_text_of_interest.split(delimiter)[-1].strip(' ,') + else: + raise ValueError(f'Could not extract {value_name} from the following line: {line}') def validate_value(casting_state: str, expected_value: Union[str, int], log_paths: List[str], line: str, value_name: str) -> Optional[str]: """Validate a value in a string against an expected value during a given casting state.""" - value = extract_value_from_string(line) + log_value_extractor = LogValueExtractor(casting_state, log_paths) + value = log_value_extractor.extract_from(line, value_name) + if not value: + logging.error(f'Failed to extract {value_name} value from the following line: {line}') + logging.error(f'Failed to validate against the expected {value_name} value: {expected_value}!') + handle_casting_failure(casting_state, log_paths) if isinstance(expected_value, int): value = int(value) @@ -154,8 +220,8 @@ def initiate_cast_request_success(tv_casting_app_info: Tuple[subprocess.Popen, T while True: # Check if we exceeded the maximum wait time for initiating 'cast request' from the Linux tv-casting-app to the Linux tv-app. if time.time() - start_wait_time > COMMISSIONING_STAGE_MAX_WAIT_SEC: - logging.error('The command `cast request ' + valid_discovered_commissioner_number + - '` was not issued to the Linux tv-casting-app process within the timeout.') + logging.error( + f'The command `cast request {valid_discovered_commissioner_number}` was not issued to the Linux tv-casting-app process within the timeout.') return False tv_casting_app_output_line = tv_casting_app_process.stdout.readline() @@ -170,13 +236,16 @@ def initiate_cast_request_success(tv_casting_app_info: Tuple[subprocess.Popen, T next_line = tv_casting_app_process.stdout.readline() linux_tv_casting_app_log_file.write(next_line) linux_tv_casting_app_log_file.flush() - logging.info('Sent `' + next_line.rstrip('\n') + '` to the Linux tv-casting-app process.') + next_line = next_line.rstrip('\n') + logging.info(f'Sent `{next_line}` to the Linux tv-casting-app process.') + return True -def extract_device_info_from_tv_casting_app(tv_casting_app_info: Tuple[subprocess.Popen, TextIO]) -> Tuple[Optional[str], Optional[int], Optional[int]]: +def extract_device_info_from_tv_casting_app(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], casting_state: str, log_paths: List[str]) -> Tuple[Optional[str], Optional[int], Optional[int]]: """Extract device information from the 'Identification Declaration' block in the Linux tv-casting-app output.""" tv_casting_app_process, linux_tv_casting_app_log_file = tv_casting_app_info + log_value_extractor = LogValueExtractor(casting_state, log_paths) device_name = None vendor_id = None @@ -186,14 +255,12 @@ def extract_device_info_from_tv_casting_app(tv_casting_app_info: Tuple[subproces linux_tv_casting_app_log_file.write(line) linux_tv_casting_app_log_file.flush() - if 'device Name' in line: - device_name = extract_value_from_string(line) - elif 'vendor id' in line: - vendor_id = extract_value_from_string(line) - vendor_id = int(vendor_id) - elif 'product id' in line: - product_id = extract_value_from_string(line) - product_id = int(product_id) + if value := log_value_extractor.extract_from(line, 'device Name'): + device_name = value + elif value := log_value_extractor.extract_from(line, 'vendor id'): + vendor_id = int(value) + elif value := log_value_extractor.extract_from(line, 'product id'): + product_id = int(value) if device_name and vendor_id and product_id: break @@ -211,7 +278,8 @@ def validate_identification_declaration_message_on_tv_app(tv_app_info: Tuple[sub while True: # Check if we exceeded the maximum wait time for validating the device information from the Linux tv-app to the corresponding values from the Linux tv-app. if time.time() - start_wait_time > COMMISSIONING_STAGE_MAX_WAIT_SEC: - logging.erro('The device information from the Linux tv-app output was not validated against the corresponding values from the Linux tv-casting-app output within the timeout.') + logging.error( + 'The device information from the Linux tv-app output was not validated against the corresponding values from the Linux tv-casting-app output within the timeout.') return False tv_app_line = tv_app_process.stdout.readline() @@ -221,7 +289,7 @@ def validate_identification_declaration_message_on_tv_app(tv_app_info: Tuple[sub linux_tv_app_log_file.flush() if 'Identification Declaration Start' in tv_app_line: - logging.info('"Identification Declaration" block from the Linux tv-app output:') + logging.info('Found the `Identification Declaration` block in the Linux tv-app output:') logging.info(tv_app_line.rstrip('\n')) parsing_identification_block = True elif parsing_identification_block: @@ -266,8 +334,8 @@ def validate_tv_casting_request_approval(tv_app_info: Tuple[subprocess.Popen, Te tv_app_line = tv_app_process.stdout.readline() linux_tv_app_log_file.write(tv_app_line) linux_tv_app_log_file.flush() - - logging.info('Sent `' + tv_app_line.rstrip('\n') + '` to the Linux tv-app process.') + tv_app_line = tv_app_line.rstrip('\n') + logging.info(f'Sent `{tv_app_line}` to the Linux tv-app process.') return True @@ -310,6 +378,55 @@ def validate_commissioning_success(tv_casting_app_info: Tuple[subprocess.Popen, return True +def parse_tv_casting_app_for_report_data_msg(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], log_paths: List[str]): + """Parse the Linux tv-casting-app for `ReportDataMessage` block and return the first message block with valid `Cluster` and `Attribute` values.""" + tv_casting_app_process, linux_tv_casting_app_log_file = tv_casting_app_info + log_value_extractor = LogValueExtractor('Testing subscription', log_paths) + + continue_parsing = False + report_data_message = [] + + start_wait_time = time.time() + + while True: + # Check if we exceeded the maximum wait time to parse the Linux tv-casting-app output for `ReportDataMessage` block. + if time.time() - start_wait_time > VERIFY_SUBSCRIPTION_STATE_MAX_WAIT_SEC: + logging.error( + 'The relevant `ReportDataMessage` block for the MediaPlayback:CurrentState subscription was not found in the Linux tv-casting-app process within the timeout.') + report_data_message.clear() + return report_data_message + + tv_casting_line = tv_casting_app_process.stdout.readline() + + if tv_casting_line: + linux_tv_casting_app_log_file.write(tv_casting_line) + linux_tv_casting_app_log_file.flush() + + if 'ReportDataMessage =' in tv_casting_line: + report_data_message.append(tv_casting_line.rstrip('\n')) + continue_parsing = True + elif continue_parsing: + report_data_message.append(tv_casting_line.rstrip('\n')) + + if cluster_value := log_value_extractor.extract_from(tv_casting_line, 'Cluster ='): + if cluster_value != CLUSTER_MEDIA_PLAYBACK: + report_data_message.clear() + continue_parsing = False + + elif attribute_value := log_value_extractor.extract_from(tv_casting_line, 'Attribute ='): + if attribute_value != ATTRIBUTE_CURRENT_PLAYBACK_STATE: + report_data_message.clear() + continue_parsing = False + + elif 'InteractionModelRevision' in tv_casting_line: + # Capture the closing brace `}` of the `ReportDataMessage` block. + tv_casting_line = tv_casting_app_process.stdout.readline() + linux_tv_casting_app_log_file.write(tv_casting_line) + linux_tv_casting_app_log_file.flush() + report_data_message.append(tv_casting_line.rstrip('\n')) + return report_data_message + + def parse_tv_app_output_for_launchUrl_msg_success(tv_app_info: Tuple[subprocess.Popen, TextIO], log_paths: List[str]): """Parse the Linux tv-app output for the relevant string indicating that the launchUrl was received.""" @@ -359,7 +476,7 @@ def parse_tv_casting_app_output_for_launchUrl_msg_success(tv_casting_app_info: T linux_tv_casting_app_log_file.flush() if 'InvokeResponseMessage =' in tv_casting_line: - logging.info('Found the InvokeResponseMessage block in the Linux tv-casting-app output:') + logging.info('Found the `InvokeResponseMessage` block in the Linux tv-casting-app output:') logging.info(tv_casting_line.rstrip('\n')) continue_parsing_invoke_response_msg_block = True @@ -395,11 +512,11 @@ def test_discovery_fn(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], log_ linux_tv_casting_app_log_file.flush() # Fail fast if "No commissioner discovered" string found. - if "No commissioner discovered" in line: + if 'No commissioner discovered' in line: logging.error(line.rstrip('\n')) handle_casting_failure('Discovery', log_paths) - elif "Discovered Commissioner" in line: + elif 'Discovered Commissioner' in line: valid_discovered_commissioner = line.rstrip('\n') elif valid_discovered_commissioner: @@ -415,7 +532,7 @@ def test_discovery_fn(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], log_ # A valid commissioner has VENDOR_ID, PRODUCT_ID, and DEVICE TYPE in its list of entries. if valid_vendor_id and valid_product_id and valid_device_type: - logging.info('Found a valid commissioner in the Linux tv-casting-app logs:') + logging.info('Found a valid commissioner in the Linux tv-casting-app output:') logging.info(valid_discovered_commissioner) logging.info(valid_vendor_id) logging.info(valid_product_id) @@ -433,7 +550,14 @@ def test_commissioning_fn(valid_discovered_commissioner_number, tv_casting_app_i handle_casting_failure('Commissioning', log_paths) # Extract the values from the 'Identification Declaration' block in the tv-casting-app output that we want to validate against. - expected_device_name, expected_vendor_id, expected_product_id = extract_device_info_from_tv_casting_app(tv_casting_app_info) + expected_device_name, expected_vendor_id, expected_product_id = extract_device_info_from_tv_casting_app( + tv_casting_app_info, 'Commissioning', log_paths) + + if not expected_device_name or not expected_vendor_id or not expected_product_id: + logging.error('There is an error with the expected device info values that were extracted from the `Identification Declaration` block.') + logging.error( + f'expected_device_name: {expected_device_name}, expected_vendor_id: {expected_vendor_id}, expected_product_id: {expected_product_id}') + handle_casting_failure('Commissioning', log_paths) if not validate_identification_declaration_message_on_tv_app(tv_app_info, expected_device_name, expected_vendor_id, expected_product_id, log_paths): handle_casting_failure('Commissioning', log_paths) @@ -445,6 +569,23 @@ def test_commissioning_fn(valid_discovered_commissioner_number, tv_casting_app_i handle_casting_failure('Commissioning', log_paths) +def test_subscription_fn(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], log_paths: List[str]): + """Test the subscription state of the Linux tv-casting-app by validating the `ReportDataMessage` block.""" + + valid_report_data_msg = parse_tv_casting_app_for_report_data_msg(tv_casting_app_info, log_paths) + + if valid_report_data_msg: + logging.info('Found the `ReportDataMessage` block in the Linux tv-casting-app output:') + + for line in valid_report_data_msg: + logging.info(line) + + logging.info('Testing subscription success!\n') + valid_report_data_msg.clear() + else: + handle_casting_failure('Testing subscription', log_paths) + + def test_launchUrl_fn(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], tv_app_info: Tuple[subprocess.Popen, TextIO], log_paths: List[str]): """Test that the Linux tv-casting-app sent the launchUrl and that the Linux tv-app received the launchUrl.""" @@ -454,7 +595,7 @@ def test_launchUrl_fn(tv_casting_app_info: Tuple[subprocess.Popen, TextIO], tv_a if not parse_tv_casting_app_output_for_launchUrl_msg_success(tv_casting_app_info, log_paths): handle_casting_failure('Testing launchUrl', log_paths) - logging.info('Testing launchUrl success!\n') + logging.info('Testing launchUrl success!') @click.command() @@ -499,12 +640,15 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path): handle_casting_failure('Discovery', log_paths) # We need the valid discovered commissioner number to continue with commissioning. - # Example string: \x1b[0;32m[1714582264602] [77989:2286038] [SVR] Discovered Commissioner #0\x1b[0m - # The value '0' will be extracted from the string. - valid_discovered_commissioner_number = valid_discovered_commissioner.split('#')[-1].replace('\x1b[0m', '') + log_value_extractor = LogValueExtractor('Commissioning', log_paths) + valid_discovered_commissioner_number = log_value_extractor.extract_from( + valid_discovered_commissioner, 'Discovered Commissioner #') + if not valid_discovered_commissioner_number: + logging.error(f'Failed to find `Discovered Commissioner #` in line: {valid_discovered_commissioner}') + handle_casting_failure('Commissioning', log_paths) test_commissioning_fn(valid_discovered_commissioner_number, tv_casting_app_info, tv_app_info, log_paths) - + test_subscription_fn(tv_casting_app_info, log_paths) test_launchUrl_fn(tv_casting_app_info, tv_app_info, log_paths) diff --git a/scripts/tools/bouffalolab/factory_qrcode.py b/scripts/tools/bouffalolab/factory_qrcode.py index 1a7f6303495775..0e12d8349d4c91 100644 --- a/scripts/tools/bouffalolab/factory_qrcode.py +++ b/scripts/tools/bouffalolab/factory_qrcode.py @@ -20,13 +20,13 @@ try: import qrcode - from generate_setup_payload import CommissioningFlow, SetupPayload + from SetupPayload import CommissioningFlow, SetupPayload except ImportError: SDK_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) sys.path.append(os.path.join(SDK_ROOT, "src/setup_payload/python")) try: import qrcode - from generate_setup_payload import CommissioningFlow, SetupPayload + from SetupPayload import CommissioningFlow, SetupPayload except ModuleNotFoundError or ImportError: no_onboarding_modules = True else: diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index 262be540a9bfed..eab2ec6b43c229 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -30,7 +30,7 @@ sys.path.insert(0, os.path.join(CHIP_TOPDIR, 'scripts', 'tools', 'spake2p')) from spake2p import generate_verifier # noqa: E402 isort:skip sys.path.insert(0, os.path.join(CHIP_TOPDIR, 'src', 'setup_payload', 'python')) -from generate_setup_payload import CommissioningFlow, SetupPayload # noqa: E402 isort:skip +from SetupPayload import CommissioningFlow, SetupPayload # noqa: E402 isort:skip if os.getenv('IDF_PATH'): sys.path.insert(0, os.path.join(os.getenv('IDF_PATH'), diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh index 5d467b4b48c23e..f761eea3843fe8 100755 --- a/scripts/tools/linux_ip_namespace_setup.sh +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -124,7 +124,7 @@ function help() { echo "sudo /$file_name -r /" echo "" echo "Terminal 2:" - echo "/chip-device-ctrl" + echo "/chip-repl" echo "" echo "This script requires sudo for setup and requires access to ebtables-legacy" echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." diff --git a/scripts/tools/memory/gh_report.py b/scripts/tools/memory/gh_report.py index ba30cdec4b12b9..22d35e76375aa1 100755 --- a/scripts/tools/memory/gh_report.py +++ b/scripts/tools/memory/gh_report.py @@ -276,6 +276,10 @@ def report_matching_commits(self) -> Dict[str, pd.DataFrame]: continue df = pd.DataFrame(changes.rows, columns=changes.columns) + + # Filter down to region reports only. + df = df[df['kind'] == 'region'].drop('kind', axis=1) + df.attrs = { 'name': f'{pr},{parent},{commit}', 'title': (f'PR #{pr}: ' if pr else '') + @@ -316,9 +320,6 @@ def format(config: Config, df: pd.DataFrame): threshold_df = df[df['% change'] > threshold] if threshold_df.empty: threshold_df = None - decrease_df = df[df['change'] < 0] - if decrease_df.empty: - decrease_df = None with io.StringIO() as md: md.write(df.attrs['title']) @@ -329,22 +330,6 @@ def format(config: Config, df: pd.DataFrame): md.write('\n\n') V1Comment.write_df(config, threshold_df, md) - if increase_df is not None: - summary = V1Comment.summary(increase_df) - md.write('
    \n') - md.write(f'Increases ({summary})\n') - md.write('\n\n') - V1Comment.write_df(config, increase_df, md) - md.write('
    \n\n') - - if decrease_df is not None: - summary = V1Comment.summary(decrease_df) - md.write('
    \n') - md.write(f'Decreases ({summary})\n') - md.write('\n\n') - V1Comment.write_df(config, decrease_df, md) - md.write('
    \n\n') - summary = V1Comment.summary(df) md.write('
    \n') md.write(f'Full report ({summary})\n') diff --git a/scripts/tools/memory/gh_sizes.py b/scripts/tools/memory/gh_sizes.py index 9decc178e15d45..012d5904517147 100755 --- a/scripts/tools/memory/gh_sizes.py +++ b/scripts/tools/memory/gh_sizes.py @@ -58,9 +58,9 @@ {"section": ".data", "size": 1648}, {"section": ".text", "size": 740236} ], - "wr": [ - {"wr": 0, "size": 262144}, - {"wr": 1, "size": 74023} + "region": [ + {"region": "FLASH", "size": 262144}, + {"region": "RAM", "size": 74023} ] } } @@ -77,8 +77,7 @@ import memdf.report import memdf.select import memdf.util -import numpy as np # type: ignore -from memdf import Config, ConfigDescription, DFs, SectionDF, SegmentDF +from memdf import Config, ConfigDescription, DFs, SectionDF PLATFORM_CONFIG_DIR = pathlib.Path('scripts/tools/memory/platform') @@ -162,7 +161,8 @@ def main(argv): **CONFIG, } # In case there is no platform configuration file, default to using a popular set of section names. - config_desc['section.select']['default'] = ['.text', '.rodata', '.data', '.bss'] + config_desc['section.select']['default'] = [ + '.text', '.rodata', '.data', '.bss'] config = Config().init(config_desc) config.put('output.file', output) @@ -183,31 +183,32 @@ def main(argv): if value := config[key]: config.putl(['output', 'metadata', key], value) - collected: DFs = memdf.collect.collect_files(config, [binary]) + # In case there is no platform configuration file or it does not define regions, + # try to find reasonable groups. + if not config.get('region.sections'): + sections = {'FLASH': [], 'RAM': []} + for section in config.get('section.select'): + print('section:', section) + for substring, region in [('text', 'FLASH'), ('rodata', 'FLASH'), ('data', 'RAM'), ('bss', 'RAM')]: + if substring in section: + sections[region].append(section) + break + config.put('region.sections', sections) - # Aggregate loaded segments, by writable (RAM) or not (flash). - segments = collected[SegmentDF.name] - segments['segment'] = segments.index - segments['wr'] = ((segments['flags'] & 2) != 0).convert_dtypes( - convert_boolean=False, convert_integer=True) - segment_summary = segments[segments['type'] == 'PT_LOAD'][[ - 'wr', 'size' - ]].groupby('wr').aggregate(np.sum).reset_index().astype( - {'size': np.int64}) - segment_summary.attrs['name'] = "wr" + collected: DFs = memdf.collect.collect_files(config, [binary]) sections = collected[SectionDF.name] - sections = sections.join(on='segment', - how='left', - other=segments, - rsuffix='-segment') - section_summary = sections[['section', 'size', - 'wr']].sort_values(by='section') + section_summary = sections[['section', + 'size']].sort_values(by='section') section_summary.attrs['name'] = "section" + region_summary = memdf.select.groupby( + config, collected['section'], 'region') + region_summary.attrs['name'] = "region" + summaries = { 'section': section_summary, - 'memory': segment_summary, + 'region': region_summary, } # Write configured (json) report to the output file. diff --git a/scripts/tools/memory/memdf/sizedb.py b/scripts/tools/memory/memdf/sizedb.py index a0704b41cd7abf..12289694e3dc2b 100644 --- a/scripts/tools/memory/memdf/sizedb.py +++ b/scripts/tools/memory/memdf/sizedb.py @@ -61,11 +61,12 @@ class SizeDatabase(memdf.util.sqlite.Database): UNIQUE(thing_id, hash, parent, pr, time, artifact) ) """, """ - -- A ‘size’ entry gives the size of a section for a particular build. + -- A ‘size’ entry gives the size of an area for a particular build. CREATE TABLE IF NOT EXISTS size ( build_id INTEGER REFERENCES build(id), - name TEXT NOT NULL, -- Section name - size INTEGER NOT NULL, -- Section size in bytes + kind TEXT NOT NULL, -- Area kind + name TEXT NOT NULL, -- Area name + size INTEGER NOT NULL, -- Size in bytes PRIMARY KEY (build_id, name) ) """ @@ -100,16 +101,14 @@ def add_sizes_from_json(self, s: Union[bytes, str], origin: Dict): r = origin.copy() r.update(json.loads(s)) r['sizes'] = [] - # Add section sizes. - for i in r['frames'].get('section', []): - r['sizes'].append({'name': i['section'], 'size': i['size']}) - # Add segment sizes. - for i in r['frames'].get('wr', []): - r['sizes'].append({ - 'name': ('(read only)', '(read/write)')[int(i['wr'])], - 'size': - i['size'] - }) + # Add section and region sizes. + for frame in ['section', 'region']: + for i in r['frames'].get(frame, []): + r['sizes'].append({ + 'name': i[frame], + 'size': i['size'], + 'kind': frame + }) self.add_sizes(**r) def add_sizes_from_zipfile(self, f: Union[IO, Path], origin: Dict): @@ -176,6 +175,7 @@ def select_changes(self, parent: str, commit: str) -> ChangeInfo: pb.id AS parent_build, cb.id AS commit_build, t.platform, t.config, t.target, + cs.kind AS kind, cs.name AS name, ps.size AS parent_size, cs.size AS commit_size, @@ -190,7 +190,7 @@ def select_changes(self, parent: str, commit: str) -> ChangeInfo: cs.name, cb.time DESC, pb.time DESC ''', (commit, parent)) - keep = ('platform', 'target', 'config', 'name', 'parent_size', + keep = ('platform', 'target', 'config', 'kind', 'name', 'parent_size', 'commit_size') things: set[int] = set() artifacts: set[int] = set() @@ -223,7 +223,7 @@ def select_changes(self, parent: str, commit: str) -> ChangeInfo: artifacts.add(row['artifact']) builds.add(row['commit_build']) - return ChangeInfo(('platform', 'target', 'config', 'section', + return ChangeInfo(('platform', 'target', 'config', 'kind', 'section', parent[:8], commit[:8], 'change', '% change'), rows, things, builds, stale_builds, artifacts, stale_artifacts) diff --git a/scripts/tools/memory/platform/bl602.cfg b/scripts/tools/memory/platform/bl602.cfg index 1370bfcf5f777c..4603d6e5176d72 100644 --- a/scripts/tools/memory/platform/bl602.cfg +++ b/scripts/tools/memory/platform/bl602.cfg @@ -30,11 +30,17 @@ # 'end': [], # } # }, - # 'region': { - # # Regions are sets of sections that can be used for aggregate reports. - # 'sections': { - # 'FLASH': [], - # 'RAM': [] - # } - # }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + '.text', + '.rodata', + ], + 'RAM': [ + '.bss', + '.data', + ], + } + }, } diff --git a/scripts/tools/memory/platform/mbed.cfg b/scripts/tools/memory/platform/mbed.cfg index ca5d43d692eb7f..9c525ee1d469ab 100644 --- a/scripts/tools/memory/platform/mbed.cfg +++ b/scripts/tools/memory/platform/mbed.cfg @@ -30,13 +30,17 @@ # 'end': [], # } # }, -# 'region': { -# # Regions are sets of sections that can be used for aggregate reports. -# 'sections': { -# 'FLASH': [ -# ], -# 'RAM': [ -# ] -# } -# }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + '.text', + '.rodata', + ], + 'RAM': [ + '.bss', + '.data', + ], + } + }, } diff --git a/scripts/tools/memory/platform/openiotsdk.cfg b/scripts/tools/memory/platform/openiotsdk.cfg index 4717f1278044dd..37426161d667d4 100644 --- a/scripts/tools/memory/platform/openiotsdk.cfg +++ b/scripts/tools/memory/platform/openiotsdk.cfg @@ -20,4 +20,17 @@ # when operating by sections. 'default': ['.text', '.data', '.bss', '.stack', '.heap'], }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + '.text', + '.rodata', + ], + 'RAM': [ + '.bss', + '.data', + ], + } + }, } diff --git a/scripts/tools/memory/platform/p6.cfg b/scripts/tools/memory/platform/p6.cfg index d1870ee8e1fb79..7b6184d378e4f6 100644 --- a/scripts/tools/memory/platform/p6.cfg +++ b/scripts/tools/memory/platform/p6.cfg @@ -30,13 +30,17 @@ # 'end': [], # } # }, -# 'region': { -# # Regions are sets of sections that can be used for aggregate reports. -# 'sections': { -# 'FLASH': [ -# ], -# 'RAM': [ -# ] -# } -# }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + '.text', + '.rodata', + ], + 'RAM': [ + '.bss', + '.data', + ], + } + }, } diff --git a/scripts/tools/memory/platform/telink.cfg b/scripts/tools/memory/platform/telink.cfg index 4db7fcd95fc201..ca0d54b77fd4ce 100644 --- a/scripts/tools/memory/platform/telink.cfg +++ b/scripts/tools/memory/platform/telink.cfg @@ -30,13 +30,19 @@ # 'end': [], # } # }, -# 'region': { -# # Regions are sets of sections that can be used for aggregate reports. -# 'sections': { -# 'FLASH': [ -# ], -# 'RAM': [ -# ] -# } -# }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + 'text', + 'rodata', + ], + 'RAM': [ + 'bss', + 'data', + 'noinit', + 'ram_code', + ], + } + }, } diff --git a/scripts/tools/memory/platform/tizen.cfg b/scripts/tools/memory/platform/tizen.cfg new file mode 100644 index 00000000000000..294bf21386de3e --- /dev/null +++ b/scripts/tools/memory/platform/tizen.cfg @@ -0,0 +1,67 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Memory tools default configuation for Tizen. + +{ + 'section': { + # By default, only these sections will be included + # when operating by sections. + 'default': [ + '.text', '.data', '.data.rel.ro', '.bss', '.dynamic', '.got', + '.init', '.init_array', '.rodata' + ] + }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + ".dynstr", + ".dynsym", + ".eh_frame_hdr", + ".eh_frame", + ".fini", + ".gcc_except_table", + ".gnu.version_d", + ".gnu.version_r", + ".gnu.version", + ".hash", + ".init", + ".interp", + ".note.ABI-tag", + ".rodata1", + ".rodata", + ".strtab", + ".symtab", + ".text", + ], + 'RAM': [ + ".bss", + ".ctors", + ".data1", + ".data.rel.ro", + ".data", + ".dtors", + ".dynamic", + ".fini_array", + ".got.plt", + ".init_array", + ".jcr", + ".preinit_array", + ".tbss", + ".tdata", + ] + } + }, +} diff --git a/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py b/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py index 78212cefd81e6e..c2fea381fefc9a 100644 --- a/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py +++ b/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py @@ -32,13 +32,13 @@ try: import qrcode - from generate_setup_payload import CommissioningFlow, SetupPayload + from SetupPayload import CommissioningFlow, SetupPayload except ImportError: SDK_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) sys.path.append(os.path.join(SDK_ROOT, "src/setup_payload/python")) try: import qrcode - from generate_setup_payload import CommissioningFlow, SetupPayload + from SetupPayload import CommissioningFlow, SetupPayload except ModuleNotFoundError or ImportError: no_onboarding_modules = True else: @@ -433,7 +433,7 @@ def _generate_onboarding_data(self): def main(): - parser = argparse.ArgumentParser(description="NrfConnect Factory Data NVS generator tool") + parser = argparse.ArgumentParser(description="nRF Connect Factory Data generator tool") def allow_any_int(i): return int(i, 0) def base64_str(s): return base64.b64decode(s) @@ -564,20 +564,20 @@ def base64_str(s): return base64.b64decode(s) if (exists(args.output + ".json") and not args.overwrite): log.error(("Output file: {} already exist, to create a new one add argument '--overwrite'. " "By default overwriting is disabled").format(args.output+".json")) - return + sys.exit(1) if args.schema and no_jsonschema_module: log.error(("Requested verification of the JSON file using jsonschema, but the module is not installed. \n" "Install only the module by invoking: pip3 install jsonschema \n" "Alternatively, install it with all dependencies for Matter by invoking: pip3 install " "-r ./scripts/setup/requirements.nrfconnect.txt from the Matter root directory.")) - return + sys.exit(1) if args.generate_onboarding and no_onboarding_modules: log.error(("Requested generation of onboarding codes, but the some modules are not installed. \n" "Install all dependencies for Matter by invoking: pip3 install " "-r ./scripts/setup/requirements.nrfconnect.txt from the Matter root directory.")) - return + sys.exit(1) generator = FactoryDataGenerator(args) generator.generate_json() diff --git a/src/BUILD.gn b/src/BUILD.gn index cf15f40ec00629..d455a596b4e346 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -96,11 +96,11 @@ if (chip_build_tests) { if (chip_device_platform != "efr32") { tests += [ "${chip_root}/src/app/tests", + "${chip_root}/src/app/tests:tests_nltest", "${chip_root}/src/credentials/tests", "${chip_root}/src/lib/format/tests", "${chip_root}/src/lib/support/tests", "${chip_root}/src/protocols/secure_channel/tests", - "${chip_root}/src/protocols/secure_channel/tests:tests_nltest", "${chip_root}/src/system/tests", "${chip_root}/src/transport/tests", ] diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 0eb7e1456e02e0..f49a40f398842a 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -179,9 +179,6 @@ static_library("interaction-model") { "ReadClient.h", # TODO: cpp is only included conditionally. Needs logic # fixing "ReadPrepareParams.h", - "RequiredPrivilege.h", - "StatusResponse.cpp", - "StatusResponse.h", "SubscriptionResumptionStorage.h", "TimedHandler.cpp", "TimedHandler.h", @@ -210,6 +207,7 @@ static_library("interaction-model") { public_deps = [ ":app_config", + ":command-handler", ":constants", ":paths", ":subscription-info-provider", @@ -248,8 +246,6 @@ static_library("interaction-model") { "dynamic_server/AccessControl.cpp", "dynamic_server/AccessControl.h", "dynamic_server/DynamicDispatcher.cpp", - "util/privilege-storage.cpp", - "util/privilege-storage.h", ] public_deps += [ @@ -301,6 +297,62 @@ static_library("attribute-access") { ] } +source_set("required-privileges") { + sources = [ "RequiredPrivilege.h" ] + + public_deps = [ + ":paths", + "${chip_root}/src/access:types", + ] + + if (chip_build_controller_dynamic_server) { + sources += [ + "util/privilege-storage.cpp", + "util/privilege-storage.h", + ] + + public_deps += [ + ":global-attributes", + "${chip_root}/src/access", + "${chip_root}/src/app/dynamic_server:mock-codegen-includes", + ] + + public_configs = [ ":config-controller-dynamic-server" ] + } +} + +source_set("status-response") { + sources = [ + "StatusResponse.cpp", + "StatusResponse.h", + ] + public_deps = [ + ":constants", + "${chip_root}/src/app/MessageDef", + "${chip_root}/src/messaging", + ] +} + +source_set("command-handler") { + sources = [ + "CommandHandler.cpp", + "CommandHandler.h", + "CommandHandlerExchangeInterface.h", + ] + + public_deps = [ + ":paths", + ":required-privileges", + ":status-response", + "${chip_root}/src/access:types", + "${chip_root}/src/app/MessageDef", + "${chip_root}/src/app/data-model", + "${chip_root}/src/app/util:callbacks", + "${chip_root}/src/lib/support", + "${chip_root}/src/messaging", + ] +} + # Note to developpers, instead of continuously adding files in the app librabry, it is recommand to create smaller source_sets that app can depend on. # This way, we can have a better understanding of dependencies and other componenets can depend on the different source_sets without needing to depend on the entire app library. static_library("app") { @@ -312,8 +364,6 @@ static_library("app") { "AttributePersistenceProvider.h", "ChunkedWriteCallback.cpp", "ChunkedWriteCallback.h", - "CommandHandler.cpp", - "CommandHandlerExchangeInterface.h", "CommandResponseHelper.h", "CommandResponseSender.cpp", "DefaultAttributePersistenceProvider.cpp", @@ -325,6 +375,8 @@ static_library("app") { "EventManagement.h", "FailSafeContext.cpp", "FailSafeContext.h", + "GenericEventManagementTestEventTriggerHandler.cpp", + "GenericEventManagementTestEventTriggerHandler.h", "OTAUserConsentCommon.h", "ReadHandler.cpp", "SafeAttributePersistenceProvider.h", @@ -336,7 +388,6 @@ static_library("app") { # (app depending on im and im including these headers): # Name with _ so that linter does not recognize it # "CommandResponseSender._h" - # "CommandHandler._h" # "ReadHandler._h", # "WriteHandler._h" ] diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp index 162ae7021a9f9f..dc2656338d791a 100644 --- a/src/app/CASESessionManager.cpp +++ b/src/app/CASESessionManager.cpp @@ -29,6 +29,11 @@ CHIP_ERROR CASESessionManager::Init(chip::System::Layer * systemLayer, const CAS return AddressResolve::Resolver::Instance().Init(systemLayer); } +void CASESessionManager::Shutdown() +{ + AddressResolve::Resolver::Instance().Shutdown(); +} + void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, Callback::Callback * onFailure, #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES diff --git a/src/app/CASESessionManager.h b/src/app/CASESessionManager.h index 38b39108b43b7e..e536a62cf80908 100644 --- a/src/app/CASESessionManager.h +++ b/src/app/CASESessionManager.h @@ -59,7 +59,7 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess } CHIP_ERROR Init(chip::System::Layer * systemLayer, const CASESessionManagerConfig & params); - void Shutdown() {} + void Shutdown(); /** * Find an existing session for the given node ID, or trigger a new session diff --git a/src/app/CommandHandler.cpp b/src/app/CommandHandler.cpp index 89ff52f9669d2e..309685491a8d82 100644 --- a/src/app/CommandHandler.cpp +++ b/src/app/CommandHandler.cpp @@ -15,21 +15,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * @file - * This file defines object for a CHIP IM Invoke Command Handler - * - */ - -#include "CommandHandler.h" -#include "InteractionModelEngine.h" -#include "RequiredPrivilege.h" -#include "messaging/ExchangeContext.h" +#include #include #include #include +#include #include #include #include @@ -37,6 +28,7 @@ #include #include #include +#include #include #include @@ -121,6 +113,26 @@ Status CommandHandler::OnInvokeCommandRequest(CommandHandlerExchangeInterface & return status; } +CHIP_ERROR CommandHandler::TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId, + DataModel::EncodableToTLV & aEncodable) +{ + ConcreteCommandPath responseCommandPath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, + aResponseCommandId }; + + InvokeResponseParameters prepareParams(aRequestCommandPath); + prepareParams.SetStartOrEndDataStruct(false); + + { + ScopedChange internalCallToAddResponse(mInternalCallToAddResponseData, true); + ReturnErrorOnFailure(PrepareInvokeResponseCommand(responseCommandPath, prepareParams)); + } + + TLV::TLVWriter * writer = GetCommandDataIBTLVWriter(); + VerifyOrReturnError(writer != nullptr, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(aEncodable.EncodeTo(*writer, TLV::ContextTag(CommandDataIB::Tag::kFields))); + return FinishCommand(/* aEndDataStruct = */ false); +} + CHIP_ERROR CommandHandler::ValidateInvokeRequestMessageAndBuildRegistry(InvokeRequestMessage::Parser & invokeRequestMessage) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -944,7 +956,8 @@ CHIP_ERROR TestOnlyExtractCommandPathFromNextInvokeRequest(TLV::TLVReader & invo case CommandHandler::NlFaultInjectionType::SkipSecondResponse: return "Single InvokeResponseMessages. Dropping response to second request"; } - VerifyOrDieWithMsg(false, DataManagement, "TH Failure: Unexpected fault type"); + ChipLogError(DataManagement, "TH Failure: Unexpected fault type"); + chipAbort(); } } // anonymous namespace diff --git a/src/app/CommandHandler.h b/src/app/CommandHandler.h index cce19879a6c8a9..ae41ec1fe350fb 100644 --- a/src/app/CommandHandler.h +++ b/src/app/CommandHandler.h @@ -30,10 +30,10 @@ #pragma once -#include "CommandPathRegistry.h" - #include +#include #include +#include #include #include #include @@ -242,7 +242,7 @@ class CommandHandler * Adds the given command status and returns any failures in adding statuses (e.g. out * of buffer space) to the caller */ - CHIP_ERROR FallibleAddStatus(const ConcreteCommandPath & aCommandPath, const Protocols::InteractionModel::Status aStatus, + CHIP_ERROR FallibleAddStatus(const ConcreteCommandPath & aRequestCommandPath, const Protocols::InteractionModel::Status aStatus, const char * context = nullptr); /** @@ -252,9 +252,9 @@ class CommandHandler void AddStatus(const ConcreteCommandPath & aCommandPath, const Protocols::InteractionModel::Status aStatus, const char * context = nullptr); - CHIP_ERROR AddClusterSpecificSuccess(const ConcreteCommandPath & aCommandPath, ClusterStatus aClusterStatus); + CHIP_ERROR AddClusterSpecificSuccess(const ConcreteCommandPath & aRequestCommandPath, ClusterStatus aClusterStatus); - CHIP_ERROR AddClusterSpecificFailure(const ConcreteCommandPath & aCommandPath, ClusterStatus aClusterStatus); + CHIP_ERROR AddClusterSpecificFailure(const ConcreteCommandPath & aRequestCommandPath, ClusterStatus aClusterStatus); /** * This adds a new CommandDataIB element into InvokeResponses for the associated @@ -328,11 +328,31 @@ class CommandHandler */ template CHIP_ERROR AddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) + { + DataModel::EncodableType encoder(aData); + return AddResponseData(aRequestCommandPath, CommandData::GetCommandId(), encoder); + } + + /** + * API for adding a data response. The `aEncodable` is generally expected to encode + * a ClusterName::Commands::CommandName::Type struct, however any object should work. + * + * @param [in] aRequestCommandPath the concrete path of the command we are + * responding to. + * @param [in] aResponseCommandId the command whose content is being encoded. + * @param [in] aEncodable - an encodable that places the command data structure + * for `aResponseCommandId` into a TLV Writer. + * + * Most applications are likely to use `AddResponseData` as a more convenient + * one-call that auto-sets command ID and creates the underlying encoders. + */ + CHIP_ERROR AddResponseData(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId, + DataModel::EncodableToTLV & aEncodable) { // Return early when response should not be sent out. VerifyOrReturnValue(ResponsesAccepted(), CHIP_NO_ERROR); - - return TryAddingResponse([&]() -> CHIP_ERROR { return TryAddResponseData(aRequestCommandPath, aData); }); + return TryAddingResponse( + [&]() -> CHIP_ERROR { return TryAddResponseData(aRequestCommandPath, aResponseCommandId, aEncodable); }); } /** @@ -352,7 +372,20 @@ class CommandHandler template void AddResponse(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) { - if (AddResponseData(aRequestCommandPath, aData) != CHIP_NO_ERROR) + DataModel::EncodableType encodable(aData); + return AddResponse(aRequestCommandPath, CommandData::GetCommandId(), encodable); + } + + /** + * API for adding a response with a given encodable of TLV data. + * + * The encodable would generally encode a ClusterName::Commands::CommandName::Type with + * the corresponding `GetCommandId` call. + */ + void AddResponse(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId, + DataModel::EncodableToTLV & aEncodable) + { + if (AddResponseData(aRequestCommandPath, aResponseCommandId, aEncodable) != CHIP_NO_ERROR) { AddStatus(aRequestCommandPath, Protocols::InteractionModel::Status::Failure); } @@ -606,62 +639,17 @@ class CommandHandler CHIP_ERROR AddStatusInternal(const ConcreteCommandPath & aCommandPath, const StatusIB & aStatus); - /** - * Non-templated function called before DataModel::Encode when attempting to add a response, - * which does all the work needed before encoding the actual type-dependent data into the buffer. - * - * **Important:** If this function fails, the TLV buffer may be left in an inconsistent state. - * Callers should create snapshots as necessary before invoking this function and implement - * rollback mechanisms if needed. - * - * **Usage:** This function is intended to be called exclusively by TryAddResponseData. It was - * factored out to optimize code size. - * - * @param aRequestCommandPath The concrete path of the command being responded to. - * @param aResponseCommandPath The concrete path of the command response. - */ - CHIP_ERROR TryAddResponseDataPreEncode(const ConcreteCommandPath & aRequestCommandPath, - const ConcreteCommandPath & aResponseCommandPath) - { - InvokeResponseParameters prepareParams(aRequestCommandPath); - prepareParams.SetStartOrEndDataStruct(false); - - ScopedChange internalCallToAddResponse(mInternalCallToAddResponseData, true); - return PrepareInvokeResponseCommand(aResponseCommandPath, prepareParams); - } - - // TODO(#31627): It would be awesome if we could remove this template all together. /** * If this function fails, it may leave our TLV buffer in an inconsistent state. * Callers should snapshot as needed before calling this function, and roll back * as needed afterward. * - * @param [in] aRequestCommandPath the concrete path of the command we are - * responding to. - * @param [in] aData the data for the response. + * @param [in] aRequestCommandPath the concrete path of the command we are responding to + * @param [in] aResponseCommandId the id of the command to encode + * @param [in] aEncodable the data to encode for the given aResponseCommandId */ - template - CHIP_ERROR TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) - { - // This method, templated with CommandData, captures all the components needs - // from CommandData with as little code as possible. - // - // Previously, non-essential code was unnecessarily templated, leading to - // compilation and duplication N times. By isolating only the code segments - // that genuinely require templating, minimizes duplicate compiled code. - ConcreteCommandPath responseCommandPath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, - CommandData::GetCommandId() }; - ReturnErrorOnFailure(TryAddResponseDataPreEncode(aRequestCommandPath, responseCommandPath)); - TLV::TLVWriter * writer = GetCommandDataIBTLVWriter(); - VerifyOrReturnError(writer != nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorOnFailure(DataModel::Encode(*writer, TLV::ContextTag(CommandDataIB::Tag::kFields), aData)); - - // FinishCommand technically should be refactored out as it is not a command that needs templating. - // But, because there is only a single function call, keeping it here takes less code. If there is - // ever more code between DataModel::Encode and the end of this function, it should be broken out into - // TryAddResponseDataPostEncode. - return FinishCommand(/* aEndDataStruct = */ false); - } + CHIP_ERROR TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId, + DataModel::EncodableToTLV & aEncodable); void SetExchangeInterface(CommandHandlerExchangeInterface * commandResponder); diff --git a/src/app/CommandHandlerInterface.h b/src/app/CommandHandlerInterface.h index 6ec2547befa1d0..d36a41e37f076c 100644 --- a/src/app/CommandHandlerInterface.h +++ b/src/app/CommandHandlerInterface.h @@ -23,8 +23,10 @@ #include #include #include // So we can encode lists +#include #include #include +#include namespace chip { namespace app { diff --git a/src/app/GenericEventManagementTestEventTriggerHandler.cpp b/src/app/GenericEventManagementTestEventTriggerHandler.cpp new file mode 100644 index 00000000000000..9c4cc11c8851a9 --- /dev/null +++ b/src/app/GenericEventManagementTestEventTriggerHandler.cpp @@ -0,0 +1,72 @@ +/* + * + * 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 "GenericEventManagementTestEventTriggerHandler.h" + +#include +#include + +namespace chip { +namespace app { + +using namespace chip::DeviceLayer; +using namespace chip::app::Clusters; + +CHIP_ERROR GenericEventManagementTestEventTriggerHandler::HandleFillUpEventLoggingBufferEventTriger() +{ + /* Create a fake hardware fault list. */ + GeneralFaults hardwareFaults; + for (uint8_t hardwareFault = to_underlying(GeneralDiagnostics::HardwareFaultEnum::kUnspecified); + hardwareFault < kMaxHardwareFaults; hardwareFault++) + { + hardwareFaults.add(hardwareFault); + } + + /* Fill up the critical logging buffer by 10 hardware faults. */ + constexpr uint8_t kHardwareFaultCountForCriticalBuffer = 10; + for (uint8_t i = 0; i < kHardwareFaultCountForCriticalBuffer; i++) + { + GeneralDiagnosticsServer::Instance().OnHardwareFaultsDetect(hardwareFaults, hardwareFaults); + } + + /* Fill up the info logging buffer. */ + FillUpEventLoggingBufferWithFakeSoftwareFault(CHIP_DEVICE_CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE); + + /* Fill up the debug logging buffer. */ + FillUpEventLoggingBufferWithFakeSoftwareFault(CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE); + + return CHIP_NO_ERROR; +} + +void GenericEventManagementTestEventTriggerHandler::FillUpEventLoggingBufferWithFakeSoftwareFault(size_t bufferSize) +{ + /* Create a fake fault message. */ + constexpr size_t kEncodingOverhead = 0x40; + const size_t recordSize = bufferSize - kEncodingOverhead; + char * recordBuffer = static_cast(Platform::MemoryAlloc(recordSize)); + VerifyOrReturn(recordBuffer != nullptr); + std::unique_ptr recordString(recordBuffer, &Platform::MemoryFree); + memset(recordString.get(), 0x55, recordSize); + recordString.get()[recordSize - 1] = '\0'; + + /* Fill up the logging buffer by a software fault. */ + TriggerSoftwareFaultEvent(recordString.get()); +} + +} // namespace app +} // namespace chip diff --git a/src/app/GenericEventManagementTestEventTriggerHandler.h b/src/app/GenericEventManagementTestEventTriggerHandler.h new file mode 100644 index 00000000000000..da205a420bfaf3 --- /dev/null +++ b/src/app/GenericEventManagementTestEventTriggerHandler.h @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace app { + +class GenericEventManagementTestEventTriggerHandler : public TestEventTriggerHandler +{ +protected: + CHIP_ERROR HandleFillUpEventLoggingBufferEventTriger(); + +private: + void FillUpEventLoggingBufferWithFakeSoftwareFault(size_t bufferSize); + virtual void TriggerSoftwareFaultEvent(const char * faultRecordString) = 0; +}; + +} // namespace app +} // namespace chip diff --git a/src/app/OperationalSessionSetup.cpp b/src/app/OperationalSessionSetup.cpp index 5733a423702226..9197a2edbddf70 100644 --- a/src/app/OperationalSessionSetup.cpp +++ b/src/app/OperationalSessionSetup.cpp @@ -792,6 +792,11 @@ CHIP_ERROR OperationalSessionSetup::ScheduleSessionSetupReattempt(System::Clock: // but in practice for old devices BUSY often sends some hardcoded value // that tells us nothing about when the other side will decide it has // timed out. + // + // Unfortunately, we do not have the MRP config for the other side here, + // but in practice if the other side is using its local config to + // compute Sigma2 response timeouts, then it's also returning useful + // values with BUSY, so we will wait long enough. auto additionalTimeout = CASESession::ComputeSigma2ResponseTimeout(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())); actualTimerDelay += additionalTimeout; } diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index e8ada20a428c70..bb058e091858c7 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -938,24 +938,26 @@ CHIP_ERROR ReadClient::ComputeLivenessCheckTimerTimeout(System::Clock::Timeout * // // To calculate the duration we're willing to wait for a report to come to us, we take into account the maximum interval of - // the subscription AND the time it takes for the report to make it to us in the worst case. This latter bit involves - // computing the Ack timeout from the publisher for the ReportData message being sent to us using our IDLE interval as the - // basis for that computation. + // the subscription AND the time it takes for the report to make it to us in the worst case. // - // Make sure to use the retransmission computation that includes backoff. For purposes of that computation, treat us as - // active now (since we are right now sending/receiving messages), and use the default "how long are we guaranteed to stay - // active" threshold for now. + // We have no way to estimate what the network latency will be, but we do know the other side will time out its ReportData + // after its computed round-trip timeout plus the processing time it gives us (app::kExpectedIMProcessingTime). Once it + // times out, assuming it sent the report at all, there's no point in us thinking we still have a subscription. // - // TODO: We need to find a good home for this logic that will correctly compute this based on transport. For now, this will - // suffice since we don't use TCP as a transport currently and subscriptions over BLE aren't really a thing. + // We can't use ComputeRoundTripTimeout() on the session for two reasons: we want the roundtrip timeout from the point of + // view of the peer, not us, and we want to start off with the assumption the peer will likely have, which is that we are + // idle, whereas ComputeRoundTripTimeout() uses the current activity state of the peer. // - const auto & localMRPConfig = GetLocalMRPConfig(); - const auto & defaultMRPConfig = GetDefaultMRPConfig(); - const auto & ourMrpConfig = localMRPConfig.ValueOr(defaultMRPConfig); - auto publisherTransmissionTimeout = - GetRetransmissionTimeout(ourMrpConfig.mActiveRetransTimeout, ourMrpConfig.mIdleRetransTimeout, - System::SystemClock().GetMonotonicTimestamp(), ourMrpConfig.mActiveThresholdTime); - *aTimeout = System::Clock::Seconds16(mMaxInterval) + publisherTransmissionTimeout; + // So recompute the round-trip timeout directly. Assume MRP, since in practice that is likely what is happening. + auto & peerMRPConfig = mReadPrepareParams.mSessionHolder->GetRemoteMRPConfig(); + // Peer will assume we are idle (hence we pass kZero to GetMessageReceiptTimeout()), but will assume we treat it as active + // for the response, so to match the retransmission timeout computation for the message back to the peeer, we should treat + // it as active. + auto roundTripTimeout = mReadPrepareParams.mSessionHolder->GetMessageReceiptTimeout(System::Clock::kZero) + + kExpectedIMProcessingTime + + GetRetransmissionTimeout(peerMRPConfig.mActiveRetransTimeout, peerMRPConfig.mIdleRetransTimeout, + System::SystemClock().GetMonotonicTimestamp(), peerMRPConfig.mActiveThresholdTime); + *aTimeout = System::Clock::Seconds16(mMaxInterval) + roundTripTimeout; return CHIP_NO_ERROR; } diff --git a/src/app/clusters/color-control-server/color-control-server.cpp b/src/app/clusters/color-control-server/color-control-server.cpp index 508f4b691bb0d1..784bca88b85955 100644 --- a/src/app/clusters/color-control-server/color-control-server.cpp +++ b/src/app/clusters/color-control-server/color-control-server.cpp @@ -431,15 +431,16 @@ ColorControlServer & ColorControlServer::Instance() return instance; } +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * ColorControlServer::GetSceneHandler() { - -#if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +#if CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS return &sColorControlSceneHandler; #else return nullptr; -#endif // defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +#endif // CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS } +#endif // ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT bool ColorControlServer::HasFeature(chip::EndpointId endpoint, Feature feature) { diff --git a/src/app/clusters/color-control-server/color-control-server.h b/src/app/clusters/color-control-server/color-control-server.h index 72dabb5600ff33..f453c6f02872e4 100644 --- a/src/app/clusters/color-control-server/color-control-server.h +++ b/src/app/clusters/color-control-server/color-control-server.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,10 @@ #include #include +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT +#include +#endif + /********************************************************** * Defines and Macros *********************************************************/ @@ -134,7 +137,9 @@ class ColorControlServer *********************************************************/ static ColorControlServer & Instance(); +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * GetSceneHandler(); +#endif bool HasFeature(chip::EndpointId endpoint, Feature feature); chip::Protocols::InteractionModel::Status stopAllColorTransitions(chip::EndpointId endpoint); @@ -272,7 +277,9 @@ class ColorControlServer EmberEventControl eventControls[kColorControlClusterServerMaxEndpointCount]; +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT friend class DefaultColorControlSceneHandler; +#endif }; /********************************************************** diff --git a/src/app/clusters/level-control/level-control.cpp b/src/app/clusters/level-control/level-control.cpp index b93bf50927c5eb..2ee9f2cfa54c04 100644 --- a/src/app/clusters/level-control/level-control.cpp +++ b/src/app/clusters/level-control/level-control.cpp @@ -608,14 +608,16 @@ Status MoveToLevel(EndpointId endpointId, const Commands::MoveToLevel::Decodable INVALID_STORED_LEVEL); // Don't revert to the stored level } +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * GetSceneHandler() { -#if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +#if CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS return &sLevelControlSceneHandler; #else return nullptr; -#endif // defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +#endif // CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS } +#endif // ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT } // namespace LevelControlServer diff --git a/src/app/clusters/level-control/level-control.h b/src/app/clusters/level-control/level-control.h index 95497cc117e6d2..0240c921acd8b4 100644 --- a/src/app/clusters/level-control/level-control.h +++ b/src/app/clusters/level-control/level-control.h @@ -28,9 +28,12 @@ #include #include -#include #include +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT +#include +#endif + /** @brief Level Control Cluster Server Post Init * * Following resolution of the Level Control state at startup for this endpoint, perform any @@ -53,6 +56,8 @@ chip::Protocols::InteractionModel::Status MoveToLevel(chip::EndpointId endpointId, const chip::app::Clusters::LevelControl::Commands::MoveToLevel::DecodableType & commandData); +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * GetSceneHandler(); +#endif } // namespace LevelControlServer diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index daa843588f5718..f2e74033d8266c 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -115,6 +115,225 @@ BitFlags WiFiFeatures(WiFiDriver * driver) return features; } +/// Performs an auto-release of the given item, generally an `Iterator` type +/// like Wifi or Thread scan results. +template +class AutoRelease +{ +public: + AutoRelease(T * iterator) : mValue(iterator) {} + ~AutoRelease() + { + if (mValue != nullptr) + { + mValue->Release(); + } + } + +private: + T * mValue; +}; + +/// Convenience macro to auto-create a variable for you to release the given name at +/// the exit of the current scope. +#define DEFER_AUTO_RELEASE(name) AutoRelease autoRelease##__COUNTER__(name) + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION || CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + +/// Handles encoding a WifiScanResponseIterator into a TLV response structure +class WifiScanResponseToTLV : public chip::app::DataModel::EncodableToTLV +{ +public: + WifiScanResponseToTLV(Status status, CharSpan debugText, WiFiScanResponseIterator * networks) : + mStatus(status), mDebugText(debugText), mNetworks(networks) + {} + + CHIP_ERROR EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const override; + +private: + Status mStatus; + CharSpan mDebugText; + WiFiScanResponseIterator * mNetworks; +}; + +CHIP_ERROR WifiScanResponseToTLV::EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const +{ + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outerType)); + + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kNetworkingStatus), mStatus)); + if (mDebugText.size() != 0) + { + ReturnErrorOnFailure( + DataModel::Encode(writer, TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kDebugText), mDebugText)); + } + + { + TLV::TLVType listContainerType; + ReturnErrorOnFailure(writer.StartContainer(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kWiFiScanResults), + TLV::kTLVType_Array, listContainerType)); + + if ((mStatus == Status::kSuccess) && (mNetworks != nullptr)) + { + WiFiScanResponse scanResponse; + size_t networksEncoded = 0; + while (mNetworks->Next(scanResponse)) + { + Structs::WiFiInterfaceScanResultStruct::Type result; + result.security = scanResponse.security; + result.ssid = ByteSpan(scanResponse.ssid, scanResponse.ssidLen); + result.bssid = ByteSpan(scanResponse.bssid, sizeof(scanResponse.bssid)); + result.channel = scanResponse.channel; + result.wiFiBand = scanResponse.wiFiBand; + result.rssi = scanResponse.rssi; + ReturnErrorOnFailure(DataModel::Encode(writer, TLV::AnonymousTag(), result)); + + ++networksEncoded; + if (networksEncoded >= kMaxNetworksInScanResponse) + { + break; + } + } + } + + ReturnErrorOnFailure(writer.EndContainer(listContainerType)); + } + + return writer.EndContainer(outerType); +} + +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION || CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + +/// Handles encoding a ThreadScanResponseIterator into a TLV response structure. +class ThreadScanResponseToTLV : public chip::app::DataModel::EncodableToTLV +{ +public: + ThreadScanResponseToTLV(Status status, CharSpan debugText, ThreadScanResponseIterator * networks) : + mStatus(status), mDebugText(debugText), mNetworks(networks) + {} + + CHIP_ERROR EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const override; + +private: + Status mStatus; + CharSpan mDebugText; + ThreadScanResponseIterator * mNetworks; + + /// Fills up scanResponseArray with valid and de-duplicated thread responses from mNetworks. + /// Handles sorting and keeping only larger rssi + /// + /// Returns the valid list of scan responses into `validResponses`, which is only valid + /// as long as scanResponseArray is valid. + CHIP_ERROR LoadResponses(Platform::ScopedMemoryBuffer & scanResponseArray, + Span & validResponses) const; +}; + +CHIP_ERROR ThreadScanResponseToTLV::LoadResponses(Platform::ScopedMemoryBuffer & scanResponseArray, + Span & validResponses) const +{ + VerifyOrReturnError(scanResponseArray.Alloc(chip::min(mNetworks->Count(), kMaxNetworksInScanResponse)), CHIP_ERROR_NO_MEMORY); + + ThreadScanResponse scanResponse; + size_t scanResponseArrayLength = 0; + for (; mNetworks != nullptr && mNetworks->Next(scanResponse);) + { + if ((scanResponseArrayLength == kMaxNetworksInScanResponse) && + (scanResponseArray[scanResponseArrayLength - 1].rssi > scanResponse.rssi)) + { + continue; + } + + bool isDuplicated = false; + + for (size_t i = 0; i < scanResponseArrayLength; i++) + { + if ((scanResponseArray[i].panId == scanResponse.panId) && + (scanResponseArray[i].extendedPanId == scanResponse.extendedPanId)) + { + if (scanResponseArray[i].rssi < scanResponse.rssi) + { + scanResponseArray[i] = scanResponseArray[--scanResponseArrayLength]; + } + else + { + isDuplicated = true; + } + break; + } + } + + if (isDuplicated) + { + continue; + } + + if (scanResponseArrayLength < kMaxNetworksInScanResponse) + { + scanResponseArrayLength++; + } + scanResponseArray[scanResponseArrayLength - 1] = scanResponse; + + // TODO: this is a sort (insertion sort even, so O(n^2)) in a O(n) loop. + /// There should be some better alternatives to not have some O(n^3) processing complexity. + Sorting::InsertionSort(scanResponseArray.Get(), scanResponseArrayLength, + [](const ThreadScanResponse & a, const ThreadScanResponse & b) -> bool { return a.rssi > b.rssi; }); + } + + validResponses = Span(scanResponseArray.Get(), scanResponseArrayLength); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ThreadScanResponseToTLV::EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const +{ + Platform::ScopedMemoryBuffer responseArray; + Span responseSpan; + + ReturnErrorOnFailure(LoadResponses(responseArray, responseSpan)); + + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outerType)); + + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kNetworkingStatus), mStatus)); + if (mDebugText.size() != 0) + { + ReturnErrorOnFailure( + DataModel::Encode(writer, TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kDebugText), mDebugText)); + } + + { + TLV::TLVType listContainerType; + ReturnErrorOnFailure(writer.StartContainer(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kThreadScanResults), + TLV::kTLVType_Array, listContainerType)); + + for (const ThreadScanResponse & response : responseSpan) + { + Structs::ThreadInterfaceScanResultStruct::Type result; + uint8_t extendedAddressBuffer[Thread::kSizeExtendedPanId]; + + Encoding::BigEndian::Put64(extendedAddressBuffer, response.extendedAddress); + result.panId = response.panId; + result.extendedPanId = response.extendedPanId; + result.networkName = CharSpan(response.networkName, response.networkNameLen); + result.channel = response.channel; + result.version = response.version; + result.extendedAddress = ByteSpan(extendedAddressBuffer); + result.rssi = response.rssi; + result.lqi = response.lqi; + + ReturnErrorOnFailure(DataModel::Encode(writer, TLV::AnonymousTag(), result)); + } + + ReturnErrorOnFailure(writer.EndContainer(listContainerType)); + } + + return writer.EndContainer(outerType); +} + +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + } // namespace Instance::Instance(EndpointId aEndpointId, WiFiDriver * apDelegate) : @@ -986,8 +1205,9 @@ void Instance::OnResult(Status commissioningError, CharSpan debugText, int32_t i void Instance::OnFinished(Status status, CharSpan debugText, ThreadScanResponseIterator * networks) { + DEFER_AUTO_RELEASE(networks); + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD - CHIP_ERROR err = CHIP_NO_ERROR; auto commandHandleRef = std::move(mAsyncCommandHandle); auto commandHandle = commandHandleRef.Get(); if (commandHandle == nullptr) @@ -999,111 +1219,21 @@ void Instance::OnFinished(Status status, CharSpan debugText, ThreadScanResponseI SetLastNetworkingStatusValue(MakeNullable(status)); - TLV::TLVWriter * writer; - TLV::TLVType listContainerType; - ThreadScanResponse scanResponse; - Platform::ScopedMemoryBuffer scanResponseArray; - size_t scanResponseArrayLength = 0; - uint8_t extendedAddressBuffer[Thread::kSizeExtendedPanId]; - - const CommandHandler::InvokeResponseParameters prepareParams(mPath); - SuccessOrExit( - err = commandHandle->PrepareInvokeResponseCommand( - ConcreteCommandPath(mPath.mEndpointId, NetworkCommissioning::Id, Commands::ScanNetworksResponse::Id), prepareParams)); - VerifyOrExit((writer = commandHandle->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - - SuccessOrExit(err = writer->Put(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kNetworkingStatus), status)); - if (debugText.size() != 0) - { - SuccessOrExit( - err = DataModel::Encode(*writer, TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kDebugText), debugText)); - } - SuccessOrExit(err = writer->StartContainer(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kThreadScanResults), - TLV::TLVType::kTLVType_Array, listContainerType)); - - // If no network was found, we encode an empty list, don't call a zero-sized alloc. - if ((status == Status::kSuccess) && (networks->Count() > 0)) - { - VerifyOrExit(scanResponseArray.Alloc(chip::min(networks->Count(), kMaxNetworksInScanResponse)), err = CHIP_ERROR_NO_MEMORY); - for (; networks != nullptr && networks->Next(scanResponse);) - { - if ((scanResponseArrayLength == kMaxNetworksInScanResponse) && - (scanResponseArray[scanResponseArrayLength - 1].rssi > scanResponse.rssi)) - { - continue; - } - - bool isDuplicated = false; - - for (size_t i = 0; i < scanResponseArrayLength; i++) - { - if ((scanResponseArray[i].panId == scanResponse.panId) && - (scanResponseArray[i].extendedPanId == scanResponse.extendedPanId)) - { - if (scanResponseArray[i].rssi < scanResponse.rssi) - { - scanResponseArray[i] = scanResponseArray[--scanResponseArrayLength]; - } - else - { - isDuplicated = true; - } - break; - } - } + ThreadScanResponseToTLV responseBuilder(status, debugText, networks); + commandHandle->AddResponse(mPath, Commands::ScanNetworksResponse::Id, responseBuilder); - if (isDuplicated) - { - continue; - } - - if (scanResponseArrayLength < kMaxNetworksInScanResponse) - { - scanResponseArrayLength++; - } - scanResponseArray[scanResponseArrayLength - 1] = scanResponse; - Sorting::InsertionSort( - scanResponseArray.Get(), scanResponseArrayLength, - [](const ThreadScanResponse & a, const ThreadScanResponse & b) -> bool { return a.rssi > b.rssi; }); - } - - for (size_t i = 0; i < scanResponseArrayLength; i++) - { - Structs::ThreadInterfaceScanResultStruct::Type result; - Encoding::BigEndian::Put64(extendedAddressBuffer, scanResponseArray[i].extendedAddress); - result.panId = scanResponseArray[i].panId; - result.extendedPanId = scanResponseArray[i].extendedPanId; - result.networkName = CharSpan(scanResponseArray[i].networkName, scanResponseArray[i].networkNameLen); - result.channel = scanResponseArray[i].channel; - result.version = scanResponseArray[i].version; - result.extendedAddress = ByteSpan(extendedAddressBuffer); - result.rssi = scanResponseArray[i].rssi; - result.lqi = scanResponseArray[i].lqi; - - SuccessOrExit(err = DataModel::Encode(*writer, TLV::AnonymousTag(), result)); - } - } - - SuccessOrExit(err = writer->EndContainer(listContainerType)); - SuccessOrExit(err = commandHandle->FinishCommand()); - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "Failed to encode response: %" CHIP_ERROR_FORMAT, err.Format()); - } if (status == Status::kSuccess) { CommitSavedBreadcrumb(); } - networks->Release(); #endif } void Instance::OnFinished(Status status, CharSpan debugText, WiFiScanResponseIterator * networks) { + DEFER_AUTO_RELEASE(networks); + #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION || CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP - CHIP_ERROR err = CHIP_NO_ERROR; auto commandHandleRef = std::move(mAsyncCommandHandle); auto commandHandle = commandHandleRef.Get(); if (commandHandle == nullptr) @@ -1122,63 +1252,13 @@ void Instance::OnFinished(Status status, CharSpan debugText, WiFiScanResponseIte SetLastNetworkingStatusValue(MakeNullable(status)); - TLV::TLVWriter * writer; - TLV::TLVType listContainerType; - WiFiScanResponse scanResponse; - size_t networksEncoded = 0; - - const CommandHandler::InvokeResponseParameters prepareParams(mPath); - SuccessOrExit( - err = commandHandle->PrepareInvokeResponseCommand( - ConcreteCommandPath(mPath.mEndpointId, NetworkCommissioning::Id, Commands::ScanNetworksResponse::Id), prepareParams)); - VerifyOrExit((writer = commandHandle->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + WifiScanResponseToTLV responseBuilder(status, debugText, networks); + commandHandle->AddResponse(mPath, Commands::ScanNetworksResponse::Id, responseBuilder); - SuccessOrExit(err = writer->Put(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kNetworkingStatus), status)); - if (debugText.size() != 0) - { - SuccessOrExit( - err = DataModel::Encode(*writer, TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kDebugText), debugText)); - } - SuccessOrExit(err = writer->StartContainer(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kWiFiScanResults), - TLV::TLVType::kTLVType_Array, listContainerType)); - - // Only encode results on success, to avoid stale contents on partial failure. - if ((status == Status::kSuccess) && (networks != nullptr)) - { - while (networks->Next(scanResponse)) - { - Structs::WiFiInterfaceScanResultStruct::Type result; - result.security = scanResponse.security; - result.ssid = ByteSpan(scanResponse.ssid, scanResponse.ssidLen); - result.bssid = ByteSpan(scanResponse.bssid, sizeof(scanResponse.bssid)); - result.channel = scanResponse.channel; - result.wiFiBand = scanResponse.wiFiBand; - result.rssi = scanResponse.rssi; - SuccessOrExit(err = DataModel::Encode(*writer, TLV::AnonymousTag(), result)); - - ++networksEncoded; - if (networksEncoded >= kMaxNetworksInScanResponse) - { - break; - } - } - } - - SuccessOrExit(err = writer->EndContainer(listContainerType)); - SuccessOrExit(err = commandHandle->FinishCommand()); -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "Failed to encode response: %" CHIP_ERROR_FORMAT, err.Format()); - } if (status == Status::kSuccess) { CommitSavedBreadcrumb(); } - if (networks != nullptr) - { - networks->Release(); - } #endif } diff --git a/src/app/clusters/on-off-server/on-off-server.cpp b/src/app/clusters/on-off-server/on-off-server.cpp index bc71044ae44075..aadac6c6e2e630 100644 --- a/src/app/clusters/on-off-server/on-off-server.cpp +++ b/src/app/clusters/on-off-server/on-off-server.cpp @@ -15,6 +15,8 @@ * limitations under the License. */ +#include + #include "on-off-server.h" #include @@ -299,15 +301,16 @@ OnOffServer & OnOffServer::Instance() return instance; } +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * OnOffServer::GetSceneHandler() { - -#if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +#if CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS return &sOnOffSceneHandler; #else return nullptr; -#endif // defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +#endif // CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS } +#endif // ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT bool OnOffServer::HasFeature(chip::EndpointId endpoint, Feature feature) { diff --git a/src/app/clusters/on-off-server/on-off-server.h b/src/app/clusters/on-off-server/on-off-server.h index 2cb5b62958a6c7..9bf8a5d4b03208 100644 --- a/src/app/clusters/on-off-server/on-off-server.h +++ b/src/app/clusters/on-off-server/on-off-server.h @@ -20,12 +20,15 @@ #include #include #include -#include #include #include #include #include +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT +#include +#endif + /********************************************************** * Defines and Macros *********************************************************/ @@ -50,7 +53,9 @@ class OnOffServer static OnOffServer & Instance(); +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * GetSceneHandler(); +#endif bool offCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath); bool onCommand(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath); @@ -97,7 +102,9 @@ class OnOffServer static OnOffServer instance; chip::System::Clock::Timestamp nextDesiredOnWithTimedOffTimestamp; +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT friend class DefaultOnOffSceneHandler; +#endif }; struct OnOffEffect diff --git a/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp new file mode 100644 index 00000000000000..1a739e354bd3df --- /dev/null +++ b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp @@ -0,0 +1,176 @@ +/** + * + * 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 "wifi-network-management-server.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::WiFiNetworkManagement::Attributes; +using namespace chip::app::Clusters::WiFiNetworkManagement::Commands; +using namespace std::placeholders; + +namespace chip { +namespace app { +namespace Clusters { + +namespace { + +// TODO: Move this into lib/support somewhere and also use it network-commissioning.cpp +bool IsValidWpaPersonalCredential(ByteSpan credential) +{ + // As per spec section 11.9.7.3. AddOrUpdateWiFiNetwork Command + if (8 <= credential.size() && credential.size() <= 63) // passphrase + { + return true; + } + if (credential.size() == 64) // raw hex psk + { + return std::all_of(credential.begin(), credential.end(), [](auto c) { return std::isxdigit(c); }); + } + return false; +} + +Global gWiFiNetworkManagementServerInstance; + +} // namespace + +WiFiNetworkManagementServer & WiFiNetworkManagementServer::Instance() +{ + return gWiFiNetworkManagementServerInstance.get(); +} + +WiFiNetworkManagementServer::WiFiNetworkManagementServer() : + AttributeAccessInterface(NullOptional, WiFiNetworkManagement::Id), + CommandHandlerInterface(NullOptional, WiFiNetworkManagement::Id) +{} + +WiFiNetworkManagementServer::~WiFiNetworkManagementServer() +{ + unregisterAttributeAccessOverride(this); + InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); +} + +CHIP_ERROR WiFiNetworkManagementServer::Init(EndpointId endpoint) +{ + VerifyOrReturnError(endpoint != kInvalidEndpointId, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mEndpointId == kInvalidEndpointId, CHIP_ERROR_INCORRECT_STATE); + + mEndpointId = endpoint; + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INTERNAL); + ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiNetworkManagementServer::ClearNetworkCredentials() +{ + VerifyOrReturnError(HaveNetworkCredentials(), CHIP_NO_ERROR); + + mSsidLen = 0; + mPassphrase.SetLength(0); + MatterReportingAttributeChangeCallback(mEndpointId, WiFiNetworkManagement::Id, Ssid::Id); + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiNetworkManagementServer::SetNetworkCredentials(ByteSpan ssid, ByteSpan passphrase) +{ + VerifyOrReturnError(1 <= ssid.size() && ssid.size() <= sizeof(mSsid), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsValidWpaPersonalCredential(passphrase), CHIP_ERROR_INVALID_ARGUMENT); + + bool ssidChanged = !SsidSpan().data_equal(ssid); + bool passphraseChanged = !PassphraseSpan().data_equal(passphrase); + VerifyOrReturnError(ssidChanged || passphraseChanged, CHIP_NO_ERROR); + + memcpy(mSsid, ssid.data(), ssid.size()); + mSsidLen = static_cast(ssid.size()); + + VerifyOrDie(mPassphrase.SetLength(passphrase.size()) == CHIP_NO_ERROR); + memcpy(mPassphrase.Bytes(), passphrase.data(), passphrase.size()); + + // Note: The spec currently defines no way to signal a passphrase change + if (ssidChanged) + { + MatterReportingAttributeChangeCallback(mEndpointId, WiFiNetworkManagement::Id, Ssid::Id); + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiNetworkManagementServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + switch (aPath.mAttributeId) + { + case Ssid::Id: + return HaveNetworkCredentials() ? aEncoder.Encode(SsidSpan()) : aEncoder.EncodeNull(); + } + return CHIP_NO_ERROR; +} + +void WiFiNetworkManagementServer::InvokeCommand(HandlerContext & ctx) +{ + switch (ctx.mRequestPath.mCommandId) + { + case NetworkPassphraseRequest::Id: + HandleCommand( + ctx, [this](HandlerContext & aCtx, const auto & req) { HandleNetworkPassphraseRequest(aCtx, req); }); + return; + } +} + +void WiFiNetworkManagementServer::HandleNetworkPassphraseRequest(HandlerContext & ctx, + const NetworkPassphraseRequest::DecodableType & req) +{ + if (HaveNetworkCredentials()) + { + NetworkPassphraseResponse::Type response; + response.passphrase = mPassphrase.Span(); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + } + else + { + // TODO: Status code TBC: https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/9234 + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::InvalidInState); + } +} + +} // namespace Clusters +} // namespace app +} // namespace chip + +#if defined(MATTER_DM_WIFI_NETWORK_MANAGEMENT_CLUSTER_SERVER_ENDPOINT_COUNT) && \ + MATTER_DM_WIFI_NETWORK_MANAGEMENT_CLUSTER_SERVER_ENDPOINT_COUNT > 1 +#error Only a single Wi-Fi Network Management Cluster instance is supported. +#endif + +void MatterWiFiNetworkManagementPluginServerInitCallback() {} + +void emberAfWiFiNetworkManagementClusterServerInitCallback(EndpointId endpoint) +{ + // We could delay constructing the instance until this point; however it's not + // clear if this is inconvenient in terms of forcing the application to initialize + // the network credentials later than it otherwise would. + LogErrorOnFailure(chip::app::Clusters::WiFiNetworkManagementServer::Instance().Init(endpoint)); +} diff --git a/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h new file mode 100644 index 00000000000000..aa3cba89636a77 --- /dev/null +++ b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h @@ -0,0 +1,74 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +void emberAfWiFiNetworkManagementClusterServerInitCallback(chip::EndpointId); + +namespace chip { +namespace app { +namespace Clusters { + +class WiFiNetworkManagementServer : private AttributeAccessInterface, private CommandHandlerInterface +{ +public: + static WiFiNetworkManagementServer & Instance(); + + CHIP_ERROR ClearNetworkCredentials(); + CHIP_ERROR SetNetworkCredentials(ByteSpan ssid, ByteSpan passphrase); + +private: + friend Global; + friend void ::emberAfWiFiNetworkManagementClusterServerInitCallback(chip::EndpointId); + + WiFiNetworkManagementServer(); + ~WiFiNetworkManagementServer(); + CHIP_ERROR Init(EndpointId endpoint); + + WiFiNetworkManagementServer(WiFiNetworkManagementServer const &) = delete; + WiFiNetworkManagementServer & operator=(WiFiNetworkManagementServer const &) = delete; + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + void InvokeCommand(HandlerContext & handlerContext) override; + + void HandleNetworkPassphraseRequest(HandlerContext & ctx, + const WiFiNetworkManagement::Commands::NetworkPassphraseRequest::DecodableType & req); + + EndpointId mEndpointId = kInvalidEndpointId; + + uint8_t mSsid[32]; + uint8_t mSsidLen = 0; + static_assert(std::numeric_limits::max() >= sizeof(mSsid)); + ByteSpan SsidSpan() const { return ByteSpan(mSsid, mSsidLen); } + + Crypto::SensitiveDataBuffer<64> mPassphrase; + ByteSpan PassphraseSpan() const { return mPassphrase.Span(); } + + bool HaveNetworkCredentials() { return mSsidLen > 0; } +}; + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 875cdbcdbd1514..83d1b682153ed7 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -40,6 +40,7 @@ CommandHandlerInterfaceOnlyClusters: - Device Energy Management Mode - Electrical Power Measurement - Electrical Energy Measurement + - Wi-Fi Network Management # We need a more configurable way of deciding which clusters have which init functions.... # See https://github.com/project-chip/connectedhomeip/issues/4369 @@ -57,6 +58,7 @@ ClustersWithInitFunctions: - Mode Select - Sample MEI - Scenes Management + - Wi-Fi Network Management ClustersWithAttributeChangedFunctions: - Bridged Device Basic diff --git a/src/app/data-model/BUILD.gn b/src/app/data-model/BUILD.gn index 6f38c056282e68..d61b30a68d9611 100644 --- a/src/app/data-model/BUILD.gn +++ b/src/app/data-model/BUILD.gn @@ -18,6 +18,7 @@ source_set("data-model") { "BasicTypes.h", "DecodableList.h", "Decode.h", + "EncodableToTLV.h", "Encode.h", "FabricScoped.h", "FabricScopedPreEncodedValue.cpp", diff --git a/src/app/data-model/EncodableToTLV.h b/src/app/data-model/EncodableToTLV.h new file mode 100644 index 00000000000000..d8b039141c226d --- /dev/null +++ b/src/app/data-model/EncodableToTLV.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace chip { +namespace app { +namespace DataModel { + +/// Defines an abstract class of something that can be encoded +/// into a TLV with a given data tag +class EncodableToTLV +{ +public: + virtual ~EncodableToTLV() = default; + + virtual CHIP_ERROR EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const = 0; +}; + +/// An `EncodableToTLV` that uses `DataModel::Encode` to encode things in one call. +/// +/// Applicable to any type for which `chip::app::DataModel::Encode` works. In +/// particular, types like ::Commands::::Type +/// can be used as a type here. +template +class EncodableType : public EncodableToTLV +{ +public: + /// Encodes the given value via `DataModel::Encode` when the underlying + /// encode is called. + /// + /// LIFETIME NOTE: uses a reference to value, so value must live longer than + /// this object. + EncodableType(const T & value) : mValue(value) {} + + CHIP_ERROR EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const override { return DataModel::Encode(writer, tag, mValue); } + +private: + const T & mValue; +}; + +} // namespace DataModel +} // namespace app +} // namespace chip diff --git a/src/app/tests/AppTestContext.cpp b/src/app/tests/AppTestContext.cpp index eca7a2db76c83b..ff1154dafbb306 100644 --- a/src/app/tests/AppTestContext.cpp +++ b/src/app/tests/AppTestContext.cpp @@ -49,6 +49,18 @@ void AppContext::SetUpTestSuite() void AppContext::TearDownTestSuite() { + // Some test suites finish with unprocessed work left in the platform manager event queue. + // This can particularly be a problem when this unprocessed work involves reporting engine runs, + // since those can take a while and cause later tests to not reach their queued work before + // their timeouts hit. This is only an issue in setups where all unit tests are compiled into + // a single file (e.g. nRF CI (Zephyr native_posix)). + // + // Work around this issue by doing a DrainAndServiceIO() here to attempt to flush out any queued-up work. + // + // TODO: Solve the underlying issue where test suites leave unprocessed work. Or is this actually + // the right solution? + LoopbackMessagingContext::DrainAndServiceIO(); + chip::DeviceLayer::PlatformMgr().Shutdown(); LoopbackMessagingContext::TearDownTestSuite(); } diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index df6737a713e6e4..e8413b92026d9a 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -15,6 +15,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("//build_overrides/nlunit_test.gni") +import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/chip_test_suite.gni") import("${chip_root}/src/app/icd/icd.gni") @@ -37,9 +38,10 @@ static_library("helpers") { "${chip_root}/src/access", "${chip_root}/src/app", "${chip_root}/src/lib/support", - "${chip_root}/src/messaging/tests:helpers", "${chip_root}/src/transport/raw/tests:helpers", ] + + public_deps = [ "${chip_root}/src/messaging/tests:helpers" ] } source_set("binding-test-srcs") { @@ -119,30 +121,33 @@ source_set("operational-state-test-srcs") { ] } -chip_test_suite_using_nltest("tests") { +source_set("app-test-stubs") { + sources = [ + "test-ember-api.cpp", + "test-ember-api.h", + "test-interaction-model-api.cpp", + "test-interaction-model-api.h", + ] + public_configs = [ "${chip_root}/src/lib/support/pw_log_chip:config" ] + + public_deps = [ + "${chip_root}/src/app/util/mock:mock_ember", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + ] +} + +chip_test_suite("tests") { output_name = "libAppTests" test_sources = [ - "TestAclEvent.cpp", "TestAttributeAccessInterfaceCache.cpp", "TestAttributePathExpandIterator.cpp", "TestAttributePersistenceProvider.cpp", "TestAttributeValueDecoder.cpp", "TestAttributeValueEncoder.cpp", - "TestBasicCommandPathRegistry.cpp", "TestBindingTable.cpp", "TestBuilderParser.cpp", - "TestClusterInfo.cpp", - "TestCommandInteraction.cpp", - "TestCommandPathParams.cpp", - "TestConcreteAttributePath.cpp", - "TestDataModelSerialization.cpp", - "TestDefaultOTARequestorStorage.cpp", - "TestEventLoggingNoUTCTime.cpp", - "TestEventOverflow.cpp", - "TestEventPathParams.cpp", - "TestFabricScopedEventLogging.cpp", - "TestInteractionModelEngine.cpp", "TestMessageDef.cpp", "TestNullable.cpp", "TestNumericAttributeTraits.cpp", @@ -150,27 +155,71 @@ chip_test_suite_using_nltest("tests") { "TestPendingNotificationMap.cpp", "TestPendingResponseTrackerImpl.cpp", "TestPowerSourceCluster.cpp", - "TestReadInteraction.cpp", - "TestReportingEngine.cpp", "TestStatusIB.cpp", "TestStatusResponseMessage.cpp", "TestTestEventTriggerDelegate.cpp", "TestTimeSyncDataProvider.cpp", - "TestTimedHandler.cpp", - "TestWriteInteraction.cpp", ] if (!chip_fake_platform) { test_sources += [ "TestFailSafeContext.cpp" ] } - test_sources += [ "TestAclAttribute.cpp" ] - # DefaultICDClientStorage assumes that raw AES key is used by the application if (chip_crypto != "psa") { test_sources += [ "TestDefaultICDClientStorage.cpp" ] } + if (chip_persist_subscriptions) { + test_sources += [ "TestSimpleSubscriptionResumptionStorage.cpp" ] + } + + cflags = [ "-Wconversion" ] + + public_deps = [ + ":app-test-stubs", + ":binding-test-srcs", + ":operational-state-test-srcs", + ":ota-requestor-test-srcs", + ":power-cluster-test-srcs", + ":time-sync-data-provider-test-srcs", + "${chip_root}/src/app", + "${chip_root}/src/app/common:cluster-objects", + "${chip_root}/src/app/icd/client:manager", + "${chip_root}/src/app/tests:helpers", + "${chip_root}/src/app/util/mock:mock_ember", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/support:test_utils", + "${chip_root}/src/lib/support:testing", + ] +} + +chip_test_suite_using_nltest("tests_nltest") { + output_name = "libAppTestsNL" + + test_sources = [ + "TestAclAttribute.cpp", + "TestAclEvent.cpp", + "TestBasicCommandPathRegistry.cpp", + "TestClusterInfo.cpp", + "TestCommandInteraction.cpp", + "TestCommandPathParams.cpp", + "TestConcreteAttributePath.cpp", + "TestDataModelSerialization.cpp", + "TestDefaultOTARequestorStorage.cpp", + "TestEventLoggingNoUTCTime.cpp", + "TestEventOverflow.cpp", + "TestEventPathParams.cpp", + "TestFabricScopedEventLogging.cpp", + "TestInteractionModelEngine.cpp", + "TestReadInteraction.cpp", + "TestReportScheduler.cpp", + "TestReportingEngine.cpp", + "TestTimedHandler.cpp", + "TestWriteInteraction.cpp", + ] + # # On NRF platforms, the allocation of a large number of pbufs in this test # to exercise chunking causes it to run out of memory. For now, disable it there. @@ -189,19 +238,10 @@ chip_test_suite_using_nltest("tests") { test_sources += [ "TestEventLogging.cpp" ] } - # The platform manager is not properly clearing queues in test teardown, which results in - # DrainIO calls not being able to run in expected time (5seconds) if unprocessed reported engine - # runs are remaining, causing tests to crash in Open IoT SDK and Zephyr tests since they are - # running all tests in one file. We need to figure out how to properly clean the event queues - # before enabling this test for these platforms. - if (chip_device_platform != "nrfconnect" && - chip_device_platform != "openiotsdk") { - test_sources += [ "TestReportScheduler.cpp" ] - } - cflags = [ "-Wconversion" ] public_deps = [ + ":app-test-stubs", ":binding-test-srcs", ":operational-state-test-srcs", ":ota-requestor-test-srcs", @@ -237,8 +277,4 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/messaging/tests/echo:common", ] } - - if (chip_persist_subscriptions) { - test_sources += [ "TestSimpleSubscriptionResumptionStorage.cpp" ] - } } diff --git a/src/app/tests/TestAclAttribute.cpp b/src/app/tests/TestAclAttribute.cpp index 427b257f9efd7c..1c928515dc5d74 100644 --- a/src/app/tests/TestAclAttribute.cpp +++ b/src/app/tests/TestAclAttribute.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -46,18 +47,13 @@ namespace { using namespace chip; using namespace chip::Access; -chip::ClusterId kTestClusterId = 1; -chip::ClusterId kTestDeniedClusterId1 = 1000; -chip::ClusterId kTestDeniedClusterId2 = 3; -chip::EndpointId kTestEndpointId = 4; - class TestAccessControlDelegate : public AccessControl::Delegate { public: CHIP_ERROR Check(const SubjectDescriptor & subjectDescriptor, const chip::Access::RequestPath & requestPath, Privilege requestPrivilege) override { - if (requestPath.cluster == kTestDeniedClusterId2) + if (requestPath.cluster == chip::Test::kTestDeniedClusterId2) { return CHIP_ERROR_ACCESS_DENIED; } @@ -125,21 +121,6 @@ class MockInteractionModelApp : public chip::app::ReadClient::Callback namespace chip { namespace app { -bool ConcreteAttributePathExists(const ConcreteAttributePath & aPath) -{ - return aPath.mClusterId != kTestDeniedClusterId1; -} - -Protocols::InteractionModel::Status CheckEventSupportStatus(const ConcreteEventPath & aPath) -{ - if (aPath.mClusterId == kTestDeniedClusterId1) - { - return Protocols::InteractionModel::Status::UnsupportedCluster; - } - - return Protocols::InteractionModel::Status::Success; -} - class TestAclAttribute { public: @@ -166,12 +147,12 @@ void TestAclAttribute::TestACLDeniedAttribute(nlTestSuite * apSuite, void * apCo chip::app::ReadClient::InteractionType::Subscribe); chip::app::AttributePathParams attributePathParams[2]; - attributePathParams[0].mEndpointId = kTestEndpointId; - attributePathParams[0].mClusterId = kTestDeniedClusterId1; + attributePathParams[0].mEndpointId = chip::Test::kTestEndpointId; + attributePathParams[0].mClusterId = chip::Test::kTestDeniedClusterId1; attributePathParams[0].mAttributeId = 1; - attributePathParams[1].mEndpointId = kTestEndpointId; - attributePathParams[1].mClusterId = kTestDeniedClusterId1; + attributePathParams[1].mEndpointId = chip::Test::kTestEndpointId; + attributePathParams[1].mClusterId = chip::Test::kTestDeniedClusterId1; attributePathParams[1].mAttributeId = 2; ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); @@ -194,10 +175,10 @@ void TestAclAttribute::TestACLDeniedAttribute(nlTestSuite * apSuite, void * apCo chip::app::AttributePathParams attributePathParams[2]; - attributePathParams[0].mClusterId = kTestDeniedClusterId2; + attributePathParams[0].mClusterId = chip::Test::kTestDeniedClusterId2; attributePathParams[0].mAttributeId = 1; - attributePathParams[1].mClusterId = kTestDeniedClusterId2; + attributePathParams[1].mClusterId = chip::Test::kTestDeniedClusterId2; attributePathParams[1].mAttributeId = 2; ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); @@ -219,12 +200,12 @@ void TestAclAttribute::TestACLDeniedAttribute(nlTestSuite * apSuite, void * apCo chip::app::ReadClient::InteractionType::Subscribe); chip::app::AttributePathParams attributePathParams[2]; - attributePathParams[0].mEndpointId = kTestEndpointId; - attributePathParams[0].mClusterId = kTestDeniedClusterId1; + attributePathParams[0].mEndpointId = chip::Test::kTestEndpointId; + attributePathParams[0].mClusterId = chip::Test::kTestDeniedClusterId1; attributePathParams[0].mAttributeId = 1; - attributePathParams[1].mEndpointId = kTestEndpointId; - attributePathParams[1].mClusterId = kTestClusterId; + attributePathParams[1].mEndpointId = chip::Test::kTestEndpointId; + attributePathParams[1].mClusterId = chip::Test::kTestClusterId; attributePathParams[1].mAttributeId = 2; ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); diff --git a/src/app/tests/TestAttributeAccessInterfaceCache.cpp b/src/app/tests/TestAttributeAccessInterfaceCache.cpp index 47b8e6d921de94..28aa91db42b16f 100644 --- a/src/app/tests/TestAttributeAccessInterfaceCache.cpp +++ b/src/app/tests/TestAttributeAccessInterfaceCache.cpp @@ -18,15 +18,15 @@ #include #include -#include -#include +#include +#include using namespace chip; using namespace chip::app; namespace { -void TestBasicLifecycle(nlTestSuite * inSuite, void * inContext) +TEST(TestAttributeAccessInterfaceCache, TestBasicLifecycle) { using CacheResult = AttributeAccessInterfaceCache::CacheResult; @@ -44,86 +44,58 @@ void TestBasicLifecycle(nlTestSuite * inSuite, void * inContext) // Cache can keep track of at least 1 entry, AttributeAccessInterface * entry = nullptr; - NL_TEST_ASSERT(inSuite, cache.Get(1, 1, &entry) == CacheResult::kCacheMiss); - NL_TEST_ASSERT(inSuite, entry == nullptr); + EXPECT_EQ(cache.Get(1, 1, &entry), CacheResult::kCacheMiss); + EXPECT_EQ(entry, nullptr); cache.MarkUsed(1, 1, accessor1); - NL_TEST_ASSERT(inSuite, cache.Get(1, 1, &entry) == CacheResult::kDefinitelyUsed); - NL_TEST_ASSERT(inSuite, entry == accessor1); + EXPECT_EQ(cache.Get(1, 1, &entry), CacheResult::kDefinitelyUsed); + EXPECT_EQ(entry, accessor1); entry = nullptr; - NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kCacheMiss); - NL_TEST_ASSERT(inSuite, entry == nullptr); - NL_TEST_ASSERT(inSuite, cache.Get(2, 1, &entry) == CacheResult::kCacheMiss); - NL_TEST_ASSERT(inSuite, entry == nullptr); + EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kCacheMiss); + EXPECT_EQ(entry, nullptr); + EXPECT_EQ(cache.Get(2, 1, &entry), CacheResult::kCacheMiss); + EXPECT_EQ(entry, nullptr); cache.MarkUsed(1, 2, accessor1); entry = nullptr; - NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kDefinitelyUsed); - NL_TEST_ASSERT(inSuite, entry == accessor1); - NL_TEST_ASSERT(inSuite, cache.Get(2, 1, &entry) == CacheResult::kCacheMiss); + EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kDefinitelyUsed); + EXPECT_EQ(entry, accessor1); + EXPECT_EQ(cache.Get(2, 1, &entry), CacheResult::kCacheMiss); cache.MarkUsed(1, 2, accessor2); entry = nullptr; - NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kDefinitelyUsed); - NL_TEST_ASSERT(inSuite, entry == accessor2); + EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kDefinitelyUsed); + EXPECT_EQ(entry, accessor2); // The following should not crash (e.g. output not used if nullptr). - NL_TEST_ASSERT(inSuite, cache.Get(1, 2, nullptr) == CacheResult::kDefinitelyUsed); + EXPECT_EQ(cache.Get(1, 2, nullptr), CacheResult::kDefinitelyUsed); // Setting used to nullptr == does not mark used. cache.MarkUsed(1, 2, nullptr); entry = nullptr; - NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kCacheMiss); - NL_TEST_ASSERT(inSuite, entry == nullptr); + EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kCacheMiss); + EXPECT_EQ(entry, nullptr); cache.Invalidate(); - NL_TEST_ASSERT(inSuite, cache.Get(1, 1, &entry) == CacheResult::kCacheMiss); - NL_TEST_ASSERT(inSuite, entry == nullptr); - NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kCacheMiss); - NL_TEST_ASSERT(inSuite, cache.Get(2, 1, &entry) == CacheResult::kCacheMiss); + EXPECT_EQ(cache.Get(1, 1, &entry), CacheResult::kCacheMiss); + EXPECT_EQ(entry, nullptr); + EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kCacheMiss); + EXPECT_EQ(cache.Get(2, 1, &entry), CacheResult::kCacheMiss); // Marking unused works, keeps single entry, and is invalidated when invalidated fully. - NL_TEST_ASSERT(inSuite, cache.Get(2, 2, nullptr) != CacheResult::kDefinitelyUnused); - NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) != CacheResult::kDefinitelyUnused); + EXPECT_NE(cache.Get(2, 2, nullptr), CacheResult::kDefinitelyUnused); + EXPECT_NE(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused); cache.MarkUnused(2, 2); - NL_TEST_ASSERT(inSuite, cache.Get(2, 2, nullptr) == CacheResult::kDefinitelyUnused); - NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) != CacheResult::kDefinitelyUnused); + EXPECT_EQ(cache.Get(2, 2, nullptr), CacheResult::kDefinitelyUnused); + EXPECT_NE(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused); cache.MarkUnused(3, 3); - NL_TEST_ASSERT(inSuite, cache.Get(2, 2, nullptr) != CacheResult::kDefinitelyUnused); - NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) == CacheResult::kDefinitelyUnused); + EXPECT_NE(cache.Get(2, 2, nullptr), CacheResult::kDefinitelyUnused); + EXPECT_EQ(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused); cache.Invalidate(); - NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) != CacheResult::kDefinitelyUnused); + EXPECT_NE(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused); } - -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("Basic AttributeAccessInterfaceCache lifecycle works", TestBasicLifecycle), - NL_TEST_SENTINEL() -}; -// clang-format on - } // namespace - -int TestAttributeAccessInterfaceCache() -{ - // clang-format off - nlTestSuite theSuite = - { - "Test for AttributeAccessInterface cache utility", - &sTests[0], - nullptr, - nullptr - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestAttributeAccessInterfaceCache) diff --git a/src/app/tests/TestAttributePathExpandIterator.cpp b/src/app/tests/TestAttributePathExpandIterator.cpp index e5505320193b81..032581bff16f8a 100644 --- a/src/app/tests/TestAttributePathExpandIterator.cpp +++ b/src/app/tests/TestAttributePathExpandIterator.cpp @@ -26,10 +26,10 @@ #include #include #include -#include #include -#include +#include +#include using namespace chip; using namespace chip::Test; @@ -39,7 +39,7 @@ namespace { using P = app::ConcreteAttributePath; -void TestAllWildcard(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestAllWildcard) { SingleLinkedListNode clusInfo; @@ -136,17 +136,18 @@ void TestAllWildcard(nlTestSuite * apSuite, void * apContext) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -void TestWildcardEndpoint(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestWildcardEndpoint) { SingleLinkedListNode clusInfo; - clusInfo.mValue.mClusterId = Test::MockClusterId(3); - clusInfo.mValue.mAttributeId = Test::MockAttributeId(3); + clusInfo.mValue.mClusterId = chip::Test::MockClusterId(3); + clusInfo.mValue.mAttributeId = chip::Test::MockAttributeId(3); app::ConcreteAttributePath path; P paths[] = { @@ -159,16 +160,17 @@ void TestWildcardEndpoint(nlTestSuite * apSuite, void * apContext) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -void TestWildcardCluster(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestWildcardCluster) { SingleLinkedListNode clusInfo; - clusInfo.mValue.mEndpointId = Test::kMockEndpoint3; + clusInfo.mValue.mEndpointId = chip::Test::kMockEndpoint3; clusInfo.mValue.mAttributeId = app::Clusters::Globals::Attributes::ClusterRevision::Id; app::ConcreteAttributePath path; @@ -185,16 +187,17 @@ void TestWildcardCluster(nlTestSuite * apSuite, void * apContext) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -void TestWildcardClusterGlobalAttributeNotInMetadata(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestWildcardClusterGlobalAttributeNotInMetadata) { SingleLinkedListNode clusInfo; - clusInfo.mValue.mEndpointId = Test::kMockEndpoint3; + clusInfo.mValue.mEndpointId = chip::Test::kMockEndpoint3; clusInfo.mValue.mAttributeId = app::Clusters::Globals::Attributes::AttributeList::Id; app::ConcreteAttributePath path; @@ -211,17 +214,18 @@ void TestWildcardClusterGlobalAttributeNotInMetadata(nlTestSuite * apSuite, void { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -void TestWildcardAttribute(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestWildcardAttribute) { SingleLinkedListNode clusInfo; - clusInfo.mValue.mEndpointId = Test::kMockEndpoint2; - clusInfo.mValue.mClusterId = Test::MockClusterId(3); + clusInfo.mValue.mEndpointId = chip::Test::kMockEndpoint2; + clusInfo.mValue.mClusterId = chip::Test::MockClusterId(3); app::ConcreteAttributePath path; P paths[] = { @@ -244,18 +248,19 @@ void TestWildcardAttribute(nlTestSuite * apSuite, void * apContext) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -void TestNoWildcard(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestNoWildcard) { SingleLinkedListNode clusInfo; - clusInfo.mValue.mEndpointId = Test::kMockEndpoint2; - clusInfo.mValue.mClusterId = Test::MockClusterId(3); - clusInfo.mValue.mAttributeId = Test::MockAttributeId(3); + clusInfo.mValue.mEndpointId = chip::Test::kMockEndpoint2; + clusInfo.mValue.mClusterId = chip::Test::MockClusterId(3); + clusInfo.mValue.mAttributeId = chip::Test::MockAttributeId(3); app::ConcreteAttributePath path; P paths[] = { @@ -268,33 +273,34 @@ void TestNoWildcard(nlTestSuite * apSuite, void * apContext) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -void TestMultipleClusInfo(nlTestSuite * apSuite, void * apContext) +TEST(TestAttributePathExpandIterator, TestMultipleClusInfo) { SingleLinkedListNode clusInfo1; SingleLinkedListNode clusInfo2; - clusInfo2.mValue.mClusterId = Test::MockClusterId(3); - clusInfo2.mValue.mAttributeId = Test::MockAttributeId(3); + clusInfo2.mValue.mClusterId = chip::Test::MockClusterId(3); + clusInfo2.mValue.mAttributeId = chip::Test::MockAttributeId(3); SingleLinkedListNode clusInfo3; - clusInfo3.mValue.mEndpointId = Test::kMockEndpoint3; + clusInfo3.mValue.mEndpointId = chip::Test::kMockEndpoint3; clusInfo3.mValue.mAttributeId = app::Clusters::Globals::Attributes::ClusterRevision::Id; SingleLinkedListNode clusInfo4; - clusInfo4.mValue.mEndpointId = Test::kMockEndpoint2; - clusInfo4.mValue.mClusterId = Test::MockClusterId(3); + clusInfo4.mValue.mEndpointId = chip::Test::kMockEndpoint2; + clusInfo4.mValue.mClusterId = chip::Test::MockClusterId(3); SingleLinkedListNode clusInfo5; - clusInfo5.mValue.mEndpointId = Test::kMockEndpoint2; - clusInfo5.mValue.mClusterId = Test::MockClusterId(3); - clusInfo5.mValue.mAttributeId = Test::MockAttributeId(3); + clusInfo5.mValue.mEndpointId = chip::Test::kMockEndpoint2; + clusInfo5.mValue.mClusterId = chip::Test::MockClusterId(3); + clusInfo5.mValue.mAttributeId = chip::Test::MockAttributeId(3); clusInfo1.mpNext = &clusInfo2; clusInfo2.mpNext = &clusInfo3; @@ -411,60 +417,11 @@ void TestMultipleClusInfo(nlTestSuite * apSuite, void * apContext) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); - NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path); + EXPECT_LT(index, ArraySize(paths)); + EXPECT_EQ(paths[index], path); index++; } - NL_TEST_ASSERT(apSuite, index == ArraySize(paths)); + EXPECT_EQ(index, ArraySize(paths)); } -static int TestSetup(void * inContext) -{ - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - return SUCCESS; -} - -/** - * Test Suite. It lists all the test functions. - */ - -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("TestAllWildcard", TestAllWildcard), - NL_TEST_DEF("TestWildcardEndpoint", TestWildcardEndpoint), - NL_TEST_DEF("TestWildcardCluster", TestWildcardCluster), - NL_TEST_DEF("TestWildcardClusterGlobalAttributeNotInMetadata", - TestWildcardClusterGlobalAttributeNotInMetadata), - NL_TEST_DEF("TestWildcardAttribute", TestWildcardAttribute), - NL_TEST_DEF("TestNoWildcard", TestNoWildcard), - NL_TEST_DEF("TestMultipleClusInfo", TestMultipleClusInfo), - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -nlTestSuite sSuite = -{ - "TestAttributePathExpandIterator", - &sTests[0], - TestSetup, - TestTeardown, -}; -// clang-format on - } // namespace - -int TestAttributePathExpandIterator() -{ - nlTestRunner(&sSuite, nullptr); - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestAttributePathExpandIterator) diff --git a/src/app/tests/TestAttributePersistenceProvider.cpp b/src/app/tests/TestAttributePersistenceProvider.cpp index 9c75715d14e03d..7ae40b52402fe0 100644 --- a/src/app/tests/TestAttributePersistenceProvider.cpp +++ b/src/app/tests/TestAttributePersistenceProvider.cpp @@ -16,17 +16,11 @@ * limitations under the License. */ -/** - * @file - * This file implements unit tests for AttributePersistenceProvider - * - */ - #include #include +#include #include -#include -#include +#include using namespace chip; using namespace chip::app; @@ -36,48 +30,36 @@ const ConcreteAttributePath TestConcretePath = ConcreteAttributePath(1, 1, 1); namespace { -/** - * Set up the test suite. - */ -int Test_Setup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - VerifyOrReturnError(error == CHIP_NO_ERROR, FAILURE); - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -int Test_Teardown(void * inContext) +class TestAttributePersistenceProvider : public ::testing::Test { - chip::Platform::MemoryShutdown(); - return SUCCESS; -} +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; /** * Tests the storage and retrival of data from the KVS as ByteSpan */ -void TestStorageAndRetrivalByteSpans(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalByteSpans) { TestPersistentStorageDelegate storageDelegate; DefaultAttributePersistenceProvider persistenceProvider; // Init ChipError err = persistenceProvider.Init(&storageDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Store ByteSpan of size 1 uint8_t valueArray[1] = { 0x42 }; ByteSpan value(valueArray); err = persistenceProvider.SafeWriteValue(TestConcretePath, value); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint8_t getArray[1]; MutableByteSpan valueReadBack(getArray); err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end())); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end())); // Finishing persistenceProvider.Shutdown(); @@ -89,17 +71,16 @@ void TestStorageAndRetrivalByteSpans(nlTestSuite * inSuite, void * inContext) * @param testValue The test value to store and retrieve */ template -void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttributePersistenceProvider & persistenceProvider, - T testValue) +void testHelperStorageAndRetrivalScalarValues(DefaultAttributePersistenceProvider & persistenceProvider, T testValue) { CHIP_ERROR err = persistenceProvider.WriteScalarValue(TestConcretePath, testValue); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); T valueReadBack = 0; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, valueReadBack == testValue); + EXPECT_EQ(valueReadBack, testValue); } /** @@ -108,55 +89,55 @@ void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttr * @param testValue The test value to store and retrieve */ template -void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttributePersistenceProvider & persistenceProvider, +void testHelperStorageAndRetrivalScalarValues(DefaultAttributePersistenceProvider & persistenceProvider, DataModel::Nullable testValue) { CHIP_ERROR err = persistenceProvider.WriteScalarValue(TestConcretePath, testValue); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DataModel::Nullable valueReadBack(0); err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, valueReadBack == testValue); + EXPECT_EQ(valueReadBack, testValue); } /** * Tests the storage and retrival of data from the KVS of types bool, uint8_t, uint16_t, uint32_t, uint64_t. */ -void TestStorageAndRetrivalScalarValues(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalScalarValues) { TestPersistentStorageDelegate storageDelegate; DefaultAttributePersistenceProvider persistenceProvider; // Init CHIP_ERROR err = persistenceProvider.Init(&storageDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Test bool - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(true)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(false)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(true)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, bool(true)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, bool(false)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, bool(true)); // Test uint8_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(42)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(0xff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint8_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint8_t(42)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint8_t(0xff)); // Test uint16_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0x0101)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0xffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint16_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint16_t(0x0101)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint16_t(0xffff)); // Test uint32_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0x01ffff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0xffffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint32_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint32_t(0x01ffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint32_t(0xffffffff)); // Test uint64_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0x0100000001)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0xffffffffffffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint64_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint64_t(0x0100000001)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint64_t(0xffffffffffffffff)); // Finishing persistenceProvider.Shutdown(); @@ -165,34 +146,34 @@ void TestStorageAndRetrivalScalarValues(nlTestSuite * inSuite, void * inContext) /** * Tests the storage and retrival of data from the KVS of types int8_t, int16_t, int32_t, int64_t. */ -void TestStorageAndRetrivalSignedScalarValues(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalSignedScalarValues) { TestPersistentStorageDelegate storageDelegate; DefaultAttributePersistenceProvider persistenceProvider; // Init CHIP_ERROR err = persistenceProvider.Init(&storageDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Test int8_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(42)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(-127)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int8_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int8_t(42)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int8_t(-127)); // Test int16_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0x7fff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0x8000)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int16_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int16_t(0x7fff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int16_t(0x8000)); // Test int32_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0x7fffffff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0x80000000)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int32_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int32_t(0x7fffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int32_t(0x80000000)); // Test int64_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0x7fffffffffffffff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0x8000000000000000)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int64_t(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int64_t(0x7fffffffffffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, int64_t(0x8000000000000000)); // Finishing persistenceProvider.Shutdown(); @@ -201,54 +182,54 @@ void TestStorageAndRetrivalSignedScalarValues(nlTestSuite * inSuite, void * inCo /** * Tests the storage and retrival of data from the KVS of DataModel::Nullable types bool, uint8_t, uint16_t, uint32_t, uint64_t. */ -void TestStorageAndRetrivalNullableScalarValues(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalNullableScalarValues) { TestPersistentStorageDelegate storageDelegate; DefaultAttributePersistenceProvider persistenceProvider; // Init CHIP_ERROR err = persistenceProvider.Init(&storageDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Test bool - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(true)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(false)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(true)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(true)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(false)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(true)); auto nullValBool = DataModel::Nullable(); nullValBool.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullValBool); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullValBool); // Test uint8_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(42)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0xfe)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(42)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0xfe)); auto nullVal8 = DataModel::Nullable(); nullVal8.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal8); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal8); // Test uint16_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0x0101)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0xfffe)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0x0101)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0xfffe)); auto nullVal16 = DataModel::Nullable(); nullVal16.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal16); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal16); // Test uint32_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0x01ffff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0xfffffffe)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0x01ffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0xfffffffe)); auto nullVal32 = DataModel::Nullable(); nullVal32.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal32); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal32); // Test uint64_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0x0100000001)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0xfffffffffffffffe)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0x0100000001)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0xfffffffffffffffe)); auto nullVal64 = DataModel::Nullable(); nullVal64.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal64); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal64); // Finishing persistenceProvider.Shutdown(); @@ -257,46 +238,46 @@ void TestStorageAndRetrivalNullableScalarValues(nlTestSuite * inSuite, void * in /** * Tests the storage and retrival of data from the KVS of DataModel::Nullable types int8_t, int16_t, int32_t, int64_t. */ -void TestStorageAndRetrivalSignedNullableScalarValues(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalSignedNullableScalarValues) { TestPersistentStorageDelegate storageDelegate; DefaultAttributePersistenceProvider persistenceProvider; // Init CHIP_ERROR err = persistenceProvider.Init(&storageDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Test int8_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(42)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(-127)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(42)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(-127)); auto nullVal8 = DataModel::Nullable(); nullVal8.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal8); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal8); // Test int16_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0x7fff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(-0x7fff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0x7fff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(-0x7fff)); auto nullVal16 = DataModel::Nullable(); nullVal16.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal16); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal16); // Test int32_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0x7fffffff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(-0x7fffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0x7fffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(-0x7fffffff)); auto nullVal32 = DataModel::Nullable(); nullVal32.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal32); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal32); // Test int64_t - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(0x7fffffffffffffff)); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable(-0x7fffffffffffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(0x7fffffffffffffff)); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable(-0x7fffffffffffffff)); auto nullVal64 = DataModel::Nullable(); nullVal64.SetNull(); - testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal64); + testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal64); // Finishing persistenceProvider.Shutdown(); @@ -305,85 +286,62 @@ void TestStorageAndRetrivalSignedNullableScalarValues(nlTestSuite * inSuite, voi /** * Test that the correct error is given when trying to read a value with a buffer that's too small. */ -void TestBufferTooSmallErrors(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAttributePersistenceProvider, TestBufferTooSmallErrors) { TestPersistentStorageDelegate storageDelegate; DefaultAttributePersistenceProvider persistenceProvider; // Init CHIP_ERROR err = persistenceProvider.Init(&storageDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Store large data uint8_t valueArray[9] = { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 }; ByteSpan value(valueArray); err = persistenceProvider.SafeWriteValue(TestConcretePath, value); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Confirm the daya is there uint8_t getArray[9]; MutableByteSpan valueReadBack(getArray); err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end())); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end())); // Fail to get data as ByteSpace of size 0 uint8_t getArray0[0]; MutableByteSpan valueReadBackByteSpan0(getArray0, 0); err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBackByteSpan0); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); // Fail to get data as ByteSpace of size > 0 but < required uint8_t getArray8[8]; MutableByteSpan valueReadBackByteSpan8(getArray8, sizeof(getArray8)); err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBackByteSpan8); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); // Fail to get value as uint8_t uint8_t valueReadBack8; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack8); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); // Fail to get value as uint16_t uint16_t valueReadBack16; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack16); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); // Fail to get value as uint32_t uint32_t valueReadBack32; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack32); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); // Fail to get value as uint64_t uint64_t valueReadBack64; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack64); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); // Finishing persistenceProvider.Shutdown(); } } // anonymous namespace - -namespace { -const nlTest sTests[] = { - NL_TEST_DEF("Storage and retrival of ByteSpans", TestStorageAndRetrivalByteSpans), - NL_TEST_DEF("Storage and retrival of unsigned scalar values", TestStorageAndRetrivalScalarValues), - NL_TEST_DEF("Storage and retrival of signed scalar values", TestStorageAndRetrivalSignedScalarValues), - NL_TEST_DEF("Storage and retrival of unsigned nullable scalar values", TestStorageAndRetrivalNullableScalarValues), - NL_TEST_DEF("Storage and retrival of signed nullable scalar values", TestStorageAndRetrivalSignedNullableScalarValues), - NL_TEST_DEF("Small buffer errors", TestBufferTooSmallErrors), - NL_TEST_SENTINEL() -}; -} - -int TestAttributePersistenceProvider() -{ - nlTestSuite theSuite = { "AttributePersistenceProvider", &sTests[0], Test_Setup, Test_Teardown }; - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestAttributePersistenceProvider) diff --git a/src/app/tests/TestAttributeValueDecoder.cpp b/src/app/tests/TestAttributeValueDecoder.cpp index c25738588e6afa..b48cd230ea2537 100644 --- a/src/app/tests/TestAttributeValueDecoder.cpp +++ b/src/app/tests/TestAttributeValueDecoder.cpp @@ -16,18 +16,13 @@ * limitations under the License. */ -/** - * @file - * This file implements unit tests for CommandPathParams - * - */ +#include +#include #include #include #include #include -#include -#include using namespace chip; using namespace chip::app; @@ -62,7 +57,7 @@ struct TestSetup TLVWriter writer; }; -void TestOverwriteFabricIndexInStruct(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueDecoder, TestOverwriteFabricIndexInStruct) { TestSetup setup; CHIP_ERROR err; @@ -73,29 +68,29 @@ void TestOverwriteFabricIndexInStruct(nlTestSuite * aSuite, void * aContext) item.fabricIndex = 0; err = setup.Encode(item); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); TLV::TLVReader reader; TLVType ignored; reader.Init(setup.buf, setup.writer.GetLengthWritten()); err = reader.Next(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.EnterContainer(ignored); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Next(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); AttributeValueDecoder decoder(reader, subjectDescriptor); err = decoder.Decode(decodeItem); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, decodeItem.fabricIndex == kTestFabricIndex); + EXPECT_EQ(decodeItem.fabricIndex, kTestFabricIndex); } -void TestOverwriteFabricIndexInListOfStructs(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueDecoder, TestOverwriteFabricIndexInListOfStructs) { TestSetup setup; CHIP_ERROR err; @@ -109,7 +104,7 @@ void TestOverwriteFabricIndexInListOfStructs(nlTestSuite * aSuite, void * aConte } err = setup.Encode(DataModel::List(items)); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); TLV::TLVReader reader; TLVType ignored; @@ -118,44 +113,27 @@ void TestOverwriteFabricIndexInListOfStructs(nlTestSuite * aSuite, void * aConte reader.Init(setup.buf, setup.writer.GetLengthWritten()); err = reader.Next(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.EnterContainer(ignored); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Next(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); AttributeValueDecoder decoder(reader, subjectDescriptor); err = decoder.Decode(decodeItems); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = decodeItems.ComputeSize(&decodeCount); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, decodeCount == kTestListElements); + EXPECT_EQ(decodeCount, kTestListElements); for (auto iter = decodeItems.begin(); iter.Next();) { const auto & entry = iter.GetValue(); - NL_TEST_ASSERT(aSuite, entry.fabricIndex == kTestFabricIndex); + EXPECT_EQ(entry.fabricIndex, kTestFabricIndex); } } } // anonymous namespace - -namespace { -const nlTest sTests[] = { NL_TEST_DEF("TestOverwriteFabricIndexInStruct", TestOverwriteFabricIndexInStruct), - NL_TEST_DEF("TestOverwriteFabricIndexInListOfStructs", TestOverwriteFabricIndexInListOfStructs), - NL_TEST_SENTINEL() }; -} - -int TestAttributeValueDecoder() -{ - nlTestSuite theSuite = { "AttributeValueDecoder", &sTests[0], nullptr, nullptr }; - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestAttributeValueDecoder) diff --git a/src/app/tests/TestAttributeValueEncoder.cpp b/src/app/tests/TestAttributeValueEncoder.cpp index 085c4f870cdf64..43a015d27c4b9e 100644 --- a/src/app/tests/TestAttributeValueEncoder.cpp +++ b/src/app/tests/TestAttributeValueEncoder.cpp @@ -16,11 +16,10 @@ * limitations under the License. */ -/** - * @file - * This file implements unit tests for CommandPathParams - * - */ +#include + +#include +#include #include #include @@ -30,10 +29,6 @@ #include #include #include -#include -#include - -#include using namespace chip; using namespace chip::app; @@ -75,7 +70,7 @@ Access::SubjectDescriptor DescriptorWithFabric(FabricIndex fabricIndex) template struct LimitedTestSetup { - LimitedTestSetup(nlTestSuite * aSuite, const FabricIndex aFabricIndex = kUndefinedFabricIndex, + LimitedTestSetup(const FabricIndex aFabricIndex = kUndefinedFabricIndex, const AttributeEncodeState & aState = AttributeEncodeState()) : encoder(builder, DescriptorWithFabric(aFabricIndex), ConcreteAttributePath(kRandomEndpointId, kRandomClusterId, kRandomAttributeId), kRandomDataVersion, @@ -85,11 +80,11 @@ struct LimitedTestSetup { TLVType ignored; CHIP_ERROR err = writer.StartContainer(AnonymousTag(), kTLVType_Structure, ignored); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } { CHIP_ERROR err = builder.Init(&writer, 1); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } } @@ -103,11 +98,11 @@ using TestSetup = LimitedTestSetup<1024>; // Macro so we get better error reporting in terms of which test failed, because // the reporting uses __LINE__. -#define VERIFY_BUFFER_STATE(aSuite, aSetup, aExpected) \ +#define VERIFY_BUFFER_STATE(aSetup, aExpected) \ do \ { \ - NL_TEST_ASSERT(aSuite, aSetup.writer.GetLengthWritten() == sizeof(aExpected)); \ - NL_TEST_ASSERT(aSuite, memcmp(aSetup.buf, aExpected, sizeof(aExpected)) == 0); \ + EXPECT_EQ(aSetup.writer.GetLengthWritten(), sizeof(aExpected)); \ + EXPECT_EQ(memcmp(aSetup.buf, aExpected, sizeof(aExpected)), 0); \ if (aSetup.writer.GetLengthWritten() != sizeof(aExpected) || memcmp(aSetup.buf, aExpected, sizeof(aExpected)) != 0) \ { \ printf("Encoded: \n"); \ @@ -125,19 +120,19 @@ using TestSetup = LimitedTestSetup<1024>; } \ } while (0) -void TestEncodeNothing(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeNothing) { - TestSetup test(aSuite); + TestSetup test{}; // Just have an anonymous struct marker, and the AttributeReportIBs opened. const uint8_t expected[] = { 0x15, 0x36, 0x01 }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeBool(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeBool) { - TestSetup test(aSuite); + TestSetup test{}; CHIP_ERROR err = test.encoder.Encode(true); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off 0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01) @@ -154,15 +149,15 @@ void TestEncodeBool(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeListOfBools1(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeListOfBools1) { - TestSetup test(aSuite); + TestSetup test{}; bool list[] = { true, false }; CHIP_ERROR err = test.encoder.Encode(DataModel::List(list)); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off 0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01) @@ -182,12 +177,12 @@ void TestEncodeListOfBools1(nlTestSuite * aSuite, void * aContext) 0x18, // End of attribute structure // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeListOfBools2(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeListOfBools2) { - TestSetup test(aSuite); + TestSetup test{}; bool list[] = { true, false }; CHIP_ERROR err = test.encoder.EncodeList([&list](const auto & encoder) -> CHIP_ERROR { for (auto & item : list) @@ -196,7 +191,7 @@ void TestEncodeListOfBools2(nlTestSuite * aSuite, void * aContext) } return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off 0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01) @@ -216,7 +211,7 @@ void TestEncodeListOfBools2(nlTestSuite * aSuite, void * aContext) 0x18, // End of attribute structure // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } constexpr uint8_t emptyListExpected[] = { @@ -238,25 +233,25 @@ constexpr uint8_t emptyListExpected[] = { // clang-format on }; -void TestEncodeEmptyList1(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeEmptyList1) { - TestSetup test(aSuite); + TestSetup test{}; CHIP_ERROR err = test.encoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); - VERIFY_BUFFER_STATE(aSuite, test, emptyListExpected); + EXPECT_EQ(err, CHIP_NO_ERROR); + VERIFY_BUFFER_STATE(test, emptyListExpected); } -void TestEncodeEmptyList2(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeEmptyList2) { - TestSetup test(aSuite); + TestSetup test{}; CHIP_ERROR err = test.encoder.EncodeEmptyList(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); - VERIFY_BUFFER_STATE(aSuite, test, emptyListExpected); + EXPECT_EQ(err, CHIP_NO_ERROR); + VERIFY_BUFFER_STATE(test, emptyListExpected); } -void TestEncodeFabricScoped(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeFabricScoped) { - TestSetup test(aSuite, kTestFabricIndex); + TestSetup test(kTestFabricIndex); Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type items[3]; items[0].fabricIndex = 1; items[1].fabricIndex = 2; @@ -270,7 +265,7 @@ void TestEncodeFabricScoped(nlTestSuite * aSuite, void * aContext) } return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off 0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01) @@ -292,10 +287,10 @@ void TestEncodeFabricScoped(nlTestSuite * aSuite, void * aContext) 0x18, // End of attribute structure // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeListChunking) { AttributeEncodeState state; @@ -316,9 +311,9 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext) // corresponding to the "test overhead" container starts. But TLVWriter automatically // reserves space when containers are opened, so we have to have enough space to have // encoded those last two close containers. - LimitedTestSetup<30> test1(aSuite, kTestFabricIndex); + LimitedTestSetup<30> test1(kTestFabricIndex); CHIP_ERROR err = test1.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); state = test1.encoder.GetState(); const uint8_t expected[] = { @@ -340,14 +335,14 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext) 0x18, // End of attribute structure // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test1, expected); + VERIFY_BUFFER_STATE(test1, expected); } { // Use 30 bytes buffer to force chunking after the second "false". The kTestFabricIndex is // not effective in this test. - LimitedTestSetup<30> test2(aSuite, 0, state); + LimitedTestSetup<30> test2(0, state); CHIP_ERROR err = test2.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); state = test2.encoder.GetState(); const uint8_t expected[] = { @@ -367,13 +362,13 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test2, expected); + VERIFY_BUFFER_STATE(test2, expected); } { // Allow encoding everything else. The kTestFabricIndex is not effective in this test. - TestSetup test3(aSuite, 0, state); + TestSetup test3(0, state); CHIP_ERROR err = test3.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off @@ -416,11 +411,11 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test3, expected); + VERIFY_BUFFER_STATE(test3, expected); } } -void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeListChunking2) { AttributeEncodeState state; @@ -441,9 +436,9 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext) // corresponding to the "test overhead" container starts. But TLVWriter automatically // reserves space when containers are opened, so we have to have enough space to have // encoded those last two close containers. - LimitedTestSetup<28> test1(aSuite, kTestFabricIndex); + LimitedTestSetup<28> test1(kTestFabricIndex); CHIP_ERROR err = test1.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); state = test1.encoder.GetState(); const uint8_t expected[] = { @@ -463,14 +458,14 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext) 0x18, // End of attribute structure // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test1, expected); + VERIFY_BUFFER_STATE(test1, expected); } { // Use 30 bytes buffer to force chunking after the first "true". The kTestFabricIndex is not // effective in this test. - LimitedTestSetup<30> test2(aSuite, 0, state); + LimitedTestSetup<30> test2(0, state); CHIP_ERROR err = test2.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); state = test2.encoder.GetState(); const uint8_t expected[] = { @@ -490,14 +485,14 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test2, expected); + VERIFY_BUFFER_STATE(test2, expected); } { // Use 60 bytes buffer to force chunking after the second "false". The kTestFabricIndex is not // effective in this test. - LimitedTestSetup<60> test3(aSuite, 0, state); + LimitedTestSetup<60> test3(0, state); CHIP_ERROR err = test3.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL); state = test3.encoder.GetState(); const uint8_t expected[] = { @@ -529,13 +524,13 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test3, expected); + VERIFY_BUFFER_STATE(test3, expected); } { // Allow encoding everything else. The kTestFabricIndex is not effective in this test. - TestSetup test4(aSuite, 0, state); + TestSetup test4(0, state); CHIP_ERROR err = test4.encoder.EncodeList(listEncoder); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off @@ -578,27 +573,27 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test4, expected); + VERIFY_BUFFER_STATE(test4, expected); } } -void TestEncodePreEncoded(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodePreEncoded) { - TestSetup test(aSuite); + TestSetup test{}; uint8_t buffer[128]; TLV::TLVWriter writer; writer.Init(buffer); // Use a random tag that is not the right tag. CHIP_ERROR err = writer.PutString(TLV::ProfileTag(0x1234abcd, 0x5678fedc), "hello"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); ByteSpan value(buffer, writer.GetLengthWritten()); err = test.encoder.Encode(DataModel::PreEncodedValue(value)); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off @@ -616,12 +611,12 @@ void TestEncodePreEncoded(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeListOfPreEncoded) { - TestSetup test(aSuite); + TestSetup test{}; uint8_t buffers[2][128]; std::optional values[2]; @@ -631,10 +626,10 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext) writer.Init(buffers[0]); // Use a random tag that is not the right tag. CHIP_ERROR err = writer.PutString(TLV::ProfileTag(0x1234abcd, 0x5678fedc), "hello"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); values[0].emplace(ByteSpan(buffers[0], writer.GetLengthWritten())); } @@ -644,10 +639,10 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext) writer.Init(buffers[1]); // Use a random tag that is not the right tag. CHIP_ERROR err = writer.PutString(TLV::ProfileTag(0x1234abcd, 0x00010002), "bye"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); values[1].emplace(ByteSpan(buffers[1], writer.GetLengthWritten())); } @@ -659,7 +654,7 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext) } return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off @@ -680,12 +675,12 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext) 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeListOfFabricScopedPreEncoded) { - TestSetup test(aSuite); + TestSetup test{}; uint8_t buffers[2][128]; std::optional values[2]; @@ -697,19 +692,19 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex TLV::TLVType outerContainerType; CHIP_ERROR err = writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x5678fedc), TLV::kTLVType_Structure, outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutString(TLV::ContextTag(7), "hello"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Put(kFabricIndexTag, kTestFabricIndex); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.EndContainer(outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); values[0].emplace(ByteSpan(buffers[0], writer.GetLengthWritten())); } @@ -721,19 +716,19 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex TLV::TLVType outerContainerType; CHIP_ERROR err = writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x00010002), TLV::kTLVType_Structure, outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutString(TLV::ContextTag(7), "bye"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Put(kFabricIndexTag, static_cast(kTestFabricIndex + 1)); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.EndContainer(outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); values[1].emplace(ByteSpan(buffers[1], writer.GetLengthWritten())); } @@ -745,7 +740,7 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex } return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off @@ -772,12 +767,12 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } -void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aContext) +TEST(TestAttributeValueEncoder, TestEncodeFabricFilteredListOfPreEncoded) { - TestSetup test(aSuite, kTestFabricIndex); + TestSetup test(kTestFabricIndex); uint8_t buffers[2][128]; std::optional values[2]; @@ -789,19 +784,19 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont TLV::TLVType outerContainerType; CHIP_ERROR err = writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x5678fedc), TLV::kTLVType_Structure, outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutString(TLV::ContextTag(7), "hello"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Put(kFabricIndexTag, kTestFabricIndex); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.EndContainer(outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); values[0].emplace(ByteSpan(buffers[0], writer.GetLengthWritten())); } @@ -813,19 +808,19 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont TLV::TLVType outerContainerType; CHIP_ERROR err = writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x00010002), TLV::kTLVType_Structure, outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutString(TLV::ContextTag(7), "bye"); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Put(kFabricIndexTag, static_cast(kTestFabricIndex + 1)); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.EndContainer(outerContainerType); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.Finalize(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); values[1].emplace(ByteSpan(buffers[1], writer.GetLengthWritten())); } @@ -837,7 +832,7 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont } return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const uint8_t expected[] = { // clang-format off @@ -861,42 +856,9 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont 0x18, // End of container // clang-format on }; - VERIFY_BUFFER_STATE(aSuite, test, expected); + VERIFY_BUFFER_STATE(test, expected); } #undef VERIFY_BUFFER_STATE } // anonymous namespace - -namespace { -const nlTest sTests[] = { - // clang-format off - NL_TEST_DEF("TestEncodeNothing", TestEncodeNothing), - NL_TEST_DEF("TestEncodeBool", TestEncodeBool), - NL_TEST_DEF("TestEncodeEmptyList1", TestEncodeEmptyList1), - NL_TEST_DEF("TestEncodeEmptyList2", TestEncodeEmptyList2), - NL_TEST_DEF("TestEncodeListOfBools1", TestEncodeListOfBools1), - NL_TEST_DEF("TestEncodeListOfBools2", TestEncodeListOfBools2), - NL_TEST_DEF("TestEncodeListChunking", TestEncodeListChunking), - NL_TEST_DEF("TestEncodeListChunking2", TestEncodeListChunking2), - NL_TEST_DEF("TestEncodeFabricScoped", TestEncodeFabricScoped), - NL_TEST_DEF("TestEncodePreEncoded", TestEncodePreEncoded), - NL_TEST_DEF("TestEncodeListOfPreEncoded", TestEncodeListOfPreEncoded), - NL_TEST_DEF("TestEncodeListFabricScopedPreEncoded", TestEncodeListOfPreEncoded), - NL_TEST_DEF("TestEncodeListOfFabricScopedPreEncoded", TestEncodeListOfFabricScopedPreEncoded), - NL_TEST_DEF("TestEncodeFabricFilteredListOfPreEncoded", TestEncodeFabricFilteredListOfPreEncoded), - NL_TEST_SENTINEL() - // clang-format on -}; -} - -int TestAttributeValueEncoder() -{ - nlTestSuite theSuite = { "AttributeValueEncoder", &sTests[0], nullptr, nullptr }; - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestAttributeValueEncoder) diff --git a/src/app/tests/TestBindingTable.cpp b/src/app/tests/TestBindingTable.cpp index db95408813a0c1..a4d5d0e2fcf6a7 100644 --- a/src/app/tests/TestBindingTable.cpp +++ b/src/app/tests/TestBindingTable.cpp @@ -15,122 +15,122 @@ * limitations under the License. */ +#include +#include + #include #include #include #include #include -#include using chip::BindingTable; namespace { -void TestEmptyBindingTable(nlTestSuite * aSuite, void * aContext) +void VerifyTableSame(BindingTable & table, const std::vector & expected) +{ + ASSERT_EQ(table.Size(), expected.size()); + auto iter1 = table.begin(); + auto iter2 = expected.begin(); + while (iter2 != expected.end()) + { + EXPECT_EQ(*iter1, *iter2); + ++iter1; + ++iter2; + } + EXPECT_EQ(iter1, table.end()); +} + +void VerifyRestored(chip::TestPersistentStorageDelegate & storage, const std::vector & expected) +{ + BindingTable restoredTable; + restoredTable.SetPersistentStorage(&storage); + EXPECT_EQ(restoredTable.LoadFromStorage(), CHIP_NO_ERROR); + VerifyTableSame(restoredTable, expected); +} + +TEST(TestBindingTable, TestEmptyBindingTable) { BindingTable table; chip::TestPersistentStorageDelegate testStorage; table.SetPersistentStorage(&testStorage); - NL_TEST_ASSERT(aSuite, table.Size() == 0); - NL_TEST_ASSERT(aSuite, table.begin() == table.end()); + EXPECT_EQ(table.Size(), 0u); + EXPECT_EQ(table.begin(), table.end()); } -void TestAdd(nlTestSuite * aSuite, void * aContext) +TEST(TestBindingTable, TestAdd) { BindingTable table; chip::TestPersistentStorageDelegate testStorage; table.SetPersistentStorage(&testStorage); EmberBindingTableEntry unusedEntry; unusedEntry.type = MATTER_UNUSED_BINDING; - NL_TEST_ASSERT(aSuite, table.Add(unusedEntry) == CHIP_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(table.Add(unusedEntry), CHIP_ERROR_INVALID_ARGUMENT); for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++) { - NL_TEST_ASSERT(aSuite, table.Add(EmberBindingTableEntry::ForNode(0, i, 0, 0, std::nullopt)) == CHIP_NO_ERROR); + EXPECT_EQ(table.Add(EmberBindingTableEntry::ForNode(0, i, 0, 0, std::nullopt)), CHIP_NO_ERROR); } - NL_TEST_ASSERT(aSuite, table.Add(EmberBindingTableEntry::ForNode(0, 0, 0, 0, std::nullopt)) == CHIP_ERROR_NO_MEMORY); - NL_TEST_ASSERT(aSuite, table.Size() == MATTER_BINDING_TABLE_SIZE); + EXPECT_EQ(table.Add(EmberBindingTableEntry::ForNode(0, 0, 0, 0, std::nullopt)), CHIP_ERROR_NO_MEMORY); + EXPECT_EQ(table.Size(), MATTER_BINDING_TABLE_SIZE); auto iter = table.begin(); for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++) { - NL_TEST_ASSERT(aSuite, iter != table.end()); - NL_TEST_ASSERT(aSuite, iter->nodeId == i); - NL_TEST_ASSERT(aSuite, iter.GetIndex() == i); + EXPECT_NE(iter, table.end()); + EXPECT_EQ(iter->nodeId, i); + EXPECT_EQ(iter.GetIndex(), i); ++iter; } - NL_TEST_ASSERT(aSuite, iter == table.end()); + EXPECT_EQ(iter, table.end()); } -void TestRemoveThenAdd(nlTestSuite * aSuite, void * aContext) +TEST(TestBindingTable, TestRemoveThenAdd) { BindingTable table; chip::TestPersistentStorageDelegate testStorage; table.SetPersistentStorage(&testStorage); - NL_TEST_ASSERT(aSuite, table.Add(EmberBindingTableEntry::ForNode(0, 0, 0, 0, std::nullopt)) == CHIP_NO_ERROR); + EXPECT_EQ(table.Add(EmberBindingTableEntry::ForNode(0, 0, 0, 0, std::nullopt)), CHIP_NO_ERROR); auto iter = table.begin(); - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, iter == table.end()); - NL_TEST_ASSERT(aSuite, table.Size() == 0); - NL_TEST_ASSERT(aSuite, table.begin() == table.end()); + EXPECT_EQ(table.RemoveAt(iter), CHIP_NO_ERROR); + EXPECT_EQ(iter, table.end()); + EXPECT_EQ(table.Size(), 0u); + EXPECT_EQ(table.begin(), table.end()); for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++) { - NL_TEST_ASSERT(aSuite, table.Add(EmberBindingTableEntry::ForNode(0, i, 0, 0, std::nullopt)) == CHIP_NO_ERROR); + EXPECT_EQ(table.Add(EmberBindingTableEntry::ForNode(0, i, 0, 0, std::nullopt)), CHIP_NO_ERROR); } iter = table.begin(); ++iter; - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, table.Size() == MATTER_BINDING_TABLE_SIZE - 1); - NL_TEST_ASSERT(aSuite, iter->nodeId == 2); - NL_TEST_ASSERT(aSuite, iter.GetIndex() == 2); + EXPECT_EQ(table.RemoveAt(iter), CHIP_NO_ERROR); + EXPECT_EQ(table.Size(), MATTER_BINDING_TABLE_SIZE - 1); + EXPECT_EQ(iter->nodeId, 2u); + EXPECT_EQ(iter.GetIndex(), 2u); auto iterCheck = table.begin(); ++iterCheck; - NL_TEST_ASSERT(aSuite, iter == iterCheck); + EXPECT_EQ(iter, iterCheck); - NL_TEST_ASSERT(aSuite, table.Add(EmberBindingTableEntry::ForNode(0, 1, 0, 0, std::nullopt)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, table.Size() == MATTER_BINDING_TABLE_SIZE); + EXPECT_EQ(table.Add(EmberBindingTableEntry::ForNode(0, 1, 0, 0, std::nullopt)), CHIP_NO_ERROR); + EXPECT_EQ(table.Size(), MATTER_BINDING_TABLE_SIZE); iter = table.begin(); for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE - 1; i++) { ++iter; } - NL_TEST_ASSERT(aSuite, iter->nodeId == 1); - NL_TEST_ASSERT(aSuite, iter.GetIndex() == 1); + EXPECT_EQ(iter->nodeId, 1u); + EXPECT_EQ(iter.GetIndex(), 1u); ++iter; - NL_TEST_ASSERT(aSuite, iter == table.end()); + EXPECT_EQ(iter, table.end()); iter = table.begin(); - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, table.Size() == MATTER_BINDING_TABLE_SIZE - 1); - NL_TEST_ASSERT(aSuite, iter == table.begin()); - NL_TEST_ASSERT(aSuite, iter.GetIndex() == 2); - NL_TEST_ASSERT(aSuite, iter->nodeId == 2); - NL_TEST_ASSERT(aSuite, table.GetAt(0).type == MATTER_UNUSED_BINDING); -} - -void VerifyTableSame(nlTestSuite * aSuite, BindingTable & table, const std::vector & expected) -{ - NL_TEST_ASSERT(aSuite, table.Size() == expected.size()); - auto iter1 = table.begin(); - auto iter2 = expected.begin(); - while (iter2 != expected.end()) - { - NL_TEST_ASSERT(aSuite, iter1 != table.end()); - NL_TEST_ASSERT(aSuite, *iter1 == *iter2); - ++iter1; - ++iter2; - } - NL_TEST_ASSERT(aSuite, iter1 == table.end()); + EXPECT_EQ(table.RemoveAt(iter), CHIP_NO_ERROR); + EXPECT_EQ(table.Size(), MATTER_BINDING_TABLE_SIZE - 1); + EXPECT_EQ(iter, table.begin()); + EXPECT_EQ(iter.GetIndex(), 2u); + EXPECT_EQ(iter->nodeId, 2u); + EXPECT_EQ(table.GetAt(0).type, MATTER_UNUSED_BINDING); } -void VerifyRestored(nlTestSuite * aSuite, chip::TestPersistentStorageDelegate & storage, - const std::vector & expected) -{ - BindingTable restoredTable; - restoredTable.SetPersistentStorage(&storage); - NL_TEST_ASSERT(aSuite, restoredTable.LoadFromStorage() == CHIP_NO_ERROR); - VerifyTableSame(aSuite, restoredTable, expected); -} - -void TestPersistentStorage(nlTestSuite * aSuite, void * aContext) +TEST(TestBindingTable, TestPersistentStorage) { chip::TestPersistentStorageDelegate testStorage; BindingTable table; @@ -142,68 +142,46 @@ void TestPersistentStorage(nlTestSuite * aSuite, void * aContext) EmberBindingTableEntry::ForGroup(3, 3, 0, cluster.std_optional()), }; table.SetPersistentStorage(&testStorage); - NL_TEST_ASSERT(aSuite, table.Add(expected[0]) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, table.Add(expected[1]) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, table.Add(expected[2]) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, table.Add(expected[3]) == CHIP_NO_ERROR); - VerifyRestored(aSuite, testStorage, expected); + EXPECT_EQ(table.Add(expected[0]), CHIP_NO_ERROR); + EXPECT_EQ(table.Add(expected[1]), CHIP_NO_ERROR); + EXPECT_EQ(table.Add(expected[2]), CHIP_NO_ERROR); + EXPECT_EQ(table.Add(expected[3]), CHIP_NO_ERROR); + VerifyRestored(testStorage, expected); // Verify storage untouched if add fails testStorage.AddPoisonKey(chip::DefaultStorageKeyAllocator::BindingTableEntry(4).KeyName()); - NL_TEST_ASSERT(aSuite, table.Add(EmberBindingTableEntry::ForNode(4, 4, 0, 0, std::nullopt)) != CHIP_NO_ERROR); - VerifyRestored(aSuite, testStorage, expected); + EXPECT_NE(table.Add(EmberBindingTableEntry::ForNode(4, 4, 0, 0, std::nullopt)), CHIP_NO_ERROR); + VerifyRestored(testStorage, expected); testStorage.ClearPoisonKeys(); // Verify storage untouched if removing head fails testStorage.AddPoisonKey(chip::DefaultStorageKeyAllocator::BindingTable().KeyName()); auto iter = table.begin(); - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) != CHIP_NO_ERROR); - VerifyTableSame(aSuite, table, expected); + EXPECT_NE(table.RemoveAt(iter), CHIP_NO_ERROR); + VerifyTableSame(table, expected); testStorage.ClearPoisonKeys(); - VerifyRestored(aSuite, testStorage, expected); + VerifyRestored(testStorage, expected); // Verify storage untouched if removing other nodes fails testStorage.AddPoisonKey(chip::DefaultStorageKeyAllocator::BindingTableEntry(0).KeyName()); iter = table.begin(); ++iter; - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) != CHIP_NO_ERROR); - VerifyTableSame(aSuite, table, expected); + EXPECT_NE(table.RemoveAt(iter), CHIP_NO_ERROR); + VerifyTableSame(table, expected); testStorage.ClearPoisonKeys(); - VerifyRestored(aSuite, testStorage, expected); + VerifyRestored(testStorage, expected); // Verify removing head iter = table.begin(); - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) == CHIP_NO_ERROR); - VerifyTableSame(aSuite, table, { expected[1], expected[2], expected[3] }); - VerifyRestored(aSuite, testStorage, { expected[1], expected[2], expected[3] }); + EXPECT_EQ(table.RemoveAt(iter), CHIP_NO_ERROR); + VerifyTableSame(table, { expected[1], expected[2], expected[3] }); + VerifyRestored(testStorage, { expected[1], expected[2], expected[3] }); // Verify removing other nodes ++iter; - NL_TEST_ASSERT(aSuite, table.RemoveAt(iter) == CHIP_NO_ERROR); - VerifyTableSame(aSuite, table, { expected[1], expected[3] }); - VerifyRestored(aSuite, testStorage, { expected[1], expected[3] }); + EXPECT_EQ(table.RemoveAt(iter), CHIP_NO_ERROR); + VerifyTableSame(table, { expected[1], expected[3] }); + VerifyRestored(testStorage, { expected[1], expected[3] }); } } // namespace - -int TestBindingTable() -{ - static nlTest sTests[] = { - NL_TEST_DEF("TestEmptyBindingTable", TestEmptyBindingTable), - NL_TEST_DEF("TestAdd", TestAdd), - NL_TEST_DEF("TestRemoveThenAdd", TestRemoveThenAdd), - NL_TEST_DEF("TestPersistentStorage", TestPersistentStorage), - NL_TEST_SENTINEL(), - }; - - nlTestSuite theSuite = { - "BindingTable", - &sTests[0], - nullptr, - nullptr, - }; - nlTestRunner(&theSuite, nullptr); - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestBindingTable) diff --git a/src/app/tests/TestBuilderParser.cpp b/src/app/tests/TestBuilderParser.cpp index 314353e8b70029..b59042c4aa6dff 100644 --- a/src/app/tests/TestBuilderParser.cpp +++ b/src/app/tests/TestBuilderParser.cpp @@ -25,23 +25,30 @@ #include #include #include -#include #include -#include +#include +#include namespace { using namespace chip::app; -void ListTest(nlTestSuite * apSuite, void * apContext) +class TestBuilderParser : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestBuilderParser, TestList) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); ListBuilder listBuilder; - NL_TEST_ASSERT(apSuite, listBuilder.Init(&writer) == CHIP_NO_ERROR); + EXPECT_EQ(listBuilder.Init(&writer), CHIP_NO_ERROR); listBuilder.EndOfContainer(); chip::System::PacketBufferHandle buf; @@ -50,18 +57,18 @@ void ListTest(nlTestSuite * apSuite, void * apContext) ListParser listParser; reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, listParser.Init(reader) == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(listParser.Init(reader), CHIP_NO_ERROR); } -void StructTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestBuilderParser, TestStruct) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); StructBuilder structBuilder; - NL_TEST_ASSERT(apSuite, structBuilder.Init(&writer) == CHIP_NO_ERROR); + EXPECT_EQ(structBuilder.Init(&writer), CHIP_NO_ERROR); structBuilder.EndOfContainer(); chip::System::PacketBufferHandle buf; @@ -71,17 +78,17 @@ void StructTest(nlTestSuite * apSuite, void * apContext) reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, structParser.Init(reader) == CHIP_NO_ERROR); + EXPECT_EQ(structParser.Init(reader), CHIP_NO_ERROR); } -void ArrayTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestBuilderParser, TestArray) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); ArrayBuilder arrayBuilder; - NL_TEST_ASSERT(apSuite, arrayBuilder.Init(&writer) == CHIP_NO_ERROR); + EXPECT_EQ(arrayBuilder.Init(&writer), CHIP_NO_ERROR); arrayBuilder.EndOfContainer(); chip::System::PacketBufferHandle buf; @@ -91,55 +98,7 @@ void ArrayTest(nlTestSuite * apSuite, void * apContext) reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, arrayParser.Init(reader) == CHIP_NO_ERROR); + EXPECT_EQ(arrayParser.Init(reader), CHIP_NO_ERROR); } -// clang-format off -const nlTest sTests[] = - { - NL_TEST_DEF("ListTest", ListTest), - NL_TEST_DEF("StructTest", StructTest), - NL_TEST_DEF("ArrayTest", ArrayTest), - NL_TEST_SENTINEL() - }; -// clang-format on } // namespace - -/** - * Set up the test suite. - */ -static int TestSetup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -int TestBuilderParser() -{ - // clang-format off - nlTestSuite theSuite = - { - "TestBuilderParser", - &sTests[0], - TestSetup, - TestTeardown, - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestBuilderParser) diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index 195580ce8702a5..dc6b6132341a63 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -87,6 +87,19 @@ constexpr CommandId kTestCommandIdFillResponseMessage = 7; constexpr CommandId kTestNonExistCommandId = 0; const app::CommandSender::TestOnlyMarker kCommandSenderTestOnlyMarker; + +class SimpleTLVPayload : public app::DataModel::EncodableToTLV +{ +public: + CHIP_ERROR EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const override + { + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outerType)); + ReturnErrorOnFailure(writer.PutBoolean(chip::TLV::ContextTag(1), true)); + return writer.EndContainer(outerType); + } +}; + } // namespace namespace app { @@ -199,12 +212,8 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPat } else { - const CommandHandler::InvokeResponseParameters prepareParams(aRequestCommandPath); - const ConcreteCommandPath responseCommandPath = aRequestCommandPath; - apCommandObj->PrepareInvokeResponseCommand(responseCommandPath, prepareParams); - chip::TLV::TLVWriter * writer = apCommandObj->GetCommandDataIBTLVWriter(); - writer->PutBoolean(chip::TLV::ContextTag(1), true); - apCommandObj->FinishCommand(); + SimpleTLVPayload payloadWriter; + apCommandObj->AddResponse(aRequestCommandPath, aRequestCommandPath.mCommandId, payloadWriter); } } @@ -597,8 +606,6 @@ void TestCommandInteraction::AddInvalidInvokeRequestData(nlTestSuite * apSuite, void TestCommandInteraction::AddInvokeResponseData(nlTestSuite * apSuite, void * apContext, CommandHandler * apCommandHandler, bool aNeedStatusCode, CommandId aResponseCommandId, CommandId aRequestCommandId) { - CHIP_ERROR err = CHIP_NO_ERROR; - constexpr EndpointId kTestEndpointId = 1; constexpr ClusterId kTestClusterId = 3; ConcreteCommandPath requestCommandPath = { kTestEndpointId, kTestClusterId, aRequestCommandId }; @@ -608,17 +615,8 @@ void TestCommandInteraction::AddInvokeResponseData(nlTestSuite * apSuite, void * } else { - const CommandHandler::InvokeResponseParameters prepareParams(requestCommandPath); - ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, aResponseCommandId }; - err = apCommandHandler->PrepareInvokeResponseCommand(responseCommandPath, prepareParams); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - - chip::TLV::TLVWriter * writer = apCommandHandler->GetCommandDataIBTLVWriter(); - - err = writer->PutBoolean(chip::TLV::ContextTag(1), true); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - - err = apCommandHandler->FinishCommand(); + SimpleTLVPayload payloadWriter; + CHIP_ERROR err = apCommandHandler->AddResponseData(requestCommandPath, aResponseCommandId, payloadWriter); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); } } diff --git a/src/app/tests/TestDefaultICDClientStorage.cpp b/src/app/tests/TestDefaultICDClientStorage.cpp index 62787a2c9e4144..8cf4c8d86fa2a1 100644 --- a/src/app/tests/TestDefaultICDClientStorage.cpp +++ b/src/app/tests/TestDefaultICDClientStorage.cpp @@ -15,9 +15,9 @@ * limitations under the License. */ +#include #include -#include -#include +#include #include #include @@ -55,7 +55,14 @@ struct TestClientInfo : public ICDClientInfo } }; -void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) +class TestDefaultICDClientStorage : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestDefaultICDClientStorage, TestClientInfoCount) { CHIP_ERROR err = CHIP_NO_ERROR; FabricIndex fabricId = 1; @@ -67,9 +74,9 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) { DefaultICDClientStorage manager; err = manager.Init(&clientInfoStorage, &keystore); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.UpdateFabricList(fabricId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Write some ClientInfos and see the counts are correct ICDClientInfo clientInfo1; clientInfo1.peer_node = ScopedNodeId(nodeId1, fabricId); @@ -78,38 +85,38 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) ICDClientInfo clientInfo3; clientInfo3.peer_node = ScopedNodeId(nodeId1, fabricId); err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo1); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo2); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo3); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); ICDClientInfo clientInfo; // Make sure iterator counts correctly auto * iterator = manager.IterateICDClientInfo(); // same nodeId for clientInfo2 and clientInfo3, so the new one replace old one - NL_TEST_ASSERT(apSuite, iterator->Count() == 2); + EXPECT_EQ(iterator->Count(), 2u); - NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo)); - NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId2); - NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo)); - NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId1); + EXPECT_TRUE(iterator->Next(clientInfo)); + EXPECT_EQ(clientInfo.peer_node.GetNodeId(), nodeId2); + EXPECT_TRUE(iterator->Next(clientInfo)); + EXPECT_EQ(clientInfo.peer_node.GetNodeId(), nodeId1); iterator->Release(); // Delete all and verify iterator counts 0 err = manager.DeleteAllEntries(fabricId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); iterator = manager.IterateICDClientInfo(); - NL_TEST_ASSERT(apSuite, iterator->Count() == 0); + EXPECT_EQ(iterator->Count(), 0u); // Verify ClientInfos manually count correctly size_t count = 0; @@ -118,19 +125,19 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) count++; } iterator->Release(); - NL_TEST_ASSERT(apSuite, count == 0); + EXPECT_EQ(count, 0u); } { DefaultICDClientStorage manager; err = manager.Init(&clientInfoStorage, &keystore); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.UpdateFabricList(fabricId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } } -void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext) +TEST_F(TestDefaultICDClientStorage, TestClientInfoCountMultipleFabric) { CHIP_ERROR err = CHIP_NO_ERROR; FabricIndex fabricId1 = 1; @@ -142,11 +149,11 @@ void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext) TestPersistentStorageDelegate clientInfoStorage; TestSessionKeystoreImpl keystore; err = manager.Init(&clientInfoStorage, &keystore); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.UpdateFabricList(fabricId1); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.UpdateFabricList(fabricId2); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Write some ClientInfos and see the counts are correct ICDClientInfo clientInfo1; @@ -157,39 +164,39 @@ void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext) clientInfo3.peer_node = ScopedNodeId(nodeId3, fabricId2); err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo1); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo2); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo3); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Make sure iterator counts correctly auto * iterator = manager.IterateICDClientInfo(); - NL_TEST_ASSERT(apSuite, iterator->Count() == 3); + EXPECT_EQ(iterator->Count(), 3u); iterator->Release(); // Delete all and verify iterator counts 0 err = manager.DeleteEntry(ScopedNodeId(nodeId1, fabricId1)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); iterator = manager.IterateICDClientInfo(); - NL_TEST_ASSERT(apSuite, iterator != nullptr); + ASSERT_NE(iterator, nullptr); DefaultICDClientStorage::ICDClientInfoIteratorWrapper clientInfoIteratorWrapper(iterator); - NL_TEST_ASSERT(apSuite, iterator->Count() == 2); + EXPECT_EQ(iterator->Count(), 2u); err = manager.DeleteEntry(ScopedNodeId(nodeId2, fabricId1)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, iterator->Count() == 1); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(iterator->Count(), 1u); err = manager.DeleteEntry(ScopedNodeId(nodeId3, fabricId2)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, iterator->Count() == 0); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(iterator->Count(), 0u); // Verify ClientInfos manually count correctly size_t count = 0; @@ -199,10 +206,10 @@ void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext) count++; } - NL_TEST_ASSERT(apSuite, count == 0); + EXPECT_FALSE(count); } -void TestProcessCheckInPayload(nlTestSuite * apSuite, void * apContext) +TEST_F(TestDefaultICDClientStorage, TestProcessCheckInPayload) { CHIP_ERROR err = CHIP_NO_ERROR; FabricIndex fabricId = 1; @@ -212,98 +219,41 @@ void TestProcessCheckInPayload(nlTestSuite * apSuite, void * apContext) DefaultICDClientStorage manager; err = manager.Init(&clientInfoStorage, &keystore); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.UpdateFabricList(fabricId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Populate clientInfo ICDClientInfo clientInfo; clientInfo.peer_node = ScopedNodeId(nodeId, fabricId); err = manager.SetKey(clientInfo, ByteSpan(kKeyBuffer1)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = manager.StoreEntry(clientInfo); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t counter = 1; System::PacketBufferHandle buffer = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize); MutableByteSpan output{ buffer->Start(), buffer->MaxDataLength() }; err = chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); buffer->SetDataLength(static_cast(output.size())); ICDClientInfo decodeClientInfo; uint32_t checkInCounter = 0; ByteSpan payload{ buffer->Start(), buffer->DataLength() }; err = manager.ProcessCheckInPayload(payload, decodeClientInfo, checkInCounter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // 2. Use a key not available in the storage for encoding err = manager.SetKey(clientInfo, ByteSpan(kKeyBuffer2)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload( clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); buffer->SetDataLength(static_cast(output.size())); ByteSpan payload1{ buffer->Start(), buffer->DataLength() }; err = manager.ProcessCheckInPayload(payload1, decodeClientInfo, checkInCounter); - NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_NOT_FOUND); -} - -/** - * Set up the test suite. - */ -int TestClientInfo_Setup(void * apContext) -{ - VerifyOrReturnError(CHIP_NO_ERROR == Platform::MemoryInit(), FAILURE); - - return SUCCESS; + EXPECT_EQ(err, CHIP_ERROR_NOT_FOUND); } - -/** - * Tear down the test suite. - */ -int TestClientInfo_Teardown(void * apContext) -{ - Platform::MemoryShutdown(); - return SUCCESS; -} - -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("TestClientInfoCount", TestClientInfoCount), - NL_TEST_DEF("TestClientInfoCountMultipleFabric", TestClientInfoCountMultipleFabric), - NL_TEST_DEF("TestProcessCheckInPayload", TestProcessCheckInPayload), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -static nlTestSuite sSuite = -{ - "TestDefaultICDClientStorage", - &sTests[0], - &TestClientInfo_Setup, &TestClientInfo_Teardown -}; -// clang-format on - -/** - * Main - */ -int TestDefaultICDClientStorage() -{ - // Run test suit against one context - nlTestRunner(&sSuite, nullptr); - - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestDefaultICDClientStorage) diff --git a/src/app/tests/TestFailSafeContext.cpp b/src/app/tests/TestFailSafeContext.cpp index 2d2b9fa15d2b7d..96868ff241fa28 100644 --- a/src/app/tests/TestFailSafeContext.cpp +++ b/src/app/tests/TestFailSafeContext.cpp @@ -28,11 +28,11 @@ #include #include +#include + #include #include #include -#include -#include #include using namespace chip; @@ -44,100 +44,62 @@ namespace { constexpr FabricIndex kTestAccessingFabricIndex1 = 1; constexpr FabricIndex kTestAccessingFabricIndex2 = 2; +class TestFailSafeContext : public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + ASSERT_EQ(PlatformMgr().InitChipStack(), CHIP_NO_ERROR); + } + static void TearDownTestSuite() + { + PlatformMgr().Shutdown(); + chip::Platform::MemoryShutdown(); + } +}; + // ================================= // Unit tests // ================================= -static void TestPlatformMgr_Init(nlTestSuite * inSuite, void * inContext) -{ - CHIP_ERROR err = PlatformMgr().InitChipStack(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); -} - -static void TestFailSafeContext_ArmFailSafe(nlTestSuite * inSuite, void * inContext) +TEST_F(TestFailSafeContext, TestFailSafeContext_ArmFailSafe) { CHIP_ERROR err = CHIP_NO_ERROR; chip::app::FailSafeContext failSafeContext; err = failSafeContext.ArmFailSafe(kTestAccessingFabricIndex1, System::Clock::Seconds16(1)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, failSafeContext.IsFailSafeArmed() == true); - NL_TEST_ASSERT(inSuite, failSafeContext.GetFabricIndex() == kTestAccessingFabricIndex1); - NL_TEST_ASSERT(inSuite, failSafeContext.IsFailSafeArmed(kTestAccessingFabricIndex1) == true); - NL_TEST_ASSERT(inSuite, failSafeContext.IsFailSafeArmed(kTestAccessingFabricIndex2) == false); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(failSafeContext.IsFailSafeArmed()); + EXPECT_EQ(failSafeContext.GetFabricIndex(), kTestAccessingFabricIndex1); + EXPECT_TRUE(failSafeContext.IsFailSafeArmed(kTestAccessingFabricIndex1)); + EXPECT_FALSE(failSafeContext.IsFailSafeArmed(kTestAccessingFabricIndex2)); failSafeContext.DisarmFailSafe(); - NL_TEST_ASSERT(inSuite, failSafeContext.IsFailSafeArmed() == false); + EXPECT_FALSE(failSafeContext.IsFailSafeArmed()); } -static void TestFailSafeContext_NocCommandInvoked(nlTestSuite * inSuite, void * inContext) +TEST_F(TestFailSafeContext, TestFailSafeContext_NocCommandInvoked) { CHIP_ERROR err = CHIP_NO_ERROR; chip::app::FailSafeContext failSafeContext; err = failSafeContext.ArmFailSafe(kTestAccessingFabricIndex1, System::Clock::Seconds16(1)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, failSafeContext.GetFabricIndex() == kTestAccessingFabricIndex1); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(failSafeContext.GetFabricIndex(), kTestAccessingFabricIndex1); failSafeContext.SetAddNocCommandInvoked(kTestAccessingFabricIndex2); - NL_TEST_ASSERT(inSuite, failSafeContext.NocCommandHasBeenInvoked() == true); - NL_TEST_ASSERT(inSuite, failSafeContext.AddNocCommandHasBeenInvoked() == true); - NL_TEST_ASSERT(inSuite, failSafeContext.GetFabricIndex() == kTestAccessingFabricIndex2); + EXPECT_TRUE(failSafeContext.NocCommandHasBeenInvoked()); + EXPECT_TRUE(failSafeContext.AddNocCommandHasBeenInvoked()); + EXPECT_EQ(failSafeContext.GetFabricIndex(), kTestAccessingFabricIndex2); failSafeContext.SetUpdateNocCommandInvoked(); - NL_TEST_ASSERT(inSuite, failSafeContext.NocCommandHasBeenInvoked() == true); - NL_TEST_ASSERT(inSuite, failSafeContext.UpdateNocCommandHasBeenInvoked() == true); + EXPECT_TRUE(failSafeContext.NocCommandHasBeenInvoked()); + EXPECT_TRUE(failSafeContext.UpdateNocCommandHasBeenInvoked()); failSafeContext.DisarmFailSafe(); } -/** - * Test Suite. It lists all the test functions. - */ -static const nlTest sTests[] = { - - NL_TEST_DEF("Test PlatformMgr::Init", TestPlatformMgr_Init), - NL_TEST_DEF("Test FailSafeContext::ArmFailSafe", TestFailSafeContext_ArmFailSafe), - NL_TEST_DEF("Test FailSafeContext::NocCommandInvoked", TestFailSafeContext_NocCommandInvoked), - - NL_TEST_SENTINEL() -}; - -/** - * Set up the test suite. - */ -int TestFailSafeContext_Setup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -int TestFailSafeContext_Teardown(void * inContext) -{ - PlatformMgr().Shutdown(); - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - } // namespace - -/** - * Main - */ -int TestFailSafeContext() -{ - nlTestSuite theSuite = { "FailSafeContext tests", &sTests[0], TestFailSafeContext_Setup, TestFailSafeContext_Teardown }; - - // Run test suite against one context. - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestFailSafeContext) diff --git a/src/app/tests/TestMessageDef.cpp b/src/app/tests/TestMessageDef.cpp index 10417fa2025522..01f3acb263877a 100644 --- a/src/app/tests/TestMessageDef.cpp +++ b/src/app/tests/TestMessageDef.cpp @@ -16,12 +16,6 @@ * limitations under the License. */ -/** - * @file - * This file implements a test for CHIP Interaction Model Message Def - * - */ - #include #include #include @@ -38,16 +32,23 @@ #include #include #include -#include #include #include -#include +#include +#include namespace { using namespace chip::app; +class TestMessageDef : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + void ENFORCE_FORMAT(1, 2) TLVPrettyPrinter(const char * aFormat, ...) { va_list args; @@ -75,7 +76,7 @@ CHIP_ERROR DebugPrettyPrint(const chip::System::PacketBufferHandle & aMsgBuf) return err; } -void BuildStatusIB(nlTestSuite * apSuite, StatusIB::Builder & aStatusIBBuilder) +void BuildStatusIB(StatusIB::Builder & aStatusIBBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -83,10 +84,10 @@ void BuildStatusIB(nlTestSuite * apSuite, StatusIB::Builder & aStatusIBBuilder) statusIB.mStatus = chip::Protocols::InteractionModel::Status::InvalidSubscription; aStatusIBBuilder.EncodeStatusIB(statusIB); err = aStatusIBBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void ParseStatusIB(nlTestSuite * apSuite, StatusIB::Parser & aStatusIBParser) +void ParseStatusIB(StatusIB::Parser & aStatusIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; StatusIB::Parser StatusIBParser; @@ -96,20 +97,20 @@ void ParseStatusIB(nlTestSuite * apSuite, StatusIB::Parser & aStatusIBParser) aStatusIBParser.PrettyPrint(); #endif err = aStatusIBParser.DecodeStatusIB(statusIB); - NL_TEST_ASSERT(apSuite, - err == CHIP_NO_ERROR && statusIB.mStatus == chip::Protocols::InteractionModel::Status::InvalidSubscription && - !statusIB.mClusterStatus.HasValue()); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(statusIB.mStatus, chip::Protocols::InteractionModel::Status::InvalidSubscription); + EXPECT_FALSE(statusIB.mClusterStatus.HasValue()); } -void BuildClusterPathIB(nlTestSuite * apSuite, ClusterPathIB::Builder & aClusterPathBuilder) +void BuildClusterPathIB(ClusterPathIB::Builder & aClusterPathBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; aClusterPathBuilder.Node(1).Endpoint(2).Cluster(3).EndOfClusterPathIB(); err = aClusterPathBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void ParseClusterPathIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseClusterPathIB(chip::TLV::TLVReader & aReader) { ClusterPathIB::Parser clusterPathParser; CHIP_ERROR err = CHIP_NO_ERROR; @@ -118,31 +119,34 @@ void ParseClusterPathIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) chip::ClusterId cluster = 0; err = clusterPathParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT clusterPathParser.PrettyPrint(); #endif err = clusterPathParser.GetNode(&node); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && node == 1); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(node, 1u); err = clusterPathParser.GetEndpoint(&endpoint); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && endpoint == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(endpoint, 2u); err = clusterPathParser.GetCluster(&cluster); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && cluster == 3); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(cluster, 3u); } -void BuildDataVersionFilterIB(nlTestSuite * apSuite, DataVersionFilterIB::Builder & aDataVersionFilterIBBuilder) +void BuildDataVersionFilterIB(DataVersionFilterIB::Builder & aDataVersionFilterIBBuilder) { ClusterPathIB::Builder & clusterPathBuilder = aDataVersionFilterIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, clusterPathBuilder.GetError() == CHIP_NO_ERROR); - BuildClusterPathIB(apSuite, clusterPathBuilder); + EXPECT_EQ(clusterPathBuilder.GetError(), CHIP_NO_ERROR); + BuildClusterPathIB(clusterPathBuilder); aDataVersionFilterIBBuilder.DataVersion(2).EndOfDataVersionFilterIB(); - NL_TEST_ASSERT(apSuite, aDataVersionFilterIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aDataVersionFilterIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseDataVersionFilterIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseDataVersionFilterIB(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; DataVersionFilterIB::Parser dataVersionFilterIBParser; @@ -150,46 +154,47 @@ void ParseDataVersionFilterIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aRea chip::DataVersion dataVersion = 2; err = dataVersionFilterIBParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT dataVersionFilterIBParser.PrettyPrint(); #endif err = dataVersionFilterIBParser.GetPath(&clusterPath); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = dataVersionFilterIBParser.GetDataVersion(&dataVersion); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && dataVersion == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(dataVersion, 2u); } -void BuildDataVersionFilterIBs(nlTestSuite * apSuite, DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder) +void BuildDataVersionFilterIBs(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder) { DataVersionFilterIB::Builder & dataVersionFilterIBBuilder = aDataVersionFilterIBsBuilder.CreateDataVersionFilter(); - NL_TEST_ASSERT(apSuite, aDataVersionFilterIBsBuilder.GetError() == CHIP_NO_ERROR); - BuildDataVersionFilterIB(apSuite, dataVersionFilterIBBuilder); + EXPECT_EQ(aDataVersionFilterIBsBuilder.GetError(), CHIP_NO_ERROR); + BuildDataVersionFilterIB(dataVersionFilterIBBuilder); aDataVersionFilterIBsBuilder.EndOfDataVersionFilterIBs(); - NL_TEST_ASSERT(apSuite, aDataVersionFilterIBsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aDataVersionFilterIBsBuilder.GetError(), CHIP_NO_ERROR); } -void ParseDataVersionFilterIBs(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseDataVersionFilterIBs(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; DataVersionFilterIBs::Parser dataVersionFilterIBsParser; err = dataVersionFilterIBsParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT dataVersionFilterIBsParser.PrettyPrint(); #endif } -void BuildEventFilterIB(nlTestSuite * apSuite, EventFilterIB::Builder & aEventFilterIBBuilder) +void BuildEventFilterIB(EventFilterIB::Builder & aEventFilterIBBuilder) { aEventFilterIBBuilder.Node(1).EventMin(2).EndOfEventFilterIB(); - NL_TEST_ASSERT(apSuite, aEventFilterIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aEventFilterIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseEventFilterIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseEventFilterIB(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; EventFilterIB::Parser eventFilterIBParser; @@ -197,39 +202,41 @@ void ParseEventFilterIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) uint64_t eventMin = 2; err = eventFilterIBParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT eventFilterIBParser.PrettyPrint(); #endif err = eventFilterIBParser.GetNode(&node); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && node == 1); + EXPECT_EQ(err, CHIP_NO_ERROR); + + EXPECT_EQ(node, 1u); err = eventFilterIBParser.GetEventMin(&eventMin); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && eventMin == 2); + EXPECT_EQ(eventMin, 2u); } -void BuildEventFilters(nlTestSuite * apSuite, EventFilterIBs::Builder & aEventFiltersBuilder) +void BuildEventFilters(EventFilterIBs::Builder & aEventFiltersBuilder) { EventFilterIB::Builder & eventFilterBuilder = aEventFiltersBuilder.CreateEventFilter(); - NL_TEST_ASSERT(apSuite, aEventFiltersBuilder.GetError() == CHIP_NO_ERROR); - BuildEventFilterIB(apSuite, eventFilterBuilder); + EXPECT_EQ(aEventFiltersBuilder.GetError(), CHIP_NO_ERROR); + BuildEventFilterIB(eventFilterBuilder); aEventFiltersBuilder.EndOfEventFilters(); - NL_TEST_ASSERT(apSuite, aEventFiltersBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aEventFiltersBuilder.GetError(), CHIP_NO_ERROR); } -void ParseEventFilters(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseEventFilters(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; EventFilterIBs::Parser eventFiltersParser; err = eventFiltersParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT eventFiltersParser.PrettyPrint(); #endif } -void BuildAttributePathIB(nlTestSuite * apSuite, AttributePathIB::Builder & aAttributePathBuilder) +void BuildAttributePathIB(AttributePathIB::Builder & aAttributePathBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; err = aAttributePathBuilder.EnableTagCompression(false) @@ -239,10 +246,10 @@ void BuildAttributePathIB(nlTestSuite * apSuite, AttributePathIB::Builder & aAtt .Attribute(4) .ListIndex(5) .EndOfAttributePathIB(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void ParseAttributePathIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseAttributePathIB(chip::TLV::TLVReader & aReader) { AttributePathIB::Parser attributePathParser; CHIP_ERROR err = CHIP_NO_ERROR; @@ -254,63 +261,69 @@ void ParseAttributePathIB(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) chip::ListIndex listIndex = 5; err = attributePathParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT attributePathParser.PrettyPrint(); #endif err = attributePathParser.GetEnableTagCompression(&enableTagCompression); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && enableTagCompression == false); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_FALSE(enableTagCompression); err = attributePathParser.GetNode(&node); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && node == 1); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(node, 1u); err = attributePathParser.GetEndpoint(&endpoint); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && endpoint == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(endpoint, 2u); err = attributePathParser.GetCluster(&cluster); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && cluster == 3); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(cluster, 3u); err = attributePathParser.GetAttribute(&attribute); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && attribute == 4); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(attribute, 4u); err = attributePathParser.GetListIndex(&listIndex); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && listIndex == 5); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(listIndex, 5u); } -void BuildAttributePathList(nlTestSuite * apSuite, AttributePathIBs::Builder & aAttributePathListBuilder) +void BuildAttributePathList(AttributePathIBs::Builder & aAttributePathListBuilder) { AttributePathIB::Builder & attributePathBuilder = aAttributePathListBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, attributePathBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributePathIB(apSuite, attributePathBuilder); + EXPECT_EQ(attributePathBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributePathIB(attributePathBuilder); aAttributePathListBuilder.EndOfAttributePathIBs(); - NL_TEST_ASSERT(apSuite, aAttributePathListBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributePathListBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributePathList(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseAttributePathList(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; AttributePathIBs::Parser attributePathListParser; AttributePathIB::Parser attributePathParser; err = attributePathListParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT attributePathListParser.PrettyPrint(); #endif } -void BuildEventPath(nlTestSuite * apSuite, EventPathIB::Builder & aEventPathBuilder) +void BuildEventPath(EventPathIB::Builder & aEventPathBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; aEventPathBuilder.Node(1).Endpoint(2).Cluster(3).Event(4).IsUrgent(true).EndOfEventPathIB(); err = aEventPathBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void ParseEventPath(nlTestSuite * apSuite, EventPathIB::Parser & aEventPathParser) +void ParseEventPath(EventPathIB::Parser & aEventPathParser) { CHIP_ERROR err = CHIP_NO_ERROR; chip::NodeId node = 1; @@ -323,50 +336,55 @@ void ParseEventPath(nlTestSuite * apSuite, EventPathIB::Parser & aEventPathParse aEventPathParser.PrettyPrint(); #endif err = aEventPathParser.GetNode(&node); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && node == 1); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(node, 1u); err = aEventPathParser.GetEndpoint(&endpoint); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && endpoint == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(endpoint, 2u); err = aEventPathParser.GetCluster(&cluster); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && cluster == 3); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(cluster, 3u); err = aEventPathParser.GetEvent(&event); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && event == 4); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(event, 4u); err = aEventPathParser.GetIsUrgent(&isUrgent); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && isUrgent == true); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(isUrgent); } -void BuildEventPaths(nlTestSuite * apSuite, EventPathIBs::Builder & aEventPathsBuilder) +void BuildEventPaths(EventPathIBs::Builder & aEventPathsBuilder) { EventPathIB::Builder & eventPathBuilder = aEventPathsBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, eventPathBuilder.GetError() == CHIP_NO_ERROR); - BuildEventPath(apSuite, eventPathBuilder); + EXPECT_EQ(eventPathBuilder.GetError(), CHIP_NO_ERROR); + BuildEventPath(eventPathBuilder); aEventPathsBuilder.EndOfEventPaths(); - NL_TEST_ASSERT(apSuite, aEventPathsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aEventPathsBuilder.GetError(), CHIP_NO_ERROR); } -void ParseEventPaths(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseEventPaths(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; EventPathIBs::Parser eventPathListParser; err = eventPathListParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT eventPathListParser.PrettyPrint(); #endif } -void BuildCommandPath(nlTestSuite * apSuite, CommandPathIB::Builder & aCommandPathBuilder) +void BuildCommandPath(CommandPathIB::Builder & aCommandPathBuilder) { aCommandPathBuilder.EndpointId(1).ClusterId(3).CommandId(4).EndOfCommandPathIB(); - NL_TEST_ASSERT(apSuite, aCommandPathBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aCommandPathBuilder.GetError(), CHIP_NO_ERROR); } -void ParseCommandPath(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseCommandPath(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; CommandPathIB::Parser commandPathParser; @@ -375,52 +393,55 @@ void ParseCommandPath(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) chip::CommandId commandId = 0; err = commandPathParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT commandPathParser.PrettyPrint(); #endif err = commandPathParser.GetEndpointId(&endpointId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && endpointId == 1); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(endpointId, 1u); err = commandPathParser.GetClusterId(&clusterId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && clusterId == 3); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(clusterId, 3u); err = commandPathParser.GetCommandId(&commandId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && commandId == 4); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(commandId, 4u); } -void BuildEventDataIB(nlTestSuite * apSuite, EventDataIB::Builder & aEventDataIBBuilder) +void BuildEventDataIB(EventDataIB::Builder & aEventDataIBBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; EventPathIB::Builder & eventPathBuilder = aEventDataIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, eventPathBuilder.GetError() == CHIP_NO_ERROR); - BuildEventPath(apSuite, eventPathBuilder); + EXPECT_EQ(eventPathBuilder.GetError(), CHIP_NO_ERROR); + BuildEventPath(eventPathBuilder); aEventDataIBBuilder.EventNumber(2).Priority(3).EpochTimestamp(4).SystemTimestamp(5).DeltaEpochTimestamp(6).DeltaSystemTimestamp( 7); err = aEventDataIBBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Construct test event data { chip::TLV::TLVWriter * pWriter = aEventDataIBBuilder.GetWriter(); chip::TLV::TLVType dummyType = chip::TLV::kTLVType_NotSpecified; err = pWriter->StartContainer(chip::TLV::ContextTag(chip::to_underlying(EventDataIB::Tag::kData)), chip::TLV::kTLVType_Structure, dummyType); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = pWriter->PutBoolean(chip::TLV::ContextTag(1), true); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = pWriter->EndContainer(dummyType); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } aEventDataIBBuilder.EndOfEventDataIB(); } -void ParseEventDataIB(nlTestSuite * apSuite, EventDataIB::Parser & aEventDataIBParser) +void ParseEventDataIB(EventDataIB::Parser & aEventDataIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; uint8_t priorityLevel = 0; @@ -437,20 +458,31 @@ void ParseEventDataIB(nlTestSuite * apSuite, EventDataIB::Parser & aEventDataIBP { EventPathIB::Parser eventPath; err = aEventDataIBParser.GetPath(&eventPath); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } err = aEventDataIBParser.GetEventNumber(&number); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && number == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(number, 2u); + err = aEventDataIBParser.GetPriority(&priorityLevel); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && priorityLevel == 3); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(priorityLevel, 3u); + err = aEventDataIBParser.GetEpochTimestamp(&EpochTimestamp); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && EpochTimestamp == 4); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(EpochTimestamp, 4u); + err = aEventDataIBParser.GetSystemTimestamp(&systemTimestamp); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && systemTimestamp == 5); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(systemTimestamp, 5u); + err = aEventDataIBParser.GetDeltaEpochTimestamp(&deltaUTCTimestamp); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && deltaUTCTimestamp == 6); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(deltaUTCTimestamp, 6u); + err = aEventDataIBParser.GetDeltaSystemTimestamp(&deltaSystemTimestamp); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && deltaSystemTimestamp == 7); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(deltaSystemTimestamp, 7u); { chip::TLV::TLVReader reader; @@ -458,35 +490,36 @@ void ParseEventDataIB(nlTestSuite * apSuite, EventDataIB::Parser & aEventDataIBP chip::TLV::TLVType container; aEventDataIBParser.GetData(&reader); err = reader.EnterContainer(container); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Get(val); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && val); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(val); err = reader.ExitContainer(container); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } } } -void BuildEventStatusIB(nlTestSuite * apSuite, EventStatusIB::Builder & aEventStatusIBBuilder) +void BuildEventStatusIB(EventStatusIB::Builder & aEventStatusIBBuilder) { EventPathIB::Builder & eventPathBuilder = aEventStatusIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, aEventStatusIBBuilder.GetError() == CHIP_NO_ERROR); - BuildEventPath(apSuite, eventPathBuilder); + EXPECT_EQ(aEventStatusIBBuilder.GetError(), CHIP_NO_ERROR); + BuildEventPath(eventPathBuilder); StatusIB::Builder & statusIBBuilder = aEventStatusIBBuilder.CreateErrorStatus(); - NL_TEST_ASSERT(apSuite, statusIBBuilder.GetError() == CHIP_NO_ERROR); - BuildStatusIB(apSuite, statusIBBuilder); + EXPECT_EQ(statusIBBuilder.GetError(), CHIP_NO_ERROR); + BuildStatusIB(statusIBBuilder); aEventStatusIBBuilder.EndOfEventStatusIB(); - NL_TEST_ASSERT(apSuite, aEventStatusIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aEventStatusIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseEventStatusIB(nlTestSuite * apSuite, EventStatusIB::Parser & aEventStatusIBParser) +void ParseEventStatusIB(EventStatusIB::Parser & aEventStatusIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; EventPathIB::Parser eventPathParser; @@ -495,23 +528,23 @@ void ParseEventStatusIB(nlTestSuite * apSuite, EventStatusIB::Parser & aEventSta aEventStatusIBParser.PrettyPrint(); #endif err = aEventStatusIBParser.GetPath(&eventPathParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = aEventStatusIBParser.GetErrorStatus(&statusParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void BuildEventReportIB(nlTestSuite * apSuite, EventReportIB::Builder & aEventReportIBBuilder) +void BuildEventReportIB(EventReportIB::Builder & aEventReportIBBuilder) { EventDataIB::Builder & eventDataIBBuilder = aEventReportIBBuilder.CreateEventData(); - NL_TEST_ASSERT(apSuite, aEventReportIBBuilder.GetError() == CHIP_NO_ERROR); - BuildEventDataIB(apSuite, eventDataIBBuilder); + EXPECT_EQ(aEventReportIBBuilder.GetError(), CHIP_NO_ERROR); + BuildEventDataIB(eventDataIBBuilder); aEventReportIBBuilder.EndOfEventReportIB(); - NL_TEST_ASSERT(apSuite, aEventReportIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aEventReportIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseEventReportIB(nlTestSuite * apSuite, EventReportIB::Parser & aEventReportIBParser) +void ParseEventReportIB(EventReportIB::Parser & aEventReportIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; EventStatusIB::Parser eventStatusParser; @@ -522,45 +555,45 @@ void ParseEventReportIB(nlTestSuite * apSuite, EventReportIB::Parser & aEventRep #endif err = aEventReportIBParser.GetEventData(&eventDataParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void BuildEventReports(nlTestSuite * apSuite, EventReportIBs::Builder & aEventReportsBuilder) +void BuildEventReports(EventReportIBs::Builder & aEventReportsBuilder) { EventReportIB::Builder & eventReportIBBuilder = aEventReportsBuilder.CreateEventReport(); - NL_TEST_ASSERT(apSuite, aEventReportsBuilder.GetError() == CHIP_NO_ERROR); - BuildEventReportIB(apSuite, eventReportIBBuilder); + EXPECT_EQ(aEventReportsBuilder.GetError(), CHIP_NO_ERROR); + BuildEventReportIB(eventReportIBBuilder); aEventReportsBuilder.EndOfEventReports(); - NL_TEST_ASSERT(apSuite, aEventReportsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aEventReportsBuilder.GetError(), CHIP_NO_ERROR); } -void ParseEventReports(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseEventReports(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; EventReportIBs::Parser eventReportsParser; err = eventReportsParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT eventReportsParser.PrettyPrint(); #endif } -void BuildAttributeStatusIB(nlTestSuite * apSuite, AttributeStatusIB::Builder & aAttributeStatusIBBuilder) +void BuildAttributeStatusIB(AttributeStatusIB::Builder & aAttributeStatusIBBuilder) { AttributePathIB::Builder & attributePathBuilder = aAttributeStatusIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, attributePathBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributePathIB(apSuite, attributePathBuilder); + EXPECT_EQ(attributePathBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributePathIB(attributePathBuilder); StatusIB::Builder & statusIBBuilder = aAttributeStatusIBBuilder.CreateErrorStatus(); - NL_TEST_ASSERT(apSuite, statusIBBuilder.GetError() == CHIP_NO_ERROR); - BuildStatusIB(apSuite, statusIBBuilder); + EXPECT_EQ(statusIBBuilder.GetError(), CHIP_NO_ERROR); + BuildStatusIB(statusIBBuilder); aAttributeStatusIBBuilder.EndOfAttributeStatusIB(); - NL_TEST_ASSERT(apSuite, aAttributeStatusIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributeStatusIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributeStatusIB(nlTestSuite * apSuite, AttributeStatusIB::Parser & aAttributeStatusIBParser) +void ParseAttributeStatusIB(AttributeStatusIB::Parser & aAttributeStatusIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; AttributePathIB::Parser attributePathParser; @@ -570,43 +603,43 @@ void ParseAttributeStatusIB(nlTestSuite * apSuite, AttributeStatusIB::Parser & a aAttributeStatusIBParser.PrettyPrint(); #endif err = aAttributeStatusIBParser.GetPath(&attributePathParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = aAttributeStatusIBParser.GetErrorStatus(&StatusIBParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void BuildAttributeStatuses(nlTestSuite * apSuite, AttributeStatusIBs::Builder & aAttributeStatusesBuilder) +void BuildAttributeStatuses(AttributeStatusIBs::Builder & aAttributeStatusesBuilder) { AttributeStatusIB::Builder & aAttributeStatusIBBuilder = aAttributeStatusesBuilder.CreateAttributeStatus(); - NL_TEST_ASSERT(apSuite, aAttributeStatusesBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeStatusIB(apSuite, aAttributeStatusIBBuilder); + EXPECT_EQ(aAttributeStatusesBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeStatusIB(aAttributeStatusIBBuilder); aAttributeStatusesBuilder.EndOfAttributeStatuses(); - NL_TEST_ASSERT(apSuite, aAttributeStatusesBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributeStatusesBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributeStatuses(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseAttributeStatuses(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeStatusIBs::Parser attributeStatusParser; err = attributeStatusParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT attributeStatusParser.PrettyPrint(); #endif } -void BuildAttributeDataIB(nlTestSuite * apSuite, AttributeDataIB::Builder & aAttributeDataIBBuilder) +void BuildAttributeDataIB(AttributeDataIB::Builder & aAttributeDataIBBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; aAttributeDataIBBuilder.DataVersion(2); AttributePathIB::Builder & attributePathBuilder = aAttributeDataIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, aAttributeDataIBBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributePathIB(apSuite, attributePathBuilder); + EXPECT_EQ(aAttributeDataIBBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributePathIB(attributePathBuilder); // Construct attribute data { @@ -614,22 +647,22 @@ void BuildAttributeDataIB(nlTestSuite * apSuite, AttributeDataIB::Builder & aAtt chip::TLV::TLVType dummyType = chip::TLV::kTLVType_NotSpecified; err = pWriter->StartContainer(chip::TLV::ContextTag(chip::to_underlying(AttributeDataIB::Tag::kData)), chip::TLV::kTLVType_Structure, dummyType); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = pWriter->PutBoolean(chip::TLV::ContextTag(1), true); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = pWriter->EndContainer(dummyType); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } err = aAttributeDataIBBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); aAttributeDataIBBuilder.EndOfAttributeDataIB(); - NL_TEST_ASSERT(apSuite, aAttributeDataIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributeDataIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributeDataIB(nlTestSuite * apSuite, AttributeDataIB::Parser & aAttributeDataIBParser) +void ParseAttributeDataIB(AttributeDataIB::Parser & aAttributeDataIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; AttributePathIB::Parser attributePathParser; @@ -638,10 +671,11 @@ void ParseAttributeDataIB(nlTestSuite * apSuite, AttributeDataIB::Parser & aAttr aAttributeDataIBParser.PrettyPrint(); #endif err = aAttributeDataIBParser.GetPath(&attributePathParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = aAttributeDataIBParser.GetDataVersion(&version); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && version == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(version, 2u); { chip::TLV::TLVReader reader; @@ -649,52 +683,53 @@ void ParseAttributeDataIB(nlTestSuite * apSuite, AttributeDataIB::Parser & aAttr chip::TLV::TLVType container; aAttributeDataIBParser.GetData(&reader); err = reader.EnterContainer(container); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Get(val); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && val); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(val); err = reader.ExitContainer(container); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } } -void BuildAttributeDataIBs(nlTestSuite * apSuite, AttributeDataIBs::Builder & aAttributeDataIBsBuilder) +void BuildAttributeDataIBs(AttributeDataIBs::Builder & aAttributeDataIBsBuilder) { AttributeDataIB::Builder & attributeDataIBBuilder = aAttributeDataIBsBuilder.CreateAttributeDataIBBuilder(); - NL_TEST_ASSERT(apSuite, aAttributeDataIBsBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeDataIB(apSuite, attributeDataIBBuilder); + EXPECT_EQ(aAttributeDataIBsBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeDataIB(attributeDataIBBuilder); aAttributeDataIBsBuilder.EndOfAttributeDataIBs(); - NL_TEST_ASSERT(apSuite, aAttributeDataIBsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributeDataIBsBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributeDataIBs(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseAttributeDataIBs(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeDataIBs::Parser AttributeDataIBsParser; err = AttributeDataIBsParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT AttributeDataIBsParser.PrettyPrint(); #endif } -void BuildAttributeReportIB(nlTestSuite * apSuite, AttributeReportIB::Builder & aAttributeReportIBBuilder) +void BuildAttributeReportIB(AttributeReportIB::Builder & aAttributeReportIBBuilder) { AttributeDataIB::Builder & attributeDataIBBuilder = aAttributeReportIBBuilder.CreateAttributeData(); - NL_TEST_ASSERT(apSuite, aAttributeReportIBBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeDataIB(apSuite, attributeDataIBBuilder); + EXPECT_EQ(aAttributeReportIBBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeDataIB(attributeDataIBBuilder); aAttributeReportIBBuilder.EndOfAttributeReportIB(); - NL_TEST_ASSERT(apSuite, aAttributeReportIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributeReportIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributeReportIB(nlTestSuite * apSuite, AttributeReportIB::Parser & aAttributeReportIBParser) +void ParseAttributeReportIB(AttributeReportIB::Parser & aAttributeReportIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeStatusIB::Parser attributeStatusParser; @@ -704,38 +739,38 @@ void ParseAttributeReportIB(nlTestSuite * apSuite, AttributeReportIB::Parser & a aAttributeReportIBParser.PrettyPrint(); #endif err = aAttributeReportIBParser.GetAttributeData(&attributeDataParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void BuildAttributeReportIBs(nlTestSuite * apSuite, AttributeReportIBs::Builder & aAttributeReportIBsBuilder) +void BuildAttributeReportIBs(AttributeReportIBs::Builder & aAttributeReportIBsBuilder) { AttributeReportIB::Builder & attributeReportIBBuilder = aAttributeReportIBsBuilder.CreateAttributeReport(); - NL_TEST_ASSERT(apSuite, aAttributeReportIBsBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeReportIB(apSuite, attributeReportIBBuilder); + EXPECT_EQ(aAttributeReportIBsBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeReportIB(attributeReportIBBuilder); aAttributeReportIBsBuilder.EndOfAttributeReportIBs(); - NL_TEST_ASSERT(apSuite, aAttributeReportIBsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aAttributeReportIBsBuilder.GetError(), CHIP_NO_ERROR); } -void ParseAttributeReportIBs(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseAttributeReportIBs(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeReportIBs::Parser attributeReportIBsParser; err = attributeReportIBsParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT attributeReportIBsParser.PrettyPrint(); #endif } -void BuildCommandDataIB(nlTestSuite * apSuite, CommandDataIB::Builder & aCommandDataIBBuilder) +void BuildCommandDataIB(CommandDataIB::Builder & aCommandDataIBBuilder) { CHIP_ERROR err = CHIP_NO_ERROR; CommandPathIB::Builder & commandPathBuilder = aCommandDataIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, aCommandDataIBBuilder.GetError() == CHIP_NO_ERROR); - BuildCommandPath(apSuite, commandPathBuilder); + EXPECT_EQ(aCommandDataIBBuilder.GetError(), CHIP_NO_ERROR); + BuildCommandPath(commandPathBuilder); // Construct command data { @@ -743,20 +778,20 @@ void BuildCommandDataIB(nlTestSuite * apSuite, CommandDataIB::Builder & aCommand chip::TLV::TLVType dummyType = chip::TLV::kTLVType_NotSpecified; err = pWriter->StartContainer(chip::TLV::ContextTag(chip::to_underlying(CommandDataIB::Tag::kFields)), chip::TLV::kTLVType_Structure, dummyType); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = pWriter->PutBoolean(chip::TLV::ContextTag(1), true); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = pWriter->EndContainer(dummyType); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } aCommandDataIBBuilder.EndOfCommandDataIB(); - NL_TEST_ASSERT(apSuite, aCommandDataIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aCommandDataIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseCommandDataIB(nlTestSuite * apSuite, CommandDataIB::Parser & aCommandDataIBParser) +void ParseCommandDataIB(CommandDataIB::Parser & aCommandDataIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; CommandPathIB::Parser commandPathParser; @@ -764,7 +799,7 @@ void ParseCommandDataIB(nlTestSuite * apSuite, CommandDataIB::Parser & aCommandD aCommandDataIBParser.PrettyPrint(); #endif err = aCommandDataIBParser.GetPath(&commandPathParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); { chip::TLV::TLVReader reader; @@ -772,34 +807,35 @@ void ParseCommandDataIB(nlTestSuite * apSuite, CommandDataIB::Parser & aCommandD chip::TLV::TLVType container; aCommandDataIBParser.GetFields(&reader); err = reader.EnterContainer(container); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reader.Get(val); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && val); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(val); err = reader.ExitContainer(container); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } } -void BuildCommandStatusIB(nlTestSuite * apSuite, CommandStatusIB::Builder & aCommandStatusIBBuilder) +void BuildCommandStatusIB(CommandStatusIB::Builder & aCommandStatusIBBuilder) { CommandPathIB::Builder & commandPathBuilder = aCommandStatusIBBuilder.CreatePath(); - NL_TEST_ASSERT(apSuite, aCommandStatusIBBuilder.GetError() == CHIP_NO_ERROR); - BuildCommandPath(apSuite, commandPathBuilder); + EXPECT_EQ(aCommandStatusIBBuilder.GetError(), CHIP_NO_ERROR); + BuildCommandPath(commandPathBuilder); StatusIB::Builder & statusIBBuilder = aCommandStatusIBBuilder.CreateErrorStatus(); - NL_TEST_ASSERT(apSuite, statusIBBuilder.GetError() == CHIP_NO_ERROR); - BuildStatusIB(apSuite, statusIBBuilder); + EXPECT_EQ(statusIBBuilder.GetError(), CHIP_NO_ERROR); + BuildStatusIB(statusIBBuilder); aCommandStatusIBBuilder.EndOfCommandStatusIB(); - NL_TEST_ASSERT(apSuite, aCommandStatusIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aCommandStatusIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseCommandStatusIB(nlTestSuite * apSuite, CommandStatusIB::Parser & aCommandStatusIBParser) +void ParseCommandStatusIB(CommandStatusIB::Parser & aCommandStatusIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; CommandPathIB::Parser commandPathParser; @@ -808,37 +844,37 @@ void ParseCommandStatusIB(nlTestSuite * apSuite, CommandStatusIB::Parser & aComm aCommandStatusIBParser.PrettyPrint(); #endif err = aCommandStatusIBParser.GetPath(&commandPathParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = aCommandStatusIBParser.GetErrorStatus(&statusParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void BuildWrongInvokeResponseIB(nlTestSuite * apSuite, InvokeResponseIB::Builder & aInvokeResponseIBBuilder) +void BuildWrongInvokeResponseIB(InvokeResponseIB::Builder & aInvokeResponseIBBuilder) { aInvokeResponseIBBuilder.CreateCommand(); - NL_TEST_ASSERT(apSuite, aInvokeResponseIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aInvokeResponseIBBuilder.GetError(), CHIP_NO_ERROR); } -void BuildInvokeResponseIBWithCommandDataIB(nlTestSuite * apSuite, InvokeResponseIB::Builder & aInvokeResponseIBBuilder) +void BuildInvokeResponseIBWithCommandDataIB(InvokeResponseIB::Builder & aInvokeResponseIBBuilder) { CommandDataIB::Builder & commandDataBuilder = aInvokeResponseIBBuilder.CreateCommand(); - NL_TEST_ASSERT(apSuite, aInvokeResponseIBBuilder.GetError() == CHIP_NO_ERROR); - BuildCommandDataIB(apSuite, commandDataBuilder); + EXPECT_EQ(aInvokeResponseIBBuilder.GetError(), CHIP_NO_ERROR); + BuildCommandDataIB(commandDataBuilder); aInvokeResponseIBBuilder.EndOfInvokeResponseIB(); - NL_TEST_ASSERT(apSuite, aInvokeResponseIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aInvokeResponseIBBuilder.GetError(), CHIP_NO_ERROR); } -void BuildInvokeResponseIBWithCommandStatusIB(nlTestSuite * apSuite, InvokeResponseIB::Builder & aInvokeResponseIBBuilder) +void BuildInvokeResponseIBWithCommandStatusIB(InvokeResponseIB::Builder & aInvokeResponseIBBuilder) { CommandStatusIB::Builder & commandStatusBuilder = aInvokeResponseIBBuilder.CreateStatus(); - NL_TEST_ASSERT(apSuite, aInvokeResponseIBBuilder.GetError() == CHIP_NO_ERROR); - BuildCommandStatusIB(apSuite, commandStatusBuilder); + EXPECT_EQ(aInvokeResponseIBBuilder.GetError(), CHIP_NO_ERROR); + BuildCommandStatusIB(commandStatusBuilder); aInvokeResponseIBBuilder.EndOfInvokeResponseIB(); - NL_TEST_ASSERT(apSuite, aInvokeResponseIBBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aInvokeResponseIBBuilder.GetError(), CHIP_NO_ERROR); } -void ParseInvokeResponseIBWithCommandDataIB(nlTestSuite * apSuite, InvokeResponseIB::Parser & aInvokeResponseIBParser) +void ParseInvokeResponseIBWithCommandDataIB(InvokeResponseIB::Parser & aInvokeResponseIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; CommandDataIB::Parser commandDataParser; @@ -847,10 +883,10 @@ void ParseInvokeResponseIBWithCommandDataIB(nlTestSuite * apSuite, InvokeRespons aInvokeResponseIBParser.PrettyPrint(); #endif err = aInvokeResponseIBParser.GetCommand(&commandDataParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void ParseInvokeResponseIBWithCommandStatusIB(nlTestSuite * apSuite, InvokeResponseIB::Parser & aInvokeResponseIBParser) +void ParseInvokeResponseIBWithCommandStatusIB(InvokeResponseIB::Parser & aInvokeResponseIBParser) { CHIP_ERROR err = CHIP_NO_ERROR; CommandDataIB::Parser commandDataParser; @@ -859,90 +895,90 @@ void ParseInvokeResponseIBWithCommandStatusIB(nlTestSuite * apSuite, InvokeRespo aInvokeResponseIBParser.PrettyPrint(); #endif err = aInvokeResponseIBParser.GetStatus(&statusIBParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void BuildInvokeRequests(nlTestSuite * apSuite, InvokeRequests::Builder & aInvokeRequestsBuilder) +void BuildInvokeRequests(InvokeRequests::Builder & aInvokeRequestsBuilder) { CommandDataIB::Builder & aCommandDataIBBuilder = aInvokeRequestsBuilder.CreateCommandData(); - NL_TEST_ASSERT(apSuite, aInvokeRequestsBuilder.GetError() == CHIP_NO_ERROR); - BuildCommandDataIB(apSuite, aCommandDataIBBuilder); + EXPECT_EQ(aInvokeRequestsBuilder.GetError(), CHIP_NO_ERROR); + BuildCommandDataIB(aCommandDataIBBuilder); aInvokeRequestsBuilder.EndOfInvokeRequests(); - NL_TEST_ASSERT(apSuite, aInvokeRequestsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aInvokeRequestsBuilder.GetError(), CHIP_NO_ERROR); } -void ParseInvokeRequests(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseInvokeRequests(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeRequests::Parser invokeRequestsParser; err = invokeRequestsParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT invokeRequestsParser.PrettyPrint(); #endif } -void BuildInvokeResponses(nlTestSuite * apSuite, InvokeResponseIBs::Builder & aInvokeResponsesBuilder) +void BuildInvokeResponses(InvokeResponseIBs::Builder & aInvokeResponsesBuilder) { InvokeResponseIB::Builder & invokeResponseIBBuilder = aInvokeResponsesBuilder.CreateInvokeResponse(); - NL_TEST_ASSERT(apSuite, aInvokeResponsesBuilder.GetError() == CHIP_NO_ERROR); - BuildInvokeResponseIBWithCommandDataIB(apSuite, invokeResponseIBBuilder); + EXPECT_EQ(aInvokeResponsesBuilder.GetError(), CHIP_NO_ERROR); + BuildInvokeResponseIBWithCommandDataIB(invokeResponseIBBuilder); aInvokeResponsesBuilder.EndOfInvokeResponses(); - NL_TEST_ASSERT(apSuite, aInvokeResponsesBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(aInvokeResponsesBuilder.GetError(), CHIP_NO_ERROR); } -void ParseInvokeResponses(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseInvokeResponses(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeResponseIBs::Parser invokeResponsesParser; err = invokeResponsesParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT invokeResponsesParser.PrettyPrint(); #endif } -void BuildInvokeRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildInvokeRequestMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeRequestMessage::Builder invokeRequestMessageBuilder; err = invokeRequestMessageBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); invokeRequestMessageBuilder.SuppressResponse(true); invokeRequestMessageBuilder.TimedRequest(true); InvokeRequests::Builder & invokeRequestsBuilder = invokeRequestMessageBuilder.CreateInvokeRequests(); - NL_TEST_ASSERT(apSuite, invokeRequestsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(invokeRequestsBuilder.GetError(), CHIP_NO_ERROR); - BuildInvokeRequests(apSuite, invokeRequestsBuilder); + BuildInvokeRequests(invokeRequestsBuilder); invokeRequestMessageBuilder.EndOfInvokeRequestMessage(); - NL_TEST_ASSERT(apSuite, invokeRequestMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(invokeRequestMessageBuilder.GetError(), CHIP_NO_ERROR); } -void ParseInvokeRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseInvokeRequestMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeRequestMessage::Parser invokeRequestMessageParser; err = invokeRequestMessageParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); bool suppressResponse = false; bool timedRequest = false; invokeRequestMessageParser.GetSuppressResponse(&suppressResponse); invokeRequestMessageParser.GetTimedRequest(&timedRequest); - NL_TEST_ASSERT(apSuite, suppressResponse == true); - NL_TEST_ASSERT(apSuite, timedRequest == true); + EXPECT_TRUE(suppressResponse); + EXPECT_TRUE(timedRequest); #if CHIP_CONFIG_IM_PRETTY_PRINT invokeRequestMessageParser.PrettyPrint(); #endif - NL_TEST_ASSERT(apSuite, invokeRequestMessageParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(invokeRequestMessageParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildInvokeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildInvokeResponseMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeResponseMessage::Builder invokeResponseMessageBuilder; @@ -950,67 +986,67 @@ void BuildInvokeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aW invokeResponseMessageBuilder.SuppressResponse(true); InvokeResponseIBs::Builder & invokeResponsesBuilder = invokeResponseMessageBuilder.CreateInvokeResponses(); - NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(invokeResponseMessageBuilder.GetError(), CHIP_NO_ERROR); - BuildInvokeResponses(apSuite, invokeResponsesBuilder); + BuildInvokeResponses(invokeResponsesBuilder); invokeResponseMessageBuilder.MoreChunkedMessages(true); - NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(invokeResponseMessageBuilder.GetError(), CHIP_NO_ERROR); invokeResponseMessageBuilder.EndOfInvokeResponseMessage(); - NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(invokeResponseMessageBuilder.GetError(), CHIP_NO_ERROR); } -void ParseInvokeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseInvokeResponseMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeResponseMessage::Parser invokeResponseMessageParser; err = invokeResponseMessageParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); bool suppressResponse = false; err = invokeResponseMessageParser.GetSuppressResponse(&suppressResponse); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, suppressResponse == true); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(suppressResponse); bool moreChunkedMessages = true; err = invokeResponseMessageParser.GetMoreChunkedMessages(&suppressResponse); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, moreChunkedMessages == true); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(moreChunkedMessages); #if CHIP_CONFIG_IM_PRETTY_PRINT invokeResponseMessageParser.PrettyPrint(); #endif - NL_TEST_ASSERT(apSuite, invokeResponseMessageParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(invokeResponseMessageParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildReportDataMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildReportDataMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; ReportDataMessage::Builder reportDataMessageBuilder; err = reportDataMessageBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); reportDataMessageBuilder.SubscriptionId(2); - NL_TEST_ASSERT(apSuite, reportDataMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(reportDataMessageBuilder.GetError(), CHIP_NO_ERROR); AttributeReportIBs::Builder & attributeReportIBs = reportDataMessageBuilder.CreateAttributeReportIBs(); - NL_TEST_ASSERT(apSuite, reportDataMessageBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeReportIBs(apSuite, attributeReportIBs); + EXPECT_EQ(reportDataMessageBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeReportIBs(attributeReportIBs); EventReportIBs::Builder & eventReportIBs = reportDataMessageBuilder.CreateEventReports(); - NL_TEST_ASSERT(apSuite, reportDataMessageBuilder.GetError() == CHIP_NO_ERROR); - BuildEventReports(apSuite, eventReportIBs); + EXPECT_EQ(reportDataMessageBuilder.GetError(), CHIP_NO_ERROR); + BuildEventReports(eventReportIBs); reportDataMessageBuilder.MoreChunkedMessages(true).SuppressResponse(true); - NL_TEST_ASSERT(apSuite, reportDataMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(reportDataMessageBuilder.GetError(), CHIP_NO_ERROR); reportDataMessageBuilder.EndOfReportDataMessage(); - NL_TEST_ASSERT(apSuite, reportDataMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(reportDataMessageBuilder.GetError(), CHIP_NO_ERROR); } -void ParseReportDataMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseReportDataMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; ReportDataMessage::Parser reportDataParser; @@ -1026,55 +1062,58 @@ void ParseReportDataMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReade reportDataParser.PrettyPrint(); #endif err = reportDataParser.GetSuppressResponse(&suppressResponse); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && suppressResponse); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(suppressResponse); err = reportDataParser.GetSubscriptionId(&subscriptionId); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && subscriptionId == 2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(subscriptionId, 2u); err = reportDataParser.GetAttributeReportIBs(&attributeReportIBsParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reportDataParser.GetEventReports(&eventReportsParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = reportDataParser.GetMoreChunkedMessages(&moreChunkedMessages); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && moreChunkedMessages); - NL_TEST_ASSERT(apSuite, reportDataParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(moreChunkedMessages); + EXPECT_EQ(reportDataParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildReadRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildReadRequestMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; ReadRequestMessage::Builder readRequestBuilder; err = readRequestBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); AttributePathIBs::Builder & attributePathIBs = readRequestBuilder.CreateAttributeRequests(); - NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributePathList(apSuite, attributePathIBs); + EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributePathList(attributePathIBs); EventPathIBs::Builder & eventPathList = readRequestBuilder.CreateEventRequests(); - NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildEventPaths(apSuite, eventPathList); + EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildEventPaths(eventPathList); EventFilterIBs::Builder & eventFilters = readRequestBuilder.CreateEventFilters(); - NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildEventFilters(apSuite, eventFilters); + EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildEventFilters(eventFilters); readRequestBuilder.IsFabricFiltered(true); - NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); DataVersionFilterIBs::Builder & dataVersionFilters = readRequestBuilder.CreateDataVersionFilters(); - NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildDataVersionFilterIBs(apSuite, dataVersionFilters); + EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildDataVersionFilterIBs(dataVersionFilters); readRequestBuilder.EndOfReadRequestMessage(); - NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); } -void ParseReadRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseReadRequestMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1086,53 +1125,54 @@ void ParseReadRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aRead bool isFabricFiltered = false; err = readRequestParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT readRequestParser.PrettyPrint(); #endif err = readRequestParser.GetAttributeRequests(&attributePathListParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = readRequestParser.GetDataVersionFilters(&dataVersionFilterIBsParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = readRequestParser.GetEventRequests(&eventPathListParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = readRequestParser.GetEventFilters(&eventFiltersParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = readRequestParser.GetIsFabricFiltered(&isFabricFiltered); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && isFabricFiltered); - NL_TEST_ASSERT(apSuite, readRequestParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(isFabricFiltered); + EXPECT_EQ(readRequestParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildWriteRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildWriteRequestMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; WriteRequestMessage::Builder writeRequestBuilder; err = writeRequestBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); writeRequestBuilder.SuppressResponse(true); - NL_TEST_ASSERT(apSuite, writeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(writeRequestBuilder.GetError(), CHIP_NO_ERROR); writeRequestBuilder.TimedRequest(true); - NL_TEST_ASSERT(apSuite, writeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(writeRequestBuilder.GetError(), CHIP_NO_ERROR); AttributeDataIBs::Builder & attributeDataIBs = writeRequestBuilder.CreateWriteRequests(); - NL_TEST_ASSERT(apSuite, writeRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeDataIBs(apSuite, attributeDataIBs); + EXPECT_EQ(writeRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeDataIBs(attributeDataIBs); writeRequestBuilder.MoreChunkedMessages(true); - NL_TEST_ASSERT(apSuite, writeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(writeRequestBuilder.GetError(), CHIP_NO_ERROR); writeRequestBuilder.EndOfWriteRequestMessage(); - NL_TEST_ASSERT(apSuite, writeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(writeRequestBuilder.GetError(), CHIP_NO_ERROR); } -void ParseWriteRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseWriteRequestMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1143,97 +1183,100 @@ void ParseWriteRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aRea bool moreChunkedMessages = false; err = writeRequestParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT writeRequestParser.PrettyPrint(); #endif err = writeRequestParser.GetSuppressResponse(&suppressResponse); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && suppressResponse); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(suppressResponse); err = writeRequestParser.GetTimedRequest(&timeRequest); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && timeRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(timeRequest); err = writeRequestParser.GetWriteRequests(&writeRequests); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeRequestParser.GetMoreChunkedMessages(&moreChunkedMessages); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && moreChunkedMessages); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(moreChunkedMessages); } -void BuildWriteResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildWriteResponseMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; WriteResponseMessage::Builder writeResponseBuilder; err = writeResponseBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); AttributeStatusIBs::Builder & attributeStatuses = writeResponseBuilder.CreateWriteResponses(); - NL_TEST_ASSERT(apSuite, writeResponseBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeStatuses(apSuite, attributeStatuses); + EXPECT_EQ(writeResponseBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeStatuses(attributeStatuses); writeResponseBuilder.EndOfWriteResponseMessage(); - NL_TEST_ASSERT(apSuite, writeResponseBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(writeResponseBuilder.GetError(), CHIP_NO_ERROR); } -void ParseWriteResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseWriteResponseMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; WriteResponseMessage::Parser writeResponseParser; AttributeStatusIBs::Parser attributeStatusesParser; err = writeResponseParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT writeResponseParser.PrettyPrint(); #endif err = writeResponseParser.GetWriteResponses(&attributeStatusesParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, writeResponseParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(writeResponseParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildSubscribeRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildSubscribeRequestMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; SubscribeRequestMessage::Builder subscribeRequestBuilder; err = subscribeRequestBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); subscribeRequestBuilder.KeepSubscriptions(true); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); subscribeRequestBuilder.MinIntervalFloorSeconds(2); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); subscribeRequestBuilder.MaxIntervalCeilingSeconds(3); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); AttributePathIBs::Builder & attributePathIBs = subscribeRequestBuilder.CreateAttributeRequests(); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributePathList(apSuite, attributePathIBs); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributePathList(attributePathIBs); EventPathIBs::Builder & eventPathList = subscribeRequestBuilder.CreateEventRequests(); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildEventPaths(apSuite, eventPathList); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildEventPaths(eventPathList); EventFilterIBs::Builder & eventFilters = subscribeRequestBuilder.CreateEventFilters(); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildEventFilters(apSuite, eventFilters); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildEventFilters(eventFilters); subscribeRequestBuilder.IsFabricFiltered(true); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); DataVersionFilterIBs::Builder & dataVersionFilters = subscribeRequestBuilder.CreateDataVersionFilters(); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); - BuildDataVersionFilterIBs(apSuite, dataVersionFilters); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); + BuildDataVersionFilterIBs(dataVersionFilters); subscribeRequestBuilder.EndOfSubscribeRequestMessage(); - NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeRequestBuilder.GetError(), CHIP_NO_ERROR); } -void ParseSubscribeRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseSubscribeRequestMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1248,55 +1291,57 @@ void ParseSubscribeRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & bool isFabricFiltered = false; err = subscribeRequestParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT subscribeRequestParser.PrettyPrint(); #endif err = subscribeRequestParser.GetAttributeRequests(&attributePathListParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = subscribeRequestParser.GetDataVersionFilters(&dataVersionFilterIBsParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = subscribeRequestParser.GetEventRequests(&eventPathListParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = subscribeRequestParser.GetEventFilters(&eventFiltersParser); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = subscribeRequestParser.GetMinIntervalFloorSeconds(&minIntervalFloorSeconds); - NL_TEST_ASSERT(apSuite, minIntervalFloorSeconds == 2 && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(minIntervalFloorSeconds, 2u); err = subscribeRequestParser.GetMaxIntervalCeilingSeconds(&maxIntervalCeilingSeconds); - NL_TEST_ASSERT(apSuite, maxIntervalCeilingSeconds == 3 && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(maxIntervalCeilingSeconds, 3u); err = subscribeRequestParser.GetKeepSubscriptions(&keepExistingSubscription); - NL_TEST_ASSERT(apSuite, keepExistingSubscription && err == CHIP_NO_ERROR); + EXPECT_TRUE(keepExistingSubscription); err = subscribeRequestParser.GetIsFabricFiltered(&isFabricFiltered); - NL_TEST_ASSERT(apSuite, isFabricFiltered && err == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, subscribeRequestParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_TRUE(isFabricFiltered); + EXPECT_EQ(subscribeRequestParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildSubscribeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildSubscribeResponseMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; SubscribeResponseMessage::Builder subscribeResponseBuilder; err = subscribeResponseBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); subscribeResponseBuilder.SubscriptionId(1); - NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeResponseBuilder.GetError(), CHIP_NO_ERROR); subscribeResponseBuilder.MaxInterval(2); - NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeResponseBuilder.GetError(), CHIP_NO_ERROR); subscribeResponseBuilder.EndOfSubscribeResponseMessage(); - NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeResponseBuilder.GetError(), CHIP_NO_ERROR); } -void ParseSubscribeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseSubscribeResponseMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1304,32 +1349,34 @@ void ParseSubscribeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & chip::SubscriptionId subscriptionId = 0; uint16_t maxInterval = 0; err = subscribeResponseParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT subscribeResponseParser.PrettyPrint(); #endif err = subscribeResponseParser.GetSubscriptionId(&subscriptionId); - NL_TEST_ASSERT(apSuite, subscriptionId == 1 && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(subscriptionId, 1u); err = subscribeResponseParser.GetMaxInterval(&maxInterval); - NL_TEST_ASSERT(apSuite, maxInterval == 2 && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(maxInterval, 2u); - NL_TEST_ASSERT(apSuite, subscribeResponseParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(subscribeResponseParser.ExitContainer(), CHIP_NO_ERROR); } -void BuildTimedRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +void BuildTimedRequestMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; TimedRequestMessage::Builder TimedRequestMessageBuilder; err = TimedRequestMessageBuilder.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); TimedRequestMessageBuilder.TimeoutMs(1); - NL_TEST_ASSERT(apSuite, TimedRequestMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(TimedRequestMessageBuilder.GetError(), CHIP_NO_ERROR); } -void ParseTimedRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader) +void ParseTimedRequestMessage(chip::TLV::TLVReader & aReader) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1337,17 +1384,19 @@ void ParseTimedRequestMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aRea uint16_t timeout = 0; err = timedRequestMessageParser.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT timedRequestMessageParser.PrettyPrint(); #endif err = timedRequestMessageParser.GetTimeoutMs(&timeout); - NL_TEST_ASSERT(apSuite, timeout == 1 && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + + EXPECT_EQ(timeout, 1u); - NL_TEST_ASSERT(apSuite, timedRequestMessageParser.ExitContainer() == CHIP_NO_ERROR); + EXPECT_EQ(timedRequestMessageParser.ExitContainer(), CHIP_NO_ERROR); } -void DataVersionFilterIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestDataVersionFilterIB) { CHIP_ERROR err = CHIP_NO_ERROR; DataVersionFilterIB::Builder dataVersionFilterIBBuilder; @@ -1355,20 +1404,20 @@ void DataVersionFilterIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); dataVersionFilterIBBuilder.Init(&writer); - BuildDataVersionFilterIB(apSuite, dataVersionFilterIBBuilder); + BuildDataVersionFilterIB(dataVersionFilterIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseDataVersionFilterIB(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseDataVersionFilterIB(reader); } -void DataVersionFilterIBsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestDataVersionFilterIBs) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1377,22 +1426,22 @@ void DataVersionFilterIBsTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); err = dataVersionFilterIBsBuilder.Init(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - BuildDataVersionFilterIBs(apSuite, dataVersionFilterIBsBuilder); + BuildDataVersionFilterIBs(dataVersionFilterIBsBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseDataVersionFilterIBs(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseDataVersionFilterIBs(reader); } -void EventFilterTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventFilter) { CHIP_ERROR err = CHIP_NO_ERROR; EventFilterIB::Builder eventFilterBuilder; @@ -1400,20 +1449,20 @@ void EventFilterTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventFilterBuilder.Init(&writer); - BuildEventFilterIB(apSuite, eventFilterBuilder); + BuildEventFilterIB(eventFilterBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseEventFilterIB(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseEventFilterIB(reader); } -void EventFiltersTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventFilters) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1423,22 +1472,22 @@ void EventFiltersTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); err = eventFiltersBuilder.Init(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - BuildEventFilters(apSuite, eventFiltersBuilder); + BuildEventFilters(eventFiltersBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseEventFilters(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseEventFilters(reader); } -void ClusterPathIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestClusterPathIB) { CHIP_ERROR err = CHIP_NO_ERROR; ClusterPathIB::Builder clusterPathBuilder; @@ -1446,21 +1495,21 @@ void ClusterPathIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); clusterPathBuilder.Init(&writer); - BuildClusterPathIB(apSuite, clusterPathBuilder); + BuildClusterPathIB(clusterPathBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ParseClusterPathIB(apSuite, reader); + ParseClusterPathIB(reader); } -void AttributePathTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributePath) { CHIP_ERROR err = CHIP_NO_ERROR; AttributePathIB::Builder attributePathBuilder; @@ -1468,21 +1517,21 @@ void AttributePathTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); attributePathBuilder.Init(&writer); - BuildAttributePathIB(apSuite, attributePathBuilder); + BuildAttributePathIB(attributePathBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ParseAttributePathIB(apSuite, reader); + ParseAttributePathIB(reader); } -void AttributePathListTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributePathList) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1492,22 +1541,22 @@ void AttributePathListTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); err = attributePathListBuilder.Init(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - BuildAttributePathList(apSuite, attributePathListBuilder); + BuildAttributePathList(attributePathListBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseAttributePathList(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseAttributePathList(reader); } -void EventPathTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventPath) { CHIP_ERROR err = CHIP_NO_ERROR; EventPathIB::Parser eventPathParser; @@ -1516,22 +1565,22 @@ void EventPathTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventPathBuilder.Init(&writer); - BuildEventPath(apSuite, eventPathBuilder); + BuildEventPath(eventPathBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); eventPathParser.Init(reader); - ParseEventPath(apSuite, eventPathParser); + ParseEventPath(eventPathParser); } -void EventPathsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventPaths) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1541,22 +1590,22 @@ void EventPathsTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); err = eventPathListBuilder.Init(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - BuildEventPaths(apSuite, eventPathListBuilder); + BuildEventPaths(eventPathListBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseEventPaths(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseEventPaths(reader); } -void CommandPathIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestCommandPathIB) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1564,24 +1613,24 @@ void CommandPathIBTest(nlTestSuite * apSuite, void * apContext) CommandPathIB::Builder commandPathBuilder; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); err = commandPathBuilder.Init(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - BuildCommandPath(apSuite, commandPathBuilder); + BuildCommandPath(commandPathBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ParseCommandPath(apSuite, reader); + ParseCommandPath(reader); } -void EventDataIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventDataIB) { CHIP_ERROR err = CHIP_NO_ERROR; EventDataIB::Builder eventDataIBBuilder; @@ -1590,22 +1639,22 @@ void EventDataIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventDataIBBuilder.Init(&writer); - BuildEventDataIB(apSuite, eventDataIBBuilder); + BuildEventDataIB(eventDataIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); eventDataIBParser.Init(reader); - ParseEventDataIB(apSuite, eventDataIBParser); + ParseEventDataIB(eventDataIBParser); } -void EventReportIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventReportIB) { CHIP_ERROR err = CHIP_NO_ERROR; EventReportIB::Builder eventReportIBBuilder; @@ -1614,22 +1663,22 @@ void EventReportIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventReportIBBuilder.Init(&writer); - BuildEventReportIB(apSuite, eventReportIBBuilder); + BuildEventReportIB(eventReportIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); eventReportIBParser.Init(reader); - ParseEventReportIB(apSuite, eventReportIBParser); + ParseEventReportIB(eventReportIBParser); } -void EventReportsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventReports) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1637,20 +1686,20 @@ void EventReportsTest(nlTestSuite * apSuite, void * apContext) EventReportIBs::Builder eventReportsBuilder; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventReportsBuilder.Init(&writer); - BuildEventReports(apSuite, eventReportsBuilder); + BuildEventReports(eventReportsBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseEventReports(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseEventReports(reader); } -void EmptyEventReportsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEmptyEventReports) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1659,20 +1708,20 @@ void EmptyEventReportsTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventReportsBuilder.Init(&writer); eventReportsBuilder.EndOfEventReports(); - NL_TEST_ASSERT(apSuite, eventReportsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(eventReportsBuilder.GetError(), CHIP_NO_ERROR); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseEventReports(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseEventReports(reader); } -void AttributeReportIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributeReportIB) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeReportIB::Builder attributeReportIBBuilder; @@ -1681,22 +1730,22 @@ void AttributeReportIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); attributeReportIBBuilder.Init(&writer); - BuildAttributeReportIB(apSuite, attributeReportIBBuilder); + BuildAttributeReportIB(attributeReportIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); attributeReportIBParser.Init(reader); - ParseAttributeReportIB(apSuite, attributeReportIBParser); + ParseAttributeReportIB(attributeReportIBParser); } -void AttributeReportIBsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributeReportIBs) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1704,20 +1753,20 @@ void AttributeReportIBsTest(nlTestSuite * apSuite, void * apContext) AttributeReportIBs::Builder attributeReportIBsBuilder; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); attributeReportIBsBuilder.Init(&writer); - BuildAttributeReportIBs(apSuite, attributeReportIBsBuilder); + BuildAttributeReportIBs(attributeReportIBsBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseAttributeReportIBs(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseAttributeReportIBs(reader); } -void EmptyAttributeReportIBsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEmptyAttributeReportIBs) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1726,20 +1775,20 @@ void EmptyAttributeReportIBsTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); attributeReportIBsBuilder.Init(&writer); attributeReportIBsBuilder.EndOfAttributeReportIBs(); - NL_TEST_ASSERT(apSuite, attributeReportIBsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(attributeReportIBsBuilder.GetError(), CHIP_NO_ERROR); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseAttributeReportIBs(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseAttributeReportIBs(reader); } -void StatusIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestStatusIB) { CHIP_ERROR err = CHIP_NO_ERROR; StatusIB::Builder statusIBBuilder; @@ -1748,22 +1797,22 @@ void StatusIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); statusIBBuilder.Init(&writer); - BuildStatusIB(apSuite, statusIBBuilder); + BuildStatusIB(statusIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); StatusIBParser.Init(reader); - ParseStatusIB(apSuite, StatusIBParser); + ParseStatusIB(StatusIBParser); } -void EventStatusIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestEventStatusIB) { CHIP_ERROR err = CHIP_NO_ERROR; EventStatusIB::Builder eventStatusIBBuilder; @@ -1772,22 +1821,22 @@ void EventStatusIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); eventStatusIBBuilder.Init(&writer); - BuildEventStatusIB(apSuite, eventStatusIBBuilder); + BuildEventStatusIB(eventStatusIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); eventStatusIBParser.Init(reader); - ParseEventStatusIB(apSuite, eventStatusIBParser); + ParseEventStatusIB(eventStatusIBParser); } -void AttributeStatusIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributeStatusIB) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeStatusIB::Builder attributeStatusIBBuilder; @@ -1796,22 +1845,22 @@ void AttributeStatusIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); attributeStatusIBBuilder.Init(&writer); - BuildAttributeStatusIB(apSuite, attributeStatusIBBuilder); + BuildAttributeStatusIB(attributeStatusIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); attributeStatusIBParser.Init(reader); - ParseAttributeStatusIB(apSuite, attributeStatusIBParser); + ParseAttributeStatusIB(attributeStatusIBParser); } -void AttributeStatusesTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributeStatuses) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1819,21 +1868,21 @@ void AttributeStatusesTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); AttributeStatusIBs::Builder attributeStatusesBuilder; err = attributeStatusesBuilder.Init(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - BuildAttributeStatuses(apSuite, attributeStatusesBuilder); + EXPECT_EQ(err, CHIP_NO_ERROR); + BuildAttributeStatuses(attributeStatusesBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseAttributeStatuses(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseAttributeStatuses(reader); } -void AttributeDataIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributeDataIB) { CHIP_ERROR err = CHIP_NO_ERROR; AttributeDataIB::Builder AttributeDataIBBuilder; @@ -1842,22 +1891,22 @@ void AttributeDataIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); AttributeDataIBBuilder.Init(&writer); - BuildAttributeDataIB(apSuite, AttributeDataIBBuilder); + BuildAttributeDataIB(AttributeDataIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); AttributeDataIBParser.Init(reader); - ParseAttributeDataIB(apSuite, AttributeDataIBParser); + ParseAttributeDataIB(AttributeDataIBParser); } -void AttributeDataIBsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestAttributeDataIBs) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -1865,20 +1914,20 @@ void AttributeDataIBsTest(nlTestSuite * apSuite, void * apContext) writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); AttributeDataIBs::Builder AttributeDataIBsBuilder; AttributeDataIBsBuilder.Init(&writer); - BuildAttributeDataIBs(apSuite, AttributeDataIBsBuilder); + BuildAttributeDataIBs(AttributeDataIBsBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseAttributeDataIBs(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseAttributeDataIBs(reader); } -void CommandDataIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestCommandDataIB) { CHIP_ERROR err = CHIP_NO_ERROR; CommandDataIB::Builder commandDataIBBuilder; @@ -1887,22 +1936,22 @@ void CommandDataIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); commandDataIBBuilder.Init(&writer); - BuildCommandDataIB(apSuite, commandDataIBBuilder); + BuildCommandDataIB(commandDataIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); commandDataIBParser.Init(reader); - ParseCommandDataIB(apSuite, commandDataIBParser); + ParseCommandDataIB(commandDataIBParser); } -void CommandStatusIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestCommandStatusIB) { CHIP_ERROR err = CHIP_NO_ERROR; CommandStatusIB::Builder commandStatusIBBuilder; @@ -1911,22 +1960,22 @@ void CommandStatusIBTest(nlTestSuite * apSuite, void * apContext) chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); commandStatusIBBuilder.Init(&writer); - BuildCommandStatusIB(apSuite, commandStatusIBBuilder); + BuildCommandStatusIB(commandStatusIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); commandStatusIBParser.Init(reader); - ParseCommandStatusIB(apSuite, commandStatusIBParser); + ParseCommandStatusIB(commandStatusIBParser); } -void InvokeResponseIBWithCommandDataIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponseIBWithCommandDataIB) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeResponseIB::Builder invokeResponseIBBuilder; @@ -1935,22 +1984,22 @@ void InvokeResponseIBWithCommandDataIBTest(nlTestSuite * apSuite, void * apConte chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); invokeResponseIBBuilder.Init(&writer); - BuildInvokeResponseIBWithCommandDataIB(apSuite, invokeResponseIBBuilder); + BuildInvokeResponseIBWithCommandDataIB(invokeResponseIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); invokeResponseIBParser.Init(reader); - ParseInvokeResponseIBWithCommandDataIB(apSuite, invokeResponseIBParser); + ParseInvokeResponseIBWithCommandDataIB(invokeResponseIBParser); } -void InvokeResponseIBWithCommandStatusIBTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponseIBWithCommandStatusIB) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeResponseIB::Builder invokeResponseIBBuilder; @@ -1959,22 +2008,22 @@ void InvokeResponseIBWithCommandStatusIBTest(nlTestSuite * apSuite, void * apCon chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); invokeResponseIBBuilder.Init(&writer); - BuildInvokeResponseIBWithCommandStatusIB(apSuite, invokeResponseIBBuilder); + BuildInvokeResponseIBWithCommandStatusIB(invokeResponseIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); invokeResponseIBParser.Init(reader); - ParseInvokeResponseIBWithCommandStatusIB(apSuite, invokeResponseIBParser); + ParseInvokeResponseIBWithCommandStatusIB(invokeResponseIBParser); } -void InvokeResponseIBWithMalformDataTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponseIBWithMalformData) { CHIP_ERROR err = CHIP_NO_ERROR; InvokeResponseIB::Builder invokeResponseIBBuilder; @@ -1983,22 +2032,22 @@ void InvokeResponseIBWithMalformDataTest(nlTestSuite * apSuite, void * apContext chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); invokeResponseIBBuilder.Init(&writer); - BuildWrongInvokeResponseIB(apSuite, invokeResponseIBBuilder); + BuildWrongInvokeResponseIB(invokeResponseIBBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = invokeResponseIBParser.Init(reader); - NL_TEST_ASSERT(apSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); } -void InvokeRequestsTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeRequests) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2006,20 +2055,20 @@ void InvokeRequestsTest(nlTestSuite * apSuite, void * apContext) InvokeRequests::Builder invokeRequestsBuilder; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); invokeRequestsBuilder.Init(&writer); - BuildInvokeRequests(apSuite, invokeRequestsBuilder); + BuildInvokeRequests(invokeRequestsBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseInvokeRequests(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseInvokeRequests(reader); } -void InvokeResponsesTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponses) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2027,37 +2076,37 @@ void InvokeResponsesTest(nlTestSuite * apSuite, void * apContext) InvokeResponseIBs::Builder invokeResponsesBuilder; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); invokeResponsesBuilder.Init(&writer); - BuildInvokeResponses(apSuite, invokeResponsesBuilder); + BuildInvokeResponses(invokeResponsesBuilder); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ParseInvokeResponses(apSuite, reader); + EXPECT_EQ(err, CHIP_NO_ERROR); + ParseInvokeResponses(reader); } -void InvokeInvokeRequestMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeInvokeRequestMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildInvokeRequestMessage(apSuite, writer); + BuildInvokeRequestMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseInvokeRequestMessage(apSuite, reader); + ParseInvokeRequestMessage(reader); } -void InvokeRequestMessageEndOfMessageReservationTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeRequestMessageEndOfMessageReservation) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2065,18 +2114,18 @@ void InvokeRequestMessageEndOfMessageReservationTest(nlTestSuite * apSuite, void const uint32_t kSmallBufferSize = 100; writer.Init(chip::System::PacketBufferHandle::New(kSmallBufferSize, /* aReservedSize = */ 0), /* useChainedBuffers = */ false); err = invokeRequestMessageBuilder.InitWithEndBufferReserved(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterInitWithReservation = writer.GetRemainingFreeLength(); err = invokeRequestMessageBuilder.EndOfInvokeRequestMessage(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterEndingInvokeRequestMessage = writer.GetRemainingFreeLength(); - NL_TEST_ASSERT(apSuite, remainingLengthAfterInitWithReservation == remainingLengthAfterEndingInvokeRequestMessage); + EXPECT_EQ(remainingLengthAfterInitWithReservation, remainingLengthAfterEndingInvokeRequestMessage); } -void InvokeRequestsEndOfRequestReservationTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeRequestsEndOfRequestReservation) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2084,41 +2133,41 @@ void InvokeRequestsEndOfRequestReservationTest(nlTestSuite * apSuite, void * apC const uint32_t kSmallBufferSize = 100; writer.Init(chip::System::PacketBufferHandle::New(kSmallBufferSize, /* aReservedSize = */ 0), /* useChainedBuffers = */ false); err = invokeRequestMessageBuilder.InitWithEndBufferReserved(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); invokeRequestMessageBuilder.CreateInvokeRequests(/* aReserveEndBuffer = */ true); InvokeRequests::Builder & invokeRequestsBuilder = invokeRequestMessageBuilder.GetInvokeRequests(); err = invokeRequestsBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); auto * invokeRequestsWriter = invokeRequestsBuilder.GetWriter(); uint32_t remainingLengthAfterInitWithReservation = invokeRequestsWriter->GetRemainingFreeLength(); err = invokeRequestsBuilder.EndOfInvokeRequests(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterEndingInvokeRequests = invokeRequestsWriter->GetRemainingFreeLength(); - NL_TEST_ASSERT(apSuite, remainingLengthAfterInitWithReservation == remainingLengthAfterEndingInvokeRequests); + EXPECT_EQ(remainingLengthAfterInitWithReservation, remainingLengthAfterEndingInvokeRequests); } -void InvokeInvokeResponseMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeInvokeResponseMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildInvokeResponseMessage(apSuite, writer); + BuildInvokeResponseMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseInvokeResponseMessage(apSuite, reader); + ParseInvokeResponseMessage(reader); } -void InvokeResponseMessageEndOfMessageReservationTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponseMessageEndOfMessageReservation) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2126,17 +2175,17 @@ void InvokeResponseMessageEndOfMessageReservationTest(nlTestSuite * apSuite, voi const uint32_t kSmallBufferSize = 100; writer.Init(chip::System::PacketBufferHandle::New(kSmallBufferSize, /* aReservedSize = */ 0), /* useChainedBuffers = */ false); err = invokeResponseMessageBuilder.InitWithEndBufferReserved(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterInitWithReservation = writer.GetRemainingFreeLength(); err = invokeResponseMessageBuilder.EndOfInvokeResponseMessage(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterEndingInvokeResponseMessage = writer.GetRemainingFreeLength(); - NL_TEST_ASSERT(apSuite, remainingLengthAfterInitWithReservation == remainingLengthAfterEndingInvokeResponseMessage); + EXPECT_EQ(remainingLengthAfterInitWithReservation, remainingLengthAfterEndingInvokeResponseMessage); } -void InvokeResponseMessageReservationForEndandMoreChunkTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponseMessageReservationForEndandMoreChunk) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2144,22 +2193,22 @@ void InvokeResponseMessageReservationForEndandMoreChunkTest(nlTestSuite * apSuit const uint32_t kSmallBufferSize = 100; writer.Init(chip::System::PacketBufferHandle::New(kSmallBufferSize, /* aReservedSize = */ 0), /* useChainedBuffers = */ false); err = invokeResponseMessageBuilder.InitWithEndBufferReserved(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = invokeResponseMessageBuilder.ReserveSpaceForMoreChunkedMessages(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAllReservations = writer.GetRemainingFreeLength(); invokeResponseMessageBuilder.MoreChunkedMessages(/* aMoreChunkedMessages = */ true); - NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(invokeResponseMessageBuilder.GetError(), CHIP_NO_ERROR); err = invokeResponseMessageBuilder.EndOfInvokeResponseMessage(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterEndingInvokeResponseMessage = writer.GetRemainingFreeLength(); - NL_TEST_ASSERT(apSuite, remainingLengthAllReservations == remainingLengthAfterEndingInvokeResponseMessage); + EXPECT_EQ(remainingLengthAllReservations, remainingLengthAfterEndingInvokeResponseMessage); } -void InvokeResponsesEndOfResponseReservationTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestInvokeResponsesEndOfResponseReservation) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; @@ -2167,142 +2216,142 @@ void InvokeResponsesEndOfResponseReservationTest(nlTestSuite * apSuite, void * a const uint32_t kSmallBufferSize = 100; writer.Init(chip::System::PacketBufferHandle::New(kSmallBufferSize, /* aReservedSize = */ 0), /* useChainedBuffers = */ false); err = invokeResponseMessageBuilder.InitWithEndBufferReserved(&writer); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); invokeResponseMessageBuilder.CreateInvokeResponses(/* aReserveEndBuffer = */ true); InvokeResponseIBs::Builder & invokeResponsesBuilder = invokeResponseMessageBuilder.GetInvokeResponses(); err = invokeResponsesBuilder.GetError(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); auto * invokeResponsesWriter = invokeResponsesBuilder.GetWriter(); uint32_t remainingLengthAfterInitWithReservation = invokeResponsesWriter->GetRemainingFreeLength(); err = invokeResponsesBuilder.EndOfInvokeResponses(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); uint32_t remainingLengthAfterEndingInvokeResponses = invokeResponsesWriter->GetRemainingFreeLength(); - NL_TEST_ASSERT(apSuite, remainingLengthAfterInitWithReservation == remainingLengthAfterEndingInvokeResponses); + EXPECT_EQ(remainingLengthAfterInitWithReservation, remainingLengthAfterEndingInvokeResponses); } -void ReportDataMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestReportDataMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildReportDataMessage(apSuite, writer); + BuildReportDataMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseReportDataMessage(apSuite, reader); + ParseReportDataMessage(reader); } -void ReadRequestMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestReadRequestMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildReadRequestMessage(apSuite, writer); + BuildReadRequestMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseReadRequestMessage(apSuite, reader); + ParseReadRequestMessage(reader); } -void WriteRequestMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestWriteRequestMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildWriteRequestMessage(apSuite, writer); + BuildWriteRequestMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseWriteRequestMessage(apSuite, reader); + ParseWriteRequestMessage(reader); } -void WriteResponseMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestWriteResponseMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildWriteResponseMessage(apSuite, writer); + BuildWriteResponseMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseWriteResponseMessage(apSuite, reader); + ParseWriteResponseMessage(reader); } -void SubscribeRequestMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestSubscribeRequestMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildSubscribeRequestMessage(apSuite, writer); + BuildSubscribeRequestMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseSubscribeRequestMessage(apSuite, reader); + ParseSubscribeRequestMessage(reader); } -void SubscribeResponseMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestSubscribeResponseMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildSubscribeResponseMessage(apSuite, writer); + BuildSubscribeResponseMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseSubscribeResponseMessage(apSuite, reader); + ParseSubscribeResponseMessage(reader); } -void TimedRequestMessageTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestTimedRequestMessage) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildTimedRequestMessage(apSuite, writer); + BuildTimedRequestMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); - ParseTimedRequestMessage(apSuite, reader); + ParseTimedRequestMessage(reader); } -void CheckPointRollbackTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestMessageDef, TestCheckPointRollback) { CHIP_ERROR err = CHIP_NO_ERROR; size_t NumDataElement = 0; @@ -2316,32 +2365,32 @@ void CheckPointRollbackTest(nlTestSuite * apSuite, void * apContext) // encode one attribute element AttributeDataIB::Builder & attributeDataIBBuilder1 = attributeDataIBsBuilder.CreateAttributeDataIBBuilder(); - NL_TEST_ASSERT(apSuite, attributeDataIBsBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeDataIB(apSuite, attributeDataIBBuilder1); + EXPECT_EQ(attributeDataIBsBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeDataIB(attributeDataIBBuilder1); // checkpoint attributeDataIBsBuilder.Checkpoint(checkpoint); // encode another attribute element AttributeDataIB::Builder & attributeDataIBBuilder2 = attributeDataIBsBuilder.CreateAttributeDataIBBuilder(); - NL_TEST_ASSERT(apSuite, attributeDataIBsBuilder.GetError() == CHIP_NO_ERROR); - BuildAttributeDataIB(apSuite, attributeDataIBBuilder2); + EXPECT_EQ(attributeDataIBsBuilder.GetError(), CHIP_NO_ERROR); + BuildAttributeDataIB(attributeDataIBBuilder2); // rollback to previous checkpoint attributeDataIBsBuilder.Rollback(checkpoint); attributeDataIBsBuilder.EndOfAttributeDataIBs(); - NL_TEST_ASSERT(apSuite, attributeDataIBsBuilder.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(attributeDataIBsBuilder.GetError(), CHIP_NO_ERROR); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); DebugPrettyPrint(buf); reader.Init(std::move(buf)); err = reader.Next(); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = AttributeDataIBsParser.Init(reader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT AttributeDataIBsParser.PrettyPrint(); @@ -2351,101 +2400,7 @@ void CheckPointRollbackTest(nlTestSuite * apSuite, void * apContext) ++NumDataElement; } - NL_TEST_ASSERT(apSuite, NumDataElement == 1); + EXPECT_EQ(NumDataElement, 1u); } -/** - * Test Suite. It lists all the test functions. - */ - -// clang-format off -const nlTest sTests[] = - { - NL_TEST_DEF("ClusterPathIBTest", ClusterPathIBTest), - NL_TEST_DEF("DataVersionFilterIBTest", DataVersionFilterIBTest), - NL_TEST_DEF("DataVersionFilterIBsTest", DataVersionFilterIBsTest), - NL_TEST_DEF("EventFilterTest", EventFilterTest), - NL_TEST_DEF("EventFiltersTest", EventFiltersTest), - NL_TEST_DEF("AttributePathTest", AttributePathTest), - NL_TEST_DEF("AttributePathListTest", AttributePathListTest), - NL_TEST_DEF("AttributeStatusIBTest", AttributeStatusIBTest), - NL_TEST_DEF("AttributeStatusesTest", AttributeStatusesTest), - NL_TEST_DEF("AttributeDataIBTest", AttributeDataIBTest), - NL_TEST_DEF("AttributeDataIBsTest", AttributeDataIBsTest), - NL_TEST_DEF("AttributeReportIBTest", AttributeReportIBTest), - NL_TEST_DEF("AttributeReportIBsTest", AttributeReportIBsTest), - NL_TEST_DEF("EmptyAttributeReportIBsTest", EmptyAttributeReportIBsTest), - NL_TEST_DEF("EventPathTest", EventPathTest), - NL_TEST_DEF("EventPathsTest", EventPathsTest), - NL_TEST_DEF("EventDataIBTest", EventDataIBTest), - NL_TEST_DEF("EventReportIBTest", EventReportIBTest), - NL_TEST_DEF("EventReportsTest", EventReportsTest), - NL_TEST_DEF("EmptyEventReportsTest", EmptyEventReportsTest), - NL_TEST_DEF("StatusIBTest", StatusIBTest), - NL_TEST_DEF("EventStatusIBTest", EventStatusIBTest), - NL_TEST_DEF("CommandPathIBTest", CommandPathIBTest), - NL_TEST_DEF("CommandDataIBTest", CommandDataIBTest), - NL_TEST_DEF("CommandStatusIBTest", CommandStatusIBTest), - NL_TEST_DEF("InvokeResponseIBWithCommandDataIBTest", InvokeResponseIBWithCommandDataIBTest), - NL_TEST_DEF("InvokeResponseIBWithCommandStatusIBTest", InvokeResponseIBWithCommandStatusIBTest), - NL_TEST_DEF("InvokeResponseIBWithMalformDataTest", InvokeResponseIBWithMalformDataTest), - NL_TEST_DEF("InvokeRequestsTest", InvokeRequestsTest), - NL_TEST_DEF("InvokeResponsesTest", InvokeResponsesTest), - NL_TEST_DEF("InvokeInvokeRequestMessageTest", InvokeInvokeRequestMessageTest), - NL_TEST_DEF("InvokeRequestMessageEndOfMessageReservationTest", InvokeRequestMessageEndOfMessageReservationTest), - NL_TEST_DEF("InvokeRequestsEndOfRequestReservationTest", InvokeRequestsEndOfRequestReservationTest), - NL_TEST_DEF("InvokeInvokeResponseMessageTest", InvokeInvokeResponseMessageTest), - NL_TEST_DEF("InvokeResponseMessageEndOfMessageReservationTest", InvokeResponseMessageEndOfMessageReservationTest), - NL_TEST_DEF("InvokeResponseMessageReservationForEndandMoreChunkTest", InvokeResponseMessageReservationForEndandMoreChunkTest), - NL_TEST_DEF("InvokeResponsesEndOfResponseReservationTest", InvokeResponsesEndOfResponseReservationTest), - NL_TEST_DEF("ReportDataMessageTest", ReportDataMessageTest), - NL_TEST_DEF("ReadRequestMessageTest", ReadRequestMessageTest), - NL_TEST_DEF("WriteRequestMessageTest", WriteRequestMessageTest), - NL_TEST_DEF("WriteResponseMessageTest", WriteResponseMessageTest), - NL_TEST_DEF("SubscribeRequestMessageTest", SubscribeRequestMessageTest), - NL_TEST_DEF("SubscribeResponseMessageTest", SubscribeResponseMessageTest), - NL_TEST_DEF("TimedRequestMessageTest", TimedRequestMessageTest), - NL_TEST_DEF("CheckPointRollbackTest", CheckPointRollbackTest), - NL_TEST_SENTINEL() - }; -// clang-format on } // namespace - -/** - * Set up the test suite. - */ -static int TestSetup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -int TestMessageDef() -{ - // clang-format off - nlTestSuite theSuite = - { - "MessageDef", - &sTests[0], - TestSetup, - TestTeardown, - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestMessageDef) diff --git a/src/app/tests/TestNullable.cpp b/src/app/tests/TestNullable.cpp index 660037339d44e1..9a8104f86ce4d3 100644 --- a/src/app/tests/TestNullable.cpp +++ b/src/app/tests/TestNullable.cpp @@ -21,10 +21,11 @@ #include #include +#include +#include + #include #include -#include -#include using namespace chip; using namespace chip::app::DataModel; @@ -79,7 +80,7 @@ int CtorDtorCounter::destroyed = 0; } // namespace -static void TestBasic(nlTestSuite * inSuite, void * inContext) +TEST(TestNullable, TestBasic) { // Set up our test CtorDtorCounter objects, which will mess with counts, before we reset the // counts. @@ -89,109 +90,109 @@ static void TestBasic(nlTestSuite * inSuite, void * inContext) { auto testNullable = MakeNullable(100); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !testNullable.IsNull() && testNullable.Value().m == 100); - NL_TEST_ASSERT(inSuite, testNullable == c100); - NL_TEST_ASSERT(inSuite, testNullable != c101); - NL_TEST_ASSERT(inSuite, testNullable != c102); + EXPECT_TRUE(CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(!testNullable.IsNull() && testNullable.Value().m == 100); + EXPECT_EQ(testNullable, c100); + EXPECT_NE(testNullable, c101); + EXPECT_NE(testNullable, c102); testNullable.SetNull(); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 1); - NL_TEST_ASSERT(inSuite, !!testNullable.IsNull()); - NL_TEST_ASSERT(inSuite, testNullable != c100); - NL_TEST_ASSERT(inSuite, testNullable != c101); - NL_TEST_ASSERT(inSuite, testNullable != c102); + EXPECT_TRUE(CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 1); + EXPECT_TRUE(testNullable.IsNull()); + EXPECT_NE(testNullable, c100); + EXPECT_NE(testNullable, c101); + EXPECT_NE(testNullable, c102); testNullable.SetNonNull(CtorDtorCounter(101)); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 2); - NL_TEST_ASSERT(inSuite, !testNullable.IsNull() && testNullable.Value().m == 101); - NL_TEST_ASSERT(inSuite, testNullable != c100); - NL_TEST_ASSERT(inSuite, testNullable == c101); - NL_TEST_ASSERT(inSuite, testNullable != c102); + EXPECT_TRUE(CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 2); + EXPECT_TRUE(!testNullable.IsNull() && testNullable.Value().m == 101); + EXPECT_NE(testNullable, c100); + EXPECT_EQ(testNullable, c101); + EXPECT_NE(testNullable, c102); testNullable.SetNonNull(102); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 4 && CtorDtorCounter::destroyed == 3); - NL_TEST_ASSERT(inSuite, !testNullable.IsNull() && testNullable.Value().m == 102); - NL_TEST_ASSERT(inSuite, testNullable != c100); - NL_TEST_ASSERT(inSuite, testNullable != c101); - NL_TEST_ASSERT(inSuite, testNullable == c102); + EXPECT_TRUE(CtorDtorCounter::created == 4 && CtorDtorCounter::destroyed == 3); + EXPECT_TRUE(!testNullable.IsNull() && testNullable.Value().m == 102); + EXPECT_NE(testNullable, c100); + EXPECT_NE(testNullable, c101); + EXPECT_EQ(testNullable, c102); } // Our test CtorDtorCounter objects are still in scope here. - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 4 && CtorDtorCounter::destroyed == 4); + EXPECT_TRUE(CtorDtorCounter::created == 4 && CtorDtorCounter::destroyed == 4); } -static void TestMake(nlTestSuite * inSuite, void * inContext) +TEST(TestNullable, TestMake) { CtorDtorCounter::ResetCounter(); { auto testNullable = MakeNullable(200); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !testNullable.IsNull() && testNullable.Value().m == 200); + EXPECT_TRUE(CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(!testNullable.IsNull() && testNullable.Value().m == 200); } - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 1); + EXPECT_TRUE(CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 1); } -static void TestCopy(nlTestSuite * inSuite, void * inContext) +TEST(TestNullable, TestCopy) { CtorDtorCounter::ResetCounter(); { auto testSrc = MakeNullable(300); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !testSrc.IsNull() && testSrc.Value().m == 300); + EXPECT_TRUE(CtorDtorCounter::created == 1 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(!testSrc.IsNull() && testSrc.Value().m == 300); { Nullable testDst(testSrc); - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !testDst.IsNull() && testDst.Value().m == 300); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(!testDst.IsNull() && testDst.Value().m == 300); } - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 1); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 1); { Nullable testDst; - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 1); - NL_TEST_ASSERT(inSuite, !!testDst.IsNull()); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 1); + EXPECT_TRUE(testDst.IsNull()); testDst = testSrc; - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 1); - NL_TEST_ASSERT(inSuite, !testDst.IsNull() && testDst.Value().m == 300); + EXPECT_TRUE(CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 1); + EXPECT_TRUE(!testDst.IsNull() && testDst.Value().m == 300); } - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 2); + EXPECT_TRUE(CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 2); } - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 3); + EXPECT_TRUE(CtorDtorCounter::created == 3 && CtorDtorCounter::destroyed == 3); } -static void TestMove(nlTestSuite * inSuite, void * inContext) +TEST(TestNullable, TestMove) { CtorDtorCounter::ResetCounter(); { auto testSrc = MakeNullable(400); // construct Nullable testDst(std::move(testSrc)); // move construct - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !testDst.IsNull() && testDst.Value().m == 400); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(!testDst.IsNull() && testDst.Value().m == 400); // destroy both testsSrc and testDst } - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 2); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 2); CtorDtorCounter::ResetCounter(); { Nullable testDst; // no object construction - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 0 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !!testDst.IsNull()); + EXPECT_TRUE(CtorDtorCounter::created == 0 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(testDst.IsNull()); auto testSrc = MakeNullable(401); // construct object testDst = std::move(testSrc); // construct a copy - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 0); - NL_TEST_ASSERT(inSuite, !testDst.IsNull() && testDst.Value().m == 401); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 0); + EXPECT_TRUE(!testDst.IsNull() && testDst.Value().m == 401); } - NL_TEST_ASSERT(inSuite, CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 2); + EXPECT_TRUE(CtorDtorCounter::created == 2 && CtorDtorCounter::destroyed == 2); } -static void TestUpdate(nlTestSuite * inSuite, void * inContext) +TEST(TestNullable, TestUpdate) { using SmallArray = std::array; // Arrays @@ -199,19 +200,19 @@ static void TestUpdate(nlTestSuite * inSuite, void * inContext) auto nullable1 = MakeNullable({ 1, 2, 3 }); auto nullable2 = MakeNullable({ 1, 2, 3 }); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); - NL_TEST_ASSERT(inSuite, !nullable2.IsNull()); - NL_TEST_ASSERT(inSuite, nullable1 == nullable2); + EXPECT_FALSE(nullable1.IsNull()); + EXPECT_FALSE(nullable2.IsNull()); + EXPECT_EQ(nullable1, nullable2); // No-op on change to same. - NL_TEST_ASSERT(inSuite, nullable1.Update(nullable2) == false); - NL_TEST_ASSERT(inSuite, nullable1 == nullable2); + EXPECT_FALSE(nullable1.Update(nullable2)); + EXPECT_EQ(nullable1, nullable2); nullable1.Value()[0] = 100; - NL_TEST_ASSERT(inSuite, nullable1 != nullable2); - NL_TEST_ASSERT(inSuite, nullable2.Update(nullable1) == true); - NL_TEST_ASSERT(inSuite, nullable1 == nullable2); + EXPECT_NE(nullable1, nullable2); + EXPECT_TRUE(nullable2.Update(nullable1)); + EXPECT_EQ(nullable1, nullable2); } // Structs @@ -227,83 +228,52 @@ static void TestUpdate(nlTestSuite * inSuite, void * inContext) auto nullable1 = MakeNullable({ 1, 2 }); auto nullable2 = MakeNullable({ 1, 2 }); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); - NL_TEST_ASSERT(inSuite, !nullable2.IsNull()); - NL_TEST_ASSERT(inSuite, nullable1 == nullable2); + EXPECT_FALSE(nullable1.IsNull()); + EXPECT_FALSE(nullable2.IsNull()); + EXPECT_EQ(nullable1, nullable2); // No-op on change to same. - NL_TEST_ASSERT(inSuite, nullable1.Update(nullable2) == false); - NL_TEST_ASSERT(inSuite, nullable1 == nullable2); + EXPECT_FALSE(nullable1.Update(nullable2)); + EXPECT_EQ(nullable1, nullable2); nullable1.Value().a = 100; - NL_TEST_ASSERT(inSuite, nullable1 != nullable2); - NL_TEST_ASSERT(inSuite, nullable2.Update(nullable1) == true); - NL_TEST_ASSERT(inSuite, nullable1 == nullable2); + EXPECT_NE(nullable1, nullable2); + EXPECT_TRUE(nullable2.Update(nullable1)); + EXPECT_EQ(nullable1, nullable2); } // Scalar cases { auto nullable1 = MakeNullable(static_cast(1)); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); + EXPECT_FALSE(nullable1.IsNull()); // Non-null to non-null same value - NL_TEST_ASSERT(inSuite, nullable1.Update(nullable1) == false); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); + EXPECT_FALSE(nullable1.Update(nullable1)); + EXPECT_FALSE(nullable1.IsNull()); // Non-null to null - NL_TEST_ASSERT(inSuite, nullable1.Update(NullNullable) == true); - NL_TEST_ASSERT(inSuite, nullable1.IsNull()); + EXPECT_TRUE(nullable1.Update(NullNullable)); + EXPECT_TRUE(nullable1.IsNull()); // Null to null - NL_TEST_ASSERT(inSuite, nullable1.Update(NullNullable) == false); - NL_TEST_ASSERT(inSuite, nullable1.IsNull()); + EXPECT_FALSE(nullable1.Update(NullNullable)); + EXPECT_TRUE(nullable1.IsNull()); // Null to non-null - NL_TEST_ASSERT(inSuite, nullable1.Update(MakeNullable(static_cast(1))) == true); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); - NL_TEST_ASSERT(inSuite, nullable1.Value() == 1); + EXPECT_TRUE(nullable1.Update(MakeNullable(static_cast(1)))); + EXPECT_FALSE(nullable1.IsNull()); + EXPECT_EQ(nullable1.Value(), 1); // Non-null to non-null different value - NL_TEST_ASSERT(inSuite, nullable1.Update(MakeNullable(static_cast(2))) == true); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); - NL_TEST_ASSERT(inSuite, nullable1.Value() == 2); + EXPECT_TRUE(nullable1.Update(MakeNullable(static_cast(2)))); + EXPECT_FALSE(nullable1.IsNull()); + EXPECT_EQ(nullable1.Value(), 2); // Non-null to extent of range --> changes to "invalid" value in range. - NL_TEST_ASSERT(inSuite, nullable1.Update(MakeNullable(static_cast(255))) == true); - NL_TEST_ASSERT(inSuite, !nullable1.IsNull()); - NL_TEST_ASSERT(inSuite, nullable1.Value() == 255); + EXPECT_TRUE(nullable1.Update(MakeNullable(static_cast(255)))); + EXPECT_FALSE(nullable1.IsNull()); + EXPECT_EQ(nullable1.Value(), 255); } } - -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("NullableBasic", TestBasic), - NL_TEST_DEF("NullableMake", TestMake), - NL_TEST_DEF("NullableCopy", TestCopy), - NL_TEST_DEF("NullableMove", TestMove), - NL_TEST_DEF("Nullable Update operation", TestUpdate), - NL_TEST_SENTINEL() -}; -// clang-format on - -int TestNullable() -{ - // clang-format off - nlTestSuite theSuite = - { - "Test for Nullable abstraction", - &sTests[0], - nullptr, - nullptr - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestNullable) diff --git a/src/app/tests/TestNumericAttributeTraits.cpp b/src/app/tests/TestNumericAttributeTraits.cpp index a88f3925c2a1d0..6d6c35735066a4 100644 --- a/src/app/tests/TestNumericAttributeTraits.cpp +++ b/src/app/tests/TestNumericAttributeTraits.cpp @@ -27,8 +27,8 @@ * */ -#include -#include +#include +#include // We are testing the odd-sized-integers.h module #include @@ -38,7 +38,7 @@ using namespace chip::app; namespace { -void Test_UINT8(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT8) { // Unsigned 8-bit Integer : 1 byte, endianness does not matter. using IntType = NumericAttributeTraits; @@ -53,8 +53,8 @@ void Test_UINT8(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 0xFF; // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 1); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 1); + EXPECT_EQ(sizeof(sValue), 1u); + EXPECT_GE(sizeof(wValue), 1u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, &storageTestData, sizeof(sValue)); @@ -63,7 +63,7 @@ void Test_UINT8(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 17); + EXPECT_EQ(wValue, 17u); StorageType sNewValue; @@ -71,22 +71,22 @@ void Test_UINT8(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_SINT8(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT8) { // Signed 8-bit Integer : 1 byte, endianness does not matter. using IntType = NumericAttributeTraits; @@ -101,8 +101,8 @@ void Test_SINT8(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = -128; // 0x80 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 1); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 1); + EXPECT_EQ(sizeof(sValue), 1u); + EXPECT_GE(sizeof(wValue), 1u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, &storageTestData, sizeof(sValue)); @@ -111,7 +111,7 @@ void Test_SINT8(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 17); + EXPECT_EQ(wValue, 17); StorageType sNewValue; @@ -119,19 +119,19 @@ void Test_SINT8(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } enum class SimpleEnum : uint8_t @@ -140,7 +140,7 @@ enum class SimpleEnum : uint8_t kOne = 1, }; -void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SimpleEnum) { // Unsigned 8-bit Integer : 1 byte, endianness does not matter. using IntType = NumericAttributeTraits; @@ -155,8 +155,8 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = static_cast(0xFF); // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 1); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 1); + EXPECT_EQ(sizeof(sValue), 1u); + EXPECT_GE(sizeof(wValue), 1u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, &storageTestData, sizeof(sValue)); @@ -165,7 +165,7 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == SimpleEnum::kOne); + EXPECT_EQ(wValue, SimpleEnum::kOne); StorageType sNewValue; @@ -173,19 +173,19 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } //////////////////////////////////////////////////////////// @@ -200,7 +200,7 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext) // $$$$$$$$/ $$/ $$$$$$$/ $$$$$$/ $$/ // // // //////////////////////////////////////////////////////////// -void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT24_LE) { // Unsigned 24-bit Integer : 3 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -215,8 +215,8 @@ void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 16777215; // 0xFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 3); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 3); + EXPECT_EQ(sizeof(sValue), 3u); + EXPECT_GE(sizeof(wValue), 3u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -225,7 +225,7 @@ void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456); + EXPECT_EQ(wValue, 0x123456u); StorageType sNewValue; @@ -233,22 +233,22 @@ void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT24_BE) { // Unsigned 24-bit Integer : 3 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -263,8 +263,8 @@ void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 16777215; // 0xFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 3); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 3); + EXPECT_EQ(sizeof(sValue), 3u); + EXPECT_GE(sizeof(wValue), 3u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -273,7 +273,7 @@ void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456); + EXPECT_EQ(wValue, 0x123456u); StorageType sNewValue; @@ -281,22 +281,22 @@ void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT24_LE) { // Signed 24-bit Integer : 3 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -315,10 +315,10 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -8388608; // -0x800000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 3); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 3); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 3); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 3); + EXPECT_EQ(sizeof(sValuePos), 3u); + EXPECT_GE(sizeof(wValuePos), 3u); + EXPECT_EQ(sizeof(sValueNeg), 3u); + EXPECT_GE(sizeof(wValueNeg), 3u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -329,8 +329,8 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -340,8 +340,8 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -349,19 +349,19 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } -void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT24_BE) { // Signed 24-bit Integer : 3 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -380,10 +380,10 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -8388608; // -0x800000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 3); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 3); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 3); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 3); + EXPECT_EQ(sizeof(sValuePos), 3u); + EXPECT_GE(sizeof(wValuePos), 3u); + EXPECT_EQ(sizeof(sValueNeg), 3u); + EXPECT_GE(sizeof(wValueNeg), 3u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -394,8 +394,8 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -405,8 +405,8 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -414,16 +414,16 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } //////////////////////////////////////////////////////////// @@ -438,7 +438,7 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext) // $$/ $$$$$$/ $$$$$$$/ $$$$$$/ $$/ // // // //////////////////////////////////////////////////////////// -void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT40_LE) { // Unsigned 40-bit Integer : 5 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -453,8 +453,8 @@ void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 1099511627775; // 0xFFFFFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 5); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 5); + EXPECT_EQ(sizeof(sValue), 5u); + EXPECT_GE(sizeof(wValue), 5u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -463,7 +463,7 @@ void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456789A); + EXPECT_EQ(wValue, 0x123456789Au); StorageType sNewValue; @@ -471,22 +471,22 @@ void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT40_BE) { // Unsigned 40-bit Integer : 5 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -500,8 +500,8 @@ void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext) const StorageType storageTestData = { 0x12, 0x34, 0x56, 0x78, 0x9A }; const WorkingType workingTestUnsignedNullValue = 1099511627775; // 0xFFFFFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 5); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 5); + EXPECT_EQ(sizeof(sValue), 5u); + EXPECT_GE(sizeof(wValue), 5u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -510,7 +510,7 @@ void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456789A); + EXPECT_EQ(wValue, 0x123456789Au); StorageType sNewValue; @@ -518,22 +518,22 @@ void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT40_LE) { // Signed 40-bit Integer : 5 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -552,10 +552,10 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -549755813888; // -0x8000000000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 5); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 5); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 5); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 5); + EXPECT_EQ(sizeof(sValuePos), 5u); + EXPECT_GE(sizeof(wValuePos), 5u); + EXPECT_EQ(sizeof(sValueNeg), 5u); + EXPECT_GE(sizeof(wValueNeg), 5u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -566,8 +566,8 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -577,8 +577,8 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -586,19 +586,19 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } -void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT40_BE) { // Signed 40-bit Integer : 5 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -617,10 +617,10 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -549755813888; // -0x8000000000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 5); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 5); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 5); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 5); + EXPECT_EQ(sizeof(sValuePos), 5u); + EXPECT_GE(sizeof(wValuePos), 5u); + EXPECT_EQ(sizeof(sValueNeg), 5u); + EXPECT_GE(sizeof(wValueNeg), 5u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -631,8 +631,8 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -642,8 +642,8 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -651,16 +651,16 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } //////////////////////////////////////////////////////////// @@ -675,7 +675,7 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext) // $$/ $$$$$$/ $$$$$$$/ $$$$$$/ $$/ // // // //////////////////////////////////////////////////////////// -void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT48_LE) { // Unsigned 48-bit Integer : 6 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -690,8 +690,8 @@ void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 281474976710655; // 0xFFFFFFFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 6); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 6); + EXPECT_EQ(sizeof(sValue), 6u); + EXPECT_GE(sizeof(wValue), 6u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -700,7 +700,7 @@ void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABC); + EXPECT_EQ(wValue, 0x123456789ABCu); StorageType sNewValue; @@ -708,22 +708,22 @@ void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT48_BE) { // Unsigned 48-bit Integer : 6 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -738,8 +738,8 @@ void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 281474976710655; // 0xFFFFFFFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 6); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 6); + EXPECT_EQ(sizeof(sValue), 6u); + EXPECT_GE(sizeof(wValue), 6u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -748,7 +748,7 @@ void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABC); + EXPECT_EQ(wValue, 0x123456789ABCu); StorageType sNewValue; @@ -756,22 +756,22 @@ void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT48_LE) { // Signed 48-bit Integer : 6 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -790,10 +790,10 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -140737488355328; // -0x800000000000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 6); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 6); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 6); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 6); + EXPECT_EQ(sizeof(sValuePos), 6u); + EXPECT_GE(sizeof(wValuePos), 6u); + EXPECT_EQ(sizeof(sValueNeg), 6u); + EXPECT_GE(sizeof(wValueNeg), 6u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -804,8 +804,8 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -815,8 +815,8 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -824,19 +824,19 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } -void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT48_BE) { // Signed 48-bit Integer : 6 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -855,10 +855,10 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -140737488355328; // -0x800000000000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 6); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 6); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 6); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 6); + EXPECT_EQ(sizeof(sValuePos), 6u); + EXPECT_GE(sizeof(wValuePos), 6u); + EXPECT_EQ(sizeof(sValueNeg), 6u); + EXPECT_GE(sizeof(wValueNeg), 6u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -869,8 +869,8 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -880,8 +880,8 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -889,16 +889,16 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } //////////////////////////////////////////////////////////// @@ -913,7 +913,7 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext) // $$$$$$/ $$$$$$/ $$$$$$$/ $$$$$$/ $$/ // // // //////////////////////////////////////////////////////////// -void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT56_LE) { // Unsigned 56-bit Integer : 7 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -928,8 +928,8 @@ void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 72057594037927935; // 0xFFFFFFFFFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 7); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 7); + EXPECT_EQ(sizeof(sValue), 7u); + EXPECT_GE(sizeof(wValue), 7u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -938,7 +938,7 @@ void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABCDE); + EXPECT_EQ(wValue, 0x123456789ABCDEu); StorageType sNewValue; @@ -946,22 +946,22 @@ void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_UINT56_BE) { // Unsigned 56-bit Integer : 7 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -976,8 +976,8 @@ void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestUnsignedNullValue = 72057594037927935; // 0xFFFFFFFFFFFFFF // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValue) == 7); - NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 7); + EXPECT_EQ(sizeof(sValue), 7u); + EXPECT_GE(sizeof(wValue), 7u); // Initialize the Storage Value with the test-buffer memcpy(&sValue, storageTestData, sizeof(sValue)); @@ -986,7 +986,7 @@ void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext) wValue = IntType::StorageToWorking(sValue); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABCDE); + EXPECT_EQ(wValue, 0x123456789ABCDEu); StorageType sNewValue; @@ -994,22 +994,22 @@ void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValue, sNewValue); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0); + EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0); // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestUnsignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); } -void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT56_LE) { // Signed 56-bit Integer : 6 bytes - little-endian using IntType = NumericAttributeTraits, false>; @@ -1028,10 +1028,10 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -36028797018963968; // -0x80000000000000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 7); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 7); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 7); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 7); + EXPECT_EQ(sizeof(sValuePos), 7u); + EXPECT_GE(sizeof(wValuePos), 7u); + EXPECT_EQ(sizeof(sValueNeg), 7u); + EXPECT_GE(sizeof(wValueNeg), 7u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -1042,8 +1042,8 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -1053,8 +1053,8 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -1062,19 +1062,19 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } -void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext) +TEST(TestNumericAttributeTraits, Test_SINT56_BE) { // Signed 56-bit Integer : 7 bytes - big-endian using IntType = NumericAttributeTraits, true>; @@ -1093,10 +1093,10 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext) const WorkingType workingTestSignedNullValue = -36028797018963968; // -0x80000000000000 // 1) Verify the size of the types - NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 7); - NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 7); - NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 7); - NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 7); + EXPECT_EQ(sizeof(sValuePos), 7u); + EXPECT_GE(sizeof(wValuePos), 7u); + EXPECT_EQ(sizeof(sValueNeg), 7u); + EXPECT_GE(sizeof(wValueNeg), 7u); // Initialize the Storage Values with the test-buffer memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos)); @@ -1107,8 +1107,8 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext) wValueNeg = IntType::StorageToWorking(sValueNeg); // 2) Verify that the correct storage format has been used - NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos); - NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg); + EXPECT_EQ(wValuePos, workingDataPos); + EXPECT_EQ(wValueNeg, workingDataNeg); StorageType sNewValuePos; StorageType sNewValueNeg; @@ -1118,8 +1118,8 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext) IntType::WorkingToStorage(wValueNeg, sNewValueNeg); // 3) Verify that the bytes are located as intended - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0); - NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0); + EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0); + EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0); StorageType sNullValue; WorkingType wNullValue; @@ -1127,82 +1127,16 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext) // Set Storage value to Null IntType::SetNull(sNullValue); wNullValue = IntType::StorageToWorking(sNullValue); - NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue); - NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true)); + EXPECT_EQ(wNullValue, workingTestSignedNullValue); + EXPECT_TRUE(IntType::IsNullValue(sNullValue)); // Verify that null values can fit into not nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true)); + EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue)); + EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue)); // Verify that null values can't fit into nullable - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false)); - NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false)); + EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue)); + EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue)); } -static int TestSetup(void * inContext) -{ - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - return SUCCESS; -} - -/** - * Test Suite. It lists all the test functions. - */ - -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("Test_UINT8", Test_UINT8), - NL_TEST_DEF("Test_SINT8", Test_SINT8), - NL_TEST_DEF("Test_SimpleEnum", Test_SimpleEnum), - - NL_TEST_DEF("Test_UINT24_LE",Test_UINT24_LE), - NL_TEST_DEF("Test_SINT24_LE",Test_SINT24_LE), - NL_TEST_DEF("Test_UINT24_BE",Test_UINT24_BE), - NL_TEST_DEF("Test_SINT24_BE",Test_SINT24_BE), - - NL_TEST_DEF("Test_UINT40_LE",Test_UINT40_LE), - NL_TEST_DEF("Test_SINT40_LE",Test_SINT40_LE), - NL_TEST_DEF("Test_UINT40_BE",Test_UINT40_BE), - NL_TEST_DEF("Test_SINT40_BE",Test_SINT40_BE), - - NL_TEST_DEF("Test_UINT48_LE",Test_UINT48_LE), - NL_TEST_DEF("Test_SINT48_LE",Test_SINT48_LE), - NL_TEST_DEF("Test_UINT48_BE",Test_UINT48_BE), - NL_TEST_DEF("Test_SINT48_BE",Test_SINT48_BE), - - NL_TEST_DEF("Test_UINT56_LE",Test_UINT56_LE), - NL_TEST_DEF("Test_SINT56_LE",Test_SINT56_LE), - NL_TEST_DEF("Test_UINT56_BE",Test_UINT56_BE), - NL_TEST_DEF("Test_SINT56_BE",Test_SINT56_BE), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -nlTestSuite theSuite = -{ - "TestNumericAttributeTraits", - &sTests[0], - TestSetup, - TestTeardown -}; -// clang-format on - } // namespace - -int TestNumericAttributeTraits() -{ - nlTestRunner(&theSuite, nullptr); - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestNumericAttributeTraits) diff --git a/src/app/tests/TestOperationalStateClusterObjects.cpp b/src/app/tests/TestOperationalStateClusterObjects.cpp index 9f7d1e1efcadac..2b305949d8fe8d 100644 --- a/src/app/tests/TestOperationalStateClusterObjects.cpp +++ b/src/app/tests/TestOperationalStateClusterObjects.cpp @@ -17,9 +17,8 @@ #include #include -#include - -#include +#include +#include using namespace chip; using namespace chip::DeviceLayer; @@ -27,31 +26,38 @@ using namespace chip::app::Clusters::OperationalState; namespace { -void TestStructGenericOperationalStateConstructorWithOnlyStateID(nlTestSuite * inSuite, void * inContext) +class TestOperationalStateClusterObjects : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateConstructorWithOnlyStateID) { using namespace chip::app::Clusters::OperationalState; // General state: Stopped GenericOperationalState operationalStateStopped(to_underlying(OperationalStateEnum::kStopped)); - NL_TEST_ASSERT(inSuite, operationalStateStopped.operationalStateID == to_underlying(OperationalStateEnum::kStopped)); - NL_TEST_ASSERT(inSuite, operationalStateStopped.operationalStateLabel.HasValue() == false); + EXPECT_EQ(operationalStateStopped.operationalStateID, to_underlying(OperationalStateEnum::kStopped)); + EXPECT_FALSE(operationalStateStopped.operationalStateLabel.HasValue()); // General state: Running GenericOperationalState operationalStateRunning(to_underlying(OperationalStateEnum::kRunning)); - NL_TEST_ASSERT(inSuite, operationalStateRunning.operationalStateID == to_underlying(OperationalStateEnum::kRunning)); - NL_TEST_ASSERT(inSuite, operationalStateRunning.operationalStateLabel.HasValue() == false); + EXPECT_EQ(operationalStateRunning.operationalStateID, to_underlying(OperationalStateEnum::kRunning)); + EXPECT_FALSE(operationalStateRunning.operationalStateLabel.HasValue()); // General state: Paused GenericOperationalState operationalStatePaused(to_underlying(OperationalStateEnum::kPaused)); - NL_TEST_ASSERT(inSuite, operationalStatePaused.operationalStateID == to_underlying(OperationalStateEnum::kPaused)); - NL_TEST_ASSERT(inSuite, operationalStatePaused.operationalStateLabel.HasValue() == false); + EXPECT_EQ(operationalStatePaused.operationalStateID, to_underlying(OperationalStateEnum::kPaused)); + EXPECT_FALSE(operationalStatePaused.operationalStateLabel.HasValue()); // General state: Error GenericOperationalState operationalStateError(to_underlying(OperationalStateEnum::kError)); - NL_TEST_ASSERT(inSuite, operationalStateError.operationalStateID == to_underlying(OperationalStateEnum::kError)); - NL_TEST_ASSERT(inSuite, operationalStateError.operationalStateLabel.HasValue() == false); + EXPECT_EQ(operationalStateError.operationalStateID, to_underlying(OperationalStateEnum::kError)); + EXPECT_FALSE(operationalStateError.operationalStateLabel.HasValue()); } -void TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel) { using namespace chip::app::Clusters::OperationalState; @@ -66,14 +72,13 @@ void TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel(nlTest GenericOperationalState operationalState(to_underlying(ManufactureOperationalStateEnum::kRebooting), Optional(CharSpan::fromCharString(buffer))); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting)); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == strlen(buffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)) == 0); + EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting)); + EXPECT_TRUE(operationalState.operationalStateLabel.HasValue()); + EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), strlen(buffer)); + EXPECT_EQ(memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)), 0); } -void TestStructGenericOperationalStateCopyConstructor(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateCopyConstructor) { using namespace chip::app::Clusters::OperationalState; @@ -89,18 +94,16 @@ void TestStructGenericOperationalStateCopyConstructor(nlTestSuite * inSuite, voi GenericOperationalState desOperationalState(srcOperationalState); - NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateID == srcOperationalState.operationalStateID); - NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, - desOperationalState.operationalStateLabel.Value().size() == - srcOperationalState.operationalStateLabel.Value().size()); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(desOperationalState.operationalStateLabel.Value().data()), - const_cast(srcOperationalState.operationalStateLabel.Value().data()), - desOperationalState.operationalStateLabel.Value().size()) == 0); + EXPECT_EQ(desOperationalState.operationalStateID, srcOperationalState.operationalStateID); + EXPECT_TRUE(desOperationalState.operationalStateLabel.HasValue()); + EXPECT_EQ(desOperationalState.operationalStateLabel.Value().size(), srcOperationalState.operationalStateLabel.Value().size()); + EXPECT_EQ(memcmp(const_cast(desOperationalState.operationalStateLabel.Value().data()), + const_cast(srcOperationalState.operationalStateLabel.Value().data()), + desOperationalState.operationalStateLabel.Value().size()), + 0); } -void TestStructGenericOperationalStateCopyAssignment(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateCopyAssignment) { using namespace chip::app::Clusters::OperationalState; @@ -116,18 +119,16 @@ void TestStructGenericOperationalStateCopyAssignment(nlTestSuite * inSuite, void GenericOperationalState desOperationalState = srcOperationalState; - NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateID == srcOperationalState.operationalStateID); - NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, - desOperationalState.operationalStateLabel.Value().size() == - srcOperationalState.operationalStateLabel.Value().size()); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(desOperationalState.operationalStateLabel.Value().data()), - const_cast(srcOperationalState.operationalStateLabel.Value().data()), - desOperationalState.operationalStateLabel.Value().size()) == 0); + EXPECT_EQ(desOperationalState.operationalStateID, srcOperationalState.operationalStateID); + EXPECT_TRUE(desOperationalState.operationalStateLabel.HasValue()); + EXPECT_EQ(desOperationalState.operationalStateLabel.Value().size(), srcOperationalState.operationalStateLabel.Value().size()); + EXPECT_EQ(memcmp(const_cast(desOperationalState.operationalStateLabel.Value().data()), + const_cast(srcOperationalState.operationalStateLabel.Value().data()), + desOperationalState.operationalStateLabel.Value().size()), + 0); } -void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateFuncSet) { using namespace chip::app::Clusters::OperationalState; @@ -144,17 +145,16 @@ void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inCo // change state without label operationalState.Set(to_underlying(OperationalStateEnum::kStopped)); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(OperationalStateEnum::kStopped)); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == false); + EXPECT_EQ(operationalState.operationalStateID, to_underlying(OperationalStateEnum::kStopped)); + EXPECT_FALSE(operationalState.operationalStateLabel.HasValue()); // change state with label operationalState.Set(to_underlying(ManufactureOperationalStateEnum::kRebooting), Optional(CharSpan::fromCharString(buffer))); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting)); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == strlen(buffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)) == 0); + EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting)); + EXPECT_TRUE(operationalState.operationalStateLabel.HasValue()); + EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), strlen(buffer)); + EXPECT_EQ(memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)), 0); // change state with label, label len = kOperationalStateLabelMaxSize for (size_t i = 0; i < sizeof(buffer); i++) @@ -163,11 +163,10 @@ void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inCo } operationalState.Set(to_underlying(ManufactureOperationalStateEnum::kRebooting), Optional(CharSpan(buffer, sizeof(buffer)))); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting)); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == sizeof(buffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer, sizeof(buffer)) == 0); + EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting)); + EXPECT_TRUE(operationalState.operationalStateLabel.HasValue()); + EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), sizeof(buffer)); + EXPECT_EQ(memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer, sizeof(buffer)), 0); // change state with label, label len larger than kOperationalStateLabelMaxSize char buffer2[kOperationalStateLabelMaxSize + 1]; @@ -178,51 +177,47 @@ void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inCo } operationalState.Set(to_underlying(ManufactureOperationalStateEnum::kRebooting), Optional(CharSpan(buffer2, sizeof(buffer2)))); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting)); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == kOperationalStateLabelMaxSize); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer2, - kOperationalStateLabelMaxSize) == 0); + EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting)); + EXPECT_TRUE(operationalState.operationalStateLabel.HasValue()); + EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), kOperationalStateLabelMaxSize); + EXPECT_EQ( + memcmp(const_cast(operationalState.operationalStateLabel.Value().data()), buffer2, kOperationalStateLabelMaxSize), + 0); } -void TestStructGenericOperationalErrorConstructorWithOnlyStateID(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorConstructorWithOnlyStateID) { using namespace chip::app::Clusters::OperationalState; // General errors: NoError GenericOperationalError operationalErrorNoErr(to_underlying(ErrorStateEnum::kNoError)); - NL_TEST_ASSERT(inSuite, operationalErrorNoErr.errorStateID == to_underlying(ErrorStateEnum::kNoError)); - NL_TEST_ASSERT(inSuite, operationalErrorNoErr.errorStateLabel.HasValue() == false); - NL_TEST_ASSERT(inSuite, operationalErrorNoErr.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalErrorNoErr.errorStateID, to_underlying(ErrorStateEnum::kNoError)); + EXPECT_FALSE(operationalErrorNoErr.errorStateLabel.HasValue()); + EXPECT_FALSE(operationalErrorNoErr.errorStateDetails.HasValue()); // General errors: UnableToStartOrResume GenericOperationalError operationalErrorUnableToStartOrResume(to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, - operationalErrorUnableToStartOrResume.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalErrorUnableToStartOrResume.errorStateLabel.HasValue() == false); - NL_TEST_ASSERT(inSuite, operationalErrorUnableToStartOrResume.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalErrorUnableToStartOrResume.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_FALSE(operationalErrorUnableToStartOrResume.errorStateLabel.HasValue()); + EXPECT_FALSE(operationalErrorUnableToStartOrResume.errorStateDetails.HasValue()); // General errors: UnableToCompleteOperation GenericOperationalError operationalErrorkUnableToCompleteOperation(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); - NL_TEST_ASSERT(inSuite, - operationalErrorkUnableToCompleteOperation.errorStateID == - to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); - NL_TEST_ASSERT(inSuite, operationalErrorkUnableToCompleteOperation.errorStateLabel.HasValue() == false); - NL_TEST_ASSERT(inSuite, operationalErrorkUnableToCompleteOperation.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalErrorkUnableToCompleteOperation.errorStateID, to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + EXPECT_FALSE(operationalErrorkUnableToCompleteOperation.errorStateLabel.HasValue()); + EXPECT_FALSE(operationalErrorkUnableToCompleteOperation.errorStateDetails.HasValue()); // General errors: CommandInvalidInState GenericOperationalError operationalErrorCommandInvalidInState(to_underlying(ErrorStateEnum::kCommandInvalidInState)); - NL_TEST_ASSERT(inSuite, - operationalErrorCommandInvalidInState.errorStateID == to_underlying(ErrorStateEnum::kCommandInvalidInState)); - NL_TEST_ASSERT(inSuite, operationalErrorCommandInvalidInState.errorStateLabel.HasValue() == false); - NL_TEST_ASSERT(inSuite, operationalErrorCommandInvalidInState.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalErrorCommandInvalidInState.errorStateID, to_underlying(ErrorStateEnum::kCommandInvalidInState)); + EXPECT_FALSE(operationalErrorCommandInvalidInState.errorStateLabel.HasValue()); + EXPECT_FALSE(operationalErrorCommandInvalidInState.errorStateDetails.HasValue()); } -void TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel) { using namespace chip::app::Clusters::OperationalState; @@ -237,16 +232,14 @@ void TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel(nlTest GenericOperationalError operationalError(to_underlying(ManufactureOperationalErrorEnum::kLowBattery), Optional(CharSpan::fromCharString(labelBuffer))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ManufactureOperationalErrorEnum::kLowBattery)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) == - 0); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ManufactureOperationalErrorEnum::kLowBattery)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0); + EXPECT_FALSE(operationalError.errorStateDetails.HasValue()); } -void TestStructGenericOperationalErrorConstructorWithFullParam(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorConstructorWithFullParam) { using namespace chip::app::Clusters::OperationalState; @@ -263,21 +256,17 @@ void TestStructGenericOperationalErrorConstructorWithFullParam(nlTestSuite * inS Optional(CharSpan::fromCharString(labelBuffer)), Optional(CharSpan::fromCharString(detailBuffer))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ManufactureOperationalErrorEnum::kLowBattery)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) == - 0); - - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.Value().size() == strlen(detailBuffer)); - NL_TEST_ASSERT( - inSuite, - memcmp(const_cast(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)) == 0); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ManufactureOperationalErrorEnum::kLowBattery)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0); + + EXPECT_TRUE(operationalError.errorStateDetails.HasValue()); + EXPECT_EQ(operationalError.errorStateDetails.Value().size(), strlen(detailBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)), 0); } -void TestStructGenericOperationalErrorCopyConstructor(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorCopyConstructor) { using namespace chip::app::Clusters::OperationalState; @@ -296,25 +285,23 @@ void TestStructGenericOperationalErrorCopyConstructor(nlTestSuite * inSuite, voi // call copy constructor GenericOperationalError desOperationalError(srcOperationalError); - NL_TEST_ASSERT(inSuite, desOperationalError.errorStateID == srcOperationalError.errorStateID); - NL_TEST_ASSERT(inSuite, desOperationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, - desOperationalError.errorStateLabel.Value().size() == srcOperationalError.errorStateLabel.Value().size()); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(desOperationalError.errorStateLabel.Value().data()), - const_cast(srcOperationalError.errorStateLabel.Value().data()), - desOperationalError.errorStateLabel.Value().size()) == 0); - - NL_TEST_ASSERT(inSuite, desOperationalError.errorStateDetails.HasValue() == true); - NL_TEST_ASSERT(inSuite, - desOperationalError.errorStateDetails.Value().size() == srcOperationalError.errorStateDetails.Value().size()); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(desOperationalError.errorStateDetails.Value().data()), - const_cast(srcOperationalError.errorStateDetails.Value().data()), - desOperationalError.errorStateDetails.Value().size()) == 0); + EXPECT_EQ(desOperationalError.errorStateID, srcOperationalError.errorStateID); + EXPECT_TRUE(desOperationalError.errorStateLabel.HasValue()); + EXPECT_EQ(desOperationalError.errorStateLabel.Value().size(), srcOperationalError.errorStateLabel.Value().size()); + EXPECT_EQ(memcmp(const_cast(desOperationalError.errorStateLabel.Value().data()), + const_cast(srcOperationalError.errorStateLabel.Value().data()), + desOperationalError.errorStateLabel.Value().size()), + 0); + + EXPECT_TRUE(desOperationalError.errorStateDetails.HasValue()); + EXPECT_EQ(desOperationalError.errorStateDetails.Value().size(), srcOperationalError.errorStateDetails.Value().size()); + EXPECT_EQ(memcmp(const_cast(desOperationalError.errorStateDetails.Value().data()), + const_cast(srcOperationalError.errorStateDetails.Value().data()), + desOperationalError.errorStateDetails.Value().size()), + 0); } -void TestStructGenericOperationalErrorCopyAssignment(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorCopyAssignment) { using namespace chip::app::Clusters::OperationalState; @@ -333,25 +320,23 @@ void TestStructGenericOperationalErrorCopyAssignment(nlTestSuite * inSuite, void // call copy assignment GenericOperationalError desOperationalError = srcOperationalError; - NL_TEST_ASSERT(inSuite, desOperationalError.errorStateID == srcOperationalError.errorStateID); - NL_TEST_ASSERT(inSuite, desOperationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, - desOperationalError.errorStateLabel.Value().size() == srcOperationalError.errorStateLabel.Value().size()); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(desOperationalError.errorStateLabel.Value().data()), - const_cast(srcOperationalError.errorStateLabel.Value().data()), - desOperationalError.errorStateLabel.Value().size()) == 0); - - NL_TEST_ASSERT(inSuite, desOperationalError.errorStateDetails.HasValue() == true); - NL_TEST_ASSERT(inSuite, - desOperationalError.errorStateDetails.Value().size() == srcOperationalError.errorStateDetails.Value().size()); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(desOperationalError.errorStateDetails.Value().data()), - const_cast(srcOperationalError.errorStateDetails.Value().data()), - desOperationalError.errorStateDetails.Value().size()) == 0); + EXPECT_EQ(desOperationalError.errorStateID, srcOperationalError.errorStateID); + EXPECT_TRUE(desOperationalError.errorStateLabel.HasValue()); + EXPECT_EQ(desOperationalError.errorStateLabel.Value().size(), srcOperationalError.errorStateLabel.Value().size()); + EXPECT_EQ(memcmp(const_cast(desOperationalError.errorStateLabel.Value().data()), + const_cast(srcOperationalError.errorStateLabel.Value().data()), + desOperationalError.errorStateLabel.Value().size()), + 0); + + EXPECT_TRUE(desOperationalError.errorStateDetails.HasValue()); + EXPECT_EQ(desOperationalError.errorStateDetails.Value().size(), srcOperationalError.errorStateDetails.Value().size()); + EXPECT_EQ(memcmp(const_cast(desOperationalError.errorStateDetails.Value().data()), + const_cast(srcOperationalError.errorStateDetails.Value().data()), + desOperationalError.errorStateDetails.Value().size()), + 0); } -void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inContext) +TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorFuncSet) { using namespace chip::app::Clusters::OperationalState; enum class ManufactureOperationalErrorEnum : uint8_t @@ -366,46 +351,40 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo // General errors: NoError GenericOperationalError operationalError(to_underlying(ErrorStateEnum::kNoError)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kNoError)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == false); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kNoError)); + EXPECT_FALSE(operationalError.errorStateLabel.HasValue()); + EXPECT_FALSE(operationalError.errorStateDetails.HasValue()); // call Set with stateId operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == false); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_FALSE(operationalError.errorStateLabel.HasValue()); + EXPECT_FALSE(operationalError.errorStateDetails.HasValue()); // call Set with stateId and StateLabel operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume), Optional(CharSpan::fromCharString(labelBuffer))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) == - 0); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0); + EXPECT_FALSE(operationalError.errorStateDetails.HasValue()); // call Set with stateId, StateLabel and StateDetails operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume), Optional(CharSpan::fromCharString(labelBuffer)), Optional(CharSpan::fromCharString(detailBuffer))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) == - 0); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.Value().size() == strlen(detailBuffer)); - NL_TEST_ASSERT( - inSuite, - memcmp(const_cast(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)) == 0); + EXPECT_TRUE(operationalError.errorStateDetails.HasValue()); + EXPECT_EQ(operationalError.errorStateDetails.Value().size(), strlen(detailBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)), 0); // change state with label, label len = kOperationalStateLabelMaxSize for (size_t i = 0; i < sizeof(labelBuffer); i++) @@ -415,13 +394,11 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume), Optional(CharSpan(labelBuffer, sizeof(labelBuffer)))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == sizeof(labelBuffer)); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, sizeof(labelBuffer)) == - 0); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), sizeof(labelBuffer)); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer, sizeof(labelBuffer)), 0); + EXPECT_FALSE(operationalError.errorStateDetails.HasValue()); // change state with label, label len = kOperationalStateLabelMaxSize + 1 char labelBuffer2[kOperationalErrorLabelMaxSize + 1]; @@ -432,13 +409,13 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume), Optional(CharSpan(labelBuffer2, sizeof(labelBuffer2)))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == kOperationalErrorLabelMaxSize); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer2, - kOperationalErrorLabelMaxSize) == 0); - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false); + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), kOperationalErrorLabelMaxSize); + EXPECT_EQ( + memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer2, kOperationalErrorLabelMaxSize), + 0); + EXPECT_FALSE(operationalError.errorStateDetails.HasValue()); // change state with label and details, details len = kOperationalErrorDetailsMaxSize + 1 char detailBuffer2[kOperationalErrorDetailsMaxSize + 1]; @@ -450,62 +427,19 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo Optional(CharSpan(labelBuffer2, sizeof(labelBuffer2))), Optional(CharSpan(detailBuffer2, sizeof(detailBuffer2)))); - NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume)); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true); - NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == kOperationalErrorLabelMaxSize); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer2, - kOperationalErrorLabelMaxSize) == 0); - - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == true); - - NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.Value().size() == kOperationalErrorDetailsMaxSize); - NL_TEST_ASSERT(inSuite, - memcmp(const_cast(operationalError.errorStateDetails.Value().data()), detailBuffer2, - kOperationalErrorDetailsMaxSize) == 0); -} - -const nlTest sTests[] = { - NL_TEST_DEF("Test struct GenericOperationalState: constructor with only StateID", - TestStructGenericOperationalStateConstructorWithOnlyStateID), - NL_TEST_DEF("Test struct GenericOperationalState: constructor with StateID and StateLabel", - TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel), - NL_TEST_DEF("Test struct GenericOperationalState: copy constructor", TestStructGenericOperationalStateCopyConstructor), - NL_TEST_DEF("Test struct GenericOperationalState: copy assignment", TestStructGenericOperationalStateCopyAssignment), - NL_TEST_DEF("Test struct GenericOperationalState: member function 'Set'", TestStructGenericOperationalStateFuncSet), - NL_TEST_DEF("Test struct GenericOperationalError: constructor with only StateID", - TestStructGenericOperationalErrorConstructorWithOnlyStateID), - NL_TEST_DEF("Test struct GenericOperationalError: constructor with StateID and StateLabel", - TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel), - NL_TEST_DEF("Test struct GenericOperationalError: constructor with StateID, StateLabel and StateDetail", - TestStructGenericOperationalErrorConstructorWithFullParam), - NL_TEST_DEF("Test struct GenericOperationalError: copy constructor", TestStructGenericOperationalErrorCopyConstructor), - NL_TEST_DEF("Test struct GenericOperationalError: copy assignment", TestStructGenericOperationalErrorCopyAssignment), - NL_TEST_DEF("Test struct GenericOperationalError: member function 'Set'", TestStructGenericOperationalErrorFuncSet), - NL_TEST_SENTINEL() -}; + EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume)); + EXPECT_TRUE(operationalError.errorStateLabel.HasValue()); + EXPECT_EQ(operationalError.errorStateLabel.Value().size(), kOperationalErrorLabelMaxSize); + EXPECT_EQ( + memcmp(const_cast(operationalError.errorStateLabel.Value().data()), labelBuffer2, kOperationalErrorLabelMaxSize), + 0); -int TestSetup(void * inContext) -{ - VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE); - return SUCCESS; -} + EXPECT_TRUE(operationalError.errorStateDetails.HasValue()); -int TestTearDown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; + EXPECT_EQ(operationalError.errorStateDetails.Value().size(), kOperationalErrorDetailsMaxSize); + EXPECT_EQ(memcmp(const_cast(operationalError.errorStateDetails.Value().data()), detailBuffer2, + kOperationalErrorDetailsMaxSize), + 0); } } // namespace - -int TestOperationalStateClusterObjects() -{ - nlTestSuite theSuite = { "Test Operational State Cluster Objects tests", &sTests[0], TestSetup, TestTearDown }; - - // Run test suite against one context. - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestOperationalStateClusterObjects) diff --git a/src/app/tests/TestPendingNotificationMap.cpp b/src/app/tests/TestPendingNotificationMap.cpp index 98e27cb5f7b45a..94089e372d367e 100644 --- a/src/app/tests/TestPendingNotificationMap.cpp +++ b/src/app/tests/TestPendingNotificationMap.cpp @@ -18,9 +18,9 @@ #include #include #include +#include #include -#include -#include +#include using chip::BindingTable; using chip::ClusterId; @@ -33,6 +33,16 @@ using chip::PendingNotificationMap; namespace { +class TestPendingNotificationMap : public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + static chip::TestPersistentStorageDelegate storage; + BindingTable::GetInstance().SetPersistentStorage(&storage); + } +}; + void ClearBindingTable(BindingTable & table) { auto iter = table.begin(); @@ -50,103 +60,83 @@ void CreateDefaultFullBindingTable(BindingTable & table) } } -void TestEmptyMap(nlTestSuite * aSuite, void * aContext) +TEST_F(TestPendingNotificationMap, TestEmptyMap) { PendingNotificationMap pendingMap; - NL_TEST_ASSERT(aSuite, pendingMap.begin() == pendingMap.end()); + EXPECT_EQ(pendingMap.begin(), pendingMap.end()); chip::ScopedNodeId peer; - NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(peer) == CHIP_ERROR_NOT_FOUND); + EXPECT_EQ(pendingMap.FindLRUConnectPeer(peer), CHIP_ERROR_NOT_FOUND); } -void TestAddRemove(nlTestSuite * aSuite, void * aContext) +TEST_F(TestPendingNotificationMap, TestAddRemove) { PendingNotificationMap pendingMap; ClearBindingTable(BindingTable::GetInstance()); CreateDefaultFullBindingTable(BindingTable::GetInstance()); for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++) { - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(i, nullptr) == CHIP_NO_ERROR); + EXPECT_EQ(pendingMap.AddPendingNotification(i, nullptr), CHIP_NO_ERROR); } // Confirm adding in one more element fails - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(MATTER_BINDING_TABLE_SIZE, nullptr) == CHIP_ERROR_NO_MEMORY); + EXPECT_EQ(pendingMap.AddPendingNotification(MATTER_BINDING_TABLE_SIZE, nullptr), CHIP_ERROR_NO_MEMORY); auto iter = pendingMap.begin(); for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++) { PendingNotificationEntry entry = *iter; - NL_TEST_ASSERT(aSuite, entry.mBindingEntryId == i); + EXPECT_EQ(entry.mBindingEntryId, i); ++iter; } - NL_TEST_ASSERT(aSuite, iter == pendingMap.end()); + EXPECT_EQ(iter, pendingMap.end()); pendingMap.RemoveAllEntriesForNode(chip::ScopedNodeId()); uint8_t expectedEntryIndecies[] = { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; iter = pendingMap.begin(); for (uint8_t ch : expectedEntryIndecies) { PendingNotificationEntry entry = *iter; - NL_TEST_ASSERT(aSuite, entry.mBindingEntryId == ch); + EXPECT_EQ(entry.mBindingEntryId, ch); ++iter; } - NL_TEST_ASSERT(aSuite, iter == pendingMap.end()); + EXPECT_EQ(iter, pendingMap.end()); pendingMap.RemoveAllEntriesForFabric(0); iter = pendingMap.begin(); for (uint8_t i = 0; i < 10; i++) { PendingNotificationEntry entry = *iter; - NL_TEST_ASSERT(aSuite, entry.mBindingEntryId == 10 + i); + EXPECT_EQ(entry.mBindingEntryId, 10u + i); ++iter; } - NL_TEST_ASSERT(aSuite, iter == pendingMap.end()); + EXPECT_EQ(iter, pendingMap.end()); pendingMap.RemoveAllEntriesForFabric(1); - NL_TEST_ASSERT(aSuite, pendingMap.begin() == pendingMap.end()); + EXPECT_EQ(pendingMap.begin(), pendingMap.end()); } -void TestLRUEntry(nlTestSuite * aSuite, void * aContext) +TEST_F(TestPendingNotificationMap, TestLRUEntry) { PendingNotificationMap pendingMap; ClearBindingTable(BindingTable::GetInstance()); CreateDefaultFullBindingTable(BindingTable::GetInstance()); - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(0, nullptr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(1, nullptr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(5, nullptr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(7, nullptr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(11, nullptr) == CHIP_NO_ERROR); + EXPECT_EQ(pendingMap.AddPendingNotification(0, nullptr), CHIP_NO_ERROR); + EXPECT_EQ(pendingMap.AddPendingNotification(1, nullptr), CHIP_NO_ERROR); + EXPECT_EQ(pendingMap.AddPendingNotification(5, nullptr), CHIP_NO_ERROR); + EXPECT_EQ(pendingMap.AddPendingNotification(7, nullptr), CHIP_NO_ERROR); + EXPECT_EQ(pendingMap.AddPendingNotification(11, nullptr), CHIP_NO_ERROR); chip::ScopedNodeId node; - NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(node) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, node.GetFabricIndex() == 0 && node.GetNodeId() == 1); + EXPECT_EQ(pendingMap.FindLRUConnectPeer(node), CHIP_NO_ERROR); + EXPECT_EQ(node.GetFabricIndex(), 0u); + EXPECT_EQ(node.GetNodeId(), 1u); pendingMap.RemoveEntry(1); - NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(node) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, node.GetFabricIndex() == 0 && node.GetNodeId() == 0); + EXPECT_EQ(pendingMap.FindLRUConnectPeer(node), CHIP_NO_ERROR); + EXPECT_EQ(node.GetFabricIndex(), 0u); + EXPECT_EQ(node.GetNodeId(), 0u); pendingMap.RemoveAllEntriesForFabric(0); - NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(node) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, node.GetFabricIndex() == 1 && node.GetNodeId() == 1); + EXPECT_EQ(pendingMap.FindLRUConnectPeer(node), CHIP_NO_ERROR); + EXPECT_EQ(node.GetFabricIndex(), 1u); + EXPECT_EQ(node.GetNodeId(), 1u); } } // namespace - -int TestPeindingNotificationMap() -{ - static nlTest sTests[] = { - NL_TEST_DEF("TestEmptyMap", TestEmptyMap), - NL_TEST_DEF("TestAddRemove", TestAddRemove), - NL_TEST_DEF("TestLRUEntry", TestLRUEntry), - NL_TEST_SENTINEL(), - }; - - nlTestSuite theSuite = { - "PendingNotificationMap", - &sTests[0], - nullptr, - nullptr, - }; - chip::TestPersistentStorageDelegate storage; - BindingTable::GetInstance().SetPersistentStorage(&storage); - nlTestRunner(&theSuite, nullptr); - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestPeindingNotificationMap) diff --git a/src/app/tests/TestPendingResponseTrackerImpl.cpp b/src/app/tests/TestPendingResponseTrackerImpl.cpp index da6239434cd3b1..556bf3d87e2b30 100644 --- a/src/app/tests/TestPendingResponseTrackerImpl.cpp +++ b/src/app/tests/TestPendingResponseTrackerImpl.cpp @@ -15,75 +15,76 @@ * limitations under the License. */ -#include -#include - #include #include #include +#include +#include +#include + namespace { using namespace chip; -void TestPendingResponseTracker_FillEntireTracker(nlTestSuite * inSuite, void * inContext) +TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_FillEntireTracker) { chip::app::PendingResponseTrackerImpl pendingResponseTracker; for (uint16_t commandRef = 0; commandRef < std::numeric_limits::max(); commandRef++) { - NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef)); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRef)); - NL_TEST_ASSERT(inSuite, true == pendingResponseTracker.IsTracked(commandRef)); + EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRef)); + EXPECT_TRUE(pendingResponseTracker.IsTracked(commandRef)); } - NL_TEST_ASSERT(inSuite, std::numeric_limits::max() == pendingResponseTracker.Count()); + EXPECT_EQ(std::numeric_limits::max(), pendingResponseTracker.Count()); for (uint16_t commandRef = 0; commandRef < std::numeric_limits::max(); commandRef++) { - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Remove(commandRef)); - NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Remove(commandRef)); + EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef)); } - NL_TEST_ASSERT(inSuite, 0 == pendingResponseTracker.Count()); + EXPECT_EQ(0u, pendingResponseTracker.Count()); } -void TestPendingResponseTracker_FillSingleEntryInTracker(nlTestSuite * inSuite, void * inContext) +TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_FillSingleEntryInTracker) { chip::app::PendingResponseTrackerImpl pendingResponseTracker; // The value 40 is arbitrary; any value would work for this purpose. uint16_t commandRefToSet = 40; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRefToSet)); + EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRefToSet)); for (uint16_t commandRef = 0; commandRef < std::numeric_limits::max(); commandRef++) { bool expectedIsSetResult = (commandRef == commandRefToSet); - NL_TEST_ASSERT(inSuite, expectedIsSetResult == pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(expectedIsSetResult, pendingResponseTracker.IsTracked(commandRef)); } } -void TestPendingResponseTracker_RemoveNonExistentEntryInTrackerFails(nlTestSuite * inSuite, void * inContext) +TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_RemoveNonExistentEntryInTrackerFails) { chip::app::PendingResponseTrackerImpl pendingResponseTracker; // The value 40 is arbitrary; any value would work for this purpose. uint16_t commandRef = 40; - NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef)); - NL_TEST_ASSERT(inSuite, CHIP_ERROR_KEY_NOT_FOUND == pendingResponseTracker.Remove(commandRef)); + EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(CHIP_ERROR_KEY_NOT_FOUND, pendingResponseTracker.Remove(commandRef)); } -void TestPendingResponseTracker_AddingSecondEntryFails(nlTestSuite * inSuite, void * inContext) +TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_AddingSecondEntryFails) { chip::app::PendingResponseTrackerImpl pendingResponseTracker; // The value 40 is arbitrary; any value would work for this purpose. uint16_t commandRef = 40; - NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef)); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRef)); - NL_TEST_ASSERT(inSuite, true == pendingResponseTracker.IsTracked(commandRef)); - NL_TEST_ASSERT(inSuite, CHIP_ERROR_INVALID_ARGUMENT == pendingResponseTracker.Add(commandRef)); + EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRef)); + EXPECT_TRUE(pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(CHIP_ERROR_INVALID_ARGUMENT, pendingResponseTracker.Add(commandRef)); } -void TestPendingResponseTracker_PopFindsAllPendingRequests(nlTestSuite * inSuite, void * inContext) +TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_PopFindsAllPendingRequests) { chip::app::PendingResponseTrackerImpl pendingResponseTracker; @@ -91,45 +92,23 @@ void TestPendingResponseTracker_PopFindsAllPendingRequests(nlTestSuite * inSuite std::vector requestsToAdd = { 0, 50, 2, 2000 }; for (const uint16_t & commandRef : requestsToAdd) { - NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef)); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRef)); - NL_TEST_ASSERT(inSuite, true == pendingResponseTracker.IsTracked(commandRef)); + EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef)); + EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRef)); + EXPECT_TRUE(pendingResponseTracker.IsTracked(commandRef)); } - NL_TEST_ASSERT(inSuite, requestsToAdd.size() == pendingResponseTracker.Count()); + EXPECT_EQ(requestsToAdd.size(), pendingResponseTracker.Count()); for (size_t i = 0; i < requestsToAdd.size(); i++) { auto commandRef = pendingResponseTracker.PopPendingResponse(); - NL_TEST_ASSERT(inSuite, true == commandRef.HasValue()); + EXPECT_TRUE(commandRef.HasValue()); bool expectedCommandRef = std::find(requestsToAdd.begin(), requestsToAdd.end(), commandRef.Value()) != requestsToAdd.end(); - NL_TEST_ASSERT(inSuite, true == expectedCommandRef); + EXPECT_TRUE(expectedCommandRef); } - NL_TEST_ASSERT(inSuite, 0 == pendingResponseTracker.Count()); + EXPECT_EQ(0u, pendingResponseTracker.Count()); auto commandRef = pendingResponseTracker.PopPendingResponse(); - NL_TEST_ASSERT(inSuite, false == commandRef.HasValue()); + EXPECT_FALSE(commandRef.HasValue()); } } // namespace - -#define NL_TEST_DEF_FN(fn) NL_TEST_DEF("Test " #fn, fn) -/** - * Test Suite. It lists all the test functions. - */ -static const nlTest sTests[] = { NL_TEST_DEF_FN(TestPendingResponseTracker_FillEntireTracker), - NL_TEST_DEF_FN(TestPendingResponseTracker_FillSingleEntryInTracker), - NL_TEST_DEF_FN(TestPendingResponseTracker_RemoveNonExistentEntryInTrackerFails), - NL_TEST_DEF_FN(TestPendingResponseTracker_AddingSecondEntryFails), - NL_TEST_DEF_FN(TestPendingResponseTracker_PopFindsAllPendingRequests), - NL_TEST_SENTINEL() }; - -int TestPendingResponseTracker() -{ - nlTestSuite theSuite = { "CHIP PendingResponseTrackerImpl tests", &sTests[0], nullptr, nullptr }; - - // Run test suite against one context. - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestPendingResponseTracker) diff --git a/src/app/tests/TestPowerSourceCluster.cpp b/src/app/tests/TestPowerSourceCluster.cpp index 374b9619d38684..0ec0b6e14a801c 100644 --- a/src/app/tests/TestPowerSourceCluster.cpp +++ b/src/app/tests/TestPowerSourceCluster.cpp @@ -15,50 +15,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include "lib/support/CHIPMem.h" #include #include +#include #include #include +#include #include #include #include #include -#include -#include #include #include -#include #include - -#include - -namespace { -chip::EndpointId numEndpoints = 0; -} -extern uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster, - uint16_t fixedClusterServerEndpointCount) -{ - // Very simple mapping here, we're just going to return the endpoint that matches the given endpoint index because the test - // uses the endpoints in order. - if (endpoint >= numEndpoints) - { - return kEmberInvalidEndpointIndex; - } - return endpoint; -} +#include namespace chip { namespace app { -class TestPowerSourceCluster +class TestPowerSourceCluster : public ::testing::Test { public: - static void TestEndpointList(nlTestSuite * apSuite, void * apContext); + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() + { + chip::app::Clusters::PowerSourceServer::Instance().Shutdown(); + chip::Platform::MemoryShutdown(); + } }; -std::vector ReadEndpointsThroughAttributeReader(nlTestSuite * apSuite, EndpointId endpoint) +std::vector ReadEndpointsThroughAttributeReader(EndpointId endpoint) { Clusters::PowerSourceAttrAccess & attrAccess = Clusters::TestOnlyGetPowerSourceAttrAccess(); CHIP_ERROR err = CHIP_NO_ERROR; @@ -85,7 +74,7 @@ std::vector ReadEndpointsThroughAttributeReader(nlTestSuite * apSuit err = attrAccess.Read(readPath, aEncoder); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Read out from the buffer. This comes back as a nested struct // AttributeReportIBs is a list of @@ -114,13 +103,13 @@ std::vector ReadEndpointsThroughAttributeReader(nlTestSuite * apSuit { attrDataReader.Next(); } - NL_TEST_ASSERT(apSuite, IsContextTag(attrDataReader.GetTag())); - NL_TEST_ASSERT(apSuite, TagNumFromTag(attrDataReader.GetTag()) == 2); + EXPECT_TRUE(IsContextTag(attrDataReader.GetTag())); + EXPECT_EQ(TagNumFromTag(attrDataReader.GetTag()), 2u); // OK, we should be in the right spot now, let's decode the list. Clusters::PowerSource::Attributes::EndpointList::TypeInfo::DecodableType list; err = list.Decode(attrDataReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); std::vector ret; auto iter = list.begin(); while (iter.Next()) @@ -130,7 +119,7 @@ std::vector ReadEndpointsThroughAttributeReader(nlTestSuite * apSuit return ret; } -void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apContext) +TEST_F(TestPowerSourceCluster, TestEndpointList) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -139,8 +128,8 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo // test that when we read everything we get an empty list as nothing has been set up yet for (EndpointId i = 0; i < 11; ++i) { - std::vector vec = ReadEndpointsThroughAttributeReader(apSuite, i); - NL_TEST_ASSERT(apSuite, vec.size() == 0); + std::vector vec = ReadEndpointsThroughAttributeReader(i); + EXPECT_EQ(vec.size(), 0u); } if (powerSourceServer.GetNumSupportedEndpointLists() < 2 || @@ -159,42 +148,42 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo // we checked earlier that this fit // This test just uses endpoints in order, so we want to set endpoints from - // 0 to numEndpoints - 1, and use this for overflow checking - numEndpoints = static_cast(powerSourceServer.GetNumSupportedEndpointLists()); + // 0 to chip::Test::numEndpoints - 1, and use this for overflow checking + chip::Test::numEndpoints = static_cast(powerSourceServer.GetNumSupportedEndpointLists()); // Endpoint 0 - list of 5 err = powerSourceServer.SetEndpointList(0, Span(list0)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); const Span * readBack = powerSourceServer.GetEndpointList(0); - NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr); - NL_TEST_ASSERT(apSuite, readBack->size() == 5); + ASSERT_NE(readBack, nullptr); + EXPECT_EQ(readBack->size(), 5u); for (size_t i = 0; i < readBack->size(); ++i) { - NL_TEST_ASSERT(apSuite, readBack->data()[i] == list0[i]); + EXPECT_EQ(readBack->data()[i], list0[i]); } // Endpoint 1 - list of 10 err = powerSourceServer.SetEndpointList(1, Span(list1)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); readBack = powerSourceServer.GetEndpointList(1); - NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr); - NL_TEST_ASSERT(apSuite, readBack->size() == 10); + ASSERT_NE(readBack, nullptr); + EXPECT_EQ(readBack->size(), 10u); for (size_t i = 0; i < readBack->size(); ++i) { - NL_TEST_ASSERT(apSuite, readBack->data()[i] == list1[i]); + EXPECT_EQ(readBack->data()[i], list1[i]); } // Remaining endpoints - list of 1 - for (EndpointId ep = 2; ep < numEndpoints; ++ep) + for (EndpointId ep = 2; ep < chip::Test::numEndpoints; ++ep) { err = powerSourceServer.SetEndpointList(ep, Span(listRest)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); readBack = powerSourceServer.GetEndpointList(ep); - NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr); - NL_TEST_ASSERT(apSuite, readBack->size() == 1); + ASSERT_NE(readBack, nullptr); + EXPECT_EQ(readBack->size(), 1u); if (readBack->size() == 1) { - NL_TEST_ASSERT(apSuite, readBack->data()[0] == listRest[0]); + EXPECT_EQ(readBack->data()[0], listRest[0]); } } @@ -203,38 +192,38 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo // ***************** // pick a random endpoint number for the power cluster - it doesn't matter, we don't have space anyway. err = powerSourceServer.SetEndpointList(55, Span(listRest)); - NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_NO_MEMORY); + EXPECT_EQ(err, CHIP_ERROR_NO_MEMORY); // ***************** // Recheck getting and reading after OOM // ***************** // EP0 readBack = powerSourceServer.GetEndpointList(0); - NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr); - NL_TEST_ASSERT(apSuite, readBack->size() == 5); + ASSERT_NE(readBack, nullptr); + EXPECT_EQ(readBack->size(), 5u); for (size_t i = 0; i < readBack->size(); ++i) { - NL_TEST_ASSERT(apSuite, readBack->data()[i] == list0[i]); + EXPECT_EQ(readBack->data()[i], list0[i]); } // EP1 readBack = powerSourceServer.GetEndpointList(1); - NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr); - NL_TEST_ASSERT(apSuite, readBack->size() == 10); + ASSERT_NE(readBack, nullptr); + EXPECT_EQ(readBack->size(), 10u); for (size_t i = 0; i < readBack->size(); ++i) { - NL_TEST_ASSERT(apSuite, readBack->data()[i] == list1[i]); + EXPECT_EQ(readBack->data()[i], list1[i]); } // Remaining endpoints - for (EndpointId ep = 2; ep < numEndpoints; ++ep) + for (EndpointId ep = 2; ep < chip::Test::numEndpoints; ++ep) { readBack = powerSourceServer.GetEndpointList(ep); - NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr); - NL_TEST_ASSERT(apSuite, readBack->size() == 1); + ASSERT_NE(readBack, nullptr); + EXPECT_EQ(readBack->size(), 1u); if (readBack->size() == 1) { - NL_TEST_ASSERT(apSuite, readBack->data()[0] == listRest[0]); + EXPECT_EQ(readBack->data()[0], listRest[0]); } } @@ -243,36 +232,36 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo // ***************** // Overwrite a list err = powerSourceServer.SetEndpointList(1, Span(listRest)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); readBack = powerSourceServer.GetEndpointList(1); - NL_TEST_ASSERT(apSuite, readBack->size() == 1); + EXPECT_EQ(readBack->size(), 1u); if (readBack->size() == 1) { - NL_TEST_ASSERT(apSuite, readBack->data()[0] == listRest[0]); + EXPECT_EQ(readBack->data()[0], listRest[0]); } // Ensure only the overwritten list was changed, using read interface - for (EndpointId ep = 0; ep < numEndpoints + 1; ++ep) + for (EndpointId ep = 0; ep < chip::Test::numEndpoints + 1; ++ep) { - std::vector vec = ReadEndpointsThroughAttributeReader(apSuite, ep); + std::vector vec = ReadEndpointsThroughAttributeReader(ep); if (ep == 0) { - NL_TEST_ASSERT(apSuite, vec.size() == 5); + EXPECT_EQ(vec.size(), 5u); for (size_t j = 0; j < vec.size(); ++j) { - NL_TEST_ASSERT(apSuite, vec[j] == list0[j]); + EXPECT_EQ(vec[j], list0[j]); } } - else if (ep == numEndpoints) + else if (ep == chip::Test::numEndpoints) { - NL_TEST_ASSERT(apSuite, vec.size() == 0); + EXPECT_EQ(vec.size(), 0u); } else { - NL_TEST_ASSERT(apSuite, vec.size() == 1); + EXPECT_EQ(vec.size(), 1u); if (vec.size() == 1) { - NL_TEST_ASSERT(apSuite, vec[0] == listRest[0]); + EXPECT_EQ(vec[0], listRest[0]); } } } @@ -280,76 +269,21 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo // ***************** // Test removal // ***************** - for (EndpointId ep = 0; ep < numEndpoints; ++ep) + for (EndpointId ep = 0; ep < chip::Test::numEndpoints; ++ep) { err = powerSourceServer.SetEndpointList(ep, Span()); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); readBack = powerSourceServer.GetEndpointList(ep); - NL_TEST_ASSERT(apSuite, readBack == nullptr); + EXPECT_EQ(readBack, nullptr); } // Check through the read interface - for (EndpointId ep = 0; ep < numEndpoints + 1; ++ep) + for (EndpointId ep = 0; ep < chip::Test::numEndpoints + 1; ++ep) { - std::vector vec = ReadEndpointsThroughAttributeReader(apSuite, ep); - NL_TEST_ASSERT(apSuite, vec.size() == 0); + std::vector vec = ReadEndpointsThroughAttributeReader(ep); + EXPECT_EQ(vec.size(), 0u); } } } // namespace app } // namespace chip - -namespace { - -/** - * Test Suite. It lists all the test functions. - */ - -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("TestEndpointList", chip::app::TestPowerSourceCluster::TestEndpointList), - NL_TEST_SENTINEL() -}; -// clang-format on - -/** - * Set up the test suite. - */ -int TestPowerSourceClusterContext_Setup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -int TestPowerSourceClusterContext_Teardown(void * inContext) -{ - chip::app::Clusters::PowerSourceServer::Instance().Shutdown(); - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -// clang-format off -nlTestSuite sSuite = -{ - "TestPowerSourceCluster", - &sTests[0], - TestPowerSourceClusterContext_Setup, - TestPowerSourceClusterContext_Teardown -}; -// clang-format on - -} // namespace - -int TestPowerSource() -{ - nlTestRunner(&sSuite, nullptr); - return nlTestRunnerStats(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestPowerSource) diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index e06721806732f6..8d1d2e686896fa 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -22,6 +22,8 @@ * */ +#include "app/tests/test-interaction-model-api.h" + #include "lib/support/CHIPMem.h" #include #include @@ -61,7 +63,6 @@ chip::EndpointId kTestEndpointId = 1; chip::EndpointId kTestEventEndpointId = chip::Test::kMockEndpoint1; chip::EventId kTestEventIdDebug = chip::Test::MockEventId(1); chip::EventId kTestEventIdCritical = chip::Test::MockEventId(2); -uint8_t kTestFieldValue1 = 1; chip::TLV::Tag kTestEventTag = chip::TLV::ContextTag(1); chip::EndpointId kInvalidTestEndpointId = 3; chip::DataVersion kTestDataVersion1 = 3; @@ -301,54 +302,6 @@ using ReadHandlerNode = chip::app::reporting::ReportScheduler::ReadHandlerNo namespace chip { namespace app { -CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, - const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports, - AttributeEncodeState * apEncoderState) -{ - if (aPath.mClusterId >= Test::kMockEndpointMin) - { - return Test::ReadSingleMockClusterData(aSubjectDescriptor.fabricIndex, aPath, aAttributeReports, apEncoderState); - } - - if (!(aPath.mClusterId == kTestClusterId && aPath.mEndpointId == kTestEndpointId)) - { - AttributeReportIB::Builder & attributeReport = aAttributeReports.CreateAttributeReport(); - ReturnErrorOnFailure(aAttributeReports.GetError()); - ChipLogDetail(DataManagement, "TEST Cluster %" PRIx32 ", Field %" PRIx32 " is dirty", aPath.mClusterId, aPath.mAttributeId); - - AttributeStatusIB::Builder & attributeStatus = attributeReport.CreateAttributeStatus(); - ReturnErrorOnFailure(attributeReport.GetError()); - AttributePathIB::Builder & attributePath = attributeStatus.CreatePath(); - ReturnErrorOnFailure(attributeStatus.GetError()); - - attributePath.Endpoint(aPath.mEndpointId).Cluster(aPath.mClusterId).Attribute(aPath.mAttributeId).EndOfAttributePathIB(); - ReturnErrorOnFailure(attributePath.GetError()); - StatusIB::Builder & errorStatus = attributeStatus.CreateErrorStatus(); - ReturnErrorOnFailure(attributeStatus.GetError()); - errorStatus.EncodeStatusIB(StatusIB(Protocols::InteractionModel::Status::UnsupportedAttribute)); - ReturnErrorOnFailure(errorStatus.GetError()); - ReturnErrorOnFailure(attributeStatus.EndOfAttributeStatusIB()); - return attributeReport.EndOfAttributeReportIB(); - } - - return AttributeValueEncoder(aAttributeReports, aSubjectDescriptor, aPath, 0 /* dataVersion */).Encode(kTestFieldValue1); -} - -bool IsClusterDataVersionEqual(const ConcreteClusterPath & aConcreteClusterPath, DataVersion aRequiredVersion) -{ - if (kTestDataVersion1 == aRequiredVersion) - { - return true; - } - - return false; -} - -bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint) -{ - return false; -} - class TestReadInteraction { using Seconds16 = System::Clock::Seconds16; diff --git a/src/app/tests/TestSimpleSubscriptionResumptionStorage.cpp b/src/app/tests/TestSimpleSubscriptionResumptionStorage.cpp index 8725acd755afd9..9f9b164e87cc07 100644 --- a/src/app/tests/TestSimpleSubscriptionResumptionStorage.cpp +++ b/src/app/tests/TestSimpleSubscriptionResumptionStorage.cpp @@ -15,13 +15,18 @@ * limitations under the License. */ -#include -#include - #include +#include +#include #include +#include -#include +class TestSimpleSubscriptionResumptionStorage : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; class SimpleSubscriptionResumptionStorageTest : public chip::app::SimpleSubscriptionResumptionStorage { @@ -71,7 +76,7 @@ struct TestSubscriptionInfo : public chip::app::SubscriptionResumptionStorage::S } }; -void TestSubscriptionCount(nlTestSuite * inSuite, void * inContext) +TEST_F(TestSimpleSubscriptionResumptionStorage, TestSubscriptionCount) { chip::TestPersistentStorageDelegate storage; SimpleSubscriptionResumptionStorageTest subscriptionStorage; @@ -88,7 +93,7 @@ void TestSubscriptionCount(nlTestSuite * inSuite, void * inContext) // Make sure iterator counts correctly auto * iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == (CHIP_IM_MAX_NUM_SUBSCRIPTIONS / 2)); + EXPECT_EQ(iterator->Count(), std::make_unsigned_t(CHIP_IM_MAX_NUM_SUBSCRIPTIONS / 2)); // Verify subscriptions manually count correctly size_t count = 0; @@ -97,13 +102,13 @@ void TestSubscriptionCount(nlTestSuite * inSuite, void * inContext) count++; } iterator->Release(); - NL_TEST_ASSERT(inSuite, count == (CHIP_IM_MAX_NUM_SUBSCRIPTIONS / 2)); + EXPECT_EQ(count, std::make_unsigned_t(CHIP_IM_MAX_NUM_SUBSCRIPTIONS / 2)); // Delete all and verify iterator counts 0 CHIP_ERROR err = subscriptionStorage.DeleteAll(46); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 0); + EXPECT_EQ(iterator->Count(), 0u); // Verify subscriptions manually count correctly count = 0; @@ -112,10 +117,10 @@ void TestSubscriptionCount(nlTestSuite * inSuite, void * inContext) count++; } iterator->Release(); - NL_TEST_ASSERT(inSuite, count == 0); + EXPECT_EQ(count, 0u); } -void TestSubscriptionMaxCount(nlTestSuite * inSuite, void * inContext) +TEST_F(TestSimpleSubscriptionResumptionStorage, TestSubscriptionMaxCount) { // Force large MacCount value and check that Init resets it properly, and deletes extra subs: @@ -126,16 +131,16 @@ void TestSubscriptionMaxCount(nlTestSuite * inSuite, void * inContext) uint16_t countMaxToSave = 2 * CHIP_IM_MAX_NUM_SUBSCRIPTIONS; CHIP_ERROR err = storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumptionMaxCount().KeyName(), &countMaxToSave, sizeof(uint16_t)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Then write something beyond CHIP_IM_MAX_NUM_SUBSCRIPTIONS chip::Platform::ScopedMemoryBuffer junkBytes; junkBytes.Calloc(subscriptionStorage.TestMaxSubscriptionSize() / 2); - NL_TEST_ASSERT(inSuite, junkBytes.Get() != nullptr); - NL_TEST_ASSERT(inSuite, - storage.SyncSetKeyValue( - chip::DefaultStorageKeyAllocator::SubscriptionResumption(CHIP_IM_MAX_NUM_SUBSCRIPTIONS + 1).KeyName(), - junkBytes.Get(), static_cast(subscriptionStorage.TestMaxSubscriptionSize() / 2)) == CHIP_NO_ERROR); + ASSERT_NE(junkBytes.Get(), nullptr); + EXPECT_EQ(storage.SyncSetKeyValue( + chip::DefaultStorageKeyAllocator::SubscriptionResumption(CHIP_IM_MAX_NUM_SUBSCRIPTIONS + 1).KeyName(), + junkBytes.Get(), static_cast(subscriptionStorage.TestMaxSubscriptionSize() / 2)), + CHIP_NO_ERROR); subscriptionStorage.Init(&storage); @@ -143,16 +148,15 @@ void TestSubscriptionMaxCount(nlTestSuite * inSuite, void * inContext) uint16_t countMax = 0; uint16_t len = sizeof(countMax); err = storage.SyncGetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumptionMaxCount().KeyName(), &countMax, len); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, countMax == CHIP_IM_MAX_NUM_SUBSCRIPTIONS); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(countMax, CHIP_IM_MAX_NUM_SUBSCRIPTIONS); // Then check the fake sub is no more - NL_TEST_ASSERT(inSuite, - !storage.SyncDoesKeyExist( - chip::DefaultStorageKeyAllocator::SubscriptionResumption(CHIP_IM_MAX_NUM_SUBSCRIPTIONS + 1).KeyName())); + EXPECT_FALSE(storage.SyncDoesKeyExist( + chip::DefaultStorageKeyAllocator::SubscriptionResumption(CHIP_IM_MAX_NUM_SUBSCRIPTIONS + 1).KeyName())); } -void TestSubscriptionState(nlTestSuite * inSuite, void * inContext) +TEST_F(TestSimpleSubscriptionResumptionStorage, TestSubscriptionState) { chip::TestPersistentStorageDelegate storage; SimpleSubscriptionResumptionStorageTest subscriptionStorage; @@ -219,25 +223,25 @@ void TestSubscriptionState(nlTestSuite * inSuite, void * inContext) CHIP_ERROR err; err = subscriptionStorage.Save(subscriptionInfo1); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = subscriptionStorage.Save(subscriptionInfo2); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = subscriptionStorage.Save(subscriptionInfo3); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); auto * iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 3); + EXPECT_EQ(iterator->Count(), 3u); // Verify subscriptions manually count correctly TestSubscriptionInfo subscriptionInfo; - NL_TEST_ASSERT(inSuite, iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, subscriptionInfo == subscriptionInfo1); - NL_TEST_ASSERT(inSuite, iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, subscriptionInfo == subscriptionInfo2); - NL_TEST_ASSERT(inSuite, iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, subscriptionInfo == subscriptionInfo3); + EXPECT_TRUE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(subscriptionInfo, subscriptionInfo1); + EXPECT_TRUE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(subscriptionInfo, subscriptionInfo2); + EXPECT_TRUE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(subscriptionInfo, subscriptionInfo3); // Verify at end of list - NL_TEST_ASSERT(inSuite, !iterator->Next(subscriptionInfo)); + EXPECT_FALSE(iterator->Next(subscriptionInfo)); iterator->Release(); // Delete fabric 1 and subscription 2 and check only 3 remains. @@ -245,30 +249,30 @@ void TestSubscriptionState(nlTestSuite * inSuite, void * inContext) subscriptionStorage.DeleteAll(subscriptionInfo2.mFabricIndex); iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 1); - NL_TEST_ASSERT(inSuite, iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, subscriptionInfo == subscriptionInfo3); + EXPECT_EQ(iterator->Count(), 1u); + EXPECT_TRUE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(subscriptionInfo, subscriptionInfo3); // Verify at end of list - NL_TEST_ASSERT(inSuite, !iterator->Next(subscriptionInfo)); + EXPECT_FALSE(iterator->Next(subscriptionInfo)); iterator->Release(); // Delete 3 also, and see that both count is 0 and MaxCount is removed from storage subscriptionStorage.DeleteAll(subscriptionInfo3.mFabricIndex); iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 0); - NL_TEST_ASSERT(inSuite, !iterator->Next(subscriptionInfo)); + EXPECT_EQ(iterator->Count(), 0u); + EXPECT_FALSE(iterator->Next(subscriptionInfo)); iterator->Release(); uint16_t countMax = 0; uint16_t len = sizeof(countMax); err = storage.SyncGetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumptionMaxCount().KeyName(), &countMax, len); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } static constexpr chip::TLV::Tag kTestValue1Tag = chip::TLV::ContextTag(30); static constexpr chip::TLV::Tag kTestValue2Tag = chip::TLV::ContextTag(31); -void TestSubscriptionStateUnexpectedFields(nlTestSuite * inSuite, void * inContext) +TEST_F(TestSimpleSubscriptionResumptionStorage, TestSubscriptionStateUnexpectedFields) { chip::TestPersistentStorageDelegate storage; SimpleSubscriptionResumptionStorageTest subscriptionStorage; @@ -293,39 +297,38 @@ void TestSubscriptionStateUnexpectedFields(nlTestSuite * inSuite, void * inConte chip::Platform::ScopedMemoryBuffer backingBuffer; backingBuffer.Calloc(subscriptionStorage.TestMaxSubscriptionSize()); - NL_TEST_ASSERT(inSuite, backingBuffer.Get() != nullptr); + ASSERT_NE(backingBuffer.Get(), nullptr); chip::TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), subscriptionStorage.TestMaxSubscriptionSize()); - NL_TEST_ASSERT(inSuite, subscriptionStorage.TestSave(writer, subscriptionInfo1) == CHIP_NO_ERROR); + EXPECT_EQ(subscriptionStorage.TestSave(writer, subscriptionInfo1), CHIP_NO_ERROR); // Additional stuff chip::TLV::TLVType containerType; - NL_TEST_ASSERT(inSuite, - writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, containerType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, containerType), CHIP_NO_ERROR); uint32_t value1 = 1; uint32_t value2 = 2; - NL_TEST_ASSERT(inSuite, writer.Put(kTestValue1Tag, value1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.Put(kTestValue2Tag, value2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.EndContainer(containerType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.Put(kTestValue1Tag, value1), CHIP_NO_ERROR); + EXPECT_EQ(writer.Put(kTestValue2Tag, value2), CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(containerType), CHIP_NO_ERROR); const auto len = writer.GetLengthWritten(); writer.Finalize(backingBuffer); - NL_TEST_ASSERT(inSuite, - storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumption(0).KeyName(), - backingBuffer.Get(), static_cast(len)) == CHIP_NO_ERROR); + EXPECT_EQ(storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumption(0).KeyName(), backingBuffer.Get(), + static_cast(len)), + CHIP_NO_ERROR); // Now read back and verify auto * iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 1); + EXPECT_EQ(iterator->Count(), 1u); TestSubscriptionInfo subscriptionInfo; - NL_TEST_ASSERT(inSuite, iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, subscriptionInfo == subscriptionInfo1); + EXPECT_TRUE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(subscriptionInfo, subscriptionInfo1); iterator->Release(); } -void TestSubscriptionStateTooBigToLoad(nlTestSuite * inSuite, void * inContext) +TEST_F(TestSimpleSubscriptionResumptionStorage, TestSubscriptionStateTooBigToLoad) { chip::TestPersistentStorageDelegate storage; SimpleSubscriptionResumptionStorageTest subscriptionStorage; @@ -350,42 +353,41 @@ void TestSubscriptionStateTooBigToLoad(nlTestSuite * inSuite, void * inContext) chip::Platform::ScopedMemoryBuffer backingBuffer; backingBuffer.Calloc(subscriptionStorage.TestMaxSubscriptionSize() * 2); - NL_TEST_ASSERT(inSuite, backingBuffer.Get() != nullptr); + ASSERT_NE(backingBuffer.Get(), nullptr); chip::TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), subscriptionStorage.TestMaxSubscriptionSize() * 2); - NL_TEST_ASSERT(inSuite, subscriptionStorage.TestSave(writer, subscriptionInfo1) == CHIP_NO_ERROR); + EXPECT_EQ(subscriptionStorage.TestSave(writer, subscriptionInfo1), CHIP_NO_ERROR); // Additional too-many bytes chip::TLV::TLVType containerType; - NL_TEST_ASSERT(inSuite, - writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, containerType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, containerType), CHIP_NO_ERROR); // Write MaxSubscriptionSize() to guarantee Load failure chip::Platform::ScopedMemoryBuffer additionalBytes; additionalBytes.Calloc(subscriptionStorage.TestMaxSubscriptionSize()); - NL_TEST_ASSERT(inSuite, additionalBytes.Get() != nullptr); - NL_TEST_ASSERT(inSuite, - writer.PutBytes(kTestValue1Tag, additionalBytes.Get(), - static_cast(subscriptionStorage.TestMaxSubscriptionSize())) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.EndContainer(containerType) == CHIP_NO_ERROR); + ASSERT_NE(additionalBytes.Get(), nullptr); + EXPECT_EQ(writer.PutBytes(kTestValue1Tag, additionalBytes.Get(), + static_cast(subscriptionStorage.TestMaxSubscriptionSize())), + CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(containerType), CHIP_NO_ERROR); const auto len = writer.GetLengthWritten(); writer.Finalize(backingBuffer); - NL_TEST_ASSERT(inSuite, - storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumption(0).KeyName(), - backingBuffer.Get(), static_cast(len)) == CHIP_NO_ERROR); + EXPECT_EQ(storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumption(0).KeyName(), backingBuffer.Get(), + static_cast(len)), + CHIP_NO_ERROR); // Now read back and verify auto * iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 1); + EXPECT_EQ(iterator->Count(), 1u); TestSubscriptionInfo subscriptionInfo; - NL_TEST_ASSERT(inSuite, !iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, iterator->Count() == 0); + EXPECT_FALSE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(iterator->Count(), 0u); iterator->Release(); } -void TestSubscriptionStateJunkData(nlTestSuite * inSuite, void * inContext) +TEST_F(TestSimpleSubscriptionResumptionStorage, TestSubscriptionStateJunkData) { chip::TestPersistentStorageDelegate storage; SimpleSubscriptionResumptionStorageTest subscriptionStorage; @@ -393,76 +395,16 @@ void TestSubscriptionStateJunkData(nlTestSuite * inSuite, void * inContext) chip::Platform::ScopedMemoryBuffer junkBytes; junkBytes.Calloc(subscriptionStorage.TestMaxSubscriptionSize() / 2); - NL_TEST_ASSERT(inSuite, junkBytes.Get() != nullptr); - NL_TEST_ASSERT(inSuite, - storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumption(0).KeyName(), junkBytes.Get(), - static_cast(subscriptionStorage.TestMaxSubscriptionSize() / 2)) == - CHIP_NO_ERROR); + ASSERT_NE(junkBytes.Get(), nullptr); + EXPECT_EQ(storage.SyncSetKeyValue(chip::DefaultStorageKeyAllocator::SubscriptionResumption(0).KeyName(), junkBytes.Get(), + static_cast(subscriptionStorage.TestMaxSubscriptionSize() / 2)), + CHIP_NO_ERROR); // Now read back and verify auto * iterator = subscriptionStorage.IterateSubscriptions(); - NL_TEST_ASSERT(inSuite, iterator->Count() == 1); + EXPECT_EQ(iterator->Count(), 1u); TestSubscriptionInfo subscriptionInfo; - NL_TEST_ASSERT(inSuite, !iterator->Next(subscriptionInfo)); - NL_TEST_ASSERT(inSuite, iterator->Count() == 0); + EXPECT_FALSE(iterator->Next(subscriptionInfo)); + EXPECT_EQ(iterator->Count(), 0u); iterator->Release(); } -/** - * Set up the test suite. - */ -int TestSubscription_Setup(void * inContext) -{ - VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE); - - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -int TestSubscription_Teardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("TestSubscriptionCount", TestSubscriptionCount), - NL_TEST_DEF("TestSubscriptionMaxCount", TestSubscriptionMaxCount), - NL_TEST_DEF("TestSubscriptionState", TestSubscriptionState), - NL_TEST_DEF("TestSubscriptionStateUnexpectedFields", TestSubscriptionStateUnexpectedFields), - NL_TEST_DEF("TestSubscriptionStateTooBigToLoad", TestSubscriptionStateTooBigToLoad), - NL_TEST_DEF("TestSubscriptionStateJunkData", TestSubscriptionStateJunkData), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-SimpleSubscriptionResumptionStorage", - &sTests[0], - &TestSubscription_Setup, &TestSubscription_Teardown -}; -// clang-format on - -/** - * Main - */ -int TestSimpleSubscriptionResumptionStorage() -{ - // Run test suit against one context - nlTestRunner(&sSuite, nullptr); - - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestSimpleSubscriptionResumptionStorage) diff --git a/src/app/tests/TestStatusIB.cpp b/src/app/tests/TestStatusIB.cpp index 2e5f78f7da64f7..8da643d2b71a31 100644 --- a/src/app/tests/TestStatusIB.cpp +++ b/src/app/tests/TestStatusIB.cpp @@ -20,11 +20,10 @@ #include #include #include +#include #include -#include #include - -#include +#include namespace { @@ -32,67 +31,78 @@ using namespace chip; using namespace chip::app; using namespace chip::Protocols::InteractionModel; +class TestStatusIB : public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); + StatusIB::RegisterErrorFormatter(); + } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + // Macro so failures will blame the right line. #define VERIFY_ROUNDTRIP(err, status) \ do \ { \ StatusIB newStatus; \ newStatus.InitFromChipError(err); \ - NL_TEST_ASSERT(aSuite, newStatus.mStatus == status.mStatus); \ - NL_TEST_ASSERT(aSuite, newStatus.mClusterStatus == status.mClusterStatus); \ + EXPECT_EQ(newStatus.mStatus, status.mStatus); \ + EXPECT_EQ(newStatus.mClusterStatus, status.mClusterStatus); \ } while (0); -void TestStatusIBToFromChipError(nlTestSuite * aSuite, void * aContext) +TEST_F(TestStatusIB, TestStatusIBToFromChipError) { StatusIB status; status.mStatus = Status::Success; CHIP_ERROR err = status.ToChipError(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); VERIFY_ROUNDTRIP(err, status); status.mStatus = Status::Failure; err = status.ToChipError(); - NL_TEST_ASSERT(aSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); VERIFY_ROUNDTRIP(err, status); status.mStatus = Status::InvalidAction; err = status.ToChipError(); - NL_TEST_ASSERT(aSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); VERIFY_ROUNDTRIP(err, status); status.mClusterStatus = MakeOptional(static_cast(5)); status.mStatus = Status::Success; err = status.ToChipError(); - NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); status.mStatus = Status::Failure; err = status.ToChipError(); - NL_TEST_ASSERT(aSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); VERIFY_ROUNDTRIP(err, status); status.mStatus = Status::InvalidAction; err = status.ToChipError(); - NL_TEST_ASSERT(aSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); { StatusIB newStatus; newStatus.InitFromChipError(err); - NL_TEST_ASSERT(aSuite, newStatus.mStatus == Status::Failure); - NL_TEST_ASSERT(aSuite, newStatus.mClusterStatus == status.mClusterStatus); + EXPECT_EQ(newStatus.mStatus, Status::Failure); + EXPECT_EQ(newStatus.mClusterStatus, status.mClusterStatus); } err = CHIP_ERROR_NO_MEMORY; { StatusIB newStatus; newStatus.InitFromChipError(err); - NL_TEST_ASSERT(aSuite, newStatus.mStatus == Status::Failure); - NL_TEST_ASSERT(aSuite, !newStatus.mClusterStatus.HasValue()); + EXPECT_EQ(newStatus.mStatus, Status::Failure); + EXPECT_FALSE(newStatus.mClusterStatus.HasValue()); } } #if !CHIP_CONFIG_SHORT_ERROR_STR -void TestStatusIBErrorToString(nlTestSuite * aSuite, void * aContext) +TEST_F(TestStatusIB, TestStatusIBErrorToString) { StatusIB status; status.mStatus = Status::InvalidAction; @@ -100,108 +110,55 @@ void TestStatusIBErrorToString(nlTestSuite * aSuite, void * aContext) const char * str = ErrorStr(err); #if CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT - NL_TEST_ASSERT(aSuite, strcmp(str, "IM Error 0x00000580: General error: 0x80 (INVALID_ACTION)") == 0); + EXPECT_STREQ(str, "IM Error 0x00000580: General error: 0x80 (INVALID_ACTION)"); #else // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT - NL_TEST_ASSERT(aSuite, strcmp(str, "IM Error 0x00000580: General error: 0x80") == 0); + EXPECT_STREQ(str, "IM Error 0x00000580: General error: 0x80"); #endif // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT status.mStatus = Status::Failure; status.mClusterStatus = MakeOptional(static_cast(5)); err = status.ToChipError(); str = ErrorStr(err); - NL_TEST_ASSERT(aSuite, strcmp(str, "IM Error 0x00000605: Cluster-specific error: 0x05") == 0); + EXPECT_STREQ(str, "IM Error 0x00000605: Cluster-specific error: 0x05"); } #endif // !CHIP_CONFIG_SHORT_ERROR_STR -void TestStatusIBEqualityOperator(nlTestSuite * aSuite, void * /*aContext*/) +TEST_F(TestStatusIB, TestStatusIBEqualityOperator) { // Equality against self is true. StatusIB one; - NL_TEST_ASSERT(aSuite, one == one); + EXPECT_EQ(one, one); // Default constructors are equal. - NL_TEST_ASSERT(aSuite, one == StatusIB()); + EXPECT_EQ(one, StatusIB()); // Different imStatus is not equal. StatusIB with_imstatus(Status::Failure); - NL_TEST_ASSERT(aSuite, one != with_imstatus); + EXPECT_NE(one, with_imstatus); // Same imStatus are equal. - NL_TEST_ASSERT(aSuite, with_imstatus == StatusIB(Status::Failure)); + EXPECT_EQ(with_imstatus, StatusIB(Status::Failure)); // Same imStatus but different clusterStatus are not equal. StatusIB with_cluster_status(Status::Failure, /*clusterStatus=*/2); - NL_TEST_ASSERT(aSuite, with_imstatus != with_cluster_status); + EXPECT_NE(with_imstatus, with_cluster_status); // Different imStatus but same clusterStatus are not equal. - NL_TEST_ASSERT(aSuite, with_cluster_status != StatusIB(Status::Success, /*clusterStatus=*/2)); + EXPECT_NE(with_cluster_status, StatusIB(Status::Success, /*clusterStatus=*/2)); // Same imStatus and clusterStatus are equal. - NL_TEST_ASSERT(aSuite, with_cluster_status == StatusIB(Status::Failure, /*clusterStatus=*/2)); + EXPECT_EQ(with_cluster_status, StatusIB(Status::Failure, /*clusterStatus=*/2)); // From same CHIP_ERROR are equal. StatusIB invalid_argument(CHIP_ERROR_INVALID_ARGUMENT); - NL_TEST_ASSERT(aSuite, invalid_argument == StatusIB(CHIP_ERROR_INVALID_ARGUMENT)); + EXPECT_EQ(invalid_argument, StatusIB(CHIP_ERROR_INVALID_ARGUMENT)); // Different CHIP_ERROR are equal if they are not from kIMClusterStatus or // kIMGlobalStatus. - NL_TEST_ASSERT(aSuite, invalid_argument == StatusIB(CHIP_ERROR_INCORRECT_STATE)); + EXPECT_EQ(invalid_argument, StatusIB(CHIP_ERROR_INCORRECT_STATE)); // Error never equals NO_ERROR - NL_TEST_ASSERT(aSuite, invalid_argument != StatusIB(CHIP_NO_ERROR)); + EXPECT_NE(invalid_argument, StatusIB(CHIP_NO_ERROR)); } -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("StatusIBToFromChipError", TestStatusIBToFromChipError), -#if !CHIP_CONFIG_SHORT_ERROR_STR - NL_TEST_DEF("StatusIBErrorToString", TestStatusIBErrorToString), -#endif // !CHIP_CONFIG_SHORT_ERROR_STR - NL_TEST_DEF("StatusIBEqualityOperator", TestStatusIBEqualityOperator), - NL_TEST_SENTINEL() -}; -// clang-format on } // namespace - -/** - * Set up the test suite. - */ -static int TestSetup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - // Hand-register the error formatter. Normally it's registered by - // InteractionModelEngine::Init, but we don't want to mess with that here. - StatusIB::RegisterErrorFormatter(); - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -int TestStatusIB() -{ - // clang-format off - nlTestSuite theSuite = - { - "StatusIB", - &sTests[0], - TestSetup, - TestTeardown, - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestStatusIB) diff --git a/src/app/tests/TestStatusResponseMessage.cpp b/src/app/tests/TestStatusResponseMessage.cpp index 565ed85dfe8af0..72cf8685d9bfff 100644 --- a/src/app/tests/TestStatusResponseMessage.cpp +++ b/src/app/tests/TestStatusResponseMessage.cpp @@ -16,40 +16,41 @@ * limitations under the License. */ -/** - * @file - * This file implements a test for CHIP Interaction Model Message Def - * - */ +#include +#include #include #include #include #include -#include #include -#include - namespace { using namespace chip::app; constexpr chip::Protocols::InteractionModel::Status statusValue = chip::Protocols::InteractionModel::Status::Success; constexpr chip::Protocols::InteractionModel::Status invalidStatusValue = chip::Protocols::InteractionModel::Status::Failure; -void BuildStatusResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) +class TestStatusResponseMessage : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +void BuildStatusResponseMessage(chip::TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; StatusResponseMessage::Builder statusResponse; err = statusResponse.Init(&aWriter); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); statusResponse.Status(statusValue); - NL_TEST_ASSERT(apSuite, statusResponse.GetError() == CHIP_NO_ERROR); + EXPECT_EQ(statusResponse.GetError(), CHIP_NO_ERROR); } -void ParseStatusResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aReader, bool aTestPositiveCase) +void ParseStatusResponseMessage(chip::TLV::TLVReader & aReader, bool aTestPositiveCase) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -57,7 +58,7 @@ void ParseStatusResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aR chip::Protocols::InteractionModel::Status status; err = statusResponse.Init(aReader); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); #if CHIP_CONFIG_IM_PRETTY_PRINT statusResponse.PrettyPrint(); #endif @@ -65,87 +66,42 @@ void ParseStatusResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aR err = statusResponse.GetStatus(status); if (aTestPositiveCase) { - NL_TEST_ASSERT(apSuite, status == statusValue && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(status, statusValue); } else { - NL_TEST_ASSERT(apSuite, status != invalidStatusValue && err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_NE(status, invalidStatusValue); } } -void StatusResponseMessagePositiveTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestStatusResponseMessage, TestStatusResponseMessagePositive) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildStatusResponseMessage(apSuite, writer); + BuildStatusResponseMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); reader.Init(std::move(buf)); - ParseStatusResponseMessage(apSuite, reader, true /*aTestPositiveCase*/); + ParseStatusResponseMessage(reader, true /*aTestPositiveCase*/); } -void StatusResponseMessageNegativeTest(nlTestSuite * apSuite, void * apContext) +TEST_F(TestStatusResponseMessage, TestStatusResponseMessageNegative) { CHIP_ERROR err = CHIP_NO_ERROR; chip::System::PacketBufferTLVWriter writer; chip::System::PacketBufferTLVReader reader; writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize)); - BuildStatusResponseMessage(apSuite, writer); + BuildStatusResponseMessage(writer); chip::System::PacketBufferHandle buf; err = writer.Finalize(&buf); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); reader.Init(std::move(buf)); - ParseStatusResponseMessage(apSuite, reader, false /*aTestPositiveCase*/); + ParseStatusResponseMessage(reader, false /*aTestPositiveCase*/); } -// clang-format off -const nlTest sTests[] = - { - NL_TEST_DEF("StatusResponseMessagePositiveTest", StatusResponseMessagePositiveTest), - NL_TEST_DEF("StatusResponseMessageNegativeTest", StatusResponseMessageNegativeTest), - NL_TEST_SENTINEL() - }; -// clang-format on } // namespace - -/** - * Set up the test suite. - */ -static int TestSetup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -int TestStatusResponseMessage() -{ - // clang-format off - nlTestSuite theSuite = - { - "StatusResponseMessage", - &sTests[0], - TestSetup, - TestTeardown, - }; - // clang-format on - - nlTestRunner(&theSuite, nullptr); - - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestStatusResponseMessage) diff --git a/src/app/tests/TestTestEventTriggerDelegate.cpp b/src/app/tests/TestTestEventTriggerDelegate.cpp index cd7f3ae9cd7be3..09e513a3d87afb 100644 --- a/src/app/tests/TestTestEventTriggerDelegate.cpp +++ b/src/app/tests/TestTestEventTriggerDelegate.cpp @@ -19,9 +19,9 @@ #include #include +#include #include -#include -#include +#include using namespace chip; @@ -66,20 +66,20 @@ class TestEventDelegate : public TestEventTriggerDelegate ByteSpan mEnableKey; }; -void TestKeyChecking(nlTestSuite * aSuite, void * aContext) +TEST(TestTestEventTriggerDelegate, TestKeyChecking) { const uint8_t kTestKey[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; const uint8_t kBadKey[16] = { 255, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; const uint8_t kDiffLenBadKey[17] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; TestEventDelegate delegate{ ByteSpan{ kTestKey } }; - NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{ kTestKey }) == true); - NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{ kBadKey }) == false); - NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{ kDiffLenBadKey }) == false); - NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{}) == false); + EXPECT_TRUE(delegate.DoesEnableKeyMatch(ByteSpan{ kTestKey })); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan{ kBadKey })); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan{ kDiffLenBadKey })); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan{})); } -void TestHandlerManagement(nlTestSuite * aSuite, void * aContext) +TEST(TestTestEventTriggerDelegate, TestHandlerManagement) { const uint8_t kTestKey[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; @@ -89,31 +89,31 @@ void TestHandlerManagement(nlTestSuite * aSuite, void * aContext) TestEventHandler event2Handler{ 2 }; // Add 2, check 2 works 1 doesn't. - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) != CHIP_NO_ERROR); + EXPECT_NE(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) != CHIP_NO_ERROR); + EXPECT_EQ(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR); + EXPECT_NE(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) != CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); + EXPECT_NE(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 0); - NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 2); + EXPECT_EQ(event1Handler.GetCount(), 0); + EXPECT_EQ(event2Handler.GetCount(), 2); event1Handler.ClearCount(); event2Handler.ClearCount(); // Add 1, check 1 and 2 work. - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event1Handler) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event1Handler) != CHIP_NO_ERROR); + EXPECT_EQ(delegate.AddHandler(&event1Handler), CHIP_NO_ERROR); + EXPECT_NE(delegate.AddHandler(&event1Handler), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 2); - NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 1); + EXPECT_EQ(event1Handler.GetCount(), 2); + EXPECT_EQ(event2Handler.GetCount(), 1); event1Handler.ClearCount(); event2Handler.ClearCount(); @@ -121,29 +121,29 @@ void TestHandlerManagement(nlTestSuite * aSuite, void * aContext) // Remove 2, check 1 works. delegate.RemoveHandler(&event2Handler); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) != CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); + EXPECT_NE(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 1); - NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 0); + EXPECT_EQ(event1Handler.GetCount(), 1); + EXPECT_EQ(event2Handler.GetCount(), 0); // Remove again, should be NO-OP. delegate.RemoveHandler(&event2Handler); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) != CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 0); + EXPECT_NE(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); + EXPECT_EQ(event2Handler.GetCount(), 0); event1Handler.ClearCount(); event2Handler.ClearCount(); // Add 2 again, check 1 and 2 work. - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) != CHIP_NO_ERROR); + EXPECT_EQ(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR); + EXPECT_NE(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); + EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 1); - NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 1); + EXPECT_EQ(event1Handler.GetCount(), 1); + EXPECT_EQ(event2Handler.GetCount(), 1); event1Handler.ClearCount(); event2Handler.ClearCount(); @@ -151,42 +151,14 @@ void TestHandlerManagement(nlTestSuite * aSuite, void * aContext) // Remove all handlers, check neither works. delegate.ClearAllHandlers(); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) != CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) != CHIP_NO_ERROR); + EXPECT_NE(delegate.HandleEventTriggers(1), CHIP_NO_ERROR); + EXPECT_NE(delegate.HandleEventTriggers(2), CHIP_NO_ERROR); - NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 0); - NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 0); + EXPECT_EQ(event1Handler.GetCount(), 0); + EXPECT_EQ(event2Handler.GetCount(), 0); // Add a handler at the end: having it remaining should not cause crashes/leaks. - NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) == CHIP_NO_ERROR); -} - -int TestSetup(void * inContext) -{ - return SUCCESS; -} - -int TestTeardown(void * inContext) -{ - return SUCCESS; + EXPECT_EQ(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR); } } // namespace - -int TestTestEventTriggerDelegate() -{ - static nlTest sTests[] = { NL_TEST_DEF("TestKeyChecking", TestKeyChecking), - NL_TEST_DEF("TestHandlerManagement", TestHandlerManagement), NL_TEST_SENTINEL() }; - - nlTestSuite theSuite = { - "TestTestEventTriggerDelegate", - &sTests[0], - TestSetup, - TestTeardown, - }; - - nlTestRunner(&theSuite, nullptr); - return (nlTestRunnerStats(&theSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestTestEventTriggerDelegate) diff --git a/src/app/tests/TestTimeSyncDataProvider.cpp b/src/app/tests/TestTimeSyncDataProvider.cpp index 3ea30d5582a642..bc73f03e55a386 100644 --- a/src/app/tests/TestTimeSyncDataProvider.cpp +++ b/src/app/tests/TestTimeSyncDataProvider.cpp @@ -17,11 +17,10 @@ #include #include +#include #include #include -#include - -#include +#include using namespace chip; using namespace chip::DeviceLayer; @@ -36,7 +35,14 @@ using DSTOffset = app::Clusters::TimeSynchronization::Structs::DSTOffset namespace { -void TestTrustedTimeSourceStoreLoad(nlTestSuite * inSuite, void * inContext) +class TestTimeSyncDataProvider : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestTimeSyncDataProvider, TestTrustedTimeSourceStoreLoad) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -44,16 +50,16 @@ void TestTrustedTimeSourceStoreLoad(nlTestSuite * inSuite, void * inContext) TrustedTimeSource tts = { chip::FabricIndex(1), chip::NodeId(20), chip::EndpointId(0) }; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreTrustedTimeSource(tts)); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreTrustedTimeSource(tts)); TrustedTimeSource retrievedTrustedTimeSource; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadTrustedTimeSource(retrievedTrustedTimeSource)); - NL_TEST_ASSERT(inSuite, retrievedTrustedTimeSource.fabricIndex == chip::FabricIndex(1)); - NL_TEST_ASSERT(inSuite, retrievedTrustedTimeSource.nodeID == chip::NodeId(20)); - NL_TEST_ASSERT(inSuite, retrievedTrustedTimeSource.endpoint == chip::EndpointId(0)); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadTrustedTimeSource(retrievedTrustedTimeSource)); + EXPECT_EQ(retrievedTrustedTimeSource.fabricIndex, chip::FabricIndex(1)); + EXPECT_EQ(retrievedTrustedTimeSource.nodeID, chip::NodeId(20)); + EXPECT_EQ(retrievedTrustedTimeSource.endpoint, chip::EndpointId(0)); } -void TestTrustedTimeSourceEmpty(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestTrustedTimeSourceEmpty) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -61,10 +67,10 @@ void TestTrustedTimeSourceEmpty(nlTestSuite * inSuite, void * inContext) TrustedTimeSource tts; - NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadTrustedTimeSource(tts)); + EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadTrustedTimeSource(tts)); } -void TestDefaultNTPStoreLoad(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestDefaultNTPStoreLoad) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -73,22 +79,22 @@ void TestDefaultNTPStoreLoad(nlTestSuite * inSuite, void * inContext) char ntp[10] = "localhost"; chip::CharSpan defaultNTP(ntp); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreDefaultNtp(defaultNTP)); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreDefaultNtp(defaultNTP)); char buf[5]; chip::MutableCharSpan getDefaultNtp(buf); - NL_TEST_ASSERT(inSuite, CHIP_ERROR_BUFFER_TOO_SMALL == timeSyncDataProv.LoadDefaultNtp(getDefaultNtp)); - NL_TEST_ASSERT(inSuite, getDefaultNtp.size() == 5); + EXPECT_EQ(CHIP_ERROR_BUFFER_TOO_SMALL, timeSyncDataProv.LoadDefaultNtp(getDefaultNtp)); + EXPECT_EQ(getDefaultNtp.size(), 5u); char buf1[20]; chip::MutableCharSpan getDefaultNtp1(buf1); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadDefaultNtp(getDefaultNtp1)); - NL_TEST_ASSERT(inSuite, getDefaultNtp1.size() == 10); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadDefaultNtp(getDefaultNtp1)); + EXPECT_EQ(getDefaultNtp1.size(), 10u); } -void TestDefaultNTPEmpty(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestDefaultNTPEmpty) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -96,10 +102,10 @@ void TestDefaultNTPEmpty(nlTestSuite * inSuite, void * inContext) chip::MutableCharSpan defaultNTP; - NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadDefaultNtp(defaultNTP)); + EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadDefaultNtp(defaultNTP)); } -void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestTimeZoneStoreLoad) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -122,26 +128,26 @@ void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext) TimeSyncDataProvider::TimeZoneStore tzS[3] = { makeTimeZone(1, 1, tzShort), makeTimeZone(2, 2, tzLong), makeTimeZone(3, 3, tzBerlin) }; TimeZoneList tzL(tzS); - NL_TEST_ASSERT(inSuite, tzL.size() == 3); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreTimeZone(tzL)); + EXPECT_EQ(tzL.size(), 3u); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreTimeZone(tzL)); TimeSyncDataProvider::TimeZoneStore emptyTzS[3] = { makeTimeZone(), makeTimeZone(), makeTimeZone() }; tzL = TimeZoneList(emptyTzS); TimeSyncDataProvider::TimeZoneObj tzObj{ tzL, 3 }; - NL_TEST_ASSERT(inSuite, tzL.size() == 3); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadTimeZone(tzObj)); - NL_TEST_ASSERT(inSuite, tzObj.validSize == 3); + EXPECT_EQ(tzL.size(), 3u); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadTimeZone(tzObj)); + EXPECT_EQ(tzObj.validSize, 3u); - NL_TEST_ASSERT(inSuite, !tzL.empty()); + EXPECT_FALSE(tzL.empty()); if (!tzL.empty()) { auto & tz = tzL[0].timeZone; - NL_TEST_ASSERT(inSuite, tz.offset == 1); - NL_TEST_ASSERT(inSuite, tz.validAt == 1); - NL_TEST_ASSERT(inSuite, tz.name.HasValue()); - NL_TEST_ASSERT(inSuite, tz.name.Value().size() == 2); + EXPECT_EQ(tz.offset, 1); + EXPECT_EQ(tz.validAt, 1u); + EXPECT_TRUE(tz.name.HasValue()); + EXPECT_EQ(tz.name.Value().size(), 2u); tzL = tzL.SubSpan(1); } @@ -149,10 +155,10 @@ void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext) if (!tzL.empty()) { auto & tz = tzL[0].timeZone; - NL_TEST_ASSERT(inSuite, tz.offset == 2); - NL_TEST_ASSERT(inSuite, tz.validAt == 2); - NL_TEST_ASSERT(inSuite, tz.name.HasValue()); - NL_TEST_ASSERT(inSuite, tz.name.Value().size() == 63); + EXPECT_EQ(tz.offset, 2); + EXPECT_EQ(tz.validAt, 2u); + EXPECT_TRUE(tz.name.HasValue()); + EXPECT_EQ(tz.name.Value().size(), 63u); tzL = tzL.SubSpan(1); } @@ -160,18 +166,18 @@ void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext) if (!tzL.empty()) { auto & tz = tzL[0].timeZone; - NL_TEST_ASSERT(inSuite, tz.offset == 3); - NL_TEST_ASSERT(inSuite, tz.validAt == 3); - NL_TEST_ASSERT(inSuite, tz.name.HasValue()); - NL_TEST_ASSERT(inSuite, tz.name.Value().size() == 6); + EXPECT_EQ(tz.offset, 3); + EXPECT_EQ(tz.validAt, 3u); + EXPECT_TRUE(tz.name.HasValue()); + EXPECT_EQ(tz.name.Value().size(), 6u); tzL = tzL.SubSpan(1); } - NL_TEST_ASSERT(inSuite, tzL.empty()); + EXPECT_TRUE(tzL.empty()); } -void TestTimeZoneEmpty(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestTimeZoneEmpty) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -179,12 +185,12 @@ void TestTimeZoneEmpty(nlTestSuite * inSuite, void * inContext) TimeSyncDataProvider::TimeZoneObj timeZoneObj; - NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadTimeZone(timeZoneObj)); - NL_TEST_ASSERT(inSuite, !timeZoneObj.timeZoneList.begin()); - NL_TEST_ASSERT(inSuite, timeZoneObj.validSize == 0); + EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadTimeZone(timeZoneObj)); + EXPECT_FALSE(timeZoneObj.timeZoneList.begin()); + EXPECT_EQ(timeZoneObj.validSize, 0u); } -void TestDSTOffset(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestDSTOffset) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -201,26 +207,26 @@ void TestDSTOffset(nlTestSuite * inSuite, void * inContext) DSTOffset dstS[3] = { makeDSTOffset(1, 1, 2), makeDSTOffset(2, 2, 3), makeDSTOffset(3, 3) }; DSTOffsetList dstL(dstS); TimeSyncDataProvider::DSTOffsetObj dstObj{ dstL, 3 }; - NL_TEST_ASSERT(inSuite, dstObj.validSize == 3); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreDSTOffset(dstL)); + EXPECT_EQ(dstObj.validSize, 3u); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreDSTOffset(dstL)); DSTOffset emtpyDstS[3] = { makeDSTOffset(), makeDSTOffset(), makeDSTOffset() }; dstObj.dstOffsetList = DSTOffsetList(emtpyDstS); dstObj.validSize = 0; - NL_TEST_ASSERT(inSuite, dstObj.dstOffsetList.size() == 3); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadDSTOffset(dstObj)); - NL_TEST_ASSERT(inSuite, dstObj.validSize == 3); + EXPECT_EQ(dstObj.dstOffsetList.size(), 3u); + EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadDSTOffset(dstObj)); + EXPECT_EQ(dstObj.validSize, 3u); - NL_TEST_ASSERT(inSuite, !dstObj.dstOffsetList.empty()); + EXPECT_FALSE(dstObj.dstOffsetList.empty()); if (!dstObj.dstOffsetList.empty()) { auto & dst = dstObj.dstOffsetList.data()[0]; - NL_TEST_ASSERT(inSuite, dst.offset == 1); - NL_TEST_ASSERT(inSuite, dst.validStarting == 1); - NL_TEST_ASSERT(inSuite, !dst.validUntil.IsNull()); - NL_TEST_ASSERT(inSuite, dst.validUntil.Value() == 2); + EXPECT_EQ(dst.offset, 1); + EXPECT_EQ(dst.validStarting, 1u); + EXPECT_FALSE(dst.validUntil.IsNull()); + EXPECT_EQ(dst.validUntil.Value(), 2u); dstObj.dstOffsetList = dstObj.dstOffsetList.SubSpan(1); } @@ -228,10 +234,10 @@ void TestDSTOffset(nlTestSuite * inSuite, void * inContext) if (!dstObj.dstOffsetList.empty()) { auto & dst = dstObj.dstOffsetList.data()[0]; - NL_TEST_ASSERT(inSuite, dst.offset == 2); - NL_TEST_ASSERT(inSuite, dst.validStarting == 2); - NL_TEST_ASSERT(inSuite, !dst.validUntil.IsNull()); - NL_TEST_ASSERT(inSuite, dst.validUntil.Value() == 3); + EXPECT_EQ(dst.offset, 2); + EXPECT_EQ(dst.validStarting, 2u); + EXPECT_FALSE(dst.validUntil.IsNull()); + EXPECT_EQ(dst.validUntil.Value(), 3u); dstObj.dstOffsetList = dstObj.dstOffsetList.SubSpan(1); } @@ -239,17 +245,17 @@ void TestDSTOffset(nlTestSuite * inSuite, void * inContext) if (!dstObj.dstOffsetList.empty()) { auto & dst = dstObj.dstOffsetList.data()[0]; - NL_TEST_ASSERT(inSuite, dst.offset == 3); - NL_TEST_ASSERT(inSuite, dst.validStarting == 3); - NL_TEST_ASSERT(inSuite, dst.validUntil.IsNull()); + EXPECT_EQ(dst.offset, 3); + EXPECT_EQ(dst.validStarting, 3u); + EXPECT_TRUE(dst.validUntil.IsNull()); dstObj.dstOffsetList = dstObj.dstOffsetList.SubSpan(1); } - NL_TEST_ASSERT(inSuite, dstObj.dstOffsetList.empty()); + EXPECT_TRUE(dstObj.dstOffsetList.empty()); } -void TestDSTOffsetEmpty(nlTestSuite * inSuite, void * inContext) +TEST_F(TestTimeSyncDataProvider, TestDSTOffsetEmpty) { TestPersistentStorageDelegate persistentStorage; TimeSyncDataProvider timeSyncDataProv; @@ -257,42 +263,9 @@ void TestDSTOffsetEmpty(nlTestSuite * inSuite, void * inContext) TimeSyncDataProvider::DSTOffsetObj dstObj; - NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadDSTOffset(dstObj)); - NL_TEST_ASSERT(inSuite, !dstObj.dstOffsetList.begin()); - NL_TEST_ASSERT(inSuite, dstObj.validSize == 0); -} - -const nlTest sTests[] = { NL_TEST_DEF("Test TrustedTimeSource store load", TestTrustedTimeSourceStoreLoad), - NL_TEST_DEF("Test TrustedTimeSource empty", TestTrustedTimeSourceEmpty), - NL_TEST_DEF("Test default NTP store load", TestDefaultNTPStoreLoad), - NL_TEST_DEF("Test default NTP empty", TestDefaultNTPEmpty), - NL_TEST_DEF("Test time zone store load", TestTimeZoneStoreLoad), - NL_TEST_DEF("Test time zone (empty list)", TestTimeZoneEmpty), - NL_TEST_DEF("Test DSTOffset", TestDSTOffset), - NL_TEST_DEF("Test DSTOffset (empty list)", TestDSTOffsetEmpty), - NL_TEST_SENTINEL() }; - -int TestSetup(void * inContext) -{ - VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE); - return SUCCESS; -} - -int TestTearDown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; + EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadDSTOffset(dstObj)); + EXPECT_TRUE(dstObj.dstOffsetList.empty()); + EXPECT_EQ(dstObj.validSize, 0u); } } // namespace - -int TestTimeSyncDataProvider() -{ - nlTestSuite theSuite = { "Time Sync data provider tests", &sTests[0], TestSetup, TestTearDown }; - - // Run test suite against one context. - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestTimeSyncDataProvider) diff --git a/src/app/tests/TestWriteInteraction.cpp b/src/app/tests/TestWriteInteraction.cpp index 795c52a9030f99..7aa2dba303bf0f 100644 --- a/src/app/tests/TestWriteInteraction.cpp +++ b/src/app/tests/TestWriteInteraction.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -40,9 +41,6 @@ namespace { -uint8_t attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE]; -size_t attributeDataTLVLen = 0; -constexpr chip::DataVersion kRejectedDataVersion = 1; constexpr chip::DataVersion kAcceptedDataVersion = 5; constexpr uint16_t kMaxGroupsPerFabric = 5; constexpr uint16_t kMaxGroupKeysPerFabric = 8; @@ -363,28 +361,6 @@ void TestWriteInteraction::TestWriteHandler(nlTestSuite * apSuite, void * apCont } } -const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aConcreteClusterPath) -{ - // Note: This test does not make use of the real attribute metadata. - static EmberAfAttributeMetadata stub = { .defaultValue = EmberAfDefaultOrMinMaxAttributeValue(uint32_t(0)) }; - return &stub; -} - -CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, const ConcreteDataAttributePath & aPath, - TLV::TLVReader & aReader, WriteHandler * aWriteHandler) -{ - if (aPath.mDataVersion.HasValue() && aPath.mDataVersion.Value() == kRejectedDataVersion) - { - return aWriteHandler->AddStatus(aPath, Protocols::InteractionModel::Status::DataVersionMismatch); - } - - TLV::TLVWriter writer; - writer.Init(attributeDataTLV); - writer.CopyElement(TLV::AnonymousTag(), aReader); - attributeDataTLVLen = writer.GetLengthWritten(); - return aWriteHandler->AddStatus(aPath, Protocols::InteractionModel::Status::Success); -} - void TestWriteInteraction::TestWriteRoundtripWithClusterObjects(nlTestSuite * apSuite, void * apContext) { TestContext & ctx = *static_cast(apContext); @@ -434,7 +410,7 @@ void TestWriteInteraction::TestWriteRoundtripWithClusterObjects(nlTestSuite * ap { app::Clusters::UnitTesting::Structs::SimpleStruct::Type dataRx; TLV::TLVReader reader; - reader.Init(attributeDataTLV, attributeDataTLVLen); + reader.Init(chip::Test::attributeDataTLV, chip::Test::attributeDataTLVLen); reader.Next(); NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == DataModel::Decode(reader, dataRx)); NL_TEST_ASSERT(apSuite, dataRx.a == dataTx.a); @@ -531,7 +507,7 @@ void TestWriteInteraction::TestWriteRoundtripWithClusterObjectsVersionMismatch(n dataTxValue.b = true; DataModel::Nullable dataTx; dataTx.SetNonNull(dataTxValue); - Optional version(kRejectedDataVersion); + Optional version(chip::Test::kRejectedDataVersion); writeClient.EncodeAttribute(attributePathParams, dataTx, version); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); diff --git a/src/app/tests/integration/chip_im_responder.cpp b/src/app/tests/integration/chip_im_responder.cpp index 72f056ca6ab8b7..86d654b99ff94c 100644 --- a/src/app/tests/integration/chip_im_responder.cpp +++ b/src/app/tests/integration/chip_im_responder.cpp @@ -50,6 +50,25 @@ namespace chip { namespace app { +namespace { + +class TestTLVDataEncoder : public DataModel::EncodableToTLV +{ +public: + CHIP_ERROR EncodeTo(TLV::TLVWriter & writer, TLV::Tag tag) const override + { + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outerType)); + + ReturnErrorOnFailure(writer.Put(chip::TLV::ContextTag(kTestFieldId1), kTestFieldValue1)); + ReturnErrorOnFailure(writer.Put(chip::TLV::ContextTag(kTestFieldId2), kTestFieldValue2)); + + return writer.EndContainer(outerType); + } +}; + +} // namespace + Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { // The Mock cluster catalog -- only have one command on one cluster on one endpoint. @@ -104,17 +123,8 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPat { printf("responder constructing command data in command"); - chip::TLV::TLVWriter * writer; - - const CommandHandler::InvokeResponseParameters prepareParams(aRequestCommandPath); - ReturnOnFailure(apCommandObj->PrepareInvokeResponseCommand(path, prepareParams)); - - writer = apCommandObj->GetCommandDataIBTLVWriter(); - ReturnOnFailure(writer->Put(chip::TLV::ContextTag(kTestFieldId1), kTestFieldValue1)); - - ReturnOnFailure(writer->Put(chip::TLV::ContextTag(kTestFieldId2), kTestFieldValue2)); - - ReturnOnFailure(apCommandObj->FinishCommand()); + TestTLVDataEncoder testData; + apCommandObj->AddResponse(path, kTestCommandId, testData); } statusCodeFlipper = !statusCodeFlipper; } diff --git a/src/app/tests/suites/TestAccessControlConstraints.yaml b/src/app/tests/suites/TestAccessControlConstraints.yaml index 1a54ea48f92365..ab7ba3cf8d5f0c 100644 --- a/src/app/tests/suites/TestAccessControlConstraints.yaml +++ b/src/app/tests/suites/TestAccessControlConstraints.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: User Label Cluster Tests +name: Test Access Control Constraints config: nodeId: 0x12344321 diff --git a/src/app/tests/suites/certification/Test_TC_ACFREMON_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ACFREMON_1_1.yaml deleted file mode 100644 index 3f4a7cc16bbd57..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ACFREMON_1_1.yaml +++ /dev/null @@ -1,183 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 165.1.1. [TC-ACFREMON-1.1] Global Attributes with DUT as Server - -PICS: - - ACFREMON.S - -config: - nodeId: 0x12344321 - cluster: "Activated Carbon Filter Monitoring" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: "!ACFREMON.S.F00 && !ACFREMON.S.F01 && !ACFREMON.S.F02" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given ACFREMON.S.F00(Condition) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ACFREMON.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given ACFREMON.S.F01(Warning) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ACFREMON.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given ACFREMON.S.F02(ReplacementProductList) ensure - featuremap has the correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ACFREMON.S.F02 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the feature dependent(ACFREMON.S.F00) attribute in - AttributeList" - PICS: ACFREMON.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2] - - - label: - "Step 4c: TH reads the optional attribute InPlaceIndicator - (ACFREMON.S.A0003) in AttributeList" - PICS: ACFREMON.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4d: TH reads the optional attribute LastChangedTime - (ACFREMON.S.A0004) in AttributeList" - PICS: ACFREMON.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4e: TH reads the optional attribute ReplacementProductList - (ACFREMON.S.F02) in AttributeList" - PICS: ACFREMON.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute." - PICS: "!ACFREMON.S.C00.Rsp" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6b: TH reads the optional command (ResetCondition) in - AcceptedCommandList" - PICS: ACFREMON.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_ACL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ACL_1_1.yaml deleted file mode 100644 index 1f33f19854e874..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ACL_1_1.yaml +++ /dev/null @@ -1,100 +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: 133.1.1. [TC-ACL-1.1] Global attributes - -PICS: - - ACL.S - -config: - nodeId: 0x12344321 - cluster: "Access Control" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads ClusterRevision attribute from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads FeatureMap attribute from DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads AttributeList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 2, 3, 4, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList attribute from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 2, 3, 4, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: TH reads optional attribute (Extension) in AttributeList" - PICS: ACL.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0, 1] - - - label: "Step 6: TH reads AcceptedCommandList attribute from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList attribute from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_ACT_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ACT_1_1.yaml deleted file mode 100644 index 50ebde13e9a2de..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ACT_1_1.yaml +++ /dev/null @@ -1,224 +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: 77.1.1. [TC-ACT-1.1] Global attributes with server as DUT - -PICS: - - ACT.S - -config: - nodeId: 0x12344321 - cluster: "Actions" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: Read the optional attribute(SetupURL) in AttributeList" - PICS: ACT.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - #Issue: https://github.com/project-chip/connectedhomeip/issues/26721 - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0, 1] - - # Checking only type check all commands are optional - - label: - "Step 6a: TH Read the optional command (InstantAction) in - AcceptedCommandList" - PICS: ACT.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x0] - - - label: - "Step 6b: TH Read the optional command (InstantActionWithTransition) - in AcceptedCommandList" - PICS: ACT.S.C01.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x01] - - - label: - "Step 6C: TH Read the optional command (StartAction) in - AcceptedCommandList" - PICS: ACT.S.C02.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x02] - - - label: - "Step 6d: TH Read the optional command (StartActionWithDuration) in - AcceptedCommandList" - PICS: ACT.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x03] - - - label: - "Step 6e: TH Read the optional command (StopAction) in - AcceptedCommandList" - PICS: ACT.S.C04.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x04] - - label: - "Step 6f: TH Read the optional command (PauseAction) in - AcceptedCommandList" - PICS: ACT.S.C05.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x05] - - - label: - "Step 6g: TH Read the optional command (PauseActionWithDuration) in - AcceptedCommandList" - PICS: ACT.S.C06.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x06] - - - label: - "Step 6h: TH Read the optional command (ResumeAction) in - AcceptedCommandList" - PICS: ACT.S.C07.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x07] - - - label: - "Step 6i: TH Read the optional command (EnableAction) in - AcceptedCommandList" - PICS: ACT.S.C08.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x08] - - label: - "Step 6j: TH Read the optional command (EnableActionWithDuration) in - AcceptedCommandList" - PICS: ACT.S.C09.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x09] - - - label: - "Step 6k: TH Read the optional command (DisableAction) in - AcceptedCommandList" - PICS: ACT.S.C0a.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x0a] - - - label: - "Step 6l: TH Read the optional command (DisableActionWithDuration) in - AcceptedCommandList" - PICS: ACT.S.C0b.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x0b] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml deleted file mode 100644 index 5bb595f91fa807..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_AIRQUAL_1_1.yaml +++ /dev/null @@ -1,137 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 164.1.1. [TC-AIRQUAL-1.1] Global Attributes with DUT as Server - -PICS: - - AIRQUAL.S - -config: - nodeId: 0x12344321 - cluster: "Air Quality" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: - "!AIRQUAL.S.F00 && !AIRQUAL.S.F01 && !AIRQUAL.S.F02 && !AIRQUAL.S.F03" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given AIRQUAL.S.F00(Fair) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: AIRQUAL.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given AIRQUAL.S.F01(Moderate) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: AIRQUAL.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given AIRQUAL.S.F02(VeryPoor) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: AIRQUAL.S.F02 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given AIRQUAL.S.F03(ExtremelyPoor) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: AIRQUAL.S.F03 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_ALOGIN_1_12.yaml b/src/app/tests/suites/certification/Test_TC_ALOGIN_1_12.yaml deleted file mode 100644 index 25e6457fd786f9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ALOGIN_1_12.yaml +++ /dev/null @@ -1,93 +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: - 19.1.12. [TC-ALOGIN-1.12] Global attributes - Account Login Cluster (DUT as - Server) - -PICS: - - ALOGIN.S - -config: - nodeId: 0x12344321 - cluster: "Account Login" - endpoint: 3 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 2, 3] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_APBSC_1_10.yaml b/src/app/tests/suites/certification/Test_TC_APBSC_1_10.yaml deleted file mode 100644 index 44e11d6cb3b53e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_APBSC_1_10.yaml +++ /dev/null @@ -1,124 +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: - 19.1.10. [TC-APBSC-1.10] Global attributes - Application Basic Cluster (DUT - as Server) - -PICS: - - APBSC.S - -config: - nodeId: 0x12344321 - cluster: "Application Basic" - endpoint: 3 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [2, 4, 5, 6, 7, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(VendorName) in AttributeList" - PICS: APBSC.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 3c: TH reads the optional attribute(VendorID) in AttributeList" - PICS: APBSC.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 3d: TH reads the optional attribute(ProductID) in AttributeList" - PICS: APBSC.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_APPLAUNCHER_1_3.yaml b/src/app/tests/suites/certification/Test_TC_APPLAUNCHER_1_3.yaml deleted file mode 100644 index e7f3817a6a8084..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_APPLAUNCHER_1_3.yaml +++ /dev/null @@ -1,124 +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: - 19.1.3. [TC-APPLAUNCHER-1.3] Global attributes - Application Launcher - Cluster (DUT as Server) - -PICS: - - APPLAUNCHER.S - -config: - nodeId: 0x12344321 - cluster: "Application Launcher" - endpoint: 1 - -tests: - - label: "Step 0: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2a: TH reads the FeatureMap attribute from the DUT" - PICS: APPLAUNCHER.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 1 - constraints: - type: bitmap32 - - - label: "Step 2b: TH reads the FeatureMap attribute from the DUT" - PICS: " !APPLAUNCHER.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(CatalogList) in - AttributeList" - PICS: APPLAUNCHER.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 3c: TH reads the optional attribute(CurrentApp) in AttributeList" - PICS: APPLAUNCHER.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_APPOBSERVER_1_13.yaml b/src/app/tests/suites/certification/Test_TC_APPOBSERVER_1_13.yaml deleted file mode 100644 index 509b0232e88ec6..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_APPOBSERVER_1_13.yaml +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: - 19.1.13. [TC-APPOBSERVER-1.13] Global attributes - Content App Observer - Cluster (DUT as Server) - -PICS: - - APPOBSERVER.S - -config: - nodeId: 0x12344321 - cluster: "ContentAppObserver" - endpoint: 1 - -tests: - - label: "Step 0: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_AUDIOOUTPUT_1_8.yaml b/src/app/tests/suites/certification/Test_TC_AUDIOOUTPUT_1_8.yaml deleted file mode 100644 index 49d43cb8a23659..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_AUDIOOUTPUT_1_8.yaml +++ /dev/null @@ -1,103 +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: - 19.1.8. [TC-AUDIOOUTPUT-1.8] Global attributes - Audio Output Cluster(DUT as - Server) - -PICS: - - AUDIOOUTPUT.S - -config: - nodeId: 0x12344321 - cluster: "Audio Output" - endpoint: 1 - -tests: - - label: "Step 0: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2a: TH reads the FeatureMap attribute from the DUT" - PICS: AUDIOOUTPUT.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 2b: TTH reads the FeatureMap attribute from the DUT" - PICS: " !AUDIOOUTPUT.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_BIND_1_1.yaml b/src/app/tests/suites/certification/Test_TC_BIND_1_1.yaml deleted file mode 100644 index a6c7b0024ffea6..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_BIND_1_1.yaml +++ /dev/null @@ -1,91 +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: 116.1.1. [TC-BIND-1.1] Global Attributes with DUT as Server - -PICS: - - BIND.S - -config: - nodeId: 0x12344321 - cluster: "Binding" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads the FeatureMap from DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList attribute from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList attribute from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_BINFO_1_1.yaml b/src/app/tests/suites/certification/Test_TC_BINFO_1_1.yaml deleted file mode 100644 index 6a9c2eb23074b9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_BINFO_1_1.yaml +++ /dev/null @@ -1,257 +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: 12.1.1. [TC-BINFO-1.1] Global Attributes with DUT as Server - -PICS: - - BINFO.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: "Step 3: TH reads the FeatureMap from DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 19, - 65528, - 65529, - 65530, - 65531, - 65532, - 65533, - ] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 19, - 65528, - 65529, - 65531, - 65532, - 65533, - ] - - - label: - "Step 4b: TH reads optional attribute(ManufacturingDate) in - attributeList" - PICS: BINFO.S.A000b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11] - - - label: "Step 4c: TH reads optional attribute(PartNumber) in attributeList" - PICS: BINFO.S.A000c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [12] - - - label: "Step 4d: TH reads optional attribute(ProductURL) in attributeList" - PICS: BINFO.S.A000d - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [13] - - - label: - "Step 4e: TH reads optional attribute(ProductLabel) in attributeList" - PICS: BINFO.S.A000e - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [14] - - - label: - "Step 4f: TH reads optional attribute(SerialNumber) in attributeList" - PICS: BINFO.S.A000f - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [15] - - - label: - "Step 4g: TH reads optional attribute(LocalConfigDisabled) in - attributeList" - PICS: BINFO.S.A0010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16] - - - label: "Step 4h: TH reads optional attribute(Reachable) in attributeList" - PICS: BINFO.S.A0011 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17] - - - label: "Step 4i: TH reads optional attribute(UniqueID) in attributeList" - PICS: BINFO.S.A0012 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - - label: - "Step 4j: TH reads optional attribute(ProductAppearance) in - attributeList" - PICS: BINFO.S.A0014 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: - " !BINFO.S.E00 && !BINFO.S.E01 && !BINFO.S.E02 && !BINFO.S.A0011 && - PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 5b: TH reads BINFO.S.E00(StartUp) event in EventList" - PICS: BINFO.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5c: TH reads BINFO.S.E01(ShutDown) event in EventList" - PICS: BINFO.S.E01 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 5d: TH reads BINFO.S.E02(Leave) event in EventList" - PICS: BINFO.S.E02 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5e: TH reads (ReachableChanged) event in EventList" - PICS: BINFO.S.A0011 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_BOOLCFG_1_1.yaml b/src/app/tests/suites/certification/Test_TC_BOOLCFG_1_1.yaml deleted file mode 100644 index d8294f379d108a..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_BOOLCFG_1_1.yaml +++ /dev/null @@ -1,292 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 69.1.1. [TC-BOOLCFG-1.1] Global attributes with server as DUT - -PICS: - - BOOLCFG.S - -config: - nodeId: 0x12344321 - cluster: "Boolean State Configuration" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: Read the global attribute: FeatureMap" - command: "readAttribute" - attribute: "FeatureMap" - PICS: - ( !BOOLCFG.S.F00 && !BOOLCFG.S.F01 && !BOOLCFG.S.F02 && !BOOLCFG.S.F03 - ) - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given BOOLCFG.S.F00(VIS) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: BOOLCFG.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given BOOLCFG.S.F01(AUD) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: BOOLCFG.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given BOOLCFG.S.F02(SPRS) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: BOOLCFG.S.F02 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3d: Given BOOLCFG.S.F03(SENSLVL) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: BOOLCFG.S.F03 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: Read the feature dependent(BOOLCFG.S.F00) attribute in - AttributeList" - PICS: BOOLCFG.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3, 6] - - - label: - "Step 4c: Read the feature dependent(BOOLCFG.S.F00) optional attribute - in AttributeList" - PICS: BOOLCFG.S.F00 && BOOLCFG.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4d: Read the feature dependent(BOOLCFG.S.F01) attribute in - AttributeList" - PICS: BOOLCFG.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3, 6] - - - label: - "Step 4e: Read the feature dependent(BOOLCFG.S.F01) optional attribute - in AttributeList" - PICS: BOOLCFG.S.F01 && BOOLCFG.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4f: Read the feature dependent(BOOLCFG.S.F02) attribute in - AttributeList" - PICS: BOOLCFG.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4g: Read the feature dependent(BOOLCFG.S.F03) attribute in - AttributeList" - PICS: BOOLCFG.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1] - - - label: - "Step 4h: Read the feature dependent(BOOLCFG.S.F03) optional attribute - in AttributeList" - PICS: BOOLCFG.S.F03 && BOOLCFG.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4i: TH reads optional (SensorFault) attribute in AttributeList" - PICS: BOOLCFG.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: "Step 5a: Read the global attribute: EventList" - PICS: - PICS_EVENT_LIST_ENABLED && !BOOLCFG.S.F00 && !BOOLCFG.S.F01 && - !BOOLCFG.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 5b: Read the feature dependent(BOOLCFG.S.F00) - (AlarmsStateChanged) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && BOOLCFG.S.F00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 5c: Read the feature dependent(BOOLCFG.S.F01) - (AlarmsStateChanged) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && BOOLCFG.S.F01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5d: Read the optional (SensorFault) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && BOOLCFG.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6a: Read the global attribute: AcceptedCommandList" - PICS: ( !BOOLCFG.S.F00 && !BOOLCFG.S.F01 && !BOOLCFG.S.F02 ) - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6b: Read the feature dependent(BOOLCFG.S.F02) (SuppressAlarm) - command in AcceptedCommandList" - PICS: BOOLCFG.S.F02 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 6c: Read the feature dependent(BOOLCFG.S.F00) - (EnableDisableAlarm) command in AcceptedCommandList" - PICS: BOOLCFG.S.F00 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 6d: Read the feature dependent(BOOLCFG.S.F01) - (EnableDisableAlarm) command in AcceptedCommandList" - PICS: BOOLCFG.S.F01 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_BOOL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_BOOL_1_1.yaml deleted file mode 100644 index d9055041616007..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_BOOL_1_1.yaml +++ /dev/null @@ -1,102 +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: 68.1.1. [TC-BOOL-1.1] Global attributes with server as DUT - -PICS: - - BOOL.S - -config: - nodeId: 0x12344321 - cluster: "Boolean State" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute" - PICS: BOOL.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [0] - constraints: - type: list - - - label: "Step 5: TH reads from the DUT the EventList attribute" - PICS: " !BOOL.S.E00 && PICS_EVENT_LIST_ENABLED " - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_BRBINFO_1_1.yaml b/src/app/tests/suites/certification/Test_TC_BRBINFO_1_1.yaml deleted file mode 100644 index ef95ddd67bb3b9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_BRBINFO_1_1.yaml +++ /dev/null @@ -1,272 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: - 130.1.1. [TC-BRBINFO-1.1] Global Attributes for Bridged Device Basic - Information Cluster Cluster [DUT-Server] - -PICS: - - BRBINFO.S - -config: - nodeId: 0x12344321 - cluster: "Bridged Device Basic Information" - endpoint: 3 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - #Issue: https://github.com/project-chip/connectedhomeip/issues/30467 - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads the FeatureMap from DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: " !PICS_EVENT_LIST_ENABLED " - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: TH reads optional attribute(VendorName) in AttributeList" - PICS: BRBINFO.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 4c: TH reads optional attribute(VendorID) in AttributeList" - PICS: BRBINFO.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4d: TH reads optional attribute(ProductName) in AttributeList" - PICS: BRBINFO.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 4e: TH reads optional attribute(NodeLabel) in AttributeList" - PICS: BRBINFO.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4f: TH reads optional attribute(HardwareVersion) in - AttributeList" - PICS: BRBINFO.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4g: TH reads optional attribute(HardwareVersionString) in - AttributeList" - PICS: BRBINFO.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4h: TH reads optional attribute(SoftwareVersion) in - AttributeList" - PICS: BRBINFO.S.A0009 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9] - - - label: - "Step 4i: TH reads optional attribute(SoftwareVersionString) in - AttributeList" - PICS: BRBINFO.S.A000a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4j: TH reads optional attribute(ManufacturingDate) in - AttributeList" - PICS: BRBINFO.S.A000b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11] - - - label: "Step 4k: TH reads optional attribute(PartNumber) in AttributeList" - PICS: BRBINFO.S.A000c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [12] - - - label: "Step 4l: TH reads optional attribute(ProductURL) in AttributeList" - PICS: BRBINFO.S.A000d - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [13] - - - label: - "Step 4m: TH reads optional attribute(ProductLabel) in AttributeList" - PICS: BRBINFO.S.A000e - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [14] - - - label: - "Step 4n: TH reads optional attribute(SerialNumber) in AttributeList" - PICS: BRBINFO.S.A000f - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [15] - - - label: "Step 4o: TH reads optional attribute(UniqueID) in AttributeList" - PICS: BRBINFO.S.A0012 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - - label: - "Step 4p: TH reads optional attribute(ProductAppearance) in - AttributeList" - PICS: BRBINFO.S.A0014 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: "Step 5a: TH reads from the DUT the EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5b: TH reads optional event(StartUp) in EventList" - PICS: BRBINFO.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5c: TH reads optional attribute(ShutDown) in EventList" - PICS: BRBINFO.S.E01 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 5d TH reads optional attribute(Leave) in EventList" - PICS: BRBINFO.S.E02 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH1 reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_CADMIN_1_5.yaml b/src/app/tests/suites/certification/Test_TC_CADMIN_1_5.yaml index 83c3617ab23343..8efb3b86885c5e 100644 --- a/src/app/tests/suites/certification/Test_TC_CADMIN_1_5.yaml +++ b/src/app/tests/suites/certification/Test_TC_CADMIN_1_5.yaml @@ -186,7 +186,7 @@ tests: [1663841939.843550][13897:13897] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1663841939.843617][13897:13897] CHIP:DL: Inet Layer shutdown - [1663841939.843673][13897:13897] CHIP:DL: BLE shutdown + [1663841939.843673][13897:13897] CHIP:DL: BLE Layer shutdown [1663841939.843727][13897:13897] CHIP:DL: System Layer shutdown [1663841939.844009][13897:13897] CHIP:TOO: Run command failure: ../../examples/chip-tool/commands/pairing/PairingCommand.cpp:151: CHIP Error 0x00000003: Incorrect state cluster: "LogCommands" diff --git a/src/app/tests/suites/certification/Test_TC_CADMIN_1_7.yaml b/src/app/tests/suites/certification/Test_TC_CADMIN_1_7.yaml index b7518730e87f65..f684e6090415ca 100644 --- a/src/app/tests/suites/certification/Test_TC_CADMIN_1_7.yaml +++ b/src/app/tests/suites/certification/Test_TC_CADMIN_1_7.yaml @@ -102,7 +102,7 @@ tests: [1663841939.843550][13897:13897] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1663841939.843617][13897:13897] CHIP:DL: Inet Layer shutdown - [1663841939.843673][13897:13897] CHIP:DL: BLE shutdown + [1663841939.843673][13897:13897] CHIP:DL: BLE Layer shutdown [1663841939.843727][13897:13897] CHIP:DL: System Layer shutdown [1663841939.844009][13897:13897] CHIP:TOO: Run command failure: ../../examples/chip-tool/commands/pairing/PairingCommand.cpp:151: CHIP Error 0x00000003: Incorrect state disabled: true @@ -161,7 +161,7 @@ tests: [1665481996.786704][4913:4913] CHIP:DL: renamed tmp file to file (/tmp/chip_counters.ini) [1665481996.786930][4913:4913] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1665481996.786999][4913:4913] CHIP:DL: Inet Layer shutdown - [1665481996.787065][4913:4913] CHIP:DL: BLE shutdown + [1665481996.787065][4913:4913] CHIP:DL: BLE Layer shutdown [1665481996.787123][4913:4913] CHIP:DL: System Layer shutdown [1665481996.787363][4913:4913] CHIP:TOO: Run command failure: ../../commands/pairing/PairingCommand.cpp:164: CHIP Error 0x00000003: Incorrect state disabled: true @@ -284,7 +284,7 @@ tests: [1678796869.645576][648903:648903] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1678796869.645584][648903:648903] CHIP:DL: Inet Layer shutdown - [1678796869.645589][648903:648903] CHIP:DL: BLE shutdown + [1678796869.645589][648903:648903] CHIP:DL: BLE Layer shutdown [1678796869.645596][648903:648903] CHIP:DL: System Layer shutdown [1678796869.645693][648903:648903] CHIP:TOO: Run command failure: ../../commands/pairing/PairingCommand.cpp:215: CHIP Error 0x00000003: Incorrect state disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_CADMIN_1_8.yaml b/src/app/tests/suites/certification/Test_TC_CADMIN_1_8.yaml index 4f26a7153f362a..f0a45e9bd04248 100644 --- a/src/app/tests/suites/certification/Test_TC_CADMIN_1_8.yaml +++ b/src/app/tests/suites/certification/Test_TC_CADMIN_1_8.yaml @@ -100,7 +100,7 @@ tests: [1663842366.887733][13938:13938] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1663842366.887797][13938:13938] CHIP:DL: Inet Layer shutdown - [1663842366.887851][13938:13938] CHIP:DL: BLE shutdown + [1663842366.887851][13938:13938] CHIP:DL: BLE Layer shutdown [1663842366.887905][13938:13938] CHIP:DL: System Layer shutdown [1663842366.888154][13938:13938] CHIP:TOO: Run command failure: ../../examples/chip-tool/commands/common/CHIPCommand.cpp:454: CHIP Error 0x00000032: Timeout disabled: true @@ -154,7 +154,7 @@ tests: verify you got the following message in the TH_CR2(CHIP-TOOL) log [1700552012.724377][27528:27528] CHIP:DL: Inet Layer shutdown - [1700552012.724405][27528:27528] CHIP:DL: BLE shutdown + [1700552012.724405][27528:27528] CHIP:DL: BLE Layer shutdown [1700552012.724445][27528:27528] CHIP:DL: System Layer shutdown [1700552012.725294][27528:27528] CHIP:TOO: Run command failure: ../../examples/chip-tool/commands/common/CHIPCommand.cpp:589: CHIP Error 0x00000032: Timeout disabled: true @@ -276,7 +276,7 @@ tests: Verify you got the following message in the TH_CR3(Chip-tool) log [1700552012.724377][27528:27528] CHIP:DL: Inet Layer shutdown - [1700552012.724405][27528:27528] CHIP:DL: BLE shutdown + [1700552012.724405][27528:27528] CHIP:DL: BLE Layer shutdown [1700552012.724445][27528:27528] CHIP:DL: System Layer shutdown [1700552012.725294][27528:27528] CHIP:TOO: Run command failure: ../../examples/chip-tool/commands/common/CHIPCommand.cpp:589: CHIP Error 0x00000032: Timeout disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_CADMIN_1_9.yaml b/src/app/tests/suites/certification/Test_TC_CADMIN_1_9.yaml index a3d2de3641699e..5ee85f98a48a72 100644 --- a/src/app/tests/suites/certification/Test_TC_CADMIN_1_9.yaml +++ b/src/app/tests/suites/certification/Test_TC_CADMIN_1_9.yaml @@ -551,7 +551,7 @@ tests: [1665484807.015876][5399:5399] CHIP:DL: renamed tmp file to file (/tmp/chip_counters.ini) [1665484807.016042][5399:5399] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1665484807.016108][5399:5399] CHIP:DL: Inet Layer shutdown - [1665484807.016163][5399:5399] CHIP:DL: BLE shutdown + [1665484807.016163][5399:5399] CHIP:DL: BLE Layer shutdown [1665484807.016215][5399:5399] CHIP:DL: System Layer shutdown [1665484807.016460][5399:5399] CHIP:TOO: Run command failure: ../../commands/pairing/PairingCommand.cpp:164: CHIP Error 0x00000003: Incorrect state cluster: "LogCommands" @@ -589,7 +589,7 @@ tests: [1665484807.015876][5399:5399] CHIP:DL: renamed tmp file to file (/tmp/chip_counters.ini) [1665484807.016042][5399:5399] CHIP:DL: NVS set: chip-counters/total-operational-hours = 0 (0x0) [1665484807.016108][5399:5399] CHIP:DL: Inet Layer shutdown - [1665484807.016163][5399:5399] CHIP:DL: BLE shutdown + [1665484807.016163][5399:5399] CHIP:DL: BLE Layer shutdown [1665484807.016215][5399:5399] CHIP:DL: System Layer shutdown [1665484807.016460][5399:5399] CHIP:TOO: Run command failure: ../../commands/pairing/PairingCommand.cpp:164: CHIP Error 0x00000003: Incorrect state cluster: "LogCommands" diff --git a/src/app/tests/suites/certification/Test_TC_CC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_CC_1_1.yaml deleted file mode 100644 index b80e541799ba32..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CC_1_1.yaml +++ /dev/null @@ -1,850 +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: 25.1.1. [TC-CC-1.1] Global attributes with server as DUT - -PICS: - - CC.S - -config: - nodeId: 0x12344321 - cluster: "Color Control" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Step 2: TH reads from the DUT the (0xFFFD) ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 6 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the (0xFFFC) FeatureMap attribute" - PICS: ( !CC.S.F00 && !CC.S.F01 && !CC.S.F02 && !CC.S.F03 && !CC.S.F04 ) - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given CC.S.F00(HS) ensure featuremap has the correct bit set" - PICS: CC.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given CC.S.F01(EHue) ensure featuremap has the correct bit - set" - PICS: CC.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given CC.S.F02(CL) ensure featuremap has the correct bit set" - PICS: CC.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given CC.S.F03(XY) ensure featuremap has the correct bit set" - PICS: CC.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3f: Given CC.S.F04(CT) ensure featuremap has the correct bit set" - PICS: CC.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: - "Step 4a: TH reads from the DUT the (0xFFFB) AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 8, - 15, - 16, - 16385, - 16394, - 65528, - 65529, - 65530, - 65531, - 65532, - 65533, - ] - - - label: - "Step 4a: TH reads from the DUT the (0xFFFB) AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [8, 15, 16, 16385, 16394, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads feature dependent attribute (CurrentHue) in - AttributeList" - PICS: CC.S.F00 && CC.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 4c: TH reads feature dependent attribute (CurrentSaturation) in - AttributeList" - PICS: CC.S.F00 && CC.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 4d: TH reads the optional attribute(RemainingTime) in - AttributeList" - PICS: CC.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4e: TH reads feature dependent attribute (CurrentX) in - AttributeList" - PICS: CC.S.F03 && CC.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4f: TH reads feature dependent attribute (CurrentY) in - AttributeList" - PICS: CC.S.F03 && CC.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4g: TH reads the optional attribute(DriftCompensation) in - AttributeList" - PICS: CC.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4h: TH reads the optional attribute(CompensationText) in - AttributeList" - PICS: CC.S.A0006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4i: TH reads feature dependent attribute - (ColorTemperatureMireds) in AttributeList" - PICS: CC.S.F04 && CC.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: "Step 4j: TH reads the Primary1X attribute in AttributeList" - PICS: CC.S.A0011 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17] - - - label: "Step 4k: TH reads the Primary1Y attribute in AttributeList" - PICS: CC.S.A0012 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - - label: - "Step 4l: TH reads the Primary1Intensity attribute in AttributeList" - PICS: CC.S.A0013 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [19] - - - label: "Step 4m: TH reads the Primary2X attribute in AttributeList" - PICS: CC.S.A0015 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [21] - - - label: "Step 4n: TH reads the Primary2Y attribute in AttributeList" - PICS: CC.S.A0016 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [22] - - - label: - "Step 4o: TH reads the Primary2Intensity attribute in AttributeList" - PICS: CC.S.A0017 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [23] - - - label: "Step 4p: TH reads the Primary3X attribute in AttributeList" - PICS: CC.S.A0019 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [25] - - - label: "Step 4q: TH reads the Primary3Y attribute in AttributeList" - PICS: CC.S.A001a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [26] - - - label: - "Step 4r: TH reads the Primary3Intensity attribute in AttributeList" - PICS: CC.S.A001b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [27] - - - label: "Step 4s: TH reads the Primary4X attribute in AttributeList" - PICS: CC.S.A0020 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [32] - - - label: "Step 4t: TH reads the Primary4Y attribute in AttributeList" - PICS: CC.S.A0021 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [33] - - - label: - "Step 4u: TH reads the Primary4Intensity attribute in AttributeList" - PICS: CC.S.A0022 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [34] - - - label: "Step 4v: TH reads the Primary5X attribute in AttributeList" - PICS: CC.S.A0024 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [36] - - - label: "Step 4w: TH reads the Primary5Y attribute in AttributeList" - PICS: CC.S.A0025 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [37] - - - label: - "Step 4x: TH reads the Primary5Intensity attribute in AttributeList" - PICS: CC.S.A0026 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [38] - - - label: "Step 4y: TH reads the Primary6X attribute in AttributeList" - PICS: CC.S.A0028 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [40] - - - label: "Step 4z: TH reads the Primary6Y attribute in AttributeList" - PICS: CC.S.A0029 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [41] - - - label: - "Step 4a1: TH reads the Primary6Intensity attribute in AttributeList" - PICS: CC.S.A002a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [42] - - - label: - "Step 4a2: TH reads the optional attribute(WhitePointX) in - AttributeList" - PICS: CC.S.A0030 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [48] - - - label: - "Step 4a3: TH reads the optional attribute(WhitePointY) in - AttributeList" - PICS: CC.S.A0031 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [49] - - - label: - "Step 4a4: TH reads the optional attribute(ColorPointRX) in - AttributeList" - PICS: CC.S.A0032 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [50] - - - label: - "Step 4a5: TH reads the optional attribute(ColorPointRY) in - AttributeList" - PICS: CC.S.A0033 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [51] - - - label: - "Step 4a6: TH reads the optional attribute(ColorPointRIntensity) in - AttributeList" - PICS: CC.S.A0034 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [52] - - - label: - "Step 4a7: TH reads the optional attribute(ColorPointGX) in - AttributeList" - PICS: CC.S.A0036 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [54] - - - label: - "Step 4a8: TH reads the optional attribute(ColorPointGY) in - AttributeList" - PICS: CC.S.A0037 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [55] - - - label: - "Step 4a9: TH reads the optional attribute(ColorPointGIntensity) in - AttributeList" - PICS: CC.S.A0038 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [56] - - - label: - "Step 4a10: TH reads the optional attribute(ColorPointBX) in - AttributeList" - PICS: CC.S.A003a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [58] - - - label: - "Step 4a11: TH reads the optional attribute(ColorPointBY) in - AttributeList" - PICS: CC.S.A003b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [59] - - - label: - "Step 4a12: TH reads the optional attribute(ColorPointBIntensity) in - AttributeList" - PICS: CC.S.A003c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [60] - - - label: - "Step 4a13: TH reads feature dependent attribute (EnhancedCurrentHue) - in AttributeList" - PICS: CC.S.F01 && CC.S.A4000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16384] - - - label: - "Step 4a14: TH reads feature dependent attribute (ColorLoopActive) in - AttributeList" - PICS: CC.S.F02 && CC.S.A4002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16386] - - - label: - "Step 4a15: TH reads feature dependent attribute (ColorLoopDirection) - in AttributeList" - PICS: CC.S.F02 && CC.S.A4003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16387] - - - label: - "Step 4a16: TH reads feature dependent attribute (ColorLoopTime) in - AttributeList" - PICS: CC.S.F02 && CC.S.A4004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16388] - - - label: - "Step 4a17: TH reads feature dependent attribute - (ColorLoopStartEnhancedHue) in AttributeList" - PICS: CC.S.F02 && CC.S.A4005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16389] - - - label: - "Step 4a18: TH reads feature dependent attribute - (ColorLoopStoredEnhancedHue) in AttributeList" - PICS: CC.S.F02 && CC.S.A4006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16390] - - - label: - "Step 4a19: TH reads feature dependent attribute - (ColorTempPhysicalMinMireds) in AttributeList" - PICS: CC.S.F04 && CC.S.A400b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16395] - - - label: - "Step 4a20: TH reads feature dependent attribute - (ColorTempPhysicalMaxMireds) in AttributeList" - PICS: CC.S.F04 && CC.S.A400c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16396] - - - label: - "Step 4a21:TH reads feature dependent attribute - (CoupleColorTempToLevelMinMireds) in AttributeList" - PICS: CC.S.F04 && CC.S.A400d - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16397] - - - label: - "Step 4a22: TH reads feature dependent attribute - (StartUpColorTemperatureMireds) in AttributeList" - PICS: CC.S.F04 && CC.S.A4010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16400] - - - label: "Step 5: TH reads from the DUT the (0xFFFA) EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6a: TH reads feature dependent command(MoveToHue) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 6b: TH reads feature dependent command(MoveHue) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C01.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 6c: TH reads feature dependent command(StepHue) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C02.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 6d: TH reads feature dependent command(MoveToSaturation) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 6e: TH reads feature dependent command(MoveSaturation) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C04.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 6f: TH reads feature dependent command(StepSaturation) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C05.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 6g: TH reads feature dependent command(MoveToHueAndSaturation) - in AcceptedCommandList" - PICS: CC.S.F00 && CC.S.C06.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 6h: TH reads feature dependent command(MoveToColor) in - AcceptedCommandList" - PICS: CC.S.F03 && CC.S.C07.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 6i: TH reads feature dependent command(MoveColor) in - AcceptedCommandList" - PICS: CC.S.F03 && CC.S.C08.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 6j: TH reads feature dependent command(StepColor) in - AcceptedCommandList" - PICS: CC.S.F03 && CC.S.C09.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [9] - - - label: - "Step 6k: TH reads feature dependent command(MoveToColorTemperature) - in AcceptedCommandList" - PICS: CC.S.F04 && CC.S.C0a.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [10] - - - label: - "Step 6l: TH reads feature dependent command(EnhancedMoveToHue) in - AcceptedCommandList" - PICS: CC.S.F01 && CC.S.C40.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [64] - - - label: - "Step 6m: TH reads feature dependent command(EnhancedMoveHue) in - AcceptedCommandList" - PICS: CC.S.F01 && CC.S.C41.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [65] - - - label: - "Step 6n: TH reads feature dependent command(EnhancedStepHue) in - AcceptedCommandList" - PICS: CC.S.F01 && CC.S.C42.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [66] - - - label: - "Step 6o:TH reads feature dependent - command(EnhancedMoveToHueAndSaturation) in AcceptedCommandList" - PICS: CC.S.F01 && CC.S.C43.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [67] - - - label: - "Step 6p: TH reads feature dependent command(ColorLoopSet) in - AcceptedCommandList" - PICS: CC.S.F02 && CC.S.C44.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [68] - - - label: - "Step 6q: TH reads feature dependent command(StopMoveStep) in - AcceptedCommandList" - PICS: CC.S.F00 && CC.S.F03 && CC.S.F04 && CC.S.C47.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [71] - - - label: - "Step 6r: TH reads feature dependent command(StopMoveStep) in - AcceptedCommandList" - PICS: CC.S.F04 && CC.S.C4b.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [75] - - - label: - "Step 6s: TH reads feature dependent command(StepColorTemperature) in - AcceptedCommandList" - PICS: CC.S.F04 && CC.S.C4c.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [76] - - - label: - "Step 7: TH reads from the DUT the (0xFFF8) GeneratedCommandList - attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_CGEN_1_1.yaml b/src/app/tests/suites/certification/Test_TC_CGEN_1_1.yaml deleted file mode 100644 index 983b77c6b33a4f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CGEN_1_1.yaml +++ /dev/null @@ -1,92 +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: 90.1. [TC-CGEN-1.1] Global Attributes [DUT-Server] - -PICS: - - CGEN.S - -config: - nodeId: 0x12344321 - cluster: "General Commissioning" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: Read the global attribute: FeatureMap" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 2, 3, 4, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 2, 4] - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1, 3, 5] diff --git a/src/app/tests/suites/certification/Test_TC_CHANNEL_1_6.yaml b/src/app/tests/suites/certification/Test_TC_CHANNEL_1_6.yaml deleted file mode 100644 index fb0379c14734f2..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CHANNEL_1_6.yaml +++ /dev/null @@ -1,178 +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: - 19.1.6. [TC-CHANNEL-1.6] Global attributes - Channel Cluster (DUT as Server) - -PICS: - - CHANNEL.S - -config: - nodeId: 0x12344321 - cluster: "Channel" - endpoint: 1 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 2a: Read the global attribute: FeatureMap" - PICS: ( !CHANNEL.S.F00 && !CHANNEL.S.F01 ) - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 2b: Given CCHANNEL.S.F00(CL) ensure featuremap has the correct - bit set" - PICS: CHANNEL.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 2c: Given CHANNEL.S.F01(LI) ensure featuremap has the correct - bit set" - PICS: CHANNEL.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 3a: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: "Step 3b: Read the optional attribute(ChannelList): AttributeList" - PICS: CHANNEL.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 3c: Reading optional attribute(Lineup) in AttributeList" - PICS: CHANNEL.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 3d: Read the optional attribute(CurrentChannel): AttributeList" - PICS: CHANNEL.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4a: Read the optional command(ChangeChannel) in - AcceptedCommandList" - PICS: CHANNEL.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 4b: Read the optional command(ChangeChannelByNumber) in - AcceptedCommandList" - PICS: CHANNEL.S.C02.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4c: Read the optional command(SkipChannel) in - AcceptedCommandList" - PICS: CHANNEL.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5a: Read the global attribute: GeneratedCommandList" - PICS: ( !CHANNEL.S.F00 && !CHANNEL.S.F01 ) - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 5b: Read the global attribute: GeneratedCommandList" - PICS: CHANNEL.S.F00 || CHANNEL.S.F01 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_CONCON_1_14.yaml b/src/app/tests/suites/certification/Test_TC_CONCON_1_14.yaml deleted file mode 100644 index 1b9c2215d3e0ce..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CONCON_1_14.yaml +++ /dev/null @@ -1,149 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: - 19.1.14. [TC-CONCON-1.14] Global attributes - Content Control Cluster (DUT - as Server) - -PICS: - - CONCON.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - verification: | - ./chip-tool contentcontrol read cluster-revision 1 1 - - [1704869094.517260][4293:4295] CHIP:DMG: } - [1704869094.517545][4293:4295] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_050F Attribute 0x0000_FFFD DataVersion: 1251967611 - [1704869094.517631][4293:4295] CHIP:TOO: ClusterRevision: 1 - [1704869094.518028][4293:4295] CHIP:EM: <<< [E:20721i S:28265 M:144462024 (Ack:200262914)] (S) Msg TX to 1:0000000000000001 [EF1D] [UDP:[fe80::e65f:1ff:fe49:ae1b%wlan0]:5640] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1704869094.518235][4293:4295] CHIP:EM: Flushed pending ack for MessageCounter:200262914 on exchange 20721i - disabled: true - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - - verification: | - ./chip-tool contentcontrol read feature-map 1 1 - - [1704869124.605470][4296:4298] CHIP:DMG: InteractionModelRevision = 11 - [1704869124.605531][4296:4298] CHIP:DMG: } - [1704869124.605872][4296:4298] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_050F Attribute 0x0000_FFFC DataVersion: 1251967611 - [1704869124.605970][4296:4298] CHIP:TOO: FeatureMap: 0 - [1704869124.606460][4296:4298] CHIP:EM: <<< [E:55393i S:13705 M:14084931 (Ack:173736992)] (S) Msg TX to 1:0000000000000001 [EF1D] [UDP:[fe80::e65f:1ff:fe49:ae1b%wlan0]:5640] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1704869124.606702][4296:4298] CHIP:EM: Flushed pending ack for MessageCounter:173736992 on exchange 55393i - [1704869124.607077][4296:4296] CHIP:CTL: Shutting down the commissioner - disabled: true - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - verification: | - ./chip-tool contentcontrol read attribute-list 1 1 - - [1704869156.246646][4299:4301] CHIP:DMG: InteractionModelRevision = 11 - [1704869156.246689][4299:4301] CHIP:DMG: } - [1704869156.247013][4299:4301] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_050F Attribute 0x0000_FFFB DataVersion: 1251967611 - [1704869156.248939][4299:4301] CHIP:TOO: AttributeList: 13 entries - [1704869156.248979][4299:4301] CHIP:TOO: [1]: 0 - [1704869156.249005][4299:4301] CHIP:TOO: [2]: 1 - [1704869156.249031][4299:4301] CHIP:TOO: [3]: 2 - [1704869156.249055][4299:4301] CHIP:TOO: [4]: 3 - [1704869156.249080][4299:4301] CHIP:TOO: [5]: 4 - [1704869156.249105][4299:4301] CHIP:TOO: [6]: 5 - [1704869156.249130][4299:4301] CHIP:TOO: [7]: 6 - [1704869156.249154][4299:4301] CHIP:TOO: [8]: 7 - [1704869156.249180][4299:4301] CHIP:TOO: [9]: 65528 - [1704869156.249204][4299:4301] CHIP:TOO: [10]: 65529 - [1704869156.249229][4299:4301] CHIP:TOO: [11]: 65531 - [1704869156.249254][4299:4301] CHIP:TOO: [12]: 65532 - [1704869156.249279][4299:4301] CHIP:TOO: [13]: 65533 - [1704869156.249630][4299:4301] CHIP:EM: <<< [E:14371i S:6146 M:117952128 (Ack:180483729)] (S) Msg TX to 1:0000000000000001 [EF1D] [UDP:[fe80::e65f:1ff:fe49:ae1b%wlan0]:5640] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1704869156.249770][4299:4301] CHIP:EM: Flushed pending ack for MessageCounter:180483729 on exchange 14371i - disabled: true - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - verification: | - ./chip-tool contentcontrol read accepted-command-list 1 1 - [1704869442.419331][4306:4308] CHIP:DMG: SuppressResponse = true, - [1704869442.419358][4306:4308] CHIP:DMG: InteractionModelRevision = 11 - [1704869442.419382][4306:4308] CHIP:DMG: } - [1704869442.419678][4306:4308] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_050F Attribute 0x0000_FFF9 DataVersion: 1251967611 - [1704869442.419774][4306:4308] CHIP:TOO: AcceptedCommandList: 10 entries - [1704869442.419808][4306:4308] CHIP:TOO: [1]: 0 - [1704869442.419835][4306:4308] CHIP:TOO: [2]: 1 - [1704869442.419860][4306:4308] CHIP:TOO: [3]: 3 - [1704869442.419885][4306:4308] CHIP:TOO: [4]: 4 - [1704869442.419909][4306:4308] CHIP:TOO: [5]: 5 - [1704869442.419933][4306:4308] CHIP:TOO: [6]: 6 - [1704869442.419958][4306:4308] CHIP:TOO: [7]: 7 - [1704869442.419982][4306:4308] CHIP:TOO: [8]: 8 - [1704869442.420006][4306:4308] CHIP:TOO: [9]: 9 - [1704869442.420031][4306:4308] CHIP:TOO: [10]: 10 - [1704869442.420310][4306:4308] CHIP:EM: <<< [E:22515i S:37055 M:163291838 (Ack:95370016)] (S) Msg TX to 1:0000000000000001 [EF1D] [UDP:[fe80::e65f:1ff:fe49:ae1a%wlan0]:5640] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1704869442.420470][4306:4308] CHIP:EM: Flushed pending ack for MessageCounter:95370016 on exchange 22515i - disabled: true - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - verification: | - ./chip-tool contentcontrol read generated-command-list 1 1 - - [1704869486.142562][4311:4313] CHIP:DMG: SuppressResponse = true, - [1704869486.142591][4311:4313] CHIP:DMG: InteractionModelRevision = 11 - [1704869486.142617][4311:4313] CHIP:DMG: } - [1704869486.142837][4311:4313] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_050F Attribute 0x0000_FFF8 DataVersion: 1251967611 - [1704869486.142903][4311:4313] CHIP:TOO: GeneratedCommandList: 1 entries - [1704869486.142938][4311:4313] CHIP:TOO: [1]: 2 - [1704869486.143197][4311:4313] CHIP:EM: <<< [E:58684i S:20913 M:112498974 (Ack:84853992)] (S) Msg TX to 1:0000000000000001 [EF1D] [UDP:[fe80::e65f:1ff:fe49:ae1a%wlan0]:5640] --- Type 0000:10 (SecureChannel:StandaloneAck) - disabled: true - - - label: "Step 6: TH reads the EventList attribute from the DUT" - verification: | - ./chip-tool contentcontrol read event-list 1 1 - - [1704869518.133231][4314:4316] CHIP:EM: Rxd Ack; Removing MessageCounter:245792542 from Retrans Table on exchange 18480i - [1704869518.133334][4314:4316] CHIP:DMG: ReportDataMessage = - [1704869518.133370][4314:4316] CHIP:DMG: { - [1704869518.133398][4314:4316] CHIP:DMG: AttributeReportIBs = - [1704869518.133440][4314:4316] CHIP:DMG: [ - [1704869518.133472][4314:4316] CHIP:DMG: AttributeReportIB = - [1704869518.133515][4314:4316] CHIP:DMG: { - [1704869518.133549][4314:4316] CHIP:DMG: AttributeStatusIB = - [1704869518.133594][4314:4316] CHIP:DMG: { - [1704869518.133631][4314:4316] CHIP:DMG: AttributePathIB = - [1704869518.133674][4314:4316] CHIP:DMG: { - [1704869518.133720][4314:4316] CHIP:DMG: Endpoint = 0x1, - [1704869518.133764][4314:4316] CHIP:DMG: Cluster = 0x50f, - [1704869518.133809][4314:4316] CHIP:DMG: Attribute = 0x0000_FFFA, - [1704869518.133850][4314:4316] CHIP:DMG: } - [1704869518.133946][4314:4316] CHIP:DMG: - [1704869518.133988][4314:4316] CHIP:DMG: StatusIB = - [1704869518.134031][4314:4316] CHIP:DMG: { - [1704869518.134072][4314:4316] CHIP:DMG: status = 0x86 (UNSUPPORTED_ATTRIBUTE), - [1704869518.134144][4314:4316] CHIP:DMG: }, - [1704869518.134189][4314:4316] CHIP:DMG: - [1704869518.134226][4314:4316] CHIP:DMG: }, - [1704869518.134268][4314:4316] CHIP:DMG: - [1704869518.134324][4314:4316] CHIP:DMG: }, - [1704869518.134368][4314:4316] CHIP:DMG: - [1704869518.134398][4314:4316] CHIP:DMG: ], - [1704869518.134438][4314:4316] CHIP:DMG: - [1704869518.134469][4314:4316] CHIP:DMG: SuppressResponse = true, - [1704869518.134501][4314:4316] CHIP:DMG: InteractionModelRevision = 11 - [1704869518.134531][4314:4316] CHIP:DMG: } - [1704869518.134726][4314:4316] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1704869518.135007][4314:4316] CHIP:EM: <<< [E:18480i S:40415 M:245792543 (Ack:116804273)] (S) Msg TX to 1:0000000000000001 [EF1D] [UDP:[fe80::e65f:1ff:fe49:ae1a%wlan0]:5640] --- Type 0000:10 (SecureChannel:StandaloneAck) - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_1_11.yaml b/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_1_11.yaml deleted file mode 100644 index a30b8ce2df79e2..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_1_11.yaml +++ /dev/null @@ -1,151 +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: - 19.1.11. [TC-CONTENTLAUNCHER-1.11] Global attributes - Content Launcher - Cluster (DUT as Server) - -PICS: - - CONTENTLAUNCHER.S - -config: - nodeId: 0x12344321 - cluster: "Content Launcher" - endpoint: 1 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 2a: TH reads the FeatureMap attribute from the DUT" - PICS: ( !CONTENTLAUNCHER.S.F00 && !CONTENTLAUNCHER.S.F01 ) - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 2b: Given CONTENTLAUNCHER.S.F00 (CS) ensure featuremap has the - correct bit set" - PICS: CONTENTLAUNCHER.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 2c: Given CONTENTLAUNCHER.S.F01(UP) ensure featuremap has the - correct bit set" - PICS: CONTENTLAUNCHER.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(AcceptHeader): AttributeList" - PICS: CONTENTLAUNCHER.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 3c: TH reads the optional - attribute(SupportedStreamingProtocols): AttributeList" - PICS: CONTENTLAUNCHER.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 4a: TH reads the optional command(LaunchContent) in - AcceptedCommandList attribute" - PICS: CONTENTLAUNCHER.C.C00.Tx - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 4b: TH reads the optional command(LaunchURL) in - AcceptedCommandList attribute" - PICS: CONTENTLAUNCHER.C.C01.Tx - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DEMM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DEMM_1_1.yaml deleted file mode 100644 index b2f927d14fd554..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DEMM_1_1.yaml +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 241.1.1. [TC-DEMM-1.1] Global attributes with DUT as Server - -PICS: - - DEMM.S - -config: - nodeId: 0x12344321 - cluster: "Device Energy Management Mode" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - #https://github.com/project-chip/connectedhomeip/issues/31599 - - label: "Step 3: TH reads from the DUT the FeatureMap attribute" - verification: | - ./chip-tool deviceenergymanagementmode read feature-map 1 1 - - On the TH(Chip-tool) Log, Verify featureMap value is 0 and below is the sample log provided for the raspi platform: - - [1707803263.396282][12695:12697] CHIP:DMG: } - [1707803263.396447][12695:12697] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_009F Attribute 0x0000_FFFC DataVersion: 3404644350 - [1707803263.396492][12695:12697] CHIP:TOO: FeatureMap: 0 - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute (StartUpMode) in AttributeList - from DUT" - PICS: DEMM.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [0] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [1] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DESC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DESC_1_1.yaml deleted file mode 100644 index cb6ce46a174404..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DESC_1_1.yaml +++ /dev/null @@ -1,114 +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: 84.1.1. [TC-DESC-1.1] Global Attributes with DUT as Server - -PICS: - - DESC.S - -config: - nodeId: 0x12344321 - cluster: "Descriptor" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: "!DESC.S.F00" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3: TH reads from the DUT the FeatureMap attribute. 0x0001: SHALL - be included if and only if DESC.S.F00(TagList)" - PICS: DESC.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads from the DUT the AttributeList attribute. 0x0004: - SHALL be included if and only if DESC.S.F00" - PICS: DESC.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList attribute from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList attribute from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DGETH_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DGETH_1_1.yaml deleted file mode 100644 index 4c101adf4a3de8..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DGETH_1_1.yaml +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 47.1.1. [TC-DGETH-1.1] Global Attributes with DUT as Server - -PICS: - - DGETH.S - -config: - nodeId: 0x12344321 - cluster: "Ethernet Network Diagnostics" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads the FeatureMap from DUT" - PICS: " !DGETH.S.F00 && !DGETH.S.F01" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given DGETH.S.F00 ensure featuremap has the correct bit set" - PICS: DGETH.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given DGETH.S.F01 ensure featuremap has the correct bit set" - PICS: DGETH.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: TH reads optional attribute(PHYRate) in AttributeList" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 4c: TH reads optional attribute(FullDuplex) in AttributeList" - PICS: DGETH.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 4d: TH reads optional attribute(PacketRxCount) and Feature - dependent(DGETH.S.F00(PKTCNT)) in AttributeList" - PICS: DGETH.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4e: TH reads optional attribute(PacketRxCount) and Feature - dependent(DGETH.S.F00(PKTCNT)) in AttributeList" - PICS: DGETH.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4f: TH reads optional attribute(PacketRxCount) and Feature - dependent(DGETH.S.F01(ERRCNT)) in AttributeList" - PICS: DGETH.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4g: TH reads optional attribute(PacketRxCount) and Feature - dependent(DGETH.S.F01(ERRCNT)) in AttributeList" - PICS: DGETH.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4h: TH reads optional attribute(PacketRxCount) and Feature - dependent(DGETH.S.F01(ERRCNT)) in AttributeList" - PICS: DGETH.S.A0006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4i: TH reads optional attribute(CarrierDetect) in AttributeList" - PICS: DGETH.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4j: TH reads optional attribute(TimeSinceReset) in AttributeList" - PICS: DGETH.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: "Step 5: TH reads EventList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - PICS: ( DGETH.S.F00 || DGETH.S.F01 ) - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - PICS: " !DGETH.S.F00 && !DGETH.S.F01 " - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DGGEN_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DGGEN_1_1.yaml deleted file mode 100644 index 6641fcf879939c..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DGGEN_1_1.yaml +++ /dev/null @@ -1,193 +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: 88.1.1. [TC-DGGEN-1.1] Global Attributes with DUT as Server - -PICS: - - DGGEN.S - -config: - nodeId: 0x12344321 - cluster: "General Diagnostics" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: "!DGGEN.S.F00" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: DGGEN.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 1 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 8, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 8, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: Validate presence of mandatory attribute(UpTime) in - AttributeList" - PICS: DGGEN.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4c: TH reads optional attribute(TotalOperationalHours) in - AttributeList" - PICS: DGGEN.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 4d: TH reads optional attribute(BootReason) in AttributeList" - PICS: DGGEN.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4e: TH reads optional attribute(ActiveHardwareFaults) in - AttributeList" - PICS: DGGEN.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4f: TH reads optional attribute(ActiveRadioFaults) in - AttributeList" - PICS: DGGEN.S.A0006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4g: TH reads optional attribute(ActiveNetworkFaults) in - AttributeList" - PICS: DGGEN.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: "Step 5a: TH reads from the DUT the EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 5b: TH reads optional event(HardwareFaultChange) in EventList" - PICS: DGGEN.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5c: TH reads optional event(RadioFaultChange) in EventList" - PICS: DGGEN.S.E01 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 5d: TH reads optional event(NetworkFaultChange) in EventList" - PICS: DGGEN.S.E02 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [2] diff --git a/src/app/tests/suites/certification/Test_TC_DGSW_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DGSW_1_1.yaml deleted file mode 100644 index 0b516f079ca053..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DGSW_1_1.yaml +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 44.1.1. [TC-DGSW-1.1] Global Attributes with DUT as Server - -PICS: - - DGSW.S - -config: - nodeId: 0x12344321 - cluster: "Software Diagnostics" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads the FeatureMap from DUT" - PICS: " !DGSW.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given DGSW.S.F00(Watermarks) ensure featuremap has the - correct bit set" - PICS: DGSW.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute(ThreadMetrics) in AttributeList" - PICS: DGSW.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 4c: TH reads optional attribute(CurrentHeapFree) in - AttributeList" - PICS: DGSW.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 4d: TH reads optional attribute(CurrentHeapUsed) in - AttributeList" - PICS: DGSW.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4e: TH reads Feature dependent - attribute(CurrentHeapHighWatermark) in AttributeList" - PICS: ( DGSW.S.F00 || DGSW.S.A0003 ) - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: DGSW.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5b: TH reads EventList from DUT" - PICS: " !DGSW.S.E00 && PICS_EVENT_LIST_ENABLED " - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - PICS: DGSW.S.F00 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - PICS: " !DGSW.S.F00 " - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DGTHREAD_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DGTHREAD_1_1.yaml deleted file mode 100644 index d1c6cd1b889987..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DGTHREAD_1_1.yaml +++ /dev/null @@ -1,318 +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: 50.1.1. [TC-DGTHREAD-1.1] Global Attributes [DUT-Server] - -PICS: - - DGTHREAD.S - -config: - nodeId: 0x12344321 - cluster: "Thread Network Diagnostics" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3a: TH reads the FeatureMap from DUT" - PICS: - " !DGTHREAD.S.F00 && !DGTHREAD.S.F01 && !DGTHREAD.S.F02 && - !DGTHREAD.S.F03 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given DGTHREAD.S.F00(PKTCNT) ensure featuremap has the - correct bit set" - PICS: DGTHREAD.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given DGTHREAD.S.F01(ERRCNT) ensure featuremap has the - correct bit set" - PICS: DGTHREAD.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given DGTHREAD.S.F02(MLECNT) ensure featuremap has the - correct bit set" - PICS: DGTHREAD.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given DGTHREAD.S.F03(MACCNT) ensure featuremap has the - correct bit set" - PICS: DGTHREAD.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: "Step 4a: TH reads mandatory attributes in AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 3, - 4, - 5, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 59, - 60, - 61, - 62, - 65528, - 65529, - 65530, - 65531, - 65532, - 65533, - ] - - - label: "Step 4a: TH reads mandatory attributes in AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 3, - 4, - 5, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 59, - 60, - 61, - 62, - 65528, - 65529, - 65531, - 65532, - 65533, - ] - - - label: - "Step 4b: TH reads Feature dependent attribute(DGTHREAD.S.F01(ERRCNT)) - in attributeList" - PICS: DGTHREAD.S.A0006 && DGTHREAD.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4c: TH reads Feature dependent attribute - (DGTHREAD.S.F02(MLECNT)) in attributeList" - PICS: DGTHREAD.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [14, 15, 16, 17, 18, 19, 20, 21] - - - label: - "Step 4d: TH reads Feature dependent attribute - (DGTHREAD.S.F03(MACCNT)) in attributeList" - PICS: DGTHREAD.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - ] - - - label: - "Step 4e: TH reads the optional attribute (ActiveTimestamp) in - AttributeList" - PICS: DGTHREAD.S.A0038 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [56] - - - label: - "Step 4f: TH reads the optional attribute (PendingTimestamp) in - AttributeList" - PICS: DGTHREAD.S.A0039 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [57] - - - label: "Step 4g: TH reads the optional attribute (Delay) in AttributeList" - PICS: DGTHREAD.S.A003a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [58] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: " !DGTHREAD.S.E00 && !DGTHREAD.S.E01 && PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 5b: TH reads DGTHREAD.S.E00(ConnectionStatus) event in EventList" - PICS: DGTHREAD.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 5c: TH reads DGTHREAD.S.E01(NetworkFaultChange) event in - EventList" - PICS: DGTHREAD.S.E01 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - PICS: " !DGTHREAD.S.F01 " - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - PICS: DGTHREAD.S.F01 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DGWIFI_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DGWIFI_1_1.yaml deleted file mode 100644 index 8ac9fd1a0afd2e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DGWIFI_1_1.yaml +++ /dev/null @@ -1,195 +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: 53.1.1. [TC-DGWIFI-1.1] Global Attributes [DUT as Server] - -PICS: - - DGWIFI.S - -config: - nodeId: 0x12344321 - cluster: "WiFi Network Diagnostics" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads the FeatureMap from DUT" - PICS: ( !DGWIFI.S.F00 && !DGWIFI.S.F01 ) - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given DGWIFI.S.F00(PacketCounts) ensure featuremap has the - correct bit set" - PICS: DGWIFI.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given DGWIFI.S.F01(ErrorCounts) ensure featuremap has the - correct bit set" - PICS: DGWIFI.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 2, 3, 4, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads Feature dependent(DGWIFI.S.F00) attributes in - attributeList from DUT" - PICS: DGWIFI.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6, 7, 8, 9, 10] - - - label: - "Step 4c: TH reads Feature dependent(DGWIFI.S.F01) attributes in - attributeList from DUT" - PICS: DGWIFI.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5, 12] - - - label: - "Step 4d: TH reads optional attribute (CurrentMaxRate) in - AttributeList from DUT" - PICS: DGWIFI.S.A000b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: - " !DGWIFI.S.E00 && !DGWIFI.S.E01 && !DGWIFI.S.E02 && - PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 5b: TH reads optional attribute (Disconnection) in EventList - from DUT" - PICS: DGWIFI.S.E00 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 5c: TH reads optional attribute (AssociationFailure) in - EventList from DUT" - PICS: DGWIFI.S.E01 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 5d: TH reads optional attribute (ConnectionStatus) in EventList - from DUT" - PICS: DGWIFI.S.E02 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 6a: TH reads AcceptedCommandList from DUT" - PICS: " !DGWIFI.S.F01 " - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6b: TH reads Feature dependent(DGWIFI.S.F01) command in - AcceptedCommandList from DUT" - PICS: DGWIFI.S.F01 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DISHALM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DISHALM_1_1.yaml deleted file mode 100644 index c18c6fc6254636..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DISHALM_1_1.yaml +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 198.1.1. [TC-DISHALM-1.1] Global attributes with DUT as Server - -PICS: - - DISHALM.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Note" - verification: | - Step 5 is currently not supported and SHALL be skipped. - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - verification: | - ./chip-tool dishwasheralarm read cluster-revision 1 1 - Verify the "ClusterRevision" value is of unit16 and reflects the highest revision number 1 on the TH(Chip-tool) and below is the sample log provided for the raspi platform: - - [1688447208.697823][4176:4178] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_005D Attribute 0x0000_FFFD DataVersion: 1386394810 - [1688447208.701428][4176:4178] CHIP:TOO: ClusterRevision: 1 - [1688447208.701860][4176:4178] CHIP:EM: <<< [E:62008i S:18101 M:251225540 (Ack:117573954)] (S) Msg TX to 1:0000000000000001 [5AF3] --- Type 0000:10 (SecureChannel:StandaloneAck) - disabled: true - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - verification: | - ./chip-tool dishwasheralarm read feature-map 1 1 - On TH(chip-tool), verify that DUT responds the Featuremap value as 1 and below is the sample log provided for the raspi platform: - - [1689841072.440418][2534:2536] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_005D Attribute 0x0000_FFFC DataVersion: 3155962179 - [1689841072.440498][2534:2536] CHIP:TOO: FeatureMap: 1 - [1689841072.440655][2534:2536] CHIP:EM: <<< [E:51712i S:9959 M:43369330 (Ack:105494463)] (S) Msg TX to 1:0000000000000001 [C4B0] --- Type 0000:10 (SecureChannel:StandaloneAck) - disabled: true - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - verification: | - ./chip-tool dishwasheralarm read attribute-list 1 1 - Verify " AttributeList " value consists the list of mandatory attributes (0, 2, 3, 65533, 65532, 65531, 65529, 65528) and optional attributes(1) on the TH(Chip-tool) Log: - Below is the sample log provided for the raspi platform: - [1692613019.157928][10524:10526] CHIP:DMG: } - [1692613019.158276][10524:10526] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_005D Attribute 0x0000_FFFB DataVersion: 2220437053 - [1692613019.158381][10524:10526] CHIP:TOO: AttributeList: 9 entries - [1692613019.158441][10524:10526] CHIP:TOO: [1]: 0 - [1692613019.158479][10524:10526] CHIP:TOO: [2]: 1 - [1692613019.158517][10524:10526] CHIP:TOO: [3]: 2 - [1692613019.158551][10524:10526] CHIP:TOO: [4]: 3 - [1692613019.158587][10524:10526] CHIP:TOO: [5]: 65528 - [1692613019.158622][10524:10526] CHIP:TOO: [6]: 65529 - [1692613019.158657][10524:10526] CHIP:TOO: [7]: 65531 - [1692613019.158692][10524:10526] CHIP:TOO: [8]: 65532 - [1692613019.158727][10524:10526] CHIP:TOO: [9]: 65533 - [1692613019.158909][10524:10526] CHIP:EM: <<< [E:17897i S:25614 M:15345399 (Ack:182319742)] (S) Msg TX to 1:0000000000000001 [5213] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1692613019.158968][10524:10526] CHIP:IN: (S) Sending msg 15345399 on secure session with LSID: 25614 - disabled: true - - - label: "Step 5: TH reads from the DUT the EventList attribute." - verification: | - ./chip-tool dishwasheralarm read event-list 1 1 - Verify " EventList attribute " consists the list may contain optional events(1) on the TH(Chip-tool) Log: - Below is the sample log provided for the raspi platform: - - [1689677416.105596][18367:18369] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_005D Attribute 0x0000_FFFA DataVersion: 1517282962 - [1689677416.105625][18367:18369] CHIP:TOO: EventList: 1 entries - [1689677416.105635][18367:18369] CHIP:TOO: [1]: 0 - [1689677416.105696][18367:18369] CHIP:EM: <<< [E:51484i S:36714 M:192916227 (Ack:1705890)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689677416.105710][18367:18369] CHIP:IN: (S) Sending msg 192916227 on secure session with LSID: 36714 - [1689677416.105737][18367:18369] CHIP:EM: Flushed pending ack for MessageCounter:1705890 on exchange 51484i - disabled: true - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - verification: | - ./chip-tool dishwasheralarm read accepted-command-list 1 1 - Verify " AcceptedCommandList " consists the list of supported events, which for this cluster should be an empty list on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - - [1689841406.078608][2570:2572] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_005D Attribute 0x0000_FFF9 DataVersion: 3155962179 - [1689841406.078674][2570:2572] CHIP:TOO: AcceptedCommandList: 2 entries - [1689841406.078701][2570:2572] CHIP:TOO: [1]: 0 - [1689841406.078724][2570:2572] CHIP:TOO: [2]: 1 - [1689841406.078870][2570:2572] CHIP:EM: <<< [E:3182i S:59744 M:116852840 (Ack:196212236)] (S) Msg TX to 1:0000000000000001 [C4B0] --- Type 0000:10 (SecureChannel:StandaloneAck) - disabled: true - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - verification: | - ./chip-tool dishwasheralarm read generated-command-list 1 1 - Verify " GeneratedCommandList " consists the list of supported events, which for this cluster should be an empty list on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - - [1688447564.178537][4220:4222] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0057 Attribute 0x0000_FFF8 DataVersion: 1795162772 - [1688447564.178684][4220:4222] CHIP:TOO: GeneratedCommandList: 0 entries - [1688447564.178984][4220:4222] CHIP:EM: <<< [E:5540i S:25125 M:256711779 (Ack:197472718)] (S) Msg TX to 1:0000000000000001 [10DB] --- Type 0000:10 (SecureChannel:StandaloneAck) - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DISHM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DISHM_1_1.yaml deleted file mode 100644 index da8a0924274e9e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DISHM_1_1.yaml +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 263.1.1. [TC-DISHM-1.1] Global attributes with DUT as Server - -PICS: - - DISHM.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - verification: | - ./chip-tool dishwashermode read cluster-revision 1 1 - - Verify the "ClusterRevision" value is of unit16 and reflects the highest revision number 2 on the TH(Chip-tool) and below is the sample log provided for the raspi platform: - - CHIP:DMG : } - CHIP:TOO : Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_FFFD DataVersion: 2488070594 - CHIP:TOO : ClusterRevision: 2 - disabled: true - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - verification: | - ./chip-tool dishwashermode read feature-map 1 1 - - On the TH(Chip-tool) Log, Verify featureMap value is 0 and below is the sample log provided for the raspi platform: - - [1690365613.351850][27441:27443] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_FFFC DataVersion: 1130015440 - [1690365613.351911][27441:27443] CHIP:TOO: FeatureMap: 1 - disabled: true - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - verification: | - ./chip-tool dishwashermode read attribute-list 1 1 - - Verify the "AttributeList " should include the mandatory attributes (values 0, 1), - - Global attributes (value 65533, 65532, 65531, 65529 and 65528) and - - List may include optional attribute(value 0x0002), if DISHM.S.A0002(StartUpMode) supports, on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - - [1696402605.599359][7921:7923] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_FFFB DataVersion: 712950283 - [1696402605.599377][7921:7923] CHIP:TOO: AttributeList: 9 entries - [1696402605.599382][7921:7923] CHIP:TOO: [1]: 0 - [1696402605.599385][7921:7923] CHIP:TOO: [2]: 1 - [1696402605.599388][7921:7923] CHIP:TOO: [3]: 2 - [1696402605.599391][7921:7923] CHIP:TOO: [4]: 3 - [1696402605.599393][7921:7923] CHIP:TOO: [5]: 65528 - [1696402605.599396][7921:7923] CHIP:TOO: [6]: 65529 - [1696402605.599399][7921:7923] CHIP:TOO: [7]: 65531 - [1696402605.599402][7921:7923] CHIP:TOO: [8]: 65532 - [1696402605.599404][7921:7923] CHIP:TOO: [9]: 65533 - disabled: true - - - label: "Step 5: TH reads from the DUT the EventList attribute." - verification: | - ./chip-tool dishwashermode read event-list 1 1 - - * Step 5 is currently not supported and SHALL be skipped. - - [1696402636.316151][7926:7928] CHIP:DMG: } - [1696402636.316183][7926:7928] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - disabled: true - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - verification: | - ./chip-tool dishwashermode read accepted-command-list 1 1 - - Verify the "AcceptedCommandList" contains a list of mandatory commands (value 0) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: - - [1690365651.143190][27451:27453] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_FFF9 DataVersion: 1130015440 - [1690365651.143256][27451:27453] CHIP:TOO: AcceptedCommandList: 1 entries - [1690365651.143284][27451:27453] CHIP:TOO: [1]: 0 - disabled: true - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - verification: | - ./chip-tool dishwashermode read generated-command-list 1 1 - - Verify " GeneratedCommandList" contains a list of mandatory commands (value 1) on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - - [1689997224.280302][360025:360027] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_FFF8 DataVersion: 1427220838 - [1689997224.280330][360025:360027] CHIP:TOO: GeneratedCommandList: 1 entries - [1689997224.280346][360025:360027] CHIP:TOO: [1]: 1 - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DLOG_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DLOG_1_1.yaml deleted file mode 100644 index 7043c694d41241..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DLOG_1_1.yaml +++ /dev/null @@ -1,91 +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: 56.1.1. [TC-DLOG-1.1] Global Attributes with DUT as Server - -PICS: - - DLOG.S - -config: - nodeId: 0x12344321 - cluster: "Diagnostic Logs" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads the FeatureMap from DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads EventList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [0] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [1] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_1_1.yaml deleted file mode 100644 index 72cd8f941de50e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DRLK_1_1.yaml +++ /dev/null @@ -1,544 +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: 113.1.1. [TC-DRLK-1.1] Global Attributes [DUT-Server] - -PICS: - - DRLK.S - -config: - nodeId: 0x12344321 - cluster: "Door Lock" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 7 - constraints: - type: int16u - - - label: "Step 3a: TH reads the FeatureMap from DUT" - PICS: - " !DRLK.S.F00 && !DRLK.S.F01 && !DRLK.S.F02 && !DRLK.S.F04 && - !DRLK.S.F05 && !DRLK.S.F06 && !DRLK.S.F07 && !DRLK.S.F08 && - !DRLK.S.F0a && !DRLK.S.F0b && !DRLK.S.F0c " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given DRLK.S.F00(PIN) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given DRLK.S.F01(RID) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given DRLK.S.F02(FGP) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given DRLK.S.F04(WDSCH) ensure featuremap has the correct - bit set" - PICS: DRLK.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: - "Step 3f: Given DRLK.S.F05(DPS) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F05 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20] - - - label: - "Step 3g: Given DRLK.S.F06(FACE) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F06 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x40] - - - label: - "Step 3h: Given DRLK.S.F07(COTA) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F07 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x80] - - - label: - "Step 3i: Given DRLK.S.F08(USR) ensure featuremap has the correct bit - set" - PICS: DRLK.S.F08 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x100] - - - label: - "Step 3j: Given DRLK.S.F0a(YDSCH) ensure featuremap has the correct - bit set" - PICS: DRLK.S.F0a - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x400] - - - label: - "Step 3k: Given DRLK.S.F0b(HDSCH) ensure featuremap has the correct - bit set" - PICS: DRLK.S.F0b - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x800] - - - label: - "Step 3l: Given DRLK.S.F0c(UBOLT) ensure featuremap has the correct - bit set" - PICS: DRLK.S.F0c - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1000] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 2, 37, 38, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 37, 38, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads Feature dependent(DRLK.S.F05) attributes in - AttributeList" - PICS: DRLK.S.F05 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4c: TH reads Feature dependent(DRLK.S.F08) attributes in - AttributeList" - PICS: DRLK.S.F08 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17, 27, 28] - - - label: - "Step 4d: TH reads Feature dependent(DRLK.S.F00) attributes in - AttributeList" - PICS: DRLK.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18, 23, 24] - - - label: - "Step 4e: TH reads Feature dependent(DRLK.S.F01) attributes in - AttributeList" - PICS: DRLK.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [19, 25, 26] - - - label: - "Step 4f: TH reads Feature dependent(DRLK.S.F04) attribute in - AttributeList" - PICS: DRLK.S.F04 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: - "Step 4g: TH reads Feature dependent(DRLK.S.F0a) attribute in - AttributeList" - PICS: DRLK.S.F0a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [21] - - - label: - "Step 4h: TH reads Feature dependent(DRLK.S.F0b) attribute in - AttributeList" - PICS: DRLK.S.F0b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [22] - - - label: - "Step 4i: TH reads Feature dependent(DRLK.S.F00 or DRLK.S.F01) - attributes in AttributeList" - PICS: DRLK.S.F00 || DRLK.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [48, 49] - - - label: - "Step 4j: TH reads Feature dependent(DRLK.S.F07 or DRLK.S.F00) - attribute in AttributeList" - PICS: DRLK.S.F07 || DRLK.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [51] - - - label: "Step 4k: TH reads optional attribute(Language) in AttributeList" - PICS: DRLK.S.A0021 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [33] - - - label: - "Step 4l: TH reads optional attribute(LEDSettings) in AttributeList" - PICS: DRLK.S.A0022 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [34] - - - label: - "Step 4m: TH reads optional attribute(AutoRelockTime) in AttributeList" - PICS: DRLK.S.A0023 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [35] - - - label: - "Step 4n: TH reads optional attribute(SoundVolume) in AttributeList" - PICS: DRLK.S.A0024 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [36] - - - label: - "Step 4o: TH reads optional attribute(DefaultConfigurationRegister) in - AttributeList" - PICS: DRLK.S.A0027 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [39] - - - label: - "Step 4p: TH reads optional attribute(EnableLocalProgramming) in - AttributeList" - PICS: DRLK.S.A0028 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [40] - - - label: - "Step 4q: TH reads optional attribute(EnableOneTouchLocking) in - AttributeList" - PICS: DRLK.S.A0029 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [41] - - - label: - "Step 4r: TH reads optional attribute(EnableInsideStatusLED) in - AttributeList" - PICS: DRLK.S.A002a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [42] - - - label: - "Step 4s: TH reads optional attribute(EnablePrivacyModeButton) in - AttributeList" - PICS: DRLK.S.A002b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [43] - - - label: - "Step 4t: TH reads optional attribute(LocalProgrammingFeatures) in - AttributeList" - PICS: DRLK.S.A002c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [44] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0, 2, 3] - - - label: - "Step 5b: TH reads optional event(Door position sensor) in EventList" - PICS: DRLK.S.F05 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 5c: TH reads optional event(User commands and database) in - EventList" - PICS: DRLK.S.F08 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [4] - - - label: "Step 6a: TH reads AcceptedCommandList from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1] - - - label: - "Step 6b: TH reads Feature dependent commands(DRLK.S.F04) in - AcceptedCommandList" - PICS: DRLK.S.F04 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [11, 12, 13] - - - label: - "Step 6c: TH reads Feature dependent commands(DRLK.S.F0a) in - AcceptedCommandList" - PICS: DRLK.S.F0a - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [14, 15, 16] - - - label: - "Step 6d: TH reads Feature dependent commands(DRLK.S.F0b) in - AcceptedCommandList" - PICS: DRLK.S.F0b - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [17, 18, 19] - - - label: - "Step 6e: TH reads Feature dependent commands(DRLK.S.F0c) in - AcceptedCommandList" - PICS: DRLK.S.F0c - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [39] - - - label: - "Step 6f: TH reads Feature dependent commands(DRLK.S.F08) in - AcceptedCommandList" - PICS: DRLK.S.F08 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [26, 27, 29, 34, 36, 38] - - - label: - "Step 6g: TH reads optional commands(DRLK.S.C03.Rsp) in - AcceptedCommandList" - PICS: DRLK.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 7a: TH reads Feature dependent command(DRLK.S.F04) in - GeneratedCommandList" - PICS: DRLK.S.F04 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [12] - - - label: - "Step 7b: TH reads Feature dependent command(DRLK.S.F0a) in - GeneratedCommandList" - PICS: DRLK.S.F0a - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [15] - - - label: - "Step 7c: TH reads Feature dependent command(DRLK.S.F0b) in - GeneratedCommandList" - PICS: DRLK.S.F0b - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [18] - - - label: - "Step 7d: TH reads Feature dependent command(DRLK.S.F08) in - GeneratedCommandList" - PICS: DRLK.S.F08 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [28, 35, 37] diff --git a/src/app/tests/suites/certification/Test_TC_DRYERCTRL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DRYERCTRL_1_1.yaml deleted file mode 100644 index 3edb48072708bd..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DRYERCTRL_1_1.yaml +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 3.1.1. [TC-DRYERCTRL-1.1] Global attributes with server as DUT - -PICS: - - DRYERCTRL.S - -config: - nodeId: 0x12344321 - cluster: "Laundry Dryer Controls" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_EEVSEM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_EEVSEM_1_1.yaml deleted file mode 100644 index 769dc5d3cba3ac..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_EEVSEM_1_1.yaml +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 265.1.1. [TC-EEVSEM-1.1] Global Attributes with DUT as Server - -PICS: - - EEVSEM.S - -config: - nodeId: 0x12344321 - cluster: "Energy EVSE Mode" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - #https://github.com/project-chip/connectedhomeip/issues/31599 - - label: "Step 3: TH reads from the DUT the FeatureMap attribute" - verification: | - ./chip-tool energyevsemode read feature-map 1 1 - - On the TH(Chip-tool) Log, Verify featureMap value is 0 and below is the sample log provided for the raspi platform: - - [1707803286.349129][12699:12701] CHIP:DMG: } - [1707803286.349183][12699:12701] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_009D Attribute 0x0000_FFFC DataVersion: 811903427 - [1707803286.349202][12699:12701] CHIP:TOO: FeatureMap: 0 - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 4: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute (StartUpMode) in AttributeList - from DUT" - PICS: EEVSEM.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5: TH reads EventList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads AcceptedCommandList from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [0] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList from DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [1] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_EEVSE_1_1.yaml b/src/app/tests/suites/certification/Test_TC_EEVSE_1_1.yaml deleted file mode 100644 index 0be6a9015ed5e9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_EEVSE_1_1.yaml +++ /dev/null @@ -1,301 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 265.1.1. [TC-EEVSE-1.1] Global Attributes with DUT as Server - -PICS: - - EEVSE.S - -config: - nodeId: 0x12344321 - cluster: "Energy EVSE" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute" - PICS: - "!EEVSE.S.F00 && !EEVSE.S.F01 && !EEVSE.S.F02 && !EEVSE.S.F03 && - !EEVSE.S.F04" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given EEVSE.S.F00(ChargingPreferences) ensure featuremap has - the correct bit set" - PICS: EEVSE.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3b: Given EEVSE.S.F01(SoCReporting) ensure featuremap has the - correct bit set" - PICS: EEVSE.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3b: Given EEVSE.S.F02(PlugAndCharge) ensure featuremap has the - correct bit set" - PICS: EEVSE.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3b: Given EEVSE.S.F03(RFID) ensure featuremap has the correct - bit set" - PICS: EEVSE.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3b: Given EEVSE.S.F04(V2X) ensure featuremap has the correct bit - set" - PICS: EEVSE.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 3, - 5, - 6, - 7, - 64, - 65, - 66, - 65528, - 65529, - 65530, - 65531, - 65532, - 65533, - ] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 3, - 5, - 6, - 7, - 64, - 65, - 66, - 65528, - 65529, - 65531, - 65532, - 65533, - ] - - - label: - "Step 4b: TH reads optional attribute (UserMaximumChargeCurrent) in - AttributeList from DUT" - PICS: EEVSE.S.A0009 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9] - - - label: - "Step 4c: TH reads optional attribute (RandomizationDelayWindow) in - AttributeList from DUT" - PICS: EEVSE.S.A000A - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4d: TH reads optional attribute (V2X) in AttributeList from DUT" - PICS: EEVSE.S.F04 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4, 8, 67] - - - label: - "Step 4e: TH reads optional attribute (ChargingPreferences) in - AttributeList from DUT" - PICS: EEVSE.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [35, 36, 37, 38, 39] - - - label: - "Step 4e: TH reads optional attribute (SoCReporting) in AttributeList - from DUT" - PICS: EEVSE.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [48, 49] - - - label: - "Step 4f: TH reads optional attribute (PlugAndCharge) in AttributeList - from DUT" - PICS: EEVSE.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [50] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4] - - - label: "Step 5b: TH reads optional attribute (RFID) in EventList from DUT" - PICS: EEVSE.S.F03 && PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [5] - - - label: "Step 6a: TH reads AcceptedCommandList from DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1, 2] - - - label: - "Step 6b: TH reads the optional (StartDiagnostics) command in - AcceptedCommandList" - PICS: EEVSE.S.C04.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 6c: TH reads Feature dependent commands(EEVSE.S.F04) in - AcceptedCommandList" - PICS: EEVSE.S.F04 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 6d: TH reads Feature dependent commands(ChargingPreferences) in - AcceptedCommandList" - PICS: EEVSE.S.F00 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [5, 6, 7] - - - label: "Step 7a: TH reads GeneratedCommandList from DUT" - PICS: " !EEVSE.S.F00 " - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7b: TH reads GeneratedCommandList from DUT" - PICS: EEVSE.S.F00 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [0] diff --git a/src/app/tests/suites/certification/Test_TC_FAN_1_1.yaml b/src/app/tests/suites/certification/Test_TC_FAN_1_1.yaml deleted file mode 100644 index e8986134e769eb..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_FAN_1_1.yaml +++ /dev/null @@ -1,217 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 263.1.1. [TC-FAN-1.1] Global attributes with DUT as Server - -PICS: - - FAN.S - -config: - nodeId: 0x12344321 - cluster: "Fan Control" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 4 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: - " !FAN.S.F00 && !FAN.S.F01 && !FAN.S.F02 && !FAN.S.F03 && !FAN.S.F04 - && !FAN.S.F05 " - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given FAN.S.F00(SPD) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FAN.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given FAN.S.F01(AUT) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FAN.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given FAN.S.F02(RCK) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FAN.S.F02 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given FAN.S.F03(WND) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FAN.S.F03 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3f: Given FAN.S.F04(STEP) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FAN.S.F04 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: - "Step 3g: Given FAN.S.F05(DIR) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FAN.S.F05 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4c: TH Reads the feature dependent FAN.S.F00 (SPD) attribute in - AttributeList" - PICS: FAN.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4, 5, 6] - - - label: - "Step 4d: TH Reads the feature dependent FAN.S.F02(RCK) attribute in - AttributeList" - PICS: FAN.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7, 8] - - - label: - "Step 4e: TH Reads the feature dependent FAN.S.F03(WND) attribute in - AttributeList" - PICS: FAN.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9, 10] - - - label: - "Step 4f: TH Reads the feature dependent FAN.S.F05(DIR) attribute in - AttributeList" - PICS: FAN.S.F05 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11] - - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6:TH reads from the DUT the AcceptedCommandList attribute." - PICS: " !FAN.S.C00.Rsp " - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6: TH Reads the optional command (Step) in AcceptedCommandList" - PICS: FAN.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_FLABEL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_FLABEL_1_1.yaml deleted file mode 100644 index bc66790a65f18f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_FLABEL_1_1.yaml +++ /dev/null @@ -1,93 +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: 110.1.1. [TC-FLABEL-1.1] Global Attributes with DUT as Server - -PICS: - - FLABEL.S - -config: - nodeId: 0x12344321 - cluster: "Fixed Label" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_FLW_1_1.yaml b/src/app/tests/suites/certification/Test_TC_FLW_1_1.yaml deleted file mode 100644 index c1b3de22020da0..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_FLW_1_1.yaml +++ /dev/null @@ -1,103 +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: 33.1.1. [TC-FLW-1.1] Global Attributes with DUT as Server - -PICS: - - FLW.S - -config: - nodeId: 0x12344321 - cluster: "Flow Measurement" - endpoint: 1 - -tests: - - label: - "Step 1:Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(Tolerance) in AttributeList" - PICS: FLW.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_GRPKEY_1_1.yaml b/src/app/tests/suites/certification/Test_TC_GRPKEY_1_1.yaml deleted file mode 100644 index ea77cb6fb19f7d..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_GRPKEY_1_1.yaml +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 26.1.1. [TC-GRPKEY-1.1] Global Attributes with DUT as Server - -PICS: - - GRPKEY.S - -config: - nodeId: 0x12344321 - cluster: "Group Key Management" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - PICS: " !GRPKEY.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given GRPKEY.S.F00(CS) ensure featuremap has the correct bit - set" - PICS: GRPKEY.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: " !PICS_EVENT_LIST_ENABLED " - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 3, 4] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [2, 5] diff --git a/src/app/tests/suites/certification/Test_TC_G_1_1.yaml b/src/app/tests/suites/certification/Test_TC_G_1_1.yaml deleted file mode 100644 index 305dc43ae0de62..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_G_1_1.yaml +++ /dev/null @@ -1,103 +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: 121.1.1. [TC-G-1.1] Global Attributes with DUT as Server - -PICS: - - G.S - -config: - nodeId: 0x12344321 - cluster: "Groups" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 4 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - PICS: " !G.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3b: Given G.S.F00 ensure featuremap has the correct bit set" - PICS: G.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4, 5] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2, 3] diff --git a/src/app/tests/suites/certification/Test_TC_HEPAFREMON_1_1.yaml b/src/app/tests/suites/certification/Test_TC_HEPAFREMON_1_1.yaml deleted file mode 100644 index 5ae91d71678e31..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_HEPAFREMON_1_1.yaml +++ /dev/null @@ -1,183 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 165.1.1. [TC-HEPAFREMON-1.1] Global Attributes with DUT as Server - -PICS: - - HEPAFREMON.S - -config: - nodeId: 0x12344321 - cluster: "HEPA Filter Monitoring" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: "!HEPAFREMON.S.F00 && !HEPAFREMON.S.F01 && !HEPAFREMON.S.F02" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given HEPAFREMON.S.F00(Condition) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: HEPAFREMON.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given HEPAFREMON.S.F01(Warning) ensure featuremap has the - correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: HEPAFREMON.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given HEPAFREMON.S.F02(ReplacementProductList) ensure - featuremap has the correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: HEPAFREMON.S.F02 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the feature dependent(HEPAFREMON.S.F00) attribute - in AttributeList" - PICS: HEPAFREMON.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2] - - - label: - "Step 4c: TH reads the optional attribute InPlaceIndicator - (HEPAFREMON.S.A0003) in AttributeList" - PICS: HEPAFREMON.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4d: TH reads the optional attribute LastChangedTime - (HEPAFREMON.S.A0004) in AttributeList" - PICS: HEPAFREMON.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4e: TH reads the optional attribute ReplacementProductList - (HEPAFREMON.S.F02) in AttributeList" - PICS: HEPAFREMON.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - PICS: "!HEPAFREMON.S.C00.Rsp" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6: TH reads the optional command (ResetCondition) in - AcceptedCommandList" - PICS: HEPAFREMON.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_ILL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ILL_1_1.yaml deleted file mode 100644 index 76f371c1145bf5..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ILL_1_1.yaml +++ /dev/null @@ -1,114 +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: 71.1.1. [TC-ILL-1.1] Global attributes with server as DUT - -PICS: - - ILL.S - -config: - nodeId: 0x12344321 - cluster: "Illuminance Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision attribute from the DUT." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: "Step 3: TH reads the FeatureMap attribute from the DUT." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads the AttributeList attribute from the DUT." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads the AttributeList attribute from the DUT." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(Tolerance) in AttributeList" - PICS: ILL.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4c: TH reads the optional attribute(LightSensorType) in - AttributeList" - PICS: ILL.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: "Step 5: TH reads the EventList attribute from the DUT." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the AcceptedCommandList attribute from the DUT." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads the GeneratedCommandList attribute from the DUT." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_I_1_1.yaml b/src/app/tests/suites/certification/Test_TC_I_1_1.yaml deleted file mode 100644 index ab2e3cffa89628..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_I_1_1.yaml +++ /dev/null @@ -1,136 +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: 57.1.1. [TC-I-1.1] Global Attributes with DUT as Server - -PICS: - - I.S - -config: - nodeId: 0x12344321 - cluster: "Identify" - endpoint: 1 - -tests: - - label: - "Step 1:Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 4 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - #Commenting out the step FeatureMap attribute feature PICS I.S.F00(QRY) which is out of scope for matter V1.0 - #- label: "TH reads the FeatureMap attribute from the DUT" - # PICS: I.S.F00 - # command: "readAttribute" - # attribute: "FeatureMap" - # response: - # value: 1 - # constraints: - # type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - #Manufacturer specific event IDs check not possible - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 6: TH reads the optional command(TriggerEffect) in - AcceptedCommandList" - PICS: I.S.C40.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [64] - - #Commenting out the step IdentifyQuery (0x01) is not supported by Matter 1.0. - #- label: "TH reads the optional attribute(IdentifyQuery) in AcceptedCommandList" - # PICS: I.S.C01.Rsp - # command: "readAttribute" - # attribute: "AcceptedCommandList" - # response: - # constraints: - # type: list - # contains: [1] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - #Commenting out the step IdentifyQueryResponse (0x00) is not supported by Matter 1.0 - #- label: - # "TH reads the optional command(IdentifyQueryResponse) in - # GeneratedCommandList" - # PICS: I.S.C00.Tx - # command: "readAttribute" - # attribute: "GeneratedCommandList" - # response: - # value: [0] - # constraints: - # type: list diff --git a/src/app/tests/suites/certification/Test_TC_KEYPADINPUT_1_2.yaml b/src/app/tests/suites/certification/Test_TC_KEYPADINPUT_1_2.yaml deleted file mode 100644 index 20cd640da5dfd1..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_KEYPADINPUT_1_2.yaml +++ /dev/null @@ -1,128 +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: - 19.1.2. [TC-KEYPADINPUT-1.2] Global attributes - Keypad Input Cluster (DUT - as Server) - -PICS: - - KEYPADINPUT.S - -config: - nodeId: 0x12344321 - cluster: "Keypad Input" - endpoint: 1 - -tests: - - label: - "Commission DUT to TH (can be skipped if done in a preceding test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2a: TH reads the FeatureMap attribute from the DUT" - PICS: " !KEYPADINPUT.S.F00 && KEYPADINPUT.S.F01 && !KEYPADINPUT.S.F02 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 2b: Given (KEYPADINPUT.S.F00(NV)) FeatureMap bit mask is set or - not" - PICS: KEYPADINPUT.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 2c: Given (KEYPADINPUT.S.F01(LK)) FeatureMap bit mask is set or - not" - PICS: KEYPADINPUT.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 2d: Given (KEYPADINPUT.S.F02(NK)) FeatureMap bit mask is set or - not" - PICS: KEYPADINPUT.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_LCFG_1_1.yaml b/src/app/tests/suites/certification/Test_TC_LCFG_1_1.yaml deleted file mode 100644 index 6cd288c1a26d5d..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LCFG_1_1.yaml +++ /dev/null @@ -1,93 +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: 101.1.1. [TC-LCFG-1.1] Global Attributes with DUT as Server - -PICS: - - LCFG.S - -config: - nodeId: 0x12344321 - cluster: "Localization Configuration" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_LOWPOWER_1_1.yaml b/src/app/tests/suites/certification/Test_TC_LOWPOWER_1_1.yaml deleted file mode 100644 index c71888c3477df0..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LOWPOWER_1_1.yaml +++ /dev/null @@ -1,93 +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: - 19.1.1. [TC-LOWPOWER-1.1] Global attributes - Low Power Cluster (DUT as - Server) - -PICS: - - LOWPOWER.S - -config: - nodeId: 0x12344321 - cluster: "Low Power" - endpoint: 1 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - value: [65528, 65529, 65530, 65531, 65532, 65533] - constraints: - type: list - - - label: "Step 3: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - value: [65528, 65529, 65531, 65532, 65533] - constraints: - type: list - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [0] - constraints: - type: list - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_LUNIT_1_2.yaml b/src/app/tests/suites/certification/Test_TC_LUNIT_1_2.yaml deleted file mode 100644 index ab55e650535f86..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LUNIT_1_2.yaml +++ /dev/null @@ -1,117 +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: 108.1.2. [TC-LUNIT-1.2] Global Attributes with DUT as Server - -PICS: - - LUNIT.S - -config: - nodeId: 0x12344321 - cluster: "Unit Localization" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: " !LUNIT.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3: Given LUNIT.S.F00(TEMP) ensure featuremap has the correct bit - set" - PICS: LUNIT.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads Feature dependent(LUNIT.S.F00) attribute in - AttributeList" - PICS: LUNIT.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_LVL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_LVL_1_1.yaml deleted file mode 100644 index 76ca0f322f0e64..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LVL_1_1.yaml +++ /dev/null @@ -1,224 +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: 18.1.1. [TC-LVL-1.1] Global Attributes with DUT as Server - -PICS: - - LVL.S - -config: - nodeId: 0x12344321 - cluster: "Level Control" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 5 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - PICS: " !LVL.S.F00 && !LVL.S.F01 && !LVL.S.F02 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given LVL.S.F00(OO) ensure featuremap has the correct bit - set" - PICS: LVL.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given LVL.S.F01(LT) ensure featuremap has the correct bit - set" - PICS: LVL.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given LVL.S.F02(FQ) ensure featuremap has the correct bit - set" - PICS: LVL.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 15, 17, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 15, 17, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4a: TH reads the optional attribute(StartUpCurrentLevel and - RemainingTime) in AttributeList" - PICS: LVL.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1, 16384] - - - label: - "Step 4b: TH reads the optional attribute(CurrentFrequency, - MinFrequency and MinFrequency) in AttributeList" - PICS: LVL.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4, 5, 6] - - - label: - "Step 4c: TH reads the optional attribute(MinLevel) in AttributeList" - PICS: LVL.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4d: TH reads the optional attribute(MaxLevel) in AttributeList" - PICS: LVL.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4e: TH reads the optional attribute(OnOffTransitionTime) in - AttributeList" - PICS: LVL.S.A0010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16] - - - label: - "Step 4f: TH reads the optional attribute(OnTransitionTime) in - AttributeList" - PICS: LVL.S.A0012 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - - label: - "Step 4g: TH reads the optional attribute(OffTransitionTime) in - AttributeList" - PICS: LVL.S.A0013 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [19] - - - label: - "Step 4h: TH reads the optional attribute(DefaultMoveRate) in - AttributeList" - PICS: LVL.S.A0014 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: "Step 5: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4, 5, 6, 7] - - - label: - "Step 6a.1: TH reads the Feature-dependent(LVL.S.F02) command in - AcceptedCommandList" - PICS: LVL.S.F02 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [8] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_LWM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_LWM_1_1.yaml deleted file mode 100644 index 0b8b51fcbe3f10..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LWM_1_1.yaml +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 183.1.2. [TC-LWM-1.1] Cluster attributes with DUT as Server - -PICS: - - LWM.S - -config: - nodeId: 0x12344321 - cluster: "Laundry Washer Mode" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - #Issue https://github.com/project-chip/connectedhomeip/issues/31551 - - label: - "Step 3:TH reads from the DUT the FeatureMap attribute., bit 0: SHALL - be 1 if and only if LWM.S.F00" - command: "readAttribute" - attribute: "FeatureMap" - PICS: LWM.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !LWM.S.F00 " - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(StartUpMode) in - AttributeList" - PICS: LWM.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - #Issue https://github.com/project-chip/connectedhomeip/issues/31551 - - label: - "Step 4c: TH reads the Feature dependent attribute in AttributeList" - PICS: LWM.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] diff --git a/src/app/tests/suites/certification/Test_TC_MEDIAINPUT_1_4.yaml b/src/app/tests/suites/certification/Test_TC_MEDIAINPUT_1_4.yaml deleted file mode 100644 index 793d412532a3bd..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_MEDIAINPUT_1_4.yaml +++ /dev/null @@ -1,128 +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: - 19.1.4. [TC-MEDIAINPUT-1.4] Global attributes - Media Input Cluster (DUT as - Server) - -PICS: - - MEDIAINPUT.S - -config: - nodeId: 0x12344321 - cluster: "Media Input" - endpoint: 1 - -tests: - - label: - "Step 0: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - PICS: " !MEDIAINPUT.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 2: Given MEDIAINPUT.S.F00(NU) ensure featuremap has the correct - bit set" - PICS: MEDIAINPUT.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(InputList) in AttributeList" - PICS: MEDIAINPUT.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 3c: TH reads the optional attribute(CurrentInput) in - AttributeList" - PICS: MEDIAINPUT.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2, 3] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_MEDIAPLAYBACK_1_7.yaml b/src/app/tests/suites/certification/Test_TC_MEDIAPLAYBACK_1_7.yaml deleted file mode 100644 index c3b55fd4e3bbac..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_MEDIAPLAYBACK_1_7.yaml +++ /dev/null @@ -1,266 +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: - 19.1.7. [TC-MEDIAPLAYBACK-1.7] Global attributes - Media Playback Cluster - (DUT as Server) - -PICS: - - MEDIAPLAYBACK.S - -config: - nodeId: 0x12344321 - cluster: "Media Playback" - endpoint: 1 - -tests: - - label: - "Commission DUT to TH (can be skipped if done in a preceding test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 2a: TH reads the FeatureMap attribute from the DUT" - PICS: " !MEDIAPLAYBACK.S.F00 && !MEDIAPLAYBACK.S.F01 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 2b: Given MEDIAPLAYBACK.S.F00(AS) ensure featuremap has the - correct bit set" - PICS: MEDIAPLAYBACK.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 2c: Given MEDIAPLAYBACK.S.F01(VS) ensure featuremap has the - correct bit set" - PICS: MEDIAPLAYBACK.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(StartTime) in AttributeList" - PICS: MEDIAPLAYBACK.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 3c: TH reads the optional attribute(Duration) in AttributeList" - PICS: MEDIAPLAYBACK.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 3d: TH reads the optional attribute(SampledPosition) in - AttributeList" - PICS: MEDIAPLAYBACK.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 3e: TH reads the optional attribute(PlaybackSpeed) in - AttributeList" - PICS: MEDIAPLAYBACK.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 3f: TH reads the optional attribute(SeekRangeEnd) in - AttributeList" - PICS: MEDIAPLAYBACK.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 3g: TH reads the optional attribute(SeekRangeStart) in - AttributeList" - PICS: MEDIAPLAYBACK.S.A0006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: "Step 4a: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2] - - - label: - "Step 4b: TH reads the optional command(StartOver) in - AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4c: TH reads the optional command(Previous) in - AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C04.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4d: TH reads the optional command(Next) in AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C05.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4e: TH reads the optional command(Rewind) in AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C06.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4f: TH reads the optional command(FastForward) in - AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C07.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4g: TH reads the optional command(SkipForward) in - AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C08.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4h: TH reads the optional command(SkipBackward) in - AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C09.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [9] - - - label: - "Step 4i: TH reads the optional command(Seek) in AcceptedCommandList" - PICS: MEDIAPLAYBACK.S.C0b.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [11] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [10] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_MOD_1_1.yaml b/src/app/tests/suites/certification/Test_TC_MOD_1_1.yaml deleted file mode 100644 index dc00d3b0f2a39f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_MOD_1_1.yaml +++ /dev/null @@ -1,125 +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: 78.1.1. [TC-MOD-1.1] Global attributes with server as DUT - -PICS: - - MOD.S - -config: - nodeId: 0x12344321 - cluster: "Mode Select" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: MOD.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 1 - constraints: - type: bitmap32 - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: " !MOD.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(StartUpMode) in - AttributeList from the DUT" - PICS: MOD.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4c: TH reads the Feature dependent attribute(OnMode) in - AttributeList from the DUT" - PICS: MOD.S.F00 && MOD.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_MWOM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_MWOM_1_1.yaml deleted file mode 100644 index a35aa47a01870f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_MWOM_1_1.yaml +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 263.1.1. [TC-MWOM-1.1] Global attributes with DUT as Server - -PICS: - - MWOM.S - -config: - nodeId: 0x12344321 - cluster: "Microwave Oven Mode" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: Read the global attribute: FeatureMap" - command: "readAttribute" - attribute: "FeatureMap" - PICS: "!MWOM.S.F00" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - excludes: [2, 3] - - - label: "Step 4b: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - excludes: [2, 3] - - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - excludes: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - excludes: [1] diff --git a/src/app/tests/suites/certification/Test_TC_OCC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_OCC_1_1.yaml deleted file mode 100644 index b62cc83b374141..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OCC_1_1.yaml +++ /dev/null @@ -1,198 +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: 24.1.1. [TC-OCC-1.1] Global attributes with server as DUT - -PICS: - - OCC.S - -config: - nodeId: 0x12344321 - cluster: "Occupancy Sensing" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Step 2: TH reads from the DUT the (0xFFFD) ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 4 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the (0xFFFC) FeatureMap attribute" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 4a: TH reads from the DUT the (0xFFFB) AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: - "Step 4a: TH reads from the DUT the (0xFFFB) AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute(PIROccupiedToUnoccupiedDelay) in - AttributeList" - PICS: OCC.S.A0010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16] - - - label: - "Step 4c: TH reads optional attribute(PIRUnoccupiedToOccupiedDelay) in - AttributeList" - PICS: OCC.S.A0011 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17] - - - label: - "Step 4d: TH reads optional - attribute(PIRUnoccupiedToOccupiedThreshold) in AttributeList" - PICS: OCC.S.A0012 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - - label: - "Step 4e: TH reads optional - attribute(UltrasonicOccupiedToUnoccupiedDelay) in AttributeList" - PICS: OCC.S.A0020 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [32] - - - label: - "Step 4f: TH reads optional - attribute(UltrasonicUnoccupiedToOccupiedDelay) in AttributeList" - PICS: OCC.S.A0021 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [33] - - - label: - "Step 4g: TH reads optional - attribute(UltrasonicUnoccupiedToOccupiedThreshold) in AttributeList" - PICS: OCC.S.A0022 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [34] - - - label: - "Step 4h: TH reads optional - attribute(PhysicalContactOccupiedToUnoccupiedDelay) in AttributeList" - PICS: OCC.S.A0030 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [48] - - - label: - "Step 4i: TH reads the optional - attribute(PhysicalContactUnoccupiedToOccupiedDelay) in AttributeList" - PICS: OCC.S.A0031 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [49] - - - label: - "Step 4j: TH reads optional - attribute(PhysicalContactUnoccupiedToOccupiedThreshold) in - AttributeList" - PICS: OCC.S.A0032 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [50] - - - label: "Step 5: TH reads from the DUT the (0xFFFA) EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6: TH reads from the DUT the (0xFFF9) AcceptedCommandList - attribute" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 7: TH reads from the DUT the (0xFFF8) GeneratedCommandList - attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml b/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml deleted file mode 100644 index 5b44953041dac7..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OO_1_1.yaml +++ /dev/null @@ -1,207 +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: 4.1.1. [TC-OO-1.1] Global Attributes with DUT as Server - -PICS: - - OO.S - -config: - nodeId: 0x12344321 - cluster: "On/Off" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - #Issue: https://github.com/project-chip/connectedhomeip/issues/29786 - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 6 - constraints: - type: int16u - - - label: - "Step 3a: Given OO.S.F00(LT) ensure featuremap has the correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( OO.S.F00 && !OO.S.F02 ) - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - label: - "Step 3b: Given OO.S.F00(LT) ensure featuremap has the correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( !( OO.S.F00 && !OO.S.F02 ) ) - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3c: Given OO.S.F01(DF) ensure featuremap has the correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( OO.S.F01 && !OO.S.F02 ) - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - label: - "Step 3d: Given OO.S.F01(DF) ensure featuremap has the correct bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( !( OO.S.F01 && !OO.S.F02 ) ) - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3e: Given OO.S.F02(OFFONLY) TH reads from the DUT the FeatureMap - attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( OO.S.F02 && !OO.S.F00 && !OO.S.F01 ) - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - label: - "Step 3f: Given OO.S.F02(OFFONLY) TH reads from the DUT the FeatureMap - attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( !( OO.S.F02 && !OO.S.F00 && !OO.S.F01 ) ) - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - label: "Step 3g: All remaining shall be zero" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0xFFFFFFF8] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the feature dependent(OO.S.F00) attribute in - AttributeList" - PICS: OO.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16384, 16385, 16386, 16387] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 6b: TH reads the feature dependent(OO.S.F02) commands in - AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - PICS: ( !OO.S.F02 ) - response: - constraints: - type: list - contains: [1, 2] - - - label: - "Step 6c: TH reads the feature dependent(OO.S.F02) commands in - AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - PICS: OO.S.F02 - response: - constraints: - type: list - excludes: [1, 2] - - - label: - "Step 6d: TH reads the feature dependent(OO.S.F00) commands in - AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - PICS: OO.S.F00 - response: - constraints: - type: list - contains: [64, 65, 66] - - - label: - "Step 6e: TH reads the feature dependent(OO.S.F00) commands in - AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - PICS: ( !OO.S.F00 ) - response: - constraints: - type: list - excludes: [64, 65, 66] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_OPCREDS_1_2.yaml b/src/app/tests/suites/certification/Test_TC_OPCREDS_1_2.yaml deleted file mode 100644 index cce8acd22655ca..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OPCREDS_1_2.yaml +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 11.1.2. [TC-OPCREDS-1.2] Global Attributes with DUT as Server - -PICS: - - OPCREDS.S - -config: - nodeId: 0x12344321 - cluster: "Operational Credentials" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0xFFFD, - 0xFFFC, - 0xFFFB, - 0xFFFA, - 0xFFF9, - 0xFFF8, - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - ] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0xFFFD, - 0xFFFC, - 0xFFFB, - 0xFFF9, - 0xFFF8, - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - ] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0x00, 0x02, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [0x01, 0x03, 0x05, 0x08] diff --git a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_7.yaml b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_7.yaml index f6751e03c3e283..67dc552f1b2215 100644 --- a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_7.yaml +++ b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_7.yaml @@ -63,14 +63,14 @@ tests: saveAs: TH1_Fabric_Index - label: - "Step 3.2: TH1 does a non-fabric-filtered read of the Fabrics - attribute from the Node Operational Credentials cluster. Save the - FabricIndex for TH1 as TH1_Fabric_Index for future use." + "Step 3.2: TH1 does a fabric-filtered read of the Fabrics attribute + from the Node Operational Credentials cluster. Save the FabricIndex + for TH1 as TH1_Fabric_Index for future use." identity: "alpha" command: "readAttribute" cluster: "Operational Credentials" attribute: "Fabrics" - fabricFiltered: false + fabricFiltered: true response: value: [{ "FabricIndex": TH1_Fabric_Index, "Label": "" }] constraints: @@ -237,20 +237,30 @@ tests: # verification: "" - label: - "Step 13: TH2 does a non-fabric-filtered read of the Fabrics attribute + "Step 13a: TH1 does a fabric-filtered read of the Fabrics attribute + from the Node Operational Credentials cluster" + nodeId: 0x43211234 + command: "readAttribute" + cluster: "Operational Credentials" + attribute: "Fabrics" + fabricFiltered: true + response: + value: [{ "FabricIndex": TH1_Fabric_Index, "Label": "" }] + constraints: + type: list + + # verification: "" + - label: + "Step 13b: TH2 does a fabric-filtered read of the Fabrics attribute from the Node Operational Credentials cluster" identity: "beta" nodeId: 0x43211234 command: "readAttribute" cluster: "Operational Credentials" attribute: "Fabrics" - fabricFiltered: false + fabricFiltered: true response: - value: - [ - { "FabricIndex": TH1_Fabric_Index, "Label": "" }, - { "FabricIndex": TH2_Fabric_Index, "Label": "" }, - ] + value: [{ "FabricIndex": TH2_Fabric_Index, "Label": "" }] constraints: type: list diff --git a/src/app/tests/suites/certification/Test_TC_OTCCM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_OTCCM_1_1.yaml deleted file mode 100644 index 008c608c9736ba..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OTCCM_1_1.yaml +++ /dev/null @@ -1,101 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 260.1.1. [TC-OTCCM-1.1] Global attributes with DUT as Server - -PICS: - - OTCCM.S - -config: - nodeId: 0x12344321 - cluster: "Oven Mode" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: Read the optional attribute(StartUpMode) in AttributeList" - PICS: OTCCM.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] diff --git a/src/app/tests/suites/certification/Test_TC_PRS_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PRS_1_1.yaml deleted file mode 100644 index 3d6f49e133bdd4..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PRS_1_1.yaml +++ /dev/null @@ -1,169 +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: 36.1.1. [TC-PRS-1.1] Global Attributes with DUT as Server - -PICS: - - PRS.S - -config: - nodeId: 0x12344321 - cluster: "Pressure Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: " !PRS.S.F00 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3: Given PRS.S.F00(EXT) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PRS.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(ScaledValue) in - AttributeList" - PICS: PRS.S.A0010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16] - - - label: - "Step 4c: TH reads the optional attribute(MinScaledValue) in - AttributeList" - PICS: PRS.S.A0011 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17] - - - label: - "Step 4d: TH reads the optional attribute(MaxScaledValue) in - AttributeList" - PICS: PRS.S.A0012 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - - label: "Step 4e: TH reads the optional attribute(Scale) in AttributeList" - PICS: PRS.S.A0014 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: - "Step 4f: TH reads the optional attribute(Tolerance) in AttributeList" - PICS: PRS.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4g: TH reads the optional attribute(ScaledTolerance) in - AttributeList" - PICS: PRS.S.A0013 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [19] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PSCFG_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PSCFG_1_1.yaml deleted file mode 100644 index d3ec7430f62bfe..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PSCFG_1_1.yaml +++ /dev/null @@ -1,93 +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: 63.1.1. [TC-PSCFG-1.1] Global Attributes with DUT as Server - -PICS: - - PSCFG.S - -config: - nodeId: 0x12344321 - cluster: "Power Source Configuration" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PS_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PS_1_1.yaml deleted file mode 100644 index f0ac68665894fb..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PS_1_1.yaml +++ /dev/null @@ -1,211 +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: 62.1.1. [TC-PS-1.1] Global Attributes with DUT as Server - -PICS: - - PS.S - -config: - nodeId: 0x12344321 - cluster: "Power Source" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Test Harness Client reads ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - PICS: " !PS.S.F00 && !PS.S.F01 && !PS.S.F02 && !PS.S.F03 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given PS.S.F00(WIRED) ensure featuremap has the correct bit - set" - PICS: PS.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given PS.S.F01(BAT) ensure featuremap has the correct bit - set" - PICS: PS.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3c: Given PS.S.F02(RECHG) ensure featuremap has the correct bit - set" - PICS: PS.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2, 0x4] - - - label: - "Step 3d: Given PS.S.F03(REPLC) ensure featuremap has the correct bit - set" - PICS: PS.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2, 0x8] - - - label: "Step 4: Test Harness Client reads AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 2, 0x1f, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: Test Harness Client reads AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 0x1f, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4a: TH reads the Feature dependent(PS.S.F00-WIRED) attribute in - AttributeList" - PICS: PS.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4b: TH reads the Feature dependent(PS.S.F01-BAT) attribute in - AttributeList" - PICS: PS.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [14, 15, 16] - - - label: - "Step 4c: TH reads the Feature dependent(PS.S.F02-RECHG) attribute in - AttributeList" - PICS: PS.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [26, 28] - - - label: - "Step 4d: TH reads the Feature dependent(PS.S.F03-REPLC) attribute in - AttributeList" - PICS: PS.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [19, 25] - - - label: "Step 5a: Test Harness Client reads EventList attribute." - PICS: "PICS_EVENT_LIST_ENABLED && !PS.S.E00 && !PS.S.E01 && !PS.S.E02 " - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 5b: TH reads PS.S.E00(WiredFaultChange) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && PS.S.E00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5c: TH reads PS.S.E01(BatFaultChange) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && PS.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 5d: TH reads PS.S.E02(BatChargeFaultChange) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && PS.S.E02 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 6: Test Harness Client reads AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: Test Harness Client reads GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_REFALM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_REFALM_1_1.yaml deleted file mode 100644 index fd9a44944b8b49..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_REFALM_1_1.yaml +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 223.1.1. [TC-REFALM-1.1] Global attributes with DUT as Server - -PICS: - - REFALM.S - -config: - nodeId: 0x12344321 - cluster: "Refrigerator Alarm" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0x0000, - 0x0002, - 0x0003, - 0xfff8, - 0xfff9, - 0xfffa, - 0xfffb, - 0xfffc, - 0xfffd, - ] - excludes: [0x0001] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0x0000, - 0x0002, - 0x0003, - 0xfff8, - 0xfff9, - 0xfffb, - 0xfffc, - 0xfffd, - ] - excludes: [0x0001] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_RH_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RH_1_1.yaml deleted file mode 100644 index 8281fc20386d14..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_RH_1_1.yaml +++ /dev/null @@ -1,103 +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: 9.1.1. [TC-RH-1.1] Global attributes with server as DUT - -PICS: - - RH.S - -config: - nodeId: 0x12344321 - cluster: "Relative Humidity Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision attribute from the DUT." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: "Step 3: TH reads the FeatureMap attribute from the DUT." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads the AttributeList attribute from the DUT." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads the AttributeList attribute from the DUT." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(Tolerance) in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: RH.S.A0003 - response: - constraints: - type: list - contains: [3] - - - label: "Step 5: TH reads the AcceptedCommandList attribute from the DUT." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the GeneratedCommandList attribute from the DUT." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads the EventList attribute from the DUT." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml deleted file mode 100644 index 1a4dbae62cb01f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_RVCCLEANM_1_1.yaml +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 78.1.1. [TC-RVCCLEANM-1.1] Global attributes with DUT as Server - -PICS: - - RVCCLEANM.S - -config: - nodeId: 0x12344321 - cluster: "RVC Clean Mode" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6: TH reads from the DUT the AcceptedCommandList attribute. - Check if it contains id 0x0 (ChangeToMode)" - PICS: RVCCLEANM.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [0] - constraints: - type: list - - - label: - "Step 7: TH reads from the DUT the GeneratedCommandList attribute. - Check if it contains id 0x1 (ChangeToModeResponse)" - PICS: RVCCLEANM.S.C01.Tx - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [1] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml deleted file mode 100644 index ce4e4e35b87467..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_1_1.yaml +++ /dev/null @@ -1,162 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 224.1.1. [TC-RVCOPSTATE-1.1] Global attributes [DUT as Server] - -PICS: - - RVCOPSTATE.S - -config: - nodeId: 0x12344321 - cluster: "RVC Operational State" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 3, 4, 5, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 3, 4, 5, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads from the DUT the optional attribute(CountdownTime) - in the AttributeList from the DUT" - PICS: RVCOPSTATE.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5a: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x00] - - - label: - "Step 5b: TH reads from the DUT the optional - event(OperationCompletion) in EventList." - PICS: PICS_EVENT_LIST_ENABLED && RVCOPSTATE.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x01] - - - label: - "Step 6a: TH reads the optional command(Pause) in AcceptedCommandList" - PICS: RVCOPSTATE.S.C00.Rsp || RVCOPSTATE.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 3] - - - label: - "Step 6b: TH reads the optional command(Stop) in AcceptedCommandList" - PICS: RVCOPSTATE.S.C01.Rsp || RVCOPSTATE.S.C02.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1, 2] - - - label: - "Step 6c: TH reads the optional command(Start) in AcceptedCommandList" - PICS: RVCOPSTATE.S.C02.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 6d: TH reads the optional command(Resume) in AcceptedCommandList" - PICS: RVCOPSTATE.S.C03.Rsp || RVCOPSTATE.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 3] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute" - PICS: - " !RVCOPSTATE.S.C00.Rsp && !RVCOPSTATE.S.C01.Rsp && - !RVCOPSTATE.S.C02.Rsp && !RVCOPSTATE.S.C03.Rsp " - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute" - PICS: - " RVCOPSTATE.S.C00.Rsp || RVCOPSTATE.S.C01.Rsp || RVCOPSTATE.S.C02.Rsp - || RVCOPSTATE.S.C03.Rsp " - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [4] diff --git a/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml deleted file mode 100644 index f9b4aed3db30c3..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_RVCRUNM_1_1.yaml +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 78.1.1. [TC-RVCRUNM-1.1] Global attributes with DUT as Server - -PICS: - - RVCRUNM.S - -config: - nodeId: 0x12344321 - cluster: "RVC Run Mode" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6: TH reads from the DUT the AcceptedCommandList attribute. - Check if it contains id 0x0 (ChangeToMode)" - PICS: RVCRUNM.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [0] - constraints: - type: list - - - label: - "Step 7: TH reads from the DUT the GeneratedCommandList attribute. - Check if it contains id 0x1 (ChangeToModeResponse)" - PICS: RVCRUNM.S.C01.Tx - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [1] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_S_1_1.yaml b/src/app/tests/suites/certification/Test_TC_S_1_1.yaml deleted file mode 100644 index c8a8c359e1cdc8..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_S_1_1.yaml +++ /dev/null @@ -1,132 +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: 123.1.1. [TC-S-1.1] Global attributes with DUT as Server - -PICS: - - S.S - -config: - nodeId: 0x12344321 - cluster: "Scenes Management" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: - "Step 3: TH reads FeatureMap NameSupport bit (global attribute 65532)" - PICS: (!S.S.F00) - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3: TH reads FeatureMap NameSupport bit (global attribute 65532)" - PICS: (S.S.F00) - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 4a: TH reads AttributeList mandatory attributes(global attribute - 65531)" - PICS: S.S - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the LastConfiguredBy optional attribute from the - AttributeList (global attribute 65531)" - PICS: S.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5: TH reads from the DUT the EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [] - - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute" - PICS: S.S - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4, 5, 6] - - - label: - "Step 6b: TH reads optional command(CopySceneResponse) - AcceptedCommandList (global attribute 65529)" - PICS: S.S.C40.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [64] - - - label: "Step 7a: TH reads from the DUT the GeneratedCommandList attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2, 3, 4, 6] - - - label: - "Step 7b: TH reads Read optional command(CopySceneResponse) in - GeneratedCommandList (global attribute 65528)" - PICS: S.S.C40.Rsp - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [64] diff --git a/src/app/tests/suites/certification/Test_TC_TCCM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TCCM_1_1.yaml deleted file mode 100644 index 4ee0ba303a1c61..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TCCM_1_1.yaml +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 219.1.1. [TC-TCCM-1.1] Global attributes with DUT as Server - -PICS: - - TCCM.S - -config: - nodeId: 0x12344321 - cluster: "Refrigerator And Temperature Controlled Cabinet Mode" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - #Issue https://github.com/project-chip/connectedhomeip/issues/31551 - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - PICS: "!TCCM.S.F00" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3: TH reads from the DUT the FeatureMap attribute, bit 0: SHALL - be 1 if and only if TCCM.S.F00" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TCCM.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads from the DUT the AttributeList attribute. 0x0002: - SHALL be included if and only if TCCM.S.A0002(StartUpMode)" - PICS: TCCM.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - #Issue https://github.com/project-chip/connectedhomeip/issues/31551 - - label: - "Step 4c: TH reads from the DUT the AttributeList attribute. 0x0003 - SHALL be included if and only if TCCM.S.F00" - PICS: TCCM.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] diff --git a/src/app/tests/suites/certification/Test_TC_TGTNAV_1_9.yaml b/src/app/tests/suites/certification/Test_TC_TGTNAV_1_9.yaml deleted file mode 100644 index 55d7d295e4369e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TGTNAV_1_9.yaml +++ /dev/null @@ -1,104 +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: - 19.1.9. [TC-TGTNAV-1.9] Global attributes - Target Navigator Cluster (DUT as - Server) - -PICS: - - TGTNAV.S - -config: - nodeId: 0x12344321 - cluster: "Target Navigator" - endpoint: 1 - -tests: - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(CurrentTarget) in - AttributeList" - PICS: TGTNAV.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 4: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: TH reads the EventList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_TIMESYNC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TIMESYNC_1_1.yaml deleted file mode 100644 index f9384780f54269..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TIMESYNC_1_1.yaml +++ /dev/null @@ -1,400 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 133.1.1. [TC-TIMESYNC-1.1] Global attributes with server as DUT - -PICS: - - TIMESYNC.S - -config: - nodeId: 0x12344321 - cluster: "Time Synchronization" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - ########################## - # TS 2: Cluster revision - ########################## - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - - ########################## - # TS 3: Feature map - ########################## - # TZ - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - PICS: TIMESYNC.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3b: Given !TIMESYNC.S.F00(TZ) ensure featuremap has the correct - bit clear" - PICS: "!TIMESYNC.S.F00" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - # NTPC - - label: - "Step 3c: Given TIMESYNC.S.F01(NTPC) ensure featuremap has the correct - bit set" - PICS: TIMESYNC.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given !TIMESYNC.S.F01(NTPC) ensure featuremap has the - correct bit clear" - PICS: "!TIMESYNC.S.F01" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - # NTPS - - label: - "Step 3e: Given TIMESYNC.S.F02(NTPS) ensure featuremap has the correct - bit set" - PICS: TIMESYNC.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3f: Given !TIMESYNC.S.F02(NTPS) ensure featuremap has the - correct bit clear" - PICS: "!TIMESYNC.S.F02" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - # TSC - - label: - "Step 3g: Given TIMESYNC.S.F03(TSC) ensure featuremap has the correct - bit set" - PICS: TIMESYNC.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3h: Given !TIMESYNC.S.F03(TSC) ensure featuremap has the correct - bit clear" - PICS: "!TIMESYNC.S.F03" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - ########################## - # TS 3: Feature map - ########################## - # Mandatory entries - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: - [ - 0x0000, - 0x0001, - 0xFFF8, - 0xFFF9, - 0xFFFA, - 0xFFFB, - 0xFFFC, - 0xFFFD, - ] - - - label: "Step 4b: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: [0x0000, 0x0001, 0xFFF8, 0xFFF9, 0xFFFB, 0xFFFC, 0xFFFD] - - # Optional - - label: "Step 4c: Check for optional attribute TimeSource in AttributeList" - PICS: TIMESYNC.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: [0x0002] - - - label: - "Step 4d: Check for optional attribute TimeSource not in AttributeList" - PICS: "!TIMESYNC.S.A0002" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - excludes: [0x0002] - - # Feature TZ - - label: "Step 4e: Check for TZ feature-based attributes in AttributeList" - PICS: TIMESYNC.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: [0x0005, 0x0006, 0x0007, 0x0008, 0x000A, 0x000B] - - - label: - "Step 4f: Check for TZ feature-based attributes not in AttributeList" - PICS: "!TIMESYNC.S.F00" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - excludes: [0x0005, 0x0006, 0x0007, 0x0008, 0x000A, 0x000B] - - # Feature NTPC - - label: "Step 4g: Check for NTPC feature-based attributes in AttributeList" - PICS: TIMESYNC.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: [0x0004, 0x000C] - - - label: - "Step 4h: Check for NTPC feature-based attributes not in AttributeList" - PICS: "!TIMESYNC.S.F01" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - excludes: [0x0004, 0x000C] - - # Feature NTPS - - label: "Step 4i: Check for NTPS feature-based attributes in AttributeList" - PICS: TIMESYNC.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: [0x0009] - - - label: - "Step 4j: Check for NTPS feature-based attributes not in AttributeList" - PICS: "!TIMESYNC.S.F02" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - excludes: [0x0009] - - # Feature TSC - - label: "Step 4k: Check for TSC feature-based attributes in AttributeList" - PICS: TIMESYNC.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - contains: [0x0003] - - - label: - "Step 4l: Check for TSC feature-based attributes not in AttributeList" - PICS: "!TIMESYNC.S.F03" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - excludes: [0x0003] - - # Note - additional exclusions not handled here - - ########################## - # TS 5: Event list - NOTE: disabled - ########################## - # mandatory - - label: "Step 5a: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - contains: [0x03] - - #Feature TZ - - label: "Step 5b: Check for TZ feature-based events in EventList" - PICS: PICS_EVENT_LIST_ENABLED && TIMESYNC.S.F00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - contains: [0x00, 0x01, 0x02] - - - label: "Step 5c: Check for TZ feature-based events not in EventList" - PICS: "PICS_EVENT_LIST_ENABLED && !TIMESYNC.S.F00" - command: "readAttribute" - attribute: "EventList" - response: - constraints: - excludes: [0x00, 0x01, 0x02] - - #Feature TSC - - label: "Step 5d: Check for TSC feature-based events in EventList" - PICS: PICS_EVENT_LIST_ENABLED && TIMESYNC.S.F03 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - contains: [0x04] - - - label: "Step 5e: Check for TSC feature-based events not in EventList" - PICS: "PICS_EVENT_LIST_ENABLED && !TIMESYNC.S.F03" - command: "readAttribute" - attribute: "EventList" - response: - constraints: - excludes: [0x04] - - # Note - additional exclusions not handled here - - ########################## - # TS 6: AcceptedCommandList - ########################## - # mandatory - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - contains: [0x00] - - # Feature TZ - - label: - "Step 6b: Check for TZ feature-based commands in AcceptedCommandList" - PICS: TIMESYNC.S.F00 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - contains: [0x02, 0x04] - - - label: - "Step 6c: Check for TZ feature-based commands in not - AcceptedCommandList" - PICS: "!TIMESYNC.S.F00" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - excludes: [0x02, 0x04] - - # Feature NTPC - - label: - "Step 6d: Check for NTPC feature-based commands in AcceptedCommandList" - PICS: TIMESYNC.S.F01 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - contains: [0x05] - - - label: - "Step 6e: Check for NTPC feature-based commands in not - AcceptedCommandList" - PICS: "!TIMESYNC.S.F01" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - excludes: [0x05] - - # Feature TSC - - label: - "Step 6f: Check for TSC feature-based commands in AcceptedCommandList" - PICS: TIMESYNC.S.F03 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - contains: [0x01] - - - label: - "Step 6g: Check for TSC feature-based commands in not - AcceptedCommandList" - PICS: "!TIMESYNC.S.F03" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - excludes: [0x01] - - # NOTE: exclusions not checked - - ########################## - # TS 7: GeneratedCommandList - ########################## - # Feature TZ - - label: "Step 7a: TH reads from the DUT the GeneratedCommandList attribute" - PICS: TIMESYNC.S.F00 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - contains: [0x03] - - - label: - "Step 7b: Check for TZ feature-based commands in not - GeneratedCommandList" - PICS: "!TIMESYNC.S.F00" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - excludes: [0x03] diff --git a/src/app/tests/suites/certification/Test_TC_TMP_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TMP_1_1.yaml deleted file mode 100644 index 48eea5b8d29552..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TMP_1_1.yaml +++ /dev/null @@ -1,101 +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: 7.1.1. [TC-TMP-1.1] Global attributes with server as DUT - -PICS: - - TMP.S - -config: - nodeId: 0x12344321 - cluster: "Temperature Measurement" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 4 - constraints: - type: int16u - - - label: "Step 3: TH reads FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute(Tolerance) in AttributeList" - PICS: TMP.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 5: TH reads AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads EventList attribute from the DUT." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_TSUIC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TSUIC_1_1.yaml deleted file mode 100644 index 333a81dc7b71a8..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TSUIC_1_1.yaml +++ /dev/null @@ -1,102 +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: 12.1.1. [TC-TSUIC-1.1] Global attributes with DUT as Server - -PICS: - - TSUIC.S - -config: - nodeId: 0x12344321 - cluster: "Thermostat User Interface Configuration" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute(ScheduleProgrammingVisibility) - in AttributeList" - PICS: TSUIC.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_ULABEL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ULABEL_1_1.yaml deleted file mode 100644 index e78f650215c24f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ULABEL_1_1.yaml +++ /dev/null @@ -1,93 +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: 95.1.1. [TC-ULABEL-1.1] Global Attributes with DUT as Server - -PICS: - - ULABEL.S - -config: - nodeId: 0x12344321 - cluster: "User Label" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_VALCC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_VALCC_1_1.yaml deleted file mode 100644 index cf00d40a21a02f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_VALCC_1_1.yaml +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 62.1.1. [TC-VALCC-1.1] Global attributes with server as DUT - -PICS: - - VALCC.S - -config: - nodeId: 0x12344321 - cluster: "Valve Configuration and Control" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: Read the global attribute: FeatureMap" - command: "readAttribute" - attribute: "FeatureMap" - PICS: ( !VALCC.S.F00 && !VALCC.S.F01 ) - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given VALCC.S.F00(TS) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: VALCC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given VALCC.S.F01(LVL) ensure featuremap has the correct bit - set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: VALCC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 3, 4, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 3, 4, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: Read the feature dependent(VALCC.S.F00) attribute in - AttributeList" - PICS: VALCC.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4c: Read the feature dependent(VALCC.S.F01) attribute in - AttributeList" - PICS: VALCC.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6, 7] - - - label: - "Step 4d: Read the feature dependent(VALCC.S.F01) optional attribute - in AttributeList" - PICS: VALCC.S.F01 && VALCC.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4e: Read the feature dependent(VALCC.S.F01) optional attribute - in AttributeList" - PICS: VALCC.S.F01 && VALCC.S.A000a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4f: TH reads optional (ValveFault) attribute in AttributeList" - PICS: VALCC.S.A0009 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9] - - - label: "Step 5a: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED && !VALCC.S.E00 && !VALCC.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 5b: Read the optional (ValveStateChanged) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && VALCC.S.E00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5c: Read the optional (ValveFault) event in EventList" - PICS: PICS_EVENT_LIST_ENABLED && VALCC.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1] - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_WAKEONLAN_1_5.yaml b/src/app/tests/suites/certification/Test_TC_WAKEONLAN_1_5.yaml deleted file mode 100644 index 59de9edbd7a636..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_WAKEONLAN_1_5.yaml +++ /dev/null @@ -1,104 +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: - 19.1.5. [TC-WAKEONLAN-1.5] Global attributes - Wake on LAN Cluster (DUT as - Server) - -PICS: - - WAKEONLAN.S - -config: - nodeId: 0x12344321 - cluster: "Wake on LAN" - endpoint: 1 - -tests: - - label: - "Commission DUT to TH (can be skipped if done in a preceding test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 1: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 2: TH reads the FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 3a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 3b: TH reads the optional attribute(MACAddress) in AttributeList" - PICS: WAKEONLAN.S.A0000 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 4: TH reads the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 5: TH reads the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_WASHERCTRL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_WASHERCTRL_1_1.yaml deleted file mode 100644 index 61e4f130dca7dd..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_WASHERCTRL_1_1.yaml +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 186.1.1. [TC-WASHERCTRL-1.1] Global Attributes with DUT as Server - -PICS: - - WASHERCTRL.S - -config: - nodeId: 0x12344321 - cluster: "Laundry Washer Controls" - endpoint: 1 - -tests: - - label: "Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: - "Step 3: TH reads from the DUT the FeatureMap attribute. If - WASHERCTRL.S.F00(SPIN) & WASHERCTRL.S.F01(RINSE) are false" - PICS: "!WASHERCTRL.S.F00 && !WASHERCTRL.S.F01" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3: TH reads from the DUT the FeatureMap attribute, bit 0 set to - 1 if the DUT is capable of controlling the washer using the spin - attributes (WASHERCTRL.S.F00(SPIN) is true)" - PICS: WASHERCTRL.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3: TH reads from the DUT the FeatureMap attribute, bit 1 set to - 1 if the DUT supports rinse attributes (WASHERCTRL.S.F01(RINSE) is - true)" - PICS: WASHERCTRL.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the feature dependent(WASHERCTRL.S.F00) attributes - in AttributeList from DUT." - PICS: WASHERCTRL.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1] - - - label: - "Step 4c: TH reads the feature dependent(WASHERCTRL.S.F01) attributes - in AttributeList from DUT." - PICS: WASHERCTRL.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2, 3] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index 26efd799ad7efd..a77ecb9a3b2838 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -1,7 +1,6 @@ { "AccessControl": [ "TestAccessControlCluster", - "Test_TC_ACL_1_1", "Test_TC_ACL_2_1", "Test_TC_ACL_2_3", "Test_TC_ACL_2_4", @@ -14,12 +13,11 @@ ], "ContentAppObserver": [], "AccessControlEnforcement": ["Test_TC_ACE_1_1", "Test_TC_ACE_1_5"], - "BooleanState": ["Test_TC_BOOL_1_1", "Test_TC_BOOL_2_1"], - "Binding": ["Test_TC_BIND_1_1"], - "BridgedDeviceBasicInformation": ["Test_TC_BRBINFO_1_1"], - "Actions": ["Test_TC_ACT_1_1"], + "BooleanState": ["Test_TC_BOOL_2_1"], + "Binding": [], + "BridgedDeviceBasicInformation": [], + "Actions": [], "ColorControl": [ - "Test_TC_CC_1_1", "Test_TC_CC_2_1", "Test_TC_CC_3_2", "Test_TC_CC_3_3", @@ -42,65 +40,43 @@ "TestColorControl_9_2" ], "DeviceManagement": [ - "Test_TC_OPCREDS_1_2", "Test_TC_OPCREDS_3_7", - "Test_TC_BINFO_1_1", "Test_TC_BINFO_2_1", "Test_TC_BINFO_2_2", "Test_TC_CNET_1_3" ], - "Descriptor": ["Test_TC_DESC_1_1"], - "DeviceEnergyManagementMode": ["Test_TC_DEMM_1_1", "Test_TC_DEMM_2_1"], - "EthernetNetworkDiagnostics": [ - "Test_TC_DGETH_1_1", - "Test_TC_DGETH_2_1", - "Test_TC_DGETH_2_2" - ], - "DiagnosticsLogs": ["Test_TC_DLOG_1_1"], - "EnergyEVSE": ["Test_TC_EEVSE_1_1", "Test_TC_EEVSE_2_1"], + "Descriptor": [], + "DeviceEnergyManagementMode": ["Test_TC_DEMM_2_1"], + "EthernetNetworkDiagnostics": ["Test_TC_DGETH_2_1", "Test_TC_DGETH_2_2"], + "DiagnosticsLogs": [], + "EnergyEVSE": ["Test_TC_EEVSE_2_1"], "EnergyEVSEMode": [ - "Test_TC_EEVSEM_1_1", "Test_TC_EEVSEM_2_1", "Test_TC_EEVSEM_3_1", "Test_TC_EEVSEM_3_2", "Test_TC_EEVSEM_3_3" ], - "FlowMeasurement": ["Test_TC_FLW_1_1", "Test_TC_FLW_2_1"], - "FixedLabel": ["Test_TC_FLABEL_1_1", "Test_TC_FLABEL_2_1"], + "FlowMeasurement": ["Test_TC_FLW_2_1"], + "FixedLabel": ["Test_TC_FLABEL_2_1"], "FanControl": [ - "Test_TC_FAN_1_1", "Test_TC_FAN_2_1", "Test_TC_FAN_2_2", "Test_TC_FAN_2_3", "Test_TC_FAN_2_4", "Test_TC_FAN_3_6" ], - "GeneralCommissioning": ["Test_TC_CGEN_1_1", "Test_TC_CGEN_2_1"], - "GeneralDiagnostics": ["Test_TC_DGGEN_1_1"], - "GroupKeyManagement": ["Test_TC_GRPKEY_1_1", "Test_TC_GRPKEY_2_2"], + "GeneralCommissioning": ["Test_TC_CGEN_2_1"], + "GeneralDiagnostics": [], + "GroupKeyManagement": ["Test_TC_GRPKEY_2_2"], "IcdManagement": [ "TestIcdManagementCluster", "Test_TC_ICDM_1_1", "Test_TC_ICDM_3_4" ], - "Identify": [ - "Test_TC_I_1_1", - "Test_TC_I_2_1", - "Test_TC_I_2_2", - "Test_TC_I_2_3" - ], - "IlluminanceMeasurement": [ - "Test_TC_ILL_1_1", - "Test_TC_ILL_2_1", - "Test_TC_ILL_2_2" - ], - "OccupancySensing": [ - "Test_TC_OCC_1_1", - "Test_TC_OCC_2_1", - "Test_TC_OCC_2_3" - ], + "Identify": ["Test_TC_I_2_1", "Test_TC_I_2_2", "Test_TC_I_2_3"], + "IlluminanceMeasurement": ["Test_TC_ILL_2_1", "Test_TC_ILL_2_2"], + "OccupancySensing": ["Test_TC_OCC_2_1", "Test_TC_OCC_2_3"], "LevelControl": [ - "Test_TC_LVL_1_1", "Test_TC_LVL_2_1", "Test_TC_LVL_2_2", "Test_TC_LVL_3_1", @@ -109,50 +85,34 @@ "Test_TC_LVL_6_1", "Test_TC_LVL_7_1" ], - "LocalizationConfiguration": ["Test_TC_LCFG_1_1"], + "LocalizationConfiguration": [], "TimeFormatLocalization": ["Test_TC_LTIME_1_2", "Test_TC_LTIME_3_1"], - "UnitLocalization": ["Test_TC_LUNIT_1_2", "Test_TC_LUNIT_3_1"], + "UnitLocalization": ["Test_TC_LUNIT_3_1"], "UserLabel": [ - "Test_TC_ULABEL_1_1", "Test_TC_ULABEL_2_1", "Test_TC_ULABEL_2_2", "Test_TC_ULABEL_2_3", "Test_TC_ULABEL_2_4" ], "LaundryWasherMode": [ - "Test_TC_LWM_1_1", "Test_TC_LWM_2_1", "Test_TC_LWM_3_1", "Test_TC_LWM_3_2", "Test_TC_LWM_3_3" ], "LaundryWasherControl": [ - "Test_TC_WASHERCTRL_1_1", "Test_TC_WASHERCTRL_2_1", "Test_TC_WASHERCTRL_2_2" ], "OvenMode": [ - "Test_TC_OTCCM_1_1", "Test_TC_OTCCM_2_1", "Test_TC_OTCCM_3_1", "Test_TC_OTCCM_3_2", "Test_TC_OTCCM_3_3" ], - "LaundryDryerControl": ["Test_TC_DRYERCTRL_1_1", "Test_TC_DRYERCTRL_2_1"], + "LaundryDryerControl": ["Test_TC_DRYERCTRL_2_1"], "MediaControl": [ - "Test_TC_LOWPOWER_1_1", - "Test_TC_KEYPADINPUT_1_2", - "Test_TC_APPLAUNCHER_1_3", - "Test_TC_MEDIAINPUT_1_4", - "Test_TC_WAKEONLAN_1_5", - "Test_TC_CHANNEL_1_6", - "Test_TC_MEDIAPLAYBACK_1_7", - "Test_TC_AUDIOOUTPUT_1_8", - "Test_TC_TGTNAV_1_9", - "Test_TC_APBSC_1_10", - "Test_TC_CONTENTLAUNCHER_1_11", - "Test_TC_ALOGIN_1_12", "Test_TC_LOWPOWER_2_1", "Test_TC_KEYPADINPUT_3_2", "Test_TC_KEYPADINPUT_3_3", @@ -181,22 +141,13 @@ "Test_TC_CONTENTLAUNCHER_10_5", "Test_TC_CONTENTLAUNCHER_10_7" ], - "ModeSelect": ["Test_TC_MOD_1_1"], + "ModeSelect": [], "MultipleFabrics": [], "OTASoftwareUpdate": ["OTA_SuccessfulTransfer"], - "OnOff": [ - "Test_TC_OO_1_1", - "Test_TC_OO_2_1", - "Test_TC_OO_2_2", - "Test_TC_OO_2_4" - ], - "PowerSource": ["Test_TC_PS_1_1", "Test_TC_PS_2_1"], + "OnOff": ["Test_TC_OO_2_1", "Test_TC_OO_2_2", "Test_TC_OO_2_4"], + "PowerSource": ["Test_TC_PS_2_1"], "PowerTopology": ["Test_TC_PWRTL_1_1"], - "PressureMeasurement": [ - "Test_TC_PRS_1_1", - "Test_TC_PRS_2_1", - "Test_TC_PRS_2_2" - ], + "PressureMeasurement": ["Test_TC_PRS_2_1", "Test_TC_PRS_2_2"], "PumpConfigurationControl": [ "Test_TC_PCC_1_1", "Test_TC_PCC_2_1", @@ -204,15 +155,10 @@ "Test_TC_PCC_2_3", "Test_TC_PCC_2_4" ], - "PowerSourceConfiguration": ["Test_TC_PSCFG_1_1", "Test_TC_PSCFG_2_1"], - "RefrigeratorAlarm": ["Test_TC_REFALM_1_1", "Test_TC_REFALM_2_1"], - "RelativeHumidityMeasurement": ["Test_TC_RH_1_1", "Test_TC_RH_2_1"], - "RoboticVacuumCleaner": [ - "Test_TC_RVCCLEANM_1_1", - "Test_TC_RVCRUNM_1_1", - "Test_TC_RVCRUNM_3_1", - "Test_TC_RVCOPSTATE_1_1" - ], + "PowerSourceConfiguration": ["Test_TC_PSCFG_2_1"], + "RefrigeratorAlarm": ["Test_TC_REFALM_2_1"], + "RelativeHumidityMeasurement": ["Test_TC_RH_2_1"], + "RoboticVacuumCleaner": ["Test_TC_RVCRUNM_3_1"], "SecureChannel": [], "SmokeCOAlarm": [ "Test_TC_SMOKECO_1_1", @@ -225,7 +171,6 @@ ], "Switch": ["Test_TC_SWTCH_1_1", "Test_TC_SWTCH_2_1"], "TemperatureControlledCabinetMode": [ - "Test_TC_TCCM_1_1", "Test_TC_TCCM_3_1", "Test_TC_TCCM_3_2", "Test_TC_TCCM_3_3" @@ -238,26 +183,17 @@ "Test_TC_TCTL_3_2", "Test_TC_TCTL_3_3" ], - "TemperatureMeasurement": ["Test_TC_TMP_1_1", "Test_TC_TMP_2_1"], + "TemperatureMeasurement": ["Test_TC_TMP_2_1"], "Thermostat": ["Test_TC_TSTAT_1_1", "Test_TC_TSTAT_2_1"], - "ThermostatUserConfiguration": [ - "Test_TC_TSUIC_1_1", - "Test_TC_TSUIC_2_1", - "Test_TC_TSUIC_2_2" - ], + "ThermostatUserConfiguration": ["Test_TC_TSUIC_2_1", "Test_TC_TSUIC_2_2"], "ThreadNetworkDiagnostics": [ - "Test_TC_DGTHREAD_1_1", "Test_TC_DGTHREAD_2_1", "Test_TC_DGTHREAD_2_2", "Test_TC_DGTHREAD_2_3", "Test_TC_DGTHREAD_2_4" ], - "TimeSynchronization": ["Test_TC_TIMESYNC_1_1", "Test_TC_TIMESYNC_2_3"], - "WiFiNetworkDiagnostics": [ - "Test_TC_DGWIFI_1_1", - "Test_TC_DGWIFI_2_1", - "Test_TC_DGWIFI_2_3" - ], + "TimeSynchronization": ["Test_TC_TIMESYNC_2_3"], + "WiFiNetworkDiagnostics": ["Test_TC_DGWIFI_2_1", "Test_TC_DGWIFI_2_3"], "WindowCovering": [ "Test_TC_WNCV_1_1", "Test_TC_WNCV_2_1", @@ -326,7 +262,7 @@ "Test_AddNewFabricFromExistingFabric" ], "MultiAdmin": ["TestMultiAdmin"], - "SoftwareDiagnostics": ["Test_TC_DGSW_1_1"], + "SoftwareDiagnostics": [], "Subscriptions": [ "TestSubscribe_OnOff", "TestSubscribe_AdministratorCommissioning" @@ -335,7 +271,6 @@ "DL_UsersAndCredentials", "DL_LockUnlock", "DL_Schedules", - "Test_TC_DRLK_1_1", "Test_TC_DRLK_2_4", "Test_TC_DRLK_2_5", "Test_TC_DRLK_2_6", @@ -343,18 +278,12 @@ "Test_TC_DRLK_2_8", "Test_TC_DRLK_2_11" ], - "Groups": [ - "TestGroupMessaging", - "TestGroupsCluster", - "Test_TC_G_1_1", - "Test_TC_G_2_1" - ], + "Groups": ["TestGroupMessaging", "TestGroupsCluster", "Test_TC_G_2_1"], "ScenesManagement": [ "TestScenesFabricRemoval", "TestScenesFabricSceneInfo", "TestScenesMultiFabric", "TestScenesMaxCapacity", - "Test_TC_S_1_1", "Test_TC_S_2_1", "Test_TC_S_2_2", "Test_TC_S_2_3", @@ -363,12 +292,10 @@ "ResourceMonitoring": [ "TestActivatedCarbonFilterMonitoring", "TestHepaFilterMonitoring", - "Test_TC_ACFREMON_1_1", "Test_TC_ACFREMON_2_1", - "Test_TC_HEPAFREMON_1_1", "Test_TC_HEPAFREMON_2_1" ], - "AirQuality": ["Test_TC_AIRQUAL_1_1", "Test_TC_AIRQUAL_2_1"], + "AirQuality": ["Test_TC_AIRQUAL_2_1"], "ConcentrationMeasurement": [ "Test_TC_CDOCONC_1_1", "Test_TC_CDOCONC_2_1", diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 0331f9eba773df..a12d2b75b8a90f 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -64,7 +64,6 @@ "Test_TC_DA_1_8" ], "DishwasherAlarm": [ - "Test_TC_DISHALM_1_1", "Test_TC_DISHALM_2_1", "Test_TC_DISHALM_3_1", "Test_TC_DISHALM_3_2", @@ -74,7 +73,6 @@ "Test_TC_DISHALM_3_6" ], "DishwasherMode": [ - "Test_TC_DISHM_1_1", "Test_TC_DISHM_1_2", "Test_TC_DISHM_2_1", "Test_TC_DISHM_3_1", @@ -170,10 +168,8 @@ "Test_TC_MC_11_2", "Test_TC_ALOGIN_12_2", "Test_TC_TGTNAV_8_2", - "Test_TC_APPOBSERVER_1_13", "Test_TC_APPOBSERVER_13_1", - "Test_TC_APPOBSERVER_13_2", - "Test_TC_CONCON_1_14" + "Test_TC_APPOBSERVER_13_2" ], "MultipleFabrics": [ "Test_TC_CADMIN_1_1", diff --git a/src/app/tests/test-ember-api.cpp b/src/app/tests/test-ember-api.cpp new file mode 100644 index 00000000000000..2b630327a21897 --- /dev/null +++ b/src/app/tests/test-ember-api.cpp @@ -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. + */ + +#include +#include +#include +#include +#include + +chip::EndpointId chip::Test::numEndpoints = 0; + +// Used by the code in TestPowerSourceCluster.cpp (and generally things using mock ember functions may need this). +uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster, + uint16_t fixedClusterServerEndpointCount) +{ + // Very simple mapping here, we're just going to return the endpoint that matches the given endpoint index because the test + // uses the endpoints in order. + if (endpoint >= chip::Test::numEndpoints) + { + return kEmberInvalidEndpointIndex; + } + return endpoint; +} diff --git a/src/app/tests/test-ember-api.h b/src/app/tests/test-ember-api.h new file mode 100644 index 00000000000000..66b1afc2ebe2f6 --- /dev/null +++ b/src/app/tests/test-ember-api.h @@ -0,0 +1,28 @@ +/* + * 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 + +/// test-ember-api was created to consolidate and centralize stub functions that are related to ember and are used by the unit-tests + +namespace chip { +namespace Test { +extern chip::EndpointId numEndpoints; +} +} // namespace chip + +// Used by the code in TestPowerSourceCluster.cpp (and generally things using mock ember functions may need this). +uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster, + uint16_t fixedClusterServerEndpointCount); diff --git a/src/app/tests/test-interaction-model-api.cpp b/src/app/tests/test-interaction-model-api.cpp new file mode 100644 index 00000000000000..ae3f559424f97c --- /dev/null +++ b/src/app/tests/test-interaction-model-api.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/support/CHIPMem.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +uint8_t Test::attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE]; +size_t Test::attributeDataTLVLen = 0; + +namespace app { + +// Used by the code in TestWriteInteraction.cpp (and generally tests that interact with the WriteHandler may need this). +const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aConcreteClusterPath) +{ + // Note: This test does not make use of the real attribute metadata. + static EmberAfAttributeMetadata stub = { .defaultValue = EmberAfDefaultOrMinMaxAttributeValue(uint32_t(0)) }; + return &stub; +} + +// Used by the code in TestWriteInteraction.cpp (and generally tests that interact with the WriteHandler may need this). +CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, const ConcreteDataAttributePath & aPath, + TLV::TLVReader & aReader, WriteHandler * aWriteHandler) +{ + if (aPath.mDataVersion.HasValue() && aPath.mDataVersion.Value() == Test::kRejectedDataVersion) + { + return aWriteHandler->AddStatus(aPath, Protocols::InteractionModel::Status::DataVersionMismatch); + } + + TLV::TLVWriter writer; + writer.Init(chip::Test::attributeDataTLV); + writer.CopyElement(TLV::AnonymousTag(), aReader); + chip::Test::attributeDataTLVLen = writer.GetLengthWritten(); + return aWriteHandler->AddStatus(aPath, Protocols::InteractionModel::Status::Success); +} + +// Used by the code in TestAclAttribute.cpp (and generally tests that interact with the InteractionModelEngine may need this). +bool ConcreteAttributePathExists(const ConcreteAttributePath & aPath) +{ + return aPath.mClusterId != Test::kTestDeniedClusterId1; +} + +// Used by the code in TestAclAttribute.cpp (and generally tests that interact with the InteractionModelEngine may need this). +Protocols::InteractionModel::Status CheckEventSupportStatus(const ConcreteEventPath & aPath) +{ + if (aPath.mClusterId == Test::kTestDeniedClusterId1) + { + return Protocols::InteractionModel::Status::UnsupportedCluster; + } + + return Protocols::InteractionModel::Status::Success; +} + +// strong defintion in TestCommandInteraction.cpp +__attribute__((weak)) Protocols::InteractionModel::Status +ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath) +{ + // Mock cluster catalog, only support commands on one cluster on one endpoint. + using Protocols::InteractionModel::Status; + + return Status::Success; +} + +// strong defintion in TestCommandInteraction.cpp +__attribute__((weak)) void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, + chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj) +{} + +// Used by the code in TestReadInteraction.cpp (and generally tests that interact with the Reporting Engine may need this). +bool IsClusterDataVersionEqual(const ConcreteClusterPath & aConcreteClusterPath, DataVersion aRequiredVersion) +{ + return (Test::kTestDataVersion1 == aRequiredVersion); +} + +// Used by the code in TestReadInteraction.cpp. +bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint) +{ + return false; +} + +// Used by the code in TestReadInteraction.cpp (and generally tests that interact with the Reporting Engine may need this). +CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, + const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports, + AttributeEncodeState * apEncoderState) +{ + if (aPath.mClusterId >= Test::kMockEndpointMin) + { + return Test::ReadSingleMockClusterData(aSubjectDescriptor.fabricIndex, aPath, aAttributeReports, apEncoderState); + } + + if (!(aPath.mClusterId == Test::kTestClusterId && aPath.mEndpointId == Test::kTestEndpointId)) + { + AttributeReportIB::Builder & attributeReport = aAttributeReports.CreateAttributeReport(); + ReturnErrorOnFailure(aAttributeReports.GetError()); + ChipLogDetail(DataManagement, "TEST Cluster %" PRIx32 ", Field %" PRIx32 " is dirty", aPath.mClusterId, aPath.mAttributeId); + + AttributeStatusIB::Builder & attributeStatus = attributeReport.CreateAttributeStatus(); + ReturnErrorOnFailure(attributeReport.GetError()); + AttributePathIB::Builder & attributePath = attributeStatus.CreatePath(); + ReturnErrorOnFailure(attributeStatus.GetError()); + + attributePath.Endpoint(aPath.mEndpointId).Cluster(aPath.mClusterId).Attribute(aPath.mAttributeId).EndOfAttributePathIB(); + ReturnErrorOnFailure(attributePath.GetError()); + StatusIB::Builder & errorStatus = attributeStatus.CreateErrorStatus(); + ReturnErrorOnFailure(attributeStatus.GetError()); + errorStatus.EncodeStatusIB(StatusIB(Protocols::InteractionModel::Status::UnsupportedAttribute)); + ReturnErrorOnFailure(errorStatus.GetError()); + ReturnErrorOnFailure(attributeStatus.EndOfAttributeStatusIB()); + return attributeReport.EndOfAttributeReportIB(); + } + + return AttributeValueEncoder(aAttributeReports, aSubjectDescriptor, aPath, 0 /* dataVersion */).Encode(Test::kTestFieldValue1); +} + +} // namespace app + +} // namespace chip diff --git a/src/app/tests/test-interaction-model-api.h b/src/app/tests/test-interaction-model-api.h new file mode 100644 index 00000000000000..88e861b267b63b --- /dev/null +++ b/src/app/tests/test-interaction-model-api.h @@ -0,0 +1,69 @@ +/* + * 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 + +/// test-interaction-model-api was created to consolidate and centralize stub functions that are used by the Interaction Model +/// during unit-testing. + +#include +#include +#include +#include +#include +#include + +namespace chip { + +namespace Test { + +constexpr chip::ClusterId kTestDeniedClusterId1 = 1000; +constexpr chip::ClusterId kTestDeniedClusterId2 = 3; + +constexpr chip::ClusterId kTestClusterId = 6; +constexpr uint8_t kTestFieldValue1 = 1; +constexpr chip::EndpointId kTestEndpointId = 1; +constexpr chip::DataVersion kTestDataVersion1 = 3; + +constexpr chip::DataVersion kRejectedDataVersion = 1; +extern uint8_t attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE]; +extern size_t attributeDataTLVLen; + +} // namespace Test +namespace app { + +CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, + const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports, + AttributeEncodeState * apEncoderState); + +bool IsClusterDataVersionEqual(const ConcreteClusterPath & aConcreteClusterPath, DataVersion aRequiredVersion); + +CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, const ConcreteDataAttributePath & aPath, + TLV::TLVReader & aReader, WriteHandler * aWriteHandler); +const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aConcreteClusterPath); + +bool ConcreteAttributePathExists(const ConcreteAttributePath & aPath); +Protocols::InteractionModel::Status CheckEventSupportStatus(const ConcreteEventPath & aPath); + +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath); + +void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, + CommandHandler * apCommandObj); + +bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint); + +} // namespace app +} // namespace chip diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 86d2085718291d..f6db1481074e3b 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -94,6 +94,7 @@ + @@ -104,6 +105,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml index f60623455c8d24..4fb33dd9749a0e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml @@ -28,7 +28,7 @@ limitations under the License. - + General Boolean State Configuration 0x0080 diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml index 0a4039badf7c97..eb05052538d2de 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + Electrical Energy Measurement Measurement & Sensing 0x0091 @@ -52,25 +52,25 @@ limitations under the License. PeriodicEnergyExported CumulativeEnergyReset - + CumulativeEnergyMeasured - + PeriodicEnergyMeasured - + - + diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml index 69be8e08570f39..7f49a643d1b1f9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + Electrical Power Measurement Measurement & Sensing 0x0090 @@ -82,18 +82,18 @@ limitations under the License. PowerFactor NeutralCurrent - + MeasurementPeriodRanges - + - + @@ -107,7 +107,7 @@ limitations under the License. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml index cbc0882ac1b3ac..5c22b8e93be8da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml @@ -14,7 +14,7 @@ limitations under the License. - + @@ -25,7 +25,7 @@ limitations under the License. - + @@ -34,7 +34,7 @@ limitations under the License. - + @@ -55,7 +55,7 @@ limitations under the License. - + @@ -86,7 +86,7 @@ limitations under the License. - + Energy EVSE Energy Management 0x0099 @@ -177,7 +177,7 @@ limitations under the License. Allows a client to disable the EVSE from charging and discharging. - + @@ -188,7 +188,7 @@ limitations under the License. Allows a client to enable the EVSE to discharge an EV. - + Allows a client to put the EVSE into a self-diagnostics mode. @@ -205,41 +205,41 @@ limitations under the License. The GetTargetsResponse is sent in response to the GetTargets Command. - + EVConnected - + - + EVNotDetected - - - - + + + + - + EnergyTransferStarted - - - + + + - + EnergyTransferStopped - - - - + + + + - + Fault - - - - + + + + - + RFID - + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml index 22e5562ed33f7f..c4b702b701d174 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml @@ -24,7 +24,7 @@ limitations under the License. - + General Energy EVSE Mode 0x009D diff --git a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml index 7015adadc2e5e1..0269b8f0f3dcad 100644 --- a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml @@ -36,7 +36,7 @@ limitations under the License. - + @@ -103,9 +103,9 @@ limitations under the License. ClientsSupportedPerFabric - UserActiveModeTriggerHint - UserActiveModeTriggerInstruction - OperatingMode + UserActiveModeTriggerHint + UserActiveModeTriggerInstruction + OperatingMode Register a client to the end device diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index 795f7a71cf54bc..83a462c4a64a4a 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 @@ -2420,11 +2420,12 @@ limitations under the License. CHIP Matter Network Infrastructure Manager 0x0103 - 0xFFF10010 + 0x0090 Simple Endpoint + diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml index 5567bc99461893..954bd898b6aa00 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml @@ -18,7 +18,7 @@ limitations under the License. - + Microwave Oven Control Appliances Attributes and commands for configuring the microwave oven control, and reporting cooking stats. @@ -47,8 +47,8 @@ limitations under the License. MinPower MaxPower PowerStep - SupportedWatts - SelectedWattIndex + SupportedWatts + SelectedWattIndex WattRating diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml index b26f022f3cc9b4..3e4e9cfe84d86c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml @@ -23,7 +23,7 @@ limitations under the License. - + General Microwave Oven Mode 0x005E diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml index f121b6357d605b..83f2fc8b7984d4 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + Appliances Oven Cavity Operational State 0x0048 diff --git a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml index 2508b4741602b3..41f95e81cdd248 100644 --- a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml @@ -30,7 +30,7 @@ limitations under the License. - + General Oven Mode 0x0049 diff --git a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml index 2fdddcbe3560da..3bca0bd43ee8af 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml @@ -17,7 +17,7 @@ limitations under the License. - + Measurement & Sensing Power Topology 0x009C diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml new file mode 100644 index 00000000000000..f802b7ab4452c0 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + Network Infrastructure + Thread Network Directory + 0x0453 + THREAD_NETWORK_DIRECTORY_CLUSTER + Manages the names and credentials of Thread networks visible to the user. + + true + true + + + + + + PreferredExtendedPanID + + + + + ThreadNetworks + + + ThreadNetworkTableSize + + + Adds an entry to the ThreadNetworks list. + + + + + Removes an entry from the ThreadNetworks list. + + + + + Retrieves a Thread Operational Dataset from the ThreadNetworks list. + + + + + This is the response to a GetOperationalDataset request. + + + + + This event SHALL be generated when an entry in ThreadNetworks is added, removed, or had its Operational Dataset changed. + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml index 4bb545112be846..80c1cdb60c8ccc 100644 --- a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml @@ -40,7 +40,7 @@ limitations under the License. - + HVAC Valve Configuration and Control 0x0081 diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml new file mode 100644 index 00000000000000..f05faad4dae4d2 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml @@ -0,0 +1,44 @@ + + + + + + + Network Infrastructure + Wi-Fi Network Management + 0x0451 + WIFI_NETWORK_MANAGEMENT_CLUSTER + Functionality to retrieve operational information about a managed Wi-Fi network. + + true + true + + + + + SSID + + + Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. + + + + This is the response to a NetworkPassphraseRequest. + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 7213b96cf0e012..30c14436667202 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -116,6 +116,7 @@ "thermostat-cluster.xml", "thermostat-user-interface-configuration-cluster.xml", "thread-network-diagnostics-cluster.xml", + "thread-network-directory-cluster.xml", "time-format-localization-cluster.xml", "time-synchronization-cluster.xml", "timer-cluster.xml", @@ -125,6 +126,7 @@ "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", "wifi-network-diagnostics-cluster.xml", + "wifi-network-management-cluster.xml", "window-covering.xml", "matter-devices.xml", "sample-mei-cluster.xml", @@ -633,7 +635,8 @@ ], "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], - "Boolean State Configuration": ["CurrentSensitivityLevel"] + "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Wi-Fi Network Management": ["SSID"] }, "defaultReportingPolicy": "mandatory", "ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"], diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 8a4159e98f7eb8..33955572d795ec 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -114,6 +114,7 @@ "thermostat-cluster.xml", "thermostat-user-interface-configuration-cluster.xml", "thread-network-diagnostics-cluster.xml", + "thread-network-directory-cluster.xml", "time-format-localization-cluster.xml", "time-synchronization-cluster.xml", "timer-cluster.xml", @@ -123,6 +124,7 @@ "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", "wifi-network-diagnostics-cluster.xml", + "wifi-network-management-cluster.xml", "window-covering.xml", "matter-devices.xml", "sample-mei-cluster.xml", @@ -631,7 +633,8 @@ ], "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], - "Boolean State Configuration": ["CurrentSensitivityLevel"] + "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Wi-Fi Network Management": ["SSID"] }, "defaultReportingPolicy": "mandatory", "ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"], diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 2edfb272ad23e1..67083c04d3177d 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -289,6 +289,7 @@ "THREAD_NETWORK_DIAGNOSTICS_CLUSTER": [ "thread-network-diagnostics-server" ], + "THREAD_NETWORK_DIRECTORY_CLUSTER": [], "TIME_CLUSTER": [], "TIME_FORMAT_LOCALIZATION_CLUSTER": ["time-format-localization-server"], "TIME_SYNCHRONIZATION_CLUSTER": ["time-synchronization-server"], @@ -306,6 +307,7 @@ "LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"], "LAUNDRY_DRYER_CONTROLS_CLUSTER": ["laundry-dryer-controls-server"], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], + "WIFI_NETWORK_MANAGEMENT_CLUSTER": ["wifi-network-management-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], "ZLL_COMMISSIONING_CLUSTER": [] } diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp index 0e69e590df7f49..78e74bdec78b1a 100644 --- a/src/ble/BLEEndPoint.cpp +++ b/src/ble/BLEEndPoint.cpp @@ -389,7 +389,7 @@ void BLEEndPoint::FinalizeClose(uint8_t oldState, uint8_t flags, CHIP_ERROR err) // Indicate close of chipConnection to peripheral via GATT unsubscribe. Keep end point allocated until // unsubscribe completes or times out, so platform doesn't close underlying BLE connection before // we're really sure the unsubscribe request has been sent. - if (!mBle->mPlatformDelegate->UnsubscribeCharacteristic(mConnObj, &CHIP_BLE_SVC_ID, &mBle->CHIP_BLE_CHAR_2_ID)) + if (!mBle->mPlatformDelegate->UnsubscribeCharacteristic(mConnObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID)) { ChipLogError(Ble, "BtpEngine unsub failed"); @@ -750,7 +750,7 @@ CHIP_ERROR BLEEndPoint::HandleHandshakeConfirmationReceived() { // Subscribe to characteristic which peripheral will use to send indications. Prompts peripheral to send // BLE transport capabilities indication. - VerifyOrExit(mBle->mPlatformDelegate->SubscribeCharacteristic(mConnObj, &CHIP_BLE_SVC_ID, &mBle->CHIP_BLE_CHAR_2_ID), + VerifyOrExit(mBle->mPlatformDelegate->SubscribeCharacteristic(mConnObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID), err = BLE_ERROR_GATT_SUBSCRIBE_FAILED); // We just sent a GATT subscribe request, so make sure to attempt unsubscribe on close. @@ -1313,14 +1313,14 @@ bool BLEEndPoint::SendWrite(PacketBufferHandle && buf) { mConnStateFlags.Set(ConnectionStateFlag::kGattOperationInFlight); - return mBle->mPlatformDelegate->SendWriteRequest(mConnObj, &CHIP_BLE_SVC_ID, &mBle->CHIP_BLE_CHAR_1_ID, std::move(buf)); + return mBle->mPlatformDelegate->SendWriteRequest(mConnObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID, std::move(buf)); } bool BLEEndPoint::SendIndication(PacketBufferHandle && buf) { mConnStateFlags.Set(ConnectionStateFlag::kGattOperationInFlight); - return mBle->mPlatformDelegate->SendIndication(mConnObj, &CHIP_BLE_SVC_ID, &mBle->CHIP_BLE_CHAR_2_ID, std::move(buf)); + return mBle->mPlatformDelegate->SendIndication(mConnObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID, std::move(buf)); } CHIP_ERROR BLEEndPoint::StartConnectTimer() diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp index de1f8458402efa..3e1473a4a1c2c2 100644 --- a/src/ble/BleLayer.cpp +++ b/src/ble/BleLayer.cpp @@ -138,20 +138,6 @@ class BleEndPointPool // static BleEndPointPool sBLEEndPointPool; -// UUIDs used internally by BleLayer: - -const ChipBleUUID BleLayer::CHIP_BLE_CHAR_1_ID = { { // 18EE2EF5-263D-4559-959F-4F9C429F9D11 - 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, - 0x9F, 0x9D, 0x11 } }; - -const ChipBleUUID BleLayer::CHIP_BLE_CHAR_2_ID = { { // 18EE2EF5-263D-4559-959F-4F9C429F9D12 - 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, - 0x9F, 0x9D, 0x12 } }; - -const ChipBleUUID BleLayer::CHIP_BLE_CHAR_3_ID = { { // 64630238-8772-45F2-B87D-748A83218F04 - 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, - 0x21, 0x8F, 0x04 } }; - // BleTransportCapabilitiesRequestMessage implementation: void BleTransportCapabilitiesRequestMessage::SetSupportedProtocolVersion(uint8_t index, uint8_t version) @@ -486,7 +472,7 @@ bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleU PacketBufferHandle && pBuf) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write received on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId), false, ChipLogError(Ble, "Write received on unknown char")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_UUID, charId), false, ChipLogError(Ble, "Write received on unknown char")); VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Write received null buffer")); // Find matching connection end point. @@ -512,7 +498,7 @@ bool BleLayer::HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const Chi PacketBufferHandle && pBuf) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication received on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId), false, ChipLogError(Ble, "Indication received on unknown char")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId), false, ChipLogError(Ble, "Indication received on unknown char")); VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Indication received null buffer")); // Find matching connection end point. @@ -528,7 +514,7 @@ bool BleLayer::HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const Chi bool BleLayer::HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write confirmation on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId), false, ChipLogError(Ble, "Write confirmation on unknown char")); + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_UUID, charId), false, ChipLogError(Ble, "Write confirmation on unknown char")); HandleAckReceived(connObj); return true; @@ -537,7 +523,7 @@ bool BleLayer::HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const Chip bool BleLayer::HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication confirmation on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId), false, + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId), false, ChipLogError(Ble, "Indication confirmation on unknown char")); HandleAckReceived(connObj); @@ -558,7 +544,7 @@ void BleLayer::HandleAckReceived(BLE_CONNECTION_OBJECT connObj) bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe received on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false, ChipLogError(Ble, "Subscribe received on unknown char")); // Find end point already associated with BLE connection, if any. @@ -572,7 +558,7 @@ bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const Chip bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe complete on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false, ChipLogError(Ble, "Subscribe complete on unknown char")); BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj); @@ -585,7 +571,7 @@ bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const Chip bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe received on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false, ChipLogError(Ble, "Unsubscribe received on unknown char")); // Find end point already associated with BLE connection, if any. @@ -599,7 +585,7 @@ bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const Ch bool BleLayer::HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId) { VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe complete on unknown svc")); - VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false, + VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_UUID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_UUID, charId), false, ChipLogError(Ble, "Unsubscribe complete on unknown char")); // Find end point already associated with BLE connection, if any. diff --git a/src/ble/BleLayer.h b/src/ble/BleLayer.h index e7d619fe13420e..7056a09e5e14d6 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -313,13 +313,6 @@ class DLL_EXPORT BleLayer private: // Private data members: - // UUID of CHIP service characteristic used for central writes. - static const ChipBleUUID CHIP_BLE_CHAR_1_ID; - // UUID of CHIP service characteristic used for peripheral indications. - static const ChipBleUUID CHIP_BLE_CHAR_2_ID; - // UUID of CHIP service characteristic used for additional data - static const ChipBleUUID CHIP_BLE_CHAR_3_ID; - BleConnectionDelegate * mConnectionDelegate; BlePlatformDelegate * mPlatformDelegate; BleApplicationDelegate * mApplicationDelegate; diff --git a/src/ble/BleUUID.cpp b/src/ble/BleUUID.cpp index 098595fd721e5c..f42fc982e403d6 100644 --- a/src/ble/BleUUID.cpp +++ b/src/ble/BleUUID.cpp @@ -26,15 +26,6 @@ namespace chip { namespace Ble { -const ChipBleUUID CHIP_BLE_SVC_ID = { { // 0000FFF6-0000-1000-8000-00805F9B34FB - 0x00, 0x00, 0xFF, 0xF6, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, - 0xFB } }; - -inline static uint8_t HexDigitToInt(const char c) -{ - return static_cast(c >= '0' && c <= '9' ? c - '0' : tolower(c) - 'a' + 10); -} - bool UUIDsMatch(const ChipBleUUID * idOne, const ChipBleUUID * idTwo) { if ((idOne == nullptr) || (idTwo == nullptr)) @@ -44,35 +35,5 @@ bool UUIDsMatch(const ChipBleUUID * idOne, const ChipBleUUID * idTwo) return (memcmp(idOne->bytes, idTwo->bytes, 16) == 0); } -// Convert a string like "0000FFF6-0000-1000-8000-00805F9B34FB" to binary UUID -bool StringToUUID(const char * str, ChipBleUUID & uuid) -{ - constexpr size_t NUM_UUID_NIBBLES = sizeof(uuid.bytes) * 2; - size_t nibbleId = 0; - - for (; *str; ++str) - { - if (*str == '-') // skip separators - continue; - - if (!isxdigit(*str)) // invalid character! - return false; - - if (nibbleId >= NUM_UUID_NIBBLES) // too long string! - return false; - - uint8_t & byte = uuid.bytes[nibbleId / 2]; - if (nibbleId % 2 == 0) - byte = static_cast(HexDigitToInt(*str) << 4); - else - byte = static_cast(byte | HexDigitToInt(*str)); - - ++nibbleId; - } - - // All bytes were initialized? - return nibbleId == NUM_UUID_NIBBLES; -} - } /* namespace Ble */ } /* namespace chip */ diff --git a/src/ble/BleUUID.h b/src/ble/BleUUID.h index 315af9e8c76a32..37e2fdc1180f5e 100644 --- a/src/ble/BleUUID.h +++ b/src/ble/BleUUID.h @@ -22,7 +22,9 @@ #error "Please include instead!" #endif +#include #include +#include namespace chip { namespace Ble { @@ -36,11 +38,79 @@ struct ChipBleUUID uint8_t bytes[16]; }; -// UUID of CHIP BLE service. Exposed for use in scan filter. -extern const ChipBleUUID CHIP_BLE_SVC_ID; +constexpr bool isValidHexChar(char c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +constexpr uint8_t HexDigitToInt(const char c) +{ + if (c >= '0' && c <= '9') + return static_cast(c - '0'); + else + return static_cast((c >= 'a' ? c - 'a' : c - 'A') + 10); +} bool UUIDsMatch(const ChipBleUUID * idOne, const ChipBleUUID * idTwo); -bool StringToUUID(const char * str, ChipBleUUID & uuid); + +/* + * StringToUUID converts a string representation of a UUID to a binary UUID. + * The string representation must be in the format "0000FFF6-0000-1000-8000-00805F9B34FB". + * The function returns a pair of a boolean indicating whether the conversion was successful + * and the binary UUID. + * + */ +template +constexpr std::pair StringToUUID(const char (&str)[N]) +{ + constexpr size_t UUID_LEN = 16; + constexpr size_t NUM_UUID_NIBBLES = UUID_LEN * 2; + static_assert(N >= NUM_UUID_NIBBLES); + ChipBleUUID uuid{}; + + size_t nibbleId = 0; + for (size_t i = 0; i < N - 1; ++i) + { + if (str[i] == '-') + continue; + if (!isValidHexChar(str[i])) + return { false, {} }; + if (nibbleId >= NUM_UUID_NIBBLES) + return { false, {} }; + uint8_t & byte = uuid.bytes[nibbleId / 2]; + if (nibbleId % 2 == 0) + byte = static_cast(HexDigitToInt(str[i]) << 4); + else + byte = static_cast(byte | HexDigitToInt(str[i])); + ++nibbleId; + } + return { nibbleId == NUM_UUID_NIBBLES, uuid }; +} + +#define StringToUUIDConstexpr(str) \ + []() { \ + constexpr std::pair res = ::chip::Ble::StringToUUID(str); \ + static_assert(res.first, "Argument: \"" #str "\" is not valid hex string"); \ + return res.second; \ + }(); + +// UUID of CHIP BLE service. +// NOTE: lower-case string seems to be required at least by bluez when +// executing g_variant_lookup_value +// +// BlueZ API https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/org.bluez.Device.rst +// describes ServiceData as "Keys are the UUIDs in string format" however no description +// on actual case required +inline constexpr char CHIP_BLE_DESC_SHORT_UUID_STR[] = "2902"; +inline constexpr char CHIP_BLE_SERVICE_SHORT_UUID_STR[] = "fff6"; +inline constexpr char CHIP_BLE_SERVICE_LONG_UUID_STR[] = "0000fff6-0000-1000-8000-00805f9b34fb"; +inline constexpr char CHIP_BLE_CHAR_1_UUID_STR[] = "18ee2ef5-263d-4559-959f-4f9c429f9d11"; +inline constexpr char CHIP_BLE_CHAR_2_UUID_STR[] = "18ee2ef5-263d-4559-959f-4f9c429f9d12"; +inline constexpr char CHIP_BLE_CHAR_3_UUID_STR[] = "64630238-8772-45f2-b87d-748a83218f04"; +inline constexpr ChipBleUUID CHIP_BLE_SVC_ID = StringToUUIDConstexpr("0000fff6-0000-1000-8000-00805f9b34fb"); +inline constexpr ChipBleUUID CHIP_BLE_CHAR_1_UUID = StringToUUIDConstexpr("18ee2ef5-263d-4559-959f-4f9c429f9d11"); +inline constexpr ChipBleUUID CHIP_BLE_CHAR_2_UUID = StringToUUIDConstexpr("18ee2ef5-263d-4559-959f-4f9c429f9d12"); +inline constexpr ChipBleUUID CHIP_BLE_CHAR_3_UUID = StringToUUIDConstexpr("64630238-8772-45f2-b87d-748a83218f04"); } /* namespace Ble */ } /* namespace chip */ diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index 9b79037acd0ea1..968293d8a72b8f 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -44,14 +44,6 @@ namespace Ble { namespace { constexpr ChipBleUUID uuidZero{}; -constexpr ChipBleUUID uuidSvc = { { 0x00, 0x00, 0xFF, 0xF6, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, - 0xFB } }; -constexpr ChipBleUUID uuidChar1 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, - 0x11 } }; -constexpr ChipBleUUID uuidChar2 = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, - 0x12 } }; -constexpr ChipBleUUID uuidChar3 = { { 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, 0x8F, - 0x04 } }; }; // namespace @@ -111,14 +103,14 @@ class TestBleLayer : public BleLayer, { constexpr uint8_t capReq[] = { 0x65, 0x6c, 0x54, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x06 }; auto buf = System::PacketBufferHandle::NewWithData(capReq, sizeof(capReq)); - return HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf)); + return HandleWriteReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID, std::move(buf)); } // Processing subscription request after capabilities request should finalize // connection establishment. bool HandleSubscribeReceivedOnChar2(BLE_CONNECTION_OBJECT connObj) { - return HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar2); + return HandleSubscribeReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID); } /// @@ -220,7 +212,7 @@ TEST_F(TestBleLayer, HandleSubscribeReceivedInvalidUUID) { auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidZero, &uuidZero)); - EXPECT_FALSE(HandleSubscribeReceived(connObj, &uuidSvc, &uuidChar1)); + EXPECT_FALSE(HandleSubscribeReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID)); } TEST_F(TestBleLayer, HandleSubscribeReceived) @@ -234,7 +226,7 @@ TEST_F(TestBleLayer, HandleSubscribeCompleteInvalidUUID) { auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidZero, &uuidZero)); - EXPECT_FALSE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar1)); + EXPECT_FALSE(HandleSubscribeComplete(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID)); } TEST_F(TestBleLayer, HandleSubscribeComplete) @@ -243,14 +235,14 @@ TEST_F(TestBleLayer, HandleSubscribeComplete) ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); - EXPECT_TRUE(HandleSubscribeComplete(connObj, &uuidSvc, &uuidChar2)); + EXPECT_TRUE(HandleSubscribeComplete(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID)); } TEST_F(TestBleLayer, HandleUnsubscribeReceivedInvalidUUID) { auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidZero, &uuidZero)); - EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar1)); + EXPECT_FALSE(HandleUnsubscribeReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID)); } TEST_F(TestBleLayer, HandleUnsubscribeReceived) @@ -259,14 +251,14 @@ TEST_F(TestBleLayer, HandleUnsubscribeReceived) ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); - EXPECT_TRUE(HandleUnsubscribeReceived(connObj, &uuidSvc, &uuidChar2)); + EXPECT_TRUE(HandleUnsubscribeReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID)); } TEST_F(TestBleLayer, HandleUnsubscribeCompleteInvalidUUID) { auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidZero, &uuidZero)); - EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar1)); + EXPECT_FALSE(HandleUnsubscribeComplete(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID)); } TEST_F(TestBleLayer, HandleUnsubscribeComplete) @@ -275,7 +267,7 @@ TEST_F(TestBleLayer, HandleUnsubscribeComplete) ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); ASSERT_TRUE(HandleSubscribeReceivedOnChar2(connObj)); - EXPECT_TRUE(HandleUnsubscribeComplete(connObj, &uuidSvc, &uuidChar2)); + EXPECT_TRUE(HandleUnsubscribeComplete(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID)); } TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID) @@ -285,7 +277,7 @@ TEST_F(TestBleLayer, HandleWriteReceivedInvalidUUID) ASSERT_FALSE(buf.IsNull()); EXPECT_FALSE(HandleWriteReceived(connObj, &uuidZero, &uuidZero, buf.Retain())); - EXPECT_FALSE(HandleWriteReceived(connObj, &uuidSvc, &uuidChar3, std::move(buf))); + EXPECT_FALSE(HandleWriteReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_3_UUID, std::move(buf))); } TEST_F(TestBleLayer, HandleWriteReceived) @@ -300,14 +292,14 @@ TEST_F(TestBleLayer, HandleWriteReceived) auto buf = System::PacketBufferHandle::NewWithData(data, sizeof(data)); ASSERT_FALSE(buf.IsNull()); - EXPECT_TRUE(HandleWriteReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf))); + EXPECT_TRUE(HandleWriteReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID, std::move(buf))); } TEST_F(TestBleLayer, HandleWriteConfirmationInvalidUUID) { auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidZero, &uuidZero)); - EXPECT_FALSE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar2)); + EXPECT_FALSE(HandleWriteConfirmation(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID)); } TEST_F(TestBleLayer, HandleWriteConfirmationUninitialized) @@ -320,7 +312,7 @@ TEST_F(TestBleLayer, HandleWriteConfirmation) auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); - EXPECT_TRUE(HandleWriteConfirmation(connObj, &uuidSvc, &uuidChar1)); + EXPECT_TRUE(HandleWriteConfirmation(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID)); } TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID) @@ -330,7 +322,7 @@ TEST_F(TestBleLayer, HandleIndicationReceivedInvalidUUID) ASSERT_FALSE(buf.IsNull()); EXPECT_FALSE(HandleIndicationReceived(connObj, &uuidZero, &uuidZero, buf.Retain())); - EXPECT_FALSE(HandleIndicationReceived(connObj, &uuidSvc, &uuidChar1, std::move(buf))); + EXPECT_FALSE(HandleIndicationReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID, std::move(buf))); } TEST_F(TestBleLayer, HandleIndicationReceived) @@ -345,14 +337,14 @@ TEST_F(TestBleLayer, HandleIndicationReceived) auto buf = System::PacketBufferHandle::NewWithData(data, sizeof(data)); ASSERT_FALSE(buf.IsNull()); - EXPECT_TRUE(HandleIndicationReceived(connObj, &uuidSvc, &uuidChar2, std::move(buf))); + EXPECT_TRUE(HandleIndicationReceived(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID, std::move(buf))); } TEST_F(TestBleLayer, HandleIndicationConfirmationInvalidUUID) { auto connObj = GetConnectionObject(); EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidZero, &uuidZero)); - EXPECT_FALSE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar1)); + EXPECT_FALSE(HandleIndicationConfirmation(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID)); } TEST_F(TestBleLayer, HandleIndicationConfirmation) @@ -360,7 +352,7 @@ TEST_F(TestBleLayer, HandleIndicationConfirmation) auto connObj = GetConnectionObject(); ASSERT_TRUE(HandleWriteReceivedCapabilitiesRequest(connObj)); - EXPECT_TRUE(HandleIndicationConfirmation(connObj, &uuidSvc, &uuidChar2)); + EXPECT_TRUE(HandleIndicationConfirmation(connObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID)); } TEST_F(TestBleLayer, HandleConnectionError) diff --git a/src/ble/tests/TestBleUUID.cpp b/src/ble/tests/TestBleUUID.cpp index 4dbc6dd4c0fcdb..445535594fae4b 100644 --- a/src/ble/tests/TestBleUUID.cpp +++ b/src/ble/tests/TestBleUUID.cpp @@ -34,6 +34,9 @@ using namespace chip::Ble; namespace { +constexpr ChipBleUUID expectedUUID = { { 0x00, 0x00, 0xFF, 0xF6, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, + 0xFB } }; + TEST(TestBleUUID, CheckUUIDsMatch_NULL) { // Test that NULL pointer UUIDs are not equal @@ -43,46 +46,36 @@ TEST(TestBleUUID, CheckUUIDsMatch_NULL) TEST(TestBleUUID, CheckStringToUUID_ChipUUID) { // Test positive scenario - CHIP Service UUID - ChipBleUUID uuid; - EXPECT_TRUE(StringToUUID("0000FFF6-0000-1000-8000-00805F9B34FB", uuid)); - EXPECT_TRUE(UUIDsMatch(&uuid, &CHIP_BLE_SVC_ID)); + ChipBleUUID uuid = StringToUUIDConstexpr("0000FFF6-0000-1000-8000-00805F9B34FB"); + EXPECT_TRUE(UUIDsMatch(&uuid, &expectedUUID)); } TEST(TestBleUUID, CheckStringToUUID_ChipUUID_RandomCase) { // Test that letter case doesn't matter - ChipBleUUID uuid; - EXPECT_TRUE(StringToUUID("0000FfF6-0000-1000-8000-00805f9B34Fb", uuid)); - EXPECT_TRUE(UUIDsMatch(&uuid, &CHIP_BLE_SVC_ID)); + ChipBleUUID uuid = StringToUUIDConstexpr("0000FfF6-0000-1000-8000-00805f9B34Fb"); + EXPECT_TRUE(UUIDsMatch(&uuid, &expectedUUID)); } TEST(TestBleUUID, CheckStringToUUID_ChipUUID_NoSeparators) { // Test that separators don't matter - ChipBleUUID uuid; - EXPECT_TRUE(StringToUUID("0000FFF600001000800000805F9B34FB", uuid)); - EXPECT_TRUE(UUIDsMatch(&uuid, &CHIP_BLE_SVC_ID)); + ChipBleUUID uuid = StringToUUIDConstexpr("0000FFF600001000800000805F9B34FB"); + EXPECT_TRUE(UUIDsMatch(&uuid, &expectedUUID)); } TEST(TestBleUUID, CheckStringToUUID_TooLong) { // Test that even one more digit is too much - ChipBleUUID uuid; - EXPECT_FALSE(StringToUUID("0000FFF600001000800000805F9B34FB0", uuid)); -} - -TEST(TestBleUUID, CheckStringToUUID_TooShort) -{ - // Test that even one less digit is too little - ChipBleUUID uuid; - EXPECT_FALSE(StringToUUID("0000FFF600001000800000805F9B34F", uuid)); + auto result = StringToUUID("0000FFF600001000800000805F9B34FB0"); + EXPECT_FALSE(result.first); } TEST(TestBleUUID, CheckStringToUUID_InvalidChar) { // Test that non-hex digits don't pass - ChipBleUUID uuid; - EXPECT_FALSE(StringToUUID("0000GFF6-0000-1000-8000-00805F9B34FB0", uuid)); + auto result = StringToUUID("0000GFF6-0000-1000-8000-00805F9B34FB"); + EXPECT_FALSE(result.first); } } // namespace diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 5b37988a491260..a72543853fa2d1 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -125,6 +125,8 @@ CHIP_ERROR AutoCommissioner::SetCommissioningParameters(const CommissioningParam mParams = params; + mNeedIcdRegistration = false; + if (haveMaybeDanglingBufferPointers) { mParams.ClearExternalBufferDependentValues(); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 1381ed3381a649..75c95ee20abc06 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1326,8 +1326,8 @@ void DeviceCommissioner::OnICDManagementRegisterClientResponse( if (commissioner->mPairingDelegate != nullptr) { - commissioner->mPairingDelegate->OnICDRegistrationComplete(commissioner->mDeviceBeingCommissioned->GetDeviceId(), - data.ICDCounter); + commissioner->mPairingDelegate->OnICDRegistrationComplete( + ScopedNodeId(commissioner->mDeviceBeingCommissioned->GetDeviceId(), commissioner->GetFabricIndex()), data.ICDCounter); } exit: @@ -1346,8 +1346,10 @@ void DeviceCommissioner::OnICDManagementStayActiveResponse( if (commissioner->mPairingDelegate != nullptr) { - commissioner->mPairingDelegate->OnICDStayActiveComplete(commissioner->mDeviceBeingCommissioned->GetDeviceId(), - data.promisedActiveDuration); + commissioner->mPairingDelegate->OnICDStayActiveComplete( + + ScopedNodeId(commissioner->mDeviceBeingCommissioned->GetDeviceId(), commissioner->GetFabricIndex()), + data.promisedActiveDuration); } exit: diff --git a/src/controller/CommissionerDiscoveryController.cpp b/src/controller/CommissionerDiscoveryController.cpp index 4df133c59e99f3..d1a5747491ad50 100644 --- a/src/controller/CommissionerDiscoveryController.cpp +++ b/src/controller/CommissionerDiscoveryController.cpp @@ -219,6 +219,34 @@ void CommissionerDiscoveryController::InternalOk() ChipLogError(AppServer, "UX InternalOk: could not find instance=%s", mCurrentInstance); return; } + + if (mAppInstallationService == nullptr) + { + ChipLogError(AppServer, "UX InternalOk: no app installation service"); + return; + } + + if (!mAppInstallationService->LookupTargetContentApp(client->GetVendorId(), client->GetProductId())) + { + ChipLogDetail(AppServer, "UX InternalOk: app not installed."); + + // notify client that app will be installed + CommissionerDeclaration cd; + cd.SetErrorCode(CommissionerDeclaration::CdError::kAppInstallConsentPending); + mUdcServer->SendCDCMessage(cd, Transport::PeerAddress::UDP(client->GetPeerAddress().GetIPAddress(), client->GetCdPort())); + + // dialog + ChipLogDetail(Controller, "------PROMPT USER: %s is requesting to install app on this TV. vendorId=%d, productId=%d", + client->GetDeviceName(), client->GetVendorId(), client->GetProductId()); + + if (mUserPrompter != nullptr) + { + mUserPrompter->PromptForAppInstallOKPermission(client->GetVendorId(), client->GetProductId(), client->GetDeviceName()); + } + ChipLogDetail(Controller, "------Via Shell Enter: app install "); + return; + } + if (client->GetUDCClientProcessingState() != UDCClientProcessingState::kPromptingUser) { ChipLogError(AppServer, "UX InternalOk: invalid state for ok"); @@ -244,6 +272,7 @@ void CommissionerDiscoveryController::InternalOk() CharSpan rotatingIdSpan(rotatingIdBuffer, 2 * rotatingIdLength); uint8_t targetAppCount = client->GetNumTargetAppInfos(); + if (targetAppCount > 0) { ChipLogDetail(AppServer, "UX InternalOk: checking for each target app specified"); @@ -583,6 +612,7 @@ void CommissionerDiscoveryController::Cancel() } client->SetUDCClientProcessingState(UDCClientProcessingState::kUserDeclined); mPendingConsent = false; + ResetState(); } void CommissionerDiscoveryController::CommissioningSucceeded(uint16_t vendorId, uint16_t productId, NodeId nodeId, diff --git a/src/controller/CommissionerDiscoveryController.h b/src/controller/CommissionerDiscoveryController.h index 521fe5c611dc3c..b2211641fd0ede 100644 --- a/src/controller/CommissionerDiscoveryController.h +++ b/src/controller/CommissionerDiscoveryController.h @@ -150,6 +150,21 @@ class DLL_EXPORT UserPrompter */ virtual void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) = 0; + /** + * @brief + * Called to prompt the user for consent to allow the app commissioneeName/vendorId/productId to be installed. + * For example "[commissioneeName] is requesting permission to install app to this TV, approve?" + * + * If user responds with OK then implementor should call CommissionerRespondOk(); + * If user responds with Cancel then implementor should call CommissionerRespondCancel(); + * + * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] commissioneeName The commissioneeName in the DNS-SD advertisement of the requesting commissionee. + * + */ + virtual void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0; + virtual ~UserPrompter() = default; }; @@ -158,7 +173,7 @@ class DLL_EXPORT PasscodeService public: /** * @brief - * Called to determine if the given target app is available to the commissionee with the given given + * Called to determine if the given target app is available to the commissionee with the given * vendorId/productId, and if so, return the passcode. * * This will be called by the main chip thread so any blocking work should be moved to a separate thread. @@ -204,6 +219,25 @@ class DLL_EXPORT PasscodeService virtual ~PasscodeService() = default; }; +class DLL_EXPORT AppInstallationService +{ +public: + /** + * @brief + * Called to check if the given target app is available to the commissione with th given + * vendorId/productId + * + * This will be called by the main chip thread so any blocking work should be moved to a separate thread. + * + * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. + * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. + * + */ + virtual bool LookupTargetContentApp(uint16_t vendorId, uint16_t productId) = 0; + + virtual ~AppInstallationService() = default; +}; + class DLL_EXPORT PostCommissioningListener { public: @@ -392,6 +426,14 @@ class CommissionerDiscoveryController : public chip::Protocols::UserDirectedComm inline void SetPasscodeService(PasscodeService * passcodeService) { mPasscodeService = passcodeService; } inline PasscodeService * GetPasscodeService() { return mPasscodeService; } + /** + * Assign an AppInstallationService + */ + inline void SetAppInstallationService(AppInstallationService * appInstallationService) + { + mAppInstallationService = appInstallationService; + } + /** * Assign a Commissioner Callback to perform commissioning once user consent has been given */ @@ -430,6 +472,7 @@ class CommissionerDiscoveryController : public chip::Protocols::UserDirectedComm UserDirectedCommissioningServer * mUdcServer = nullptr; UserPrompter * mUserPrompter = nullptr; PasscodeService * mPasscodeService = nullptr; + AppInstallationService * mAppInstallationService = nullptr; CommissionerCallback * mCommissionerCallback = nullptr; PostCommissioningListener * mPostCommissioningListener = nullptr; }; diff --git a/src/controller/DevicePairingDelegate.h b/src/controller/DevicePairingDelegate.h index 558a6c16a6bc2e..849df45436d9e8 100644 --- a/src/controller/DevicePairingDelegate.h +++ b/src/controller/DevicePairingDelegate.h @@ -136,7 +136,7 @@ class DLL_EXPORT DevicePairingDelegate * @param[in] icdNodeId The node id of the ICD. * @param[in] icdCounter The ICD Counter received from the device. */ - virtual void OnICDRegistrationComplete(NodeId icdNodeId, uint32_t icdCounter) {} + virtual void OnICDRegistrationComplete(ScopedNodeId icdNodeId, uint32_t icdCounter) {} /** * @brief @@ -147,7 +147,7 @@ class DLL_EXPORT DevicePairingDelegate * @param[in] promisedActiveDurationMsec The actual duration that the ICD server can stay active * from the time it receives the StayActiveRequest command. */ - virtual void OnICDStayActiveComplete(NodeId icdNodeId, uint32_t promisedActiveDurationMsec) {} + virtual void OnICDStayActiveComplete(ScopedNodeId icdNodeId, uint32_t promisedActiveDurationMsec) {} }; } // namespace Controller diff --git a/src/controller/README.md b/src/controller/README.md index e46c191f55489b..70a3fa5e8f8352 100644 --- a/src/controller/README.md +++ b/src/controller/README.md @@ -26,7 +26,7 @@ The POSIX CLI chip-tool is located in ### Python -The Python chip-device-ctrl is located in +The Python CHIP Controller library is located in [../controller/python/](../controller/python). ## Feature Overview diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 4e99c7ebe5d260..ab2e0db009c888 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -2804,7 +2804,7 @@ provisional cluster Timer = 71 { } /** This cluster supports remotely monitoring and, where supported, changing the operational state of an Oven. */ -provisional cluster OvenCavityOperationalState = 72 { +cluster OvenCavityOperationalState = 72 { revision 1; enum ErrorStateEnum : enum8 { @@ -2870,7 +2870,7 @@ provisional cluster OvenCavityOperationalState = 72 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster OvenMode = 73 { +cluster OvenMode = 73 { revision 1; enum ModeTag : enum16 { @@ -3526,7 +3526,7 @@ cluster DishwasherAlarm = 93 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster MicrowaveOvenMode = 94 { +cluster MicrowaveOvenMode = 94 { revision 1; enum ModeTag : enum16 { @@ -3560,7 +3560,7 @@ provisional cluster MicrowaveOvenMode = 94 { } /** Attributes and commands for configuring the microwave oven control, and reporting cooking stats. */ -provisional cluster MicrowaveOvenControl = 95 { +cluster MicrowaveOvenControl = 95 { revision 1; // NOTE: Default/not specifically set bitmap Feature : bitmap32 { @@ -3988,7 +3988,7 @@ cluster ActivatedCarbonFilterMonitoring = 114 { } /** This cluster is used to configure a boolean sensor. */ -provisional cluster BooleanStateConfiguration = 128 { +cluster BooleanStateConfiguration = 128 { revision 1; bitmap AlarmModeBitmap : bitmap8 { @@ -4046,7 +4046,7 @@ provisional cluster BooleanStateConfiguration = 128 { } /** This cluster is used to configure a valve. */ -provisional cluster ValveConfigurationAndControl = 129 { +cluster ValveConfigurationAndControl = 129 { revision 1; enum StatusCodeEnum : enum8 { @@ -4112,7 +4112,7 @@ provisional cluster ValveConfigurationAndControl = 129 { } /** This cluster provides a mechanism for querying data about electrical power as measured by the server. */ -provisional cluster ElectricalPowerMeasurement = 144 { +cluster ElectricalPowerMeasurement = 144 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -4217,7 +4217,7 @@ provisional cluster ElectricalPowerMeasurement = 144 { } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ -provisional cluster ElectricalEnergyMeasurement = 145 { +cluster ElectricalEnergyMeasurement = 145 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -4803,7 +4803,7 @@ provisional cluster DeviceEnergyManagement = 152 { } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ -provisional cluster EnergyEvse = 153 { +cluster EnergyEvse = 153 { revision 2; enum EnergyTransferStoppedReasonEnum : enum8 { @@ -5015,7 +5015,7 @@ provisional cluster EnergyPreference = 155 { } /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ -provisional cluster PowerTopology = 156 { +cluster PowerTopology = 156 { revision 1; bitmap Feature : bitmap32 { @@ -5036,7 +5036,7 @@ provisional cluster PowerTopology = 156 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster EnergyEvseMode = 157 { +cluster EnergyEvseMode = 157 { revision 1; enum ModeTag : enum16 { @@ -7654,6 +7654,74 @@ cluster RadonConcentrationMeasurement = 1071 { readonly attribute int16u clusterRevision = 65533; } +/** Functionality to retrieve operational information about a managed Wi-Fi network. */ +cluster WiFiNetworkManagement = 1105 { + revision 1; + + readonly attribute nullable octet_string<32> ssid = 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; + + response struct NetworkPassphraseResponse = 1 { + octet_string<64> passphrase = 0; + } + + /** Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. */ + command access(invoke: administer) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0; +} + +/** Manages the names and credentials of Thread networks visible to the user. */ +cluster ThreadNetworkDirectory = 1107 { + revision 1; + + struct ThreadNetworkStruct { + int64u extendedPanID = 0; + char_string<16> networkName = 1; + int16u channel = 2; + } + + info event access(read: operate) NetworkChanged = 0 { + int64u extendedPanID = 0; + } + + attribute access(read: manage, write: manage) nullable int64u preferredExtendedPanID = 0; + readonly attribute access(read: operate) ThreadNetworkStruct threadNetworks[] = 1; + readonly attribute int8u threadNetworkTableSize = 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 AddNetworkRequest { + octet_string<254> operationalDataset = 0; + } + + request struct RemoveNetworkRequest { + int64u extendedPanID = 0; + } + + request struct GetOperationalDatasetRequest { + int64u extendedPanID = 0; + } + + response struct OperationalDatasetResponse = 3 { + octet_string<254> operationalDataset = 0; + } + + /** Adds an entry to the ThreadNetworks list. */ + timed command access(invoke: manage) AddNetwork(AddNetworkRequest): DefaultSuccess = 0; + /** Removes an entry from the ThreadNetworks list. */ + timed command access(invoke: manage) RemoveNetwork(RemoveNetworkRequest): DefaultSuccess = 1; + /** Retrieves a Thread Operational Dataset from the ThreadNetworks list. */ + timed command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2; +} + /** This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol. */ cluster WakeOnLan = 1283 { revision 1; diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 1576e5883ca256..87f53735bcf617 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -25,6 +25,8 @@ #include +#include + #include #include #include @@ -992,13 +994,13 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationInfoRequired() env->CallVoidMethod(mJavaObjectRef.ObjectRef(), onICDRegistrationInfoRequiredMethod); } -void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) +void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::ScopedNodeId icdNodeId, uint32_t icdCounter) { chip::DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; chip::app::ICDClientInfo clientInfo; - clientInfo.peer_node = ScopedNodeId(icdNodeId, Controller()->GetFabricIndex()); + clientInfo.peer_node = icdNodeId; clientInfo.monitored_subject = mAutoCommissioner.GetCommissioningParameters().GetICDMonitoredSubject().Value(); clientInfo.start_icd_counter = icdCounter; @@ -1012,13 +1014,13 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdN if (err == CHIP_NO_ERROR) { - ChipLogProgress(Controller, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(icdNodeId)); + ChipLogProgress(Controller, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(icdNodeId.GetNodeId())); } else { getICDClientStorage()->RemoveKey(clientInfo); - ChipLogError(Controller, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", ChipLogValueX64(icdNodeId), - err.AsString()); + ChipLogError(Controller, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", + ChipLogValueX64(icdNodeId.GetNodeId()), err.AsString()); } mDeviceIsICD = true; @@ -1053,7 +1055,7 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdN icdDeviceInfoObj = env->NewObject( icdDeviceInfoClass, icdDeviceInfoStructCtor, jSymmetricKey, static_cast(mUserActiveModeTriggerHint.Raw()), jUserActiveModeTriggerInstruction, static_cast(mIdleModeDuration), static_cast(mActiveModeDuration), - static_cast(mActiveModeThreshold), static_cast(icdNodeId), static_cast(icdCounter), + static_cast(mActiveModeThreshold), static_cast(icdNodeId.GetNodeId()), static_cast(icdCounter), static_cast(mAutoCommissioner.GetCommissioningParameters().GetICDMonitoredSubject().Value()), static_cast(Controller()->GetFabricId()), static_cast(Controller()->GetFabricIndex())); @@ -1063,7 +1065,7 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdN CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { - ChipLogProgress(chipTool, "KVS: Getting key %s", StringOrNullMarker(key)); + ChipLogProgress(Controller, "KVS: Getting key %s", StringOrNullMarker(key)); size_t read_size = 0; @@ -1076,12 +1078,25 @@ CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, voi CHIP_ERROR AndroidDeviceControllerWrapper::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { - ChipLogProgress(chipTool, "KVS: Setting key %s", StringOrNullMarker(key)); + ChipLogProgress(Controller, "KVS: Setting key %s", StringOrNullMarker(key)); return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(key, value, size); } CHIP_ERROR AndroidDeviceControllerWrapper::SyncDeleteKeyValue(const char * key) { - ChipLogProgress(chipTool, "KVS: Deleting key %s", StringOrNullMarker(key)); + ChipLogProgress(Controller, "KVS: Deleting key %s", StringOrNullMarker(key)); return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(key); } + +void AndroidDeviceControllerWrapper::StartDnssd() +{ + FabricTable * fabricTable = DeviceControllerFactory::GetInstance().GetSystemState()->Fabrics(); + VerifyOrReturn(fabricTable != nullptr, ChipLogError(Controller, "Fail to get fabricTable in StartDnssd")); + chip::app::DnssdServer::Instance().SetFabricTable(fabricTable); + chip::app::DnssdServer::Instance().StartServer(); +} + +void AndroidDeviceControllerWrapper::StopDnssd() +{ + chip::app::DnssdServer::Instance().StopServer(); +} diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index 51beae2d0eba48..02d50499bbbcda 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -118,7 +118,7 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse) override; void OnScanNetworksFailure(CHIP_ERROR error) override; void OnICDRegistrationInfoRequired() override; - void OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) override; + void OnICDRegistrationComplete(chip::ScopedNodeId icdNodeId, uint32_t icdCounter) override; // PersistentStorageDelegate implementation CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; @@ -214,6 +214,10 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel CHIP_ERROR SetICDCheckInDelegate(jobject checkInDelegate); + void StartDnssd(); + + void StopDnssd(); + private: using ChipDeviceControllerPtr = std::unique_ptr; diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index e22c50cd023788..ec522e367c60f4 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -262,7 +262,11 @@ kotlin_library("tlv") { "src/matter/tlv/values.kt", ] - kotlinc_flags = [ "-Xlint:deprecation" ] + kotlinc_flags = [ + "-Xlint:deprecation", + "-module-name", + "com.matter.tlv", + ] } kotlin_library("tlv_reader_test") { @@ -323,7 +327,11 @@ kotlin_library("jsontlv") { "src/matter/jsontlv/types.kt", ] - kotlinc_flags = [ "-Xlint:deprecation" ] + kotlinc_flags = [ + "-Xlint:deprecation", + "-module-name", + "com.matter.matterjson", + ] } kotlin_library("json_to_tlv_to_json_test") { @@ -363,6 +371,10 @@ kotlin_library("onboarding_payload") { "src/matter/onboardingpayload/Verhoeff.kt", "src/matter/onboardingpayload/Verhoeff10.kt", ] + kotlinc_flags = [ + "-module-name", + "com.matter.onboarding", + ] } kotlin_library("onboardingpayload_manual_code_test") { @@ -404,7 +416,11 @@ kotlin_library("chipcluster") { sources = structs_sources sources += eventstructs_sources - kotlinc_flags = [ "-Xlint:deprecation" ] + kotlinc_flags = [ + "-Xlint:deprecation", + "-module-name", + "com.matter.chipcluster", + ] } kotlin_library("chipcluster_test") { diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 9b3d10a2bf1d31..a6c93c55885070 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -2154,6 +2154,28 @@ JNI_METHOD(jbyteArray, validateAndExtractCSR)(JNIEnv * env, jclass clazz, jbyteA return javaCsr; } +JNI_METHOD(void, startDnssd)(JNIEnv * env, jobject self, jlong handle) +{ + ChipLogProgress(Controller, "startDnssd() called"); + chip::DeviceLayer::StackLock lock; + + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + VerifyOrReturn(wrapper != nullptr, + ChipLogError(Controller, "AndroidDeviceControllerWrapper::FromJNIHandle in startDnssd fails!")); + wrapper->StartDnssd(); +} + +JNI_METHOD(void, stopDnssd)(JNIEnv * env, jobject self, jlong handle) +{ + ChipLogProgress(Controller, "stopDnssd() called"); + chip::DeviceLayer::StackLock lock; + + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + VerifyOrReturn(wrapper != nullptr, + ChipLogError(Controller, "AndroidDeviceControllerWrapper::FromJNIHandle in stopDnssd fails!")); + wrapper->StopDnssd(); +} + void * IOThreadMain(void * arg) { JNIEnv * env; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 2e64d37cd62b11..7a16c3355daf4f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -52829,6 +52829,616 @@ public void onSuccess(byte[] tlv) { } } + public static class WiFiNetworkManagementCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1105L; + + private static final long SSID_ATTRIBUTE_ID = 1L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public WiFiNetworkManagementCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void networkPassphraseRequest(NetworkPassphraseResponseCallback callback) { + networkPassphraseRequest(callback, 0); + } + + public void networkPassphraseRequest(NetworkPassphraseResponseCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long passphraseFieldID = 0L; + byte[] passphrase = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == passphraseFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + passphrase = castingValue.value(byte[].class); + } + } + } + callback.onSuccess(passphrase); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface NetworkPassphraseResponseCallback extends BaseClusterCallback { + void onSuccess(byte[] passphrase); + } + + public interface SsidAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable byte[] value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readSsidAttribute( + SsidAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SSID_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable byte[] value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SSID_ATTRIBUTE_ID, true); + } + + public void subscribeSsidAttribute( + SsidAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SSID_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable byte[] value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SSID_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + + public static class ThreadNetworkDirectoryCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1107L; + + private static final long PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID = 0L; + private static final long THREAD_NETWORKS_ATTRIBUTE_ID = 1L; + private static final long THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID = 2L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public ThreadNetworkDirectoryCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + + public void addNetwork(DefaultClusterCallback callback, byte[] operationalDataset, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long operationalDatasetFieldID = 0L; + BaseTLVType operationalDatasettlvValue = new ByteArrayType(operationalDataset); + elements.add(new StructElement(operationalDatasetFieldID, operationalDatasettlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + + public void removeNetwork(DefaultClusterCallback callback, Long extendedPanID, int timedInvokeTimeoutMs) { + final long commandId = 1L; + + ArrayList elements = new ArrayList<>(); + final long extendedPanIDFieldID = 0L; + BaseTLVType extendedPanIDtlvValue = new UIntType(extendedPanID); + elements.add(new StructElement(extendedPanIDFieldID, extendedPanIDtlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + + public void getOperationalDataset(OperationalDatasetResponseCallback callback, Long extendedPanID, int timedInvokeTimeoutMs) { + final long commandId = 2L; + + ArrayList elements = new ArrayList<>(); + final long extendedPanIDFieldID = 0L; + BaseTLVType extendedPanIDtlvValue = new UIntType(extendedPanID); + elements.add(new StructElement(extendedPanIDFieldID, extendedPanIDtlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long operationalDatasetFieldID = 0L; + byte[] operationalDataset = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == operationalDatasetFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + operationalDataset = castingValue.value(byte[].class); + } + } + } + callback.onSuccess(operationalDataset); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface OperationalDatasetResponseCallback extends BaseClusterCallback { + void onSuccess(byte[] operationalDataset); + } + + public interface PreferredExtendedPanIDAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + + public interface ThreadNetworksAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readPreferredExtendedPanIDAttribute( + PreferredExtendedPanIDAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID, true); + } + + public void writePreferredExtendedPanIDAttribute(DefaultClusterCallback callback, Long value) { + writePreferredExtendedPanIDAttribute(callback, value, 0); + } + + public void writePreferredExtendedPanIDAttribute(DefaultClusterCallback callback, Long value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribePreferredExtendedPanIDAttribute( + PreferredExtendedPanIDAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PREFERRED_EXTENDED_PAN_I_D_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readThreadNetworksAttribute( + ThreadNetworksAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORKS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_NETWORKS_ATTRIBUTE_ID, true); + } + + public void subscribeThreadNetworksAttribute( + ThreadNetworksAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORKS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_NETWORKS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readThreadNetworkTableSizeAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID, true); + } + + public void subscribeThreadNetworkTableSizeAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, THREAD_NETWORK_TABLE_SIZE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class WakeOnLanCluster extends BaseChipCluster { public static final long CLUSTER_ID = 1283L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index ce1a79c5a4a710..d25d80c3f791fc 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -5584,6 +5584,52 @@ public String toString() { return output.toString(); } } +public static class ThreadNetworkDirectoryClusterNetworkChangedEvent { + public Long extendedPanID; + private static final long EXTENDED_PAN_I_D_ID = 0L; + + public ThreadNetworkDirectoryClusterNetworkChangedEvent( + Long extendedPanID + ) { + this.extendedPanID = extendedPanID; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(EXTENDED_PAN_I_D_ID, new UIntType(extendedPanID))); + + return new StructType(values); + } + + public static ThreadNetworkDirectoryClusterNetworkChangedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long extendedPanID = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == EXTENDED_PAN_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + extendedPanID = castingValue.value(Long.class); + } + } + } + return new ThreadNetworkDirectoryClusterNetworkChangedEvent( + extendedPanID + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ThreadNetworkDirectoryClusterNetworkChangedEvent {\n"); + output.append("\textendedPanID: "); + output.append(extendedPanID); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class TargetNavigatorClusterTargetUpdatedEvent { public ArrayList targetList; public Integer currentTarget; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 7730f05efe734a..c8d48cce340e23 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -9277,6 +9277,82 @@ public String toString() { return output.toString(); } } +public static class ThreadNetworkDirectoryClusterThreadNetworkStruct { + public Long extendedPanID; + public String networkName; + public Integer channel; + private static final long EXTENDED_PAN_I_D_ID = 0L; + private static final long NETWORK_NAME_ID = 1L; + private static final long CHANNEL_ID = 2L; + + public ThreadNetworkDirectoryClusterThreadNetworkStruct( + Long extendedPanID, + String networkName, + Integer channel + ) { + this.extendedPanID = extendedPanID; + this.networkName = networkName; + this.channel = channel; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(EXTENDED_PAN_I_D_ID, new UIntType(extendedPanID))); + values.add(new StructElement(NETWORK_NAME_ID, new StringType(networkName))); + values.add(new StructElement(CHANNEL_ID, new UIntType(channel))); + + return new StructType(values); + } + + public static ThreadNetworkDirectoryClusterThreadNetworkStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long extendedPanID = null; + String networkName = null; + Integer channel = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == EXTENDED_PAN_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + extendedPanID = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == NETWORK_NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + networkName = castingValue.value(String.class); + } + } else if (element.contextTagNum() == CHANNEL_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + channel = castingValue.value(Integer.class); + } + } + } + return new ThreadNetworkDirectoryClusterThreadNetworkStruct( + extendedPanID, + networkName, + channel + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ThreadNetworkDirectoryClusterThreadNetworkStruct {\n"); + output.append("\textendedPanID: "); + output.append(extendedPanID); + output.append("\n"); + output.append("\tnetworkName: "); + output.append(networkName); + output.append("\n"); + output.append("\tchannel: "); + output.append(channel); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class ChannelClusterProgramCastStruct { public String name; public String role; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 3437b8a981e476..cd89fd9df6d472 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -328,6 +328,12 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == RadonConcentrationMeasurement.ID) { return new RadonConcentrationMeasurement(); } + if (clusterId == WiFiNetworkManagement.ID) { + return new WiFiNetworkManagement(); + } + if (clusterId == ThreadNetworkDirectory.ID) { + return new ThreadNetworkDirectory(); + } if (clusterId == WakeOnLan.ID) { return new WakeOnLan(); } @@ -14313,6 +14319,266 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class WiFiNetworkManagement implements BaseCluster { + public static final long ID = 1105L; + public long getID() { + return ID; + } + + public enum Attribute { + Ssid(1L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + NetworkPassphraseRequest(0L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } + public static class ThreadNetworkDirectory implements BaseCluster { + public static final long ID = 1107L; + public long getID() { + return ID; + } + + public enum Attribute { + PreferredExtendedPanID(0L), + ThreadNetworks(1L), + ThreadNetworkTableSize(2L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event { + NetworkChanged(0L),; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + AddNetwork(0L), + RemoveNetwork(1L), + GetOperationalDataset(2L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum AddNetworkCommandField {OperationalDataset(0),; + private final int id; + AddNetworkCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static AddNetworkCommandField value(int id) throws NoSuchFieldError { + for (AddNetworkCommandField field : AddNetworkCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum RemoveNetworkCommandField {ExtendedPanID(0),; + private final int id; + RemoveNetworkCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static RemoveNetworkCommandField value(int id) throws NoSuchFieldError { + for (RemoveNetworkCommandField field : RemoveNetworkCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum GetOperationalDatasetCommandField {ExtendedPanID(0),; + private final int id; + GetOperationalDatasetCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static GetOperationalDatasetCommandField value(int id) throws NoSuchFieldError { + for (GetOperationalDatasetCommandField field : GetOperationalDatasetCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class WakeOnLan implements BaseCluster { public static final long ID = 1283L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 4ded328fad6ed5..47ee02f5ede86c 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -17299,6 +17299,281 @@ public void onError(Exception ex) { } } + + public static class DelegatedWiFiNetworkManagementClusterNetworkPassphraseResponseCallback implements ChipClusters.WiFiNetworkManagementCluster.NetworkPassphraseResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(byte[] passphrase) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo passphraseResponseValue = new CommandResponseInfo("passphrase", "byte[]"); + responseValues.put(passphraseResponseValue, passphrase); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedWiFiNetworkManagementClusterSsidAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.SsidAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable byte[] value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "byte[]"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWiFiNetworkManagementClusterGeneratedCommandListAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWiFiNetworkManagementClusterAcceptedCommandListAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWiFiNetworkManagementClusterEventListAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWiFiNetworkManagementClusterAttributeListAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + + public static class DelegatedThreadNetworkDirectoryClusterOperationalDatasetResponseCallback implements ChipClusters.ThreadNetworkDirectoryCluster.OperationalDatasetResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(byte[] operationalDataset) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo operationalDatasetResponseValue = new CommandResponseInfo("operationalDataset", "byte[]"); + responseValues.put(operationalDatasetResponseValue, operationalDataset); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedThreadNetworkDirectoryClusterPreferredExtendedPanIDAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.PreferredExtendedPanIDAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Long value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadNetworkDirectoryClusterThreadNetworksAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.ThreadNetworksAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadNetworkDirectoryClusterGeneratedCommandListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadNetworkDirectoryClusterAcceptedCommandListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadNetworkDirectoryClusterEventListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedThreadNetworkDirectoryClusterAttributeListAttributeCallback implements ChipClusters.ThreadNetworkDirectoryCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedWakeOnLanClusterGeneratedCommandListAttributeCallback implements ChipClusters.WakeOnLanCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21177,6 +21452,14 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.RadonConcentrationMeasurementCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("radonConcentrationMeasurement", radonConcentrationMeasurementClusterInfo); + ClusterInfo wiFiNetworkManagementClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.WiFiNetworkManagementCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("wiFiNetworkManagement", wiFiNetworkManagementClusterInfo); + + ClusterInfo threadNetworkDirectoryClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.ThreadNetworkDirectoryCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("threadNetworkDirectory", threadNetworkDirectoryClusterInfo); + ClusterInfo wakeOnLanClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.WakeOnLanCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("wakeOnLan", wakeOnLanClusterInfo); @@ -21353,6 +21636,8 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("radonConcentrationMeasurement", radonConcentrationMeasurementClusterInteractionInfoMap); + Map wiFiNetworkManagementClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map wiFiNetworkManagementnetworkPassphraseRequestCommandParams = new LinkedHashMap(); + InteractionInfo wiFiNetworkManagementnetworkPassphraseRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster) + .networkPassphraseRequest((ChipClusters.WiFiNetworkManagementCluster.NetworkPassphraseResponseCallback) callback + ); + }, + () -> new DelegatedWiFiNetworkManagementClusterNetworkPassphraseResponseCallback(), + wiFiNetworkManagementnetworkPassphraseRequestCommandParams + ); + wiFiNetworkManagementClusterInteractionInfoMap.put("networkPassphraseRequest", wiFiNetworkManagementnetworkPassphraseRequestInteractionInfo); + + commandMap.put("wiFiNetworkManagement", wiFiNetworkManagementClusterInteractionInfoMap); + + Map threadNetworkDirectoryClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map threadNetworkDirectoryaddNetworkCommandParams = new LinkedHashMap(); + + CommandParameterInfo threadNetworkDirectoryaddNetworkoperationalDatasetCommandParameterInfo = new CommandParameterInfo("operationalDataset", byte[].class, byte[].class); + threadNetworkDirectoryaddNetworkCommandParams.put("operationalDataset",threadNetworkDirectoryaddNetworkoperationalDatasetCommandParameterInfo); + InteractionInfo threadNetworkDirectoryaddNetworkInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster) + .addNetwork((DefaultClusterCallback) callback + , (byte[]) + commandArguments.get("operationalDataset"), 10000 + ); + }, + () -> new DelegatedDefaultClusterCallback(), + threadNetworkDirectoryaddNetworkCommandParams + ); + threadNetworkDirectoryClusterInteractionInfoMap.put("addNetwork", threadNetworkDirectoryaddNetworkInteractionInfo); + + Map threadNetworkDirectoryremoveNetworkCommandParams = new LinkedHashMap(); + + CommandParameterInfo threadNetworkDirectoryremoveNetworkextendedPanIDCommandParameterInfo = new CommandParameterInfo("extendedPanID", Long.class, Long.class); + threadNetworkDirectoryremoveNetworkCommandParams.put("extendedPanID",threadNetworkDirectoryremoveNetworkextendedPanIDCommandParameterInfo); + InteractionInfo threadNetworkDirectoryremoveNetworkInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster) + .removeNetwork((DefaultClusterCallback) callback + , (Long) + commandArguments.get("extendedPanID"), 10000 + ); + }, + () -> new DelegatedDefaultClusterCallback(), + threadNetworkDirectoryremoveNetworkCommandParams + ); + threadNetworkDirectoryClusterInteractionInfoMap.put("removeNetwork", threadNetworkDirectoryremoveNetworkInteractionInfo); + + Map threadNetworkDirectorygetOperationalDatasetCommandParams = new LinkedHashMap(); + + CommandParameterInfo threadNetworkDirectorygetOperationalDatasetextendedPanIDCommandParameterInfo = new CommandParameterInfo("extendedPanID", Long.class, Long.class); + threadNetworkDirectorygetOperationalDatasetCommandParams.put("extendedPanID",threadNetworkDirectorygetOperationalDatasetextendedPanIDCommandParameterInfo); + InteractionInfo threadNetworkDirectorygetOperationalDatasetInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster) + .getOperationalDataset((ChipClusters.ThreadNetworkDirectoryCluster.OperationalDatasetResponseCallback) callback + , (Long) + commandArguments.get("extendedPanID") + + , 10000); + }, + () -> new DelegatedThreadNetworkDirectoryClusterOperationalDatasetResponseCallback(), + threadNetworkDirectorygetOperationalDatasetCommandParams + ); + threadNetworkDirectoryClusterInteractionInfoMap.put("getOperationalDataset", threadNetworkDirectorygetOperationalDatasetInteractionInfo); + + commandMap.put("threadNetworkDirectory", threadNetworkDirectoryClusterInteractionInfoMap); + Map wakeOnLanClusterInteractionInfoMap = new LinkedHashMap<>(); commandMap.put("wakeOnLan", wakeOnLanClusterInteractionInfoMap); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index cc18af0810cc10..c607d8deca891a 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -16529,6 +16529,190 @@ private static Map readRadonConcentrationMeasurementInt return result; } + private static Map readWiFiNetworkManagementInteractionInfo() { + Map result = new LinkedHashMap<>();Map readWiFiNetworkManagementSsidCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementSsidAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readSsidAttribute( + (ChipClusters.WiFiNetworkManagementCluster.SsidAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWiFiNetworkManagementClusterSsidAttributeCallback(), + readWiFiNetworkManagementSsidCommandParams + ); + result.put("readSsidAttribute", readWiFiNetworkManagementSsidAttributeInteractionInfo); + Map readWiFiNetworkManagementGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.WiFiNetworkManagementCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWiFiNetworkManagementClusterGeneratedCommandListAttributeCallback(), + readWiFiNetworkManagementGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readWiFiNetworkManagementGeneratedCommandListAttributeInteractionInfo); + Map readWiFiNetworkManagementAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.WiFiNetworkManagementCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWiFiNetworkManagementClusterAcceptedCommandListAttributeCallback(), + readWiFiNetworkManagementAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readWiFiNetworkManagementAcceptedCommandListAttributeInteractionInfo); + Map readWiFiNetworkManagementEventListCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readEventListAttribute( + (ChipClusters.WiFiNetworkManagementCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWiFiNetworkManagementClusterEventListAttributeCallback(), + readWiFiNetworkManagementEventListCommandParams + ); + result.put("readEventListAttribute", readWiFiNetworkManagementEventListAttributeInteractionInfo); + Map readWiFiNetworkManagementAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readAttributeListAttribute( + (ChipClusters.WiFiNetworkManagementCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWiFiNetworkManagementClusterAttributeListAttributeCallback(), + readWiFiNetworkManagementAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readWiFiNetworkManagementAttributeListAttributeInteractionInfo); + Map readWiFiNetworkManagementFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readWiFiNetworkManagementFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readWiFiNetworkManagementFeatureMapAttributeInteractionInfo); + Map readWiFiNetworkManagementClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWiFiNetworkManagementClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readWiFiNetworkManagementClusterRevisionAttributeInteractionInfo); + + return result; + } + private static Map readThreadNetworkDirectoryInteractionInfo() { + Map result = new LinkedHashMap<>();Map readThreadNetworkDirectoryPreferredExtendedPanIDCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readPreferredExtendedPanIDAttribute( + (ChipClusters.ThreadNetworkDirectoryCluster.PreferredExtendedPanIDAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterPreferredExtendedPanIDAttributeCallback(), + readThreadNetworkDirectoryPreferredExtendedPanIDCommandParams + ); + result.put("readPreferredExtendedPanIDAttribute", readThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo); + Map readThreadNetworkDirectoryThreadNetworksCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryThreadNetworksAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readThreadNetworksAttribute( + (ChipClusters.ThreadNetworkDirectoryCluster.ThreadNetworksAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterThreadNetworksAttributeCallback(), + readThreadNetworkDirectoryThreadNetworksCommandParams + ); + result.put("readThreadNetworksAttribute", readThreadNetworkDirectoryThreadNetworksAttributeInteractionInfo); + Map readThreadNetworkDirectoryThreadNetworkTableSizeCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryThreadNetworkTableSizeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readThreadNetworkTableSizeAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readThreadNetworkDirectoryThreadNetworkTableSizeCommandParams + ); + result.put("readThreadNetworkTableSizeAttribute", readThreadNetworkDirectoryThreadNetworkTableSizeAttributeInteractionInfo); + Map readThreadNetworkDirectoryGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.ThreadNetworkDirectoryCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterGeneratedCommandListAttributeCallback(), + readThreadNetworkDirectoryGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readThreadNetworkDirectoryGeneratedCommandListAttributeInteractionInfo); + Map readThreadNetworkDirectoryAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.ThreadNetworkDirectoryCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterAcceptedCommandListAttributeCallback(), + readThreadNetworkDirectoryAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readThreadNetworkDirectoryAcceptedCommandListAttributeInteractionInfo); + Map readThreadNetworkDirectoryEventListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readEventListAttribute( + (ChipClusters.ThreadNetworkDirectoryCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterEventListAttributeCallback(), + readThreadNetworkDirectoryEventListCommandParams + ); + result.put("readEventListAttribute", readThreadNetworkDirectoryEventListAttributeInteractionInfo); + Map readThreadNetworkDirectoryAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readAttributeListAttribute( + (ChipClusters.ThreadNetworkDirectoryCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedThreadNetworkDirectoryClusterAttributeListAttributeCallback(), + readThreadNetworkDirectoryAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readThreadNetworkDirectoryAttributeListAttributeInteractionInfo); + Map readThreadNetworkDirectoryFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readThreadNetworkDirectoryFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readThreadNetworkDirectoryFeatureMapAttributeInteractionInfo); + Map readThreadNetworkDirectoryClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readThreadNetworkDirectoryClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readThreadNetworkDirectoryClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readThreadNetworkDirectoryClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readWakeOnLanInteractionInfo() { Map result = new LinkedHashMap<>();Map readWakeOnLanMACAddressCommandParams = new LinkedHashMap(); InteractionInfo readWakeOnLanMACAddressAttributeInteractionInfo = new InteractionInfo( @@ -20588,6 +20772,8 @@ public Map> getReadAttributeMap() { put("pm10ConcentrationMeasurement", readPm10ConcentrationMeasurementInteractionInfo()); put("totalVolatileOrganicCompoundsConcentrationMeasurement", readTotalVolatileOrganicCompoundsConcentrationMeasurementInteractionInfo()); put("radonConcentrationMeasurement", readRadonConcentrationMeasurementInteractionInfo()); + put("wiFiNetworkManagement", readWiFiNetworkManagementInteractionInfo()); + put("threadNetworkDirectory", readThreadNetworkDirectoryInteractionInfo()); put("wakeOnLan", readWakeOnLanInteractionInfo()); put("channel", readChannelInteractionInfo()); put("targetNavigator", readTargetNavigatorInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 0e5a32b23f04c4..61b492fde61abd 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -3636,6 +3636,32 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("totalVolatileOrganicCompoundsConcentrationMeasurement", writeTotalVolatileOrganicCompoundsConcentrationMeasurementInteractionInfo); Map writeRadonConcentrationMeasurementInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("radonConcentrationMeasurement", writeRadonConcentrationMeasurementInteractionInfo); + Map writeWiFiNetworkManagementInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("wiFiNetworkManagement", writeWiFiNetworkManagementInteractionInfo); + Map writeThreadNetworkDirectoryInteractionInfo = new LinkedHashMap<>(); + Map writeThreadNetworkDirectoryPreferredExtendedPanIDCommandParams = new LinkedHashMap(); + CommandParameterInfo threadNetworkDirectorypreferredExtendedPanIDCommandParameterInfo = + new CommandParameterInfo( + "value", + Long.class, + Long.class + ); + writeThreadNetworkDirectoryPreferredExtendedPanIDCommandParams.put( + "value", + threadNetworkDirectorypreferredExtendedPanIDCommandParameterInfo + ); + InteractionInfo writeThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ThreadNetworkDirectoryCluster) cluster).writePreferredExtendedPanIDAttribute( + (DefaultClusterCallback) callback, + (Long) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeThreadNetworkDirectoryPreferredExtendedPanIDCommandParams + ); + writeThreadNetworkDirectoryInteractionInfo.put("writePreferredExtendedPanIDAttribute", writeThreadNetworkDirectoryPreferredExtendedPanIDAttributeInteractionInfo); + writeAttributeMap.put("threadNetworkDirectory", writeThreadNetworkDirectoryInteractionInfo); Map writeWakeOnLanInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("wakeOnLan", writeWakeOnLanInteractionInfo); Map writeChannelInteractionInfo = new LinkedHashMap<>(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt new file mode 100644 index 00000000000000..df86cf8e4f6f47 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package chip.devicecontroller.cluster.eventstructs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadNetworkDirectoryClusterNetworkChangedEvent(val extendedPanID: ULong) { + override fun toString(): String = buildString { + append("ThreadNetworkDirectoryClusterNetworkChangedEvent {\n") + append("\textendedPanID : $extendedPanID\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID) + endStructure() + } + } + + companion object { + private const val TAG_EXTENDED_PAN_I_D = 0 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadNetworkDirectoryClusterNetworkChangedEvent { + tlvReader.enterStructure(tlvTag) + val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D)) + + tlvReader.exitContainer() + + return ThreadNetworkDirectoryClusterNetworkChangedEvent(extendedPanID) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index 34fd21bb27d770..4f8bcd19a75f60 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -127,6 +127,7 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterRouteTableStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDiagnosticsClusterSecurityPolicy.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TimeSynchronizationClusterDSTOffsetStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TimeSynchronizationClusterFabricScopedTrustedTimeSourceStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TimeSynchronizationClusterTimeZoneStruct.kt", @@ -211,6 +212,7 @@ eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/TargetNavigatorClusterTargetUpdatedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/TimeSynchronizationClusterDSTStatusEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/TimeSynchronizationClusterTimeZoneStatusEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/UnitTestingClusterTestDifferentVendorMeiEventEvent.kt", diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt new file mode 100644 index 00000000000000..ffc00a108110d7 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadNetworkDirectoryClusterThreadNetworkStruct( + val extendedPanID: ULong, + val networkName: String, + val channel: UInt +) { + override fun toString(): String = buildString { + append("ThreadNetworkDirectoryClusterThreadNetworkStruct {\n") + append("\textendedPanID : $extendedPanID\n") + append("\tnetworkName : $networkName\n") + append("\tchannel : $channel\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID) + put(ContextSpecificTag(TAG_NETWORK_NAME), networkName) + put(ContextSpecificTag(TAG_CHANNEL), channel) + endStructure() + } + } + + companion object { + private const val TAG_EXTENDED_PAN_I_D = 0 + private const val TAG_NETWORK_NAME = 1 + private const val TAG_CHANNEL = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadNetworkDirectoryClusterThreadNetworkStruct { + tlvReader.enterStructure(tlvTag) + val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D)) + val networkName = tlvReader.getString(ContextSpecificTag(TAG_NETWORK_NAME)) + val channel = tlvReader.getUInt(ContextSpecificTag(TAG_CHANNEL)) + + tlvReader.exitContainer() + + return ThreadNetworkDirectoryClusterThreadNetworkStruct(extendedPanID, networkName, channel) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt new file mode 100644 index 00000000000000..8695d588b06d9b --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt @@ -0,0 +1,1074 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UByteSubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.WriteRequest +import matter.controller.WriteRequests +import matter.controller.WriteResponse +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadNetworkDirectoryCluster( + private val controller: MatterController, + private val endpointId: UShort +) { + class OperationalDatasetResponse(val operationalDataset: ByteArray) + + class PreferredExtendedPanIDAttribute(val value: ULong?) + + sealed class PreferredExtendedPanIDAttributeSubscriptionState { + data class Success(val value: ULong?) : PreferredExtendedPanIDAttributeSubscriptionState() + + data class Error(val exception: Exception) : PreferredExtendedPanIDAttributeSubscriptionState() + + object SubscriptionEstablished : PreferredExtendedPanIDAttributeSubscriptionState() + } + + class ThreadNetworksAttribute(val value: List) + + sealed class ThreadNetworksAttributeSubscriptionState { + data class Success(val value: List) : + ThreadNetworksAttributeSubscriptionState() + + data class Error(val exception: Exception) : ThreadNetworksAttributeSubscriptionState() + + object SubscriptionEstablished : ThreadNetworksAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun addNetwork(operationalDataset: ByteArray, timedInvokeTimeout: Duration) { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPERATIONAL_DATASET_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPERATIONAL_DATASET_REQ), operationalDataset) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun removeNetwork(extendedPanID: ULong, timedInvokeTimeout: Duration) { + val commandId: UInt = 1u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EXTENDED_PAN_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D_REQ), extendedPanID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun getOperationalDataset( + extendedPanID: ULong, + timedInvokeTimeout: Duration + ): OperationalDatasetResponse { + val commandId: UInt = 2u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EXTENDED_PAN_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D_REQ), extendedPanID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_OPERATIONAL_DATASET: Int = 0 + var operationalDataset_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_OPERATIONAL_DATASET)) { + operationalDataset_decoded = tlvReader.getByteArray(tag) + } else { + tlvReader.skipElement() + } + } + + if (operationalDataset_decoded == null) { + throw IllegalStateException("operationalDataset not found in TLV") + } + + tlvReader.exitContainer() + + return OperationalDatasetResponse(operationalDataset_decoded) + } + + suspend fun readPreferredExtendedPanIDAttribute(): PreferredExtendedPanIDAttribute { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Preferredextendedpanid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PreferredExtendedPanIDAttribute(decodedValue) + } + + suspend fun writePreferredExtendedPanIDAttribute( + value: ULong, + timedWriteTimeout: Duration? = null + ) { + val ATTRIBUTE_ID: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timedWriteTimeout + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribePreferredExtendedPanIDAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + PreferredExtendedPanIDAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Preferredextendedpanid attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(PreferredExtendedPanIDAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(PreferredExtendedPanIDAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readThreadNetworksAttribute(): ThreadNetworksAttribute { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Threadnetworks attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ThreadNetworkDirectoryClusterThreadNetworkStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return ThreadNetworksAttribute(decodedValue) + } + + suspend fun subscribeThreadNetworksAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + ThreadNetworksAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Threadnetworks attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + ThreadNetworkDirectoryClusterThreadNetworkStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + emit(ThreadNetworksAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(ThreadNetworksAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readThreadNetworkTableSizeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Threadnetworktablesize attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeThreadNetworkTableSizeAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Threadnetworktablesize attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + emit(UByteSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(ThreadNetworkDirectoryCluster::class.java.name) + const val CLUSTER_ID: UInt = 1107u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt new file mode 100644 index 00000000000000..5deb4b8317d3a4 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt @@ -0,0 +1,786 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WiFiNetworkManagementCluster( + private val controller: MatterController, + private val endpointId: UShort +) { + class NetworkPassphraseResponse(val passphrase: ByteArray) + + class SsidAttribute(val value: ByteArray?) + + sealed class SsidAttributeSubscriptionState { + data class Success(val value: ByteArray?) : SsidAttributeSubscriptionState() + + data class Error(val exception: Exception) : SsidAttributeSubscriptionState() + + object SubscriptionEstablished : SsidAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun networkPassphraseRequest( + timedInvokeTimeout: Duration? = null + ): NetworkPassphraseResponse { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_PASSPHRASE: Int = 0 + var passphrase_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_PASSPHRASE)) { + passphrase_decoded = tlvReader.getByteArray(tag) + } else { + tlvReader.skipElement() + } + } + + if (passphrase_decoded == null) { + throw IllegalStateException("passphrase not found in TLV") + } + + tlvReader.exitContainer() + + return NetworkPassphraseResponse(passphrase_decoded) + } + + suspend fun readSsidAttribute(): SsidAttribute { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ssid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SsidAttribute(decodedValue) + } + + suspend fun subscribeSsidAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + SsidAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Ssid attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(SsidAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(SsidAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(WiFiNetworkManagementCluster::class.java.name) + const val CLUSTER_ID: UInt = 1105u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt new file mode 100644 index 00000000000000..8200ee623c2362 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package matter.controller.cluster.eventstructs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadNetworkDirectoryClusterNetworkChangedEvent(val extendedPanID: ULong) { + override fun toString(): String = buildString { + append("ThreadNetworkDirectoryClusterNetworkChangedEvent {\n") + append("\textendedPanID : $extendedPanID\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID) + endStructure() + } + } + + companion object { + private const val TAG_EXTENDED_PAN_I_D = 0 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadNetworkDirectoryClusterNetworkChangedEvent { + tlvReader.enterStructure(tlvTag) + val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D)) + + tlvReader.exitContainer() + + return ThreadNetworkDirectoryClusterNetworkChangedEvent(extendedPanID) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index f62cee23bdd5b3..f7670310f95cfd 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -127,6 +127,7 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterRouteTableStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDiagnosticsClusterSecurityPolicy.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TimeSynchronizationClusterDSTOffsetStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TimeSynchronizationClusterFabricScopedTrustedTimeSourceStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TimeSynchronizationClusterTimeZoneStruct.kt", @@ -211,6 +212,7 @@ matter_eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/TargetNavigatorClusterTargetUpdatedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ThreadNetworkDirectoryClusterNetworkChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/TimeSynchronizationClusterDSTStatusEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/TimeSynchronizationClusterTimeZoneStatusEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/UnitTestingClusterTestDifferentVendorMeiEventEvent.kt", @@ -331,6 +333,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimeFormatLocalizationCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimerCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/TimeSynchronizationCluster.kt", @@ -341,5 +344,6 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WakeOnLanCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WindowCoveringCluster.kt", ] \ No newline at end of file diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt new file mode 100644 index 00000000000000..f7fb08d535fef5 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ThreadNetworkDirectoryClusterThreadNetworkStruct.kt @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ThreadNetworkDirectoryClusterThreadNetworkStruct( + val extendedPanID: ULong, + val networkName: String, + val channel: UShort +) { + override fun toString(): String = buildString { + append("ThreadNetworkDirectoryClusterThreadNetworkStruct {\n") + append("\textendedPanID : $extendedPanID\n") + append("\tnetworkName : $networkName\n") + append("\tchannel : $channel\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_EXTENDED_PAN_I_D), extendedPanID) + put(ContextSpecificTag(TAG_NETWORK_NAME), networkName) + put(ContextSpecificTag(TAG_CHANNEL), channel) + endStructure() + } + } + + companion object { + private const val TAG_EXTENDED_PAN_I_D = 0 + private const val TAG_NETWORK_NAME = 1 + private const val TAG_CHANNEL = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader + ): ThreadNetworkDirectoryClusterThreadNetworkStruct { + tlvReader.enterStructure(tlvTag) + val extendedPanID = tlvReader.getULong(ContextSpecificTag(TAG_EXTENDED_PAN_I_D)) + val networkName = tlvReader.getString(ContextSpecificTag(TAG_NETWORK_NAME)) + val channel = tlvReader.getUShort(ContextSpecificTag(TAG_CHANNEL)) + + tlvReader.exitContainer() + + return ThreadNetworkDirectoryClusterThreadNetworkStruct(extendedPanID, networkName, channel) + } + } +} diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 653cebf89d1030..4cf4c9ee0f83cc 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -803,6 +803,14 @@ public byte[] getAttestationChallenge(long devicePtr) { return getAttestationChallenge(deviceControllerPtr, devicePtr); } + public void startDnssd() { + startDnssd(deviceControllerPtr); + } + + public void stopDnssd() { + stopDnssd(deviceControllerPtr); + } + /** * @brief Auto-Resubscribe to the given attribute path with keepSubscriptions and isFabricFiltered * @param SubscriptionEstablishedCallback Callback when a subscribe response has been received and @@ -1587,6 +1595,10 @@ private native void updateCommissioningICDRegistrationInfo( private native void shutdownCommissioning(long deviceControllerPtr); + private native void startDnssd(long deviceControllerPtr); + + private native void stopDnssd(long deviceControllerPtr); + static { System.loadLibrary("CHIPController"); } diff --git a/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt b/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt index a51fd8367be335..853b3308953afd 100644 --- a/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt +++ b/src/controller/java/src/matter/onboardingpayload/QRCodeBasicOnboardingPayloadGenerator.kt @@ -178,6 +178,6 @@ private fun populateTLVBits( for (i in 0 until tlvBufSizeInBytes) { val value = tlvBuf[i] - populateBits(bits, offset, value.toLong(), 8, totalPayloadDataSizeInBits) + populateBits(bits, offset, value.toUByte().toLong(), 8, totalPayloadDataSizeInBits) } } diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 2400ba818c7cb9..3b58043e65ee78 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -37156,6 +37156,411 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::WiFiNetworkManagement::Id: { + using namespace app::Clusters::WiFiNetworkManagement; + switch (aPath.mAttributeId) + { + case Attributes::Ssid::Id: { + using TypeInfo = Attributes::Ssid::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + jbyteArray valueByteArray = env->NewByteArray(static_cast(cppValue.Value().size())); + env->SetByteArrayRegion(valueByteArray, 0, static_cast(cppValue.Value().size()), + reinterpret_cast(cppValue.Value().data())); + value = valueByteArray; + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } + case app::Clusters::ThreadNetworkDirectory::Id: { + using namespace app::Clusters::ThreadNetworkDirectory; + switch (aPath.mAttributeId) + { + case Attributes::PreferredExtendedPanID::Id: { + using TypeInfo = Attributes::PreferredExtendedPanID::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::ThreadNetworks::Id: { + using TypeInfo = Attributes::ThreadNetworks::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + jobject newElement_0_extendedPanID; + std::string newElement_0_extendedPanIDClassName = "java/lang/Long"; + std::string newElement_0_extendedPanIDCtorSignature = "(J)V"; + jlong jninewElement_0_extendedPanID = static_cast(entry_0.extendedPanID); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_extendedPanIDClassName.c_str(), newElement_0_extendedPanIDCtorSignature.c_str(), + jninewElement_0_extendedPanID, newElement_0_extendedPanID); + jobject newElement_0_networkName; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(entry_0.networkName, newElement_0_networkName)); + jobject newElement_0_channel; + std::string newElement_0_channelClassName = "java/lang/Integer"; + std::string newElement_0_channelCtorSignature = "(I)V"; + jint jninewElement_0_channel = static_cast(entry_0.channel); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_channelClassName.c_str(), + newElement_0_channelCtorSignature.c_str(), + jninewElement_0_channel, newElement_0_channel); + + jclass threadNetworkStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ThreadNetworkDirectoryClusterThreadNetworkStruct", + threadNetworkStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ThreadNetworkDirectoryClusterThreadNetworkStruct"); + return nullptr; + } + + jmethodID threadNetworkStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, threadNetworkStructStructClass_1, "", + "(Ljava/lang/Long;Ljava/lang/String;Ljava/lang/Integer;)V", + &threadNetworkStructStructCtor_1); + if (err != CHIP_NO_ERROR || threadNetworkStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ThreadNetworkDirectoryClusterThreadNetworkStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(threadNetworkStructStructClass_1, threadNetworkStructStructCtor_1, + newElement_0_extendedPanID, newElement_0_networkName, newElement_0_channel); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::ThreadNetworkTableSize::Id: { + using TypeInfo = Attributes::ThreadNetworkTableSize::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::WakeOnLan::Id: { using namespace app::Clusters::WakeOnLan; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 370e510894c121..ac55ed9125654e 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -7389,6 +7389,64 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::WiFiNetworkManagement::Id: { + using namespace app::Clusters::WiFiNetworkManagement; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } + case app::Clusters::ThreadNetworkDirectory::Id: { + using namespace app::Clusters::ThreadNetworkDirectory; + switch (aPath.mEventId) + { + case Events::NetworkChanged::Id: { + Events::NetworkChanged::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value_extendedPanID; + std::string value_extendedPanIDClassName = "java/lang/Long"; + std::string value_extendedPanIDCtorSignature = "(J)V"; + jlong jnivalue_extendedPanID = static_cast(cppValue.extendedPanID); + chip::JniReferences::GetInstance().CreateBoxedObject(value_extendedPanIDClassName.c_str(), + value_extendedPanIDCtorSignature.c_str(), + jnivalue_extendedPanID, value_extendedPanID); + + jclass networkChangedStructClass; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipEventStructs$ThreadNetworkDirectoryClusterNetworkChangedEvent", + networkChangedStructClass); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipEventStructs$ThreadNetworkDirectoryClusterNetworkChangedEvent"); + return nullptr; + } + + jmethodID networkChangedStructCtor; + err = chip::JniReferences::GetInstance().FindMethod(env, networkChangedStructClass, "", "(Ljava/lang/Long;)V", + &networkChangedStructCtor); + if (err != CHIP_NO_ERROR || networkChangedStructCtor == nullptr) + { + ChipLogError(Zcl, "Could not find ChipEventStructs$ThreadNetworkDirectoryClusterNetworkChangedEvent constructor"); + return nullptr; + } + + jobject value = env->NewObject(networkChangedStructClass, networkChangedStructCtor, value_extendedPanID); + + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::WakeOnLan::Id: { using namespace app::Clusters::WakeOnLan; switch (aPath.mEventId) diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 5fc2212098fea8..9adda770125317 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -76,6 +76,8 @@ shared_library("ChipDeviceCtrl") { "chip/crypto/p256keypair.cpp", "chip/crypto/p256keypair.h", "chip/discovery/NodeResolution.cpp", + "chip/icd/PyChipCheckInDelegate.cpp", + "chip/icd/PyChipCheckInDelegate.h", "chip/interaction_model/Delegate.cpp", "chip/interaction_model/Delegate.h", "chip/internal/ChipThreadWork.cpp", @@ -121,6 +123,7 @@ shared_library("ChipDeviceCtrl") { public_deps = [ "${chip_root}/src/app", + "${chip_root}/src/app/icd/client:handler", "${chip_root}/src/app/server", "${chip_root}/src/credentials:default_attestation_verifier", "${chip_root}/src/lib", @@ -414,10 +417,7 @@ chip_python_wheel_action("chip-clusters") { } chip_python_wheel_action("chip-repl") { - py_scripts = [ - "chip-device-ctrl.py", - "chip-repl.py", - ] + py_scripts = [ "chip-repl.py" ] py_manifest_files = [ { diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index a55d3865bdccae..821b2a34e03b60 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -42,6 +42,9 @@ #include #include +#include +#include +#include #include #include #include @@ -55,7 +58,9 @@ #include #include #include +#include #include +#include #include #include @@ -101,20 +106,24 @@ chip::Platform::ScopedMemoryBuffer sDefaultNTPBuf; app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type sDSTBuf; app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type sTimeZoneBuf; chip::Platform::ScopedMemoryBuffer sTimeZoneNameBuf; -chip::Controller::CommissioningParameters sCommissioningParameters; - } // namespace +chip::Controller::CommissioningParameters sCommissioningParameters; +chip::app::DefaultICDClientStorage sICDClientStorage; chip::Controller::ScriptPairingDeviceDiscoveryDelegate sPairingDeviceDiscoveryDelegate; chip::Credentials::GroupDataProviderImpl sGroupDataProvider; chip::Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore; chip::Crypto::RawKeySessionKeystore sSessionKeystore; +chip::app::CheckInHandler sCheckInHandler; + // NOTE: Remote device ID is in sync with the echo server device id // At some point, we may want to add an option to connect to a device without // knowing its id, because the ID can be learned on the first response that is received. +chip::Controller::PyChipCheckInDelegate sCheckInDelegate; chip::NodeId kDefaultLocalDeviceId = chip::kTestControllerNodeId; chip::NodeId kRemoteDeviceId = chip::kTestDeviceNodeId; +uint8_t sICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; extern "C" { PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter * storageAdapter, bool enableServerInteractions); @@ -126,6 +135,7 @@ PyChipError pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCo char * outAddress, uint64_t maxAddressLen, uint16_t * outPort); PyChipError pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId); PyChipError pychip_DeviceController_GetFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId); +PyChipError pychip_DeviceController_GetFabricIndex(chip::Controller::DeviceCommissioner * devCtrl, uint8_t * outFabricIndex); PyChipError pychip_DeviceController_GetNodeId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outNodeId); // Rendezvous @@ -144,6 +154,8 @@ PyChipError pychip_DeviceController_SetDSTOffset(int32_t offset, uint64_t validS PyChipError pychip_DeviceController_SetDefaultNtp(const char * defaultNTP); PyChipError pychip_DeviceController_SetTrustedTimeSource(chip::NodeId nodeId, chip::EndpointId endpoint); PyChipError pychip_DeviceController_SetCheckMatchingFabric(bool check); +struct IcdRegistrationParameters; +PyChipError pychip_DeviceController_SetIcdRegistrationParameters(bool enabled, const IcdRegistrationParameters * params); PyChipError pychip_DeviceController_ResetCommissioningParameters(); PyChipError pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid); PyChipError pychip_DeviceController_EstablishPASESessionIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr, @@ -212,7 +224,6 @@ PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::Devic const char * pychip_Stack_ErrorToString(ChipError::StorageType err); const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode); -void pychip_Stack_SetLogFunct(LogMessageFunct logFunct); PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback); @@ -236,6 +247,11 @@ void * pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObjec chip::Controller::Python::SetGetKeyValueCb getCb, chip::Controller::Python::SyncDeleteKeyValueCb deleteCb); void pychip_Storage_ShutdownAdapter(chip::Controller::Python::StorageAdapter * storageAdapter); + +// +// ICD +// +void pychip_CheckInDelegate_SetOnCheckInCompleteCallback(PyChipCheckInDelegate::OnCheckInCompleteCallback * callback); } void * pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObject * context, @@ -261,6 +277,8 @@ PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter factoryParams.fabricIndependentStorage = storageAdapter; factoryParams.sessionKeystore = &sSessionKeystore; + sICDClientStorage.Init(storageAdapter, &sSessionKeystore); + sGroupDataProvider.SetStorageDelegate(storageAdapter); sGroupDataProvider.SetSessionKeystore(factoryParams.sessionKeystore); PyReturnErrorOnFailure(ToPyChipError(sGroupDataProvider.Init())); @@ -291,6 +309,11 @@ PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter // DeviceControllerFactory::GetInstance().RetainSystemState(); + auto engine = chip::app::InteractionModelEngine::GetInstance(); + PyReturnErrorOnFailure(ToPyChipError(sCheckInDelegate.Init(&sICDClientStorage, engine))); + PyReturnErrorOnFailure(ToPyChipError(sCheckInHandler.Init( + DeviceControllerFactory::GetInstance().GetSystemState()->ExchangeMgr(), &sICDClientStorage, &sCheckInDelegate, engine))); + // // Finally, start up the main Matter thread. Any further interactions with the stack // will now need to happen on the Matter thread, OR protected with the stack lock. @@ -343,6 +366,12 @@ PyChipError pychip_DeviceController_GetFabricId(chip::Controller::DeviceCommissi return ToPyChipError(CHIP_NO_ERROR); } +PyChipError pychip_DeviceController_GetFabricIndex(chip::Controller::DeviceCommissioner * devCtrl, uint8_t * outFabricIndex) +{ + *outFabricIndex = devCtrl->GetFabricIndex(); + return ToPyChipError(CHIP_NO_ERROR); +} + PyChipError pychip_DeviceController_GetNodeId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outNodeId) { *outNodeId = devCtrl->GetNodeId(); @@ -555,6 +584,55 @@ PyChipError pychip_DeviceController_SetCheckMatchingFabric(bool check) return ToPyChipError(CHIP_NO_ERROR); } +struct IcdRegistrationParameters +{ + uint8_t * symmetricKey; + size_t symmetricKeyLength; + uint64_t checkInNodeId; + uint64_t monitoredSubject; + uint32_t stayActiveMsec; +}; + +PyChipError pychip_DeviceController_SetIcdRegistrationParameters(bool enabled, const IcdRegistrationParameters * params) +{ + if (!enabled) + { + sCommissioningParameters.SetICDRegistrationStrategy(ICDRegistrationStrategy::kIgnore); + return ToPyChipError(CHIP_NO_ERROR); + } + + if (params == nullptr) + { + return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT); + } + + if (params->symmetricKey == nullptr || params->symmetricKeyLength != sizeof(sICDSymmetricKey)) + { + return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT); + } + + if (params->checkInNodeId == 0) + { + return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT); + } + if (params->monitoredSubject == 0) + { + return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT); + } + + memcpy(sICDSymmetricKey, params->symmetricKey, sizeof(sICDSymmetricKey)); + sCommissioningParameters.SetICDSymmetricKey(ByteSpan(sICDSymmetricKey)); + if (params->stayActiveMsec != 0) + { + sCommissioningParameters.SetICDStayActiveDurationMsec(params->stayActiveMsec); + } + sCommissioningParameters.SetICDCheckInNodeId(params->checkInNodeId); + sCommissioningParameters.SetICDMonitoredSubject(params->monitoredSubject); + sCommissioningParameters.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + + return ToPyChipError(CHIP_NO_ERROR); +} + PyChipError pychip_DeviceController_ResetCommissioningParameters() { sCommissioningParameters = CommissioningParameters(); @@ -863,17 +941,6 @@ uint64_t pychip_GetCommandSenderHandle(chip::DeviceProxy * device) return 0; } -void pychip_Stack_SetLogFunct(LogMessageFunct logFunct) -{ - // TODO: determine if log redirection is supposed to be functioning in CHIP - // - // Background: original log baseline supported 'redirect logs to this - // function' however CHIP does not currently provide this. - // - // Ideally log redirection should work so that python code can do things - // like using the log module. -} - PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext) { if (callback == nullptr || pythonContext == nullptr) @@ -883,3 +950,8 @@ PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFun PlatformMgr().ScheduleWork(callback, reinterpret_cast(pythonContext)); return ToPyChipError(CHIP_NO_ERROR); } + +void pychip_CheckInDelegate_SetOnCheckInCompleteCallback(PyChipCheckInDelegate::OnCheckInCompleteCallback * callback) +{ + chip::MainLoopWork::ExecuteInMainLoop([callback]() { sCheckInDelegate.SetOnCheckInCompleteCallback(callback); }); +} diff --git a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp index c1df8125793d02..c979e0d9cd77a3 100644 --- a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp +++ b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp @@ -19,12 +19,17 @@ #include "ChipDeviceController-ScriptDevicePairingDelegate.h" #include "lib/support/TypeTraits.h" +#include #include #include #include #include +extern chip::app::DefaultICDClientStorage sICDClientStorage; +extern chip::Controller::CommissioningParameters sCommissioningParameters; +extern uint8_t sICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; + namespace chip { namespace Controller { @@ -180,5 +185,40 @@ ScriptDevicePairingDelegate::GetOpenWindowCallback(Controller::CommissioningWind return &mOpenWindowCallback; } +void ScriptDevicePairingDelegate::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icdCounter) +{ + app::ICDClientInfo clientInfo; + clientInfo.peer_node = nodeId; + clientInfo.monitored_subject = sCommissioningParameters.GetICDMonitoredSubject().Value(); + clientInfo.start_icd_counter = icdCounter; + + CHIP_ERROR err = sICDClientStorage.SetKey(clientInfo, ByteSpan(sICDSymmetricKey)); + if (err == CHIP_NO_ERROR) + { + err = sICDClientStorage.StoreEntry(clientInfo); + } + + if (err != CHIP_NO_ERROR) + { + sICDClientStorage.RemoveKey(clientInfo); + ChipLogError(Controller, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", + ChipLogValueX64(nodeId.GetNodeId()), err.AsString()); + return; + } + + ChipLogProgress(Controller, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId.GetNodeId())); + ChipLogProgress(Controller, + "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 + " / Monitored Subject: " ChipLogFormatX64 " / ICDCounter %u", + ChipLogValueX64(nodeId.GetNodeId()), ChipLogValueX64(sCommissioningParameters.GetICDCheckInNodeId().Value()), + ChipLogValueX64(clientInfo.monitored_subject), icdCounter); +} + +void ScriptDevicePairingDelegate::OnICDStayActiveComplete(ScopedNodeId deviceId, uint32_t promisedActiveDuration) +{ + ChipLogProgress(Controller, "ICD Stay Active Complete for device " ChipLogFormatX64 " / promisedActiveDuration: %u", + ChipLogValueX64(deviceId.GetNodeId()), promisedActiveDuration); +} + } // namespace Controller } // namespace chip diff --git a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.h b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.h index 2740b6eb85e983..d6665f8fb2baba 100644 --- a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.h +++ b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.h @@ -27,6 +27,7 @@ #include #include +#include #include namespace chip { @@ -68,11 +69,14 @@ class ScriptDevicePairingDelegate final : public Controller::DevicePairingDelega void OnCommissioningFailure(PeerId peerId, CHIP_ERROR error, CommissioningStage stageFailed, Optional additionalErrorInfo) override; void OnCommissioningStatusUpdate(PeerId peerId, CommissioningStage stageCompleted, CHIP_ERROR error) override; + void OnICDRegistrationComplete(ScopedNodeId deviceId, uint32_t icdCounter) override; + void OnICDStayActiveComplete(ScopedNodeId deviceId, uint32_t promisedActiveDuration) override; void OnFabricCheck(NodeId matchingNodeId) override; Callback::Callback * GetOpenWindowCallback(Controller::CommissioningWindowOpener * context); void OnOpenCommissioningWindow(NodeId deviceId, CHIP_ERROR status, SetupPayload payload); void SetExpectingPairingComplete(bool value) { expectingPairingComplete = value; } + void SetFabricIndex(FabricIndex fabricIndex) { mFabricIndex = fabricIndex; } private: DevicePairingDelegate_OnPairingCompleteFunct mOnPairingCompleteCallback = nullptr; @@ -84,7 +88,9 @@ class ScriptDevicePairingDelegate final : public Controller::DevicePairingDelega DevicePairingDelegate_OnFabricCheckFunct mOnFabricCheckCallback = nullptr; Callback::Callback mOpenWindowCallback; Controller::CommissioningWindowOpener * mWindowOpener = nullptr; - bool expectingPairingComplete = false; + + bool expectingPairingComplete = false; + FabricIndex mFabricIndex = 0; }; } // namespace Controller diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp index 5fd4205d4c7ce7..427ee9be46ba3c 100644 --- a/src/controller/python/OpCredsBinding.cpp +++ b/src/controller/python/OpCredsBinding.cpp @@ -26,6 +26,7 @@ #include "controller/python/chip/crypto/p256keypair.h" #include "controller/python/chip/interaction_model/Delegate.h" +#include #include #include #include @@ -104,6 +105,7 @@ class OperationalCredentialsAdapter : public OperationalCredentialsDelegate extern chip::Credentials::GroupDataProviderImpl sGroupDataProvider; extern chip::Controller::ScriptDevicePairingDelegate sPairingDelegate; +extern chip::app::DefaultICDClientStorage sICDClientStorage; class TestCommissioner : public chip::Controller::AutoCommissioner { @@ -569,6 +571,9 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), defaultIpk, compressedFabricIdSpan); VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); + sICDClientStorage.UpdateFabricList(devCtrl->GetFabricIndex()); + pairingDelegate->SetFabricIndex(devCtrl->GetFabricIndex()); + *outDevCtrl = devCtrl.release(); *outPairingDelegate = pairingDelegate.release(); diff --git a/src/controller/python/README.md b/src/controller/python/README.md index 34edea444650b1..e94a95e1585e0b 100644 --- a/src/controller/python/README.md +++ b/src/controller/python/README.md @@ -1,10 +1,14 @@ -# Python CHIP Device Controller +# Python CHIP Controller -The Python CHIP controller is a tool that allows to commission a Matter device -into the network and to communicate with it using the Zigbee Cluster Library -(ZCL) messages. The tool uses the generic [Chip Device Controller](../) library. +The Python CHIP controller is a library that allows to create a Matter fabric +and commission Matter devices with it, as well as communicate with commissioned +devices by reading/subscribing and writing Attributes and sending Commands. The +Python CHIP controller is based on the native [Chip Device Controller](../) +library. -To learn more about the tool, how to build it and use its commands and advanced +The Python CHIP Controller comes with a REPL which allows to explore and use the +Python CHIP controller library from a shell. To learn more about the Python CHIP +Controller and the REPL, how to build it and use its commands and advanced features, read the following guides: - [Working with Python CHIP Controller](../../../docs/guides/python_chip_controller_building.md) diff --git a/src/controller/python/chip-device-ctrl.py b/src/controller/python/chip-device-ctrl.py deleted file mode 100755 index 469fb2c49fdfc8..00000000000000 --- a/src/controller/python/chip-device-ctrl.py +++ /dev/null @@ -1,1202 +0,0 @@ -#!/usr/bin/env python - -# -# Copyright (c) 2020-2021 Project CHIP Authors -# Copyright (c) 2013-2018 Nest Labs, Inc. -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# @file -# This file implements the Python-based Chip Device Controller Shell. -# - -from __future__ import absolute_import, print_function - -import argparse -import base64 -import ctypes -import logging -import os -import platform -import random -import shlex -import string -import sys -import textwrap -import time -import traceback -import warnings -from cmd import Cmd -from optparse import OptionParser, OptionValueError - -import chip.logging -import coloredlogs -from chip import ChipCommissionableNodeCtrl, ChipStack, exceptions, native -from chip.setup_payload import SetupPayload -from rich import pretty, print - -# Extend sys.path with one or more directories, relative to the location of the -# running script, in which the chip package might be found . This makes it -# possible to run the device manager shell from a non-standard install location, -# as well as directly from its location the CHIP source tree. -# -# Note that relative package locations are prepended to sys.path so as to give -# the local version of the package higher priority over any version installed in -# a standard location. -# -scriptDir = os.path.dirname(os.path.abspath(__file__)) -relChipPackageInstallDirs = [ - ".", - "../lib/python", - "../lib/python%s.%s" % (sys.version_info.major, sys.version_info.minor), - "../lib/Python%s%s" % (sys.version_info.major, sys.version_info.minor), -] -for relInstallDir in relChipPackageInstallDirs: - absInstallDir = os.path.realpath(os.path.join(scriptDir, relInstallDir)) - if os.path.isdir(os.path.join(absInstallDir, "chip")): - sys.path.insert(0, absInstallDir) - - -if platform.system() == 'Darwin': - from chip.ChipCoreBluetoothMgr import CoreBluetoothManager as BleManager -elif sys.platform.startswith('linux'): - from chip.ChipBluezMgr import BluezManager as BleManager - -# The exceptions for CHIP Device Controller CLI - - -class ChipDevCtrlException(exceptions.ChipStackException): - pass - - -class ParsingError(ChipDevCtrlException): - def __init__(self, msg=None): - self.msg = "Parsing Error: " + msg - - def __str__(self): - return self.msg - - -def DecodeBase64Option(option, opt, value): - try: - return base64.standard_b64decode(value) - except TypeError: - raise OptionValueError( - "option %s: invalid base64 value: %r" % (opt, value)) - - -def DecodeHexIntOption(option, opt, value): - try: - return int(value, 16) - except ValueError: - raise OptionValueError("option %s: invalid value: %r" % (opt, value)) - - -def ParseEncodedString(value): - if value.find(":") < 0: - raise ParsingError( - "value should be encoded in encoding:encodedvalue format") - enc, encValue = value.split(":", 1) - if enc == "str": - return encValue.encode("utf-8") + b'\x00' - elif enc == "hex": - return bytes.fromhex(encValue) - raise ParsingError("only str and hex encoding is supported") - - -def ParseValueWithType(value, type): - if type == 'int': - return int(value) - elif type == 'str': - return value - elif type == 'bytes': - return ParseEncodedString(value) - elif type == 'bool': - return (value.upper() not in ['F', 'FALSE', '0']) - else: - raise ParsingError('cannot recognize type: {}'.format(type)) - - -def FormatZCLArguments(args, command): - commandArgs = {} - for kvPair in args: - if kvPair.find("=") < 0: - raise ParsingError("Argument should in key=value format") - key, value = kvPair.split("=", 1) - valueType = command.get(key, None) - commandArgs[key] = ParseValueWithType(value, valueType) - return commandArgs - - -def ShowColoredWarnings(message, category, filename, lineno, file=None, line=None): - logging.warning(' %s:%s: %s:%s' % - (filename, lineno, category.__name__, message)) - return - - -class DeviceMgrCmd(Cmd): - def __init__(self, rendezvousAddr=None, controllerNodeId=1, bluetoothAdapter=None): - self.lastNetworkId = None - self.replHint = None - - pretty.install(indent_guides=True, expand_all=True) - - coloredlogs.install(level='DEBUG') - chip.logging.RedirectToPythonLogging() - - logging.getLogger().setLevel(logging.DEBUG) - warnings.showwarning = ShowColoredWarnings - - Cmd.__init__(self) - - Cmd.identchars = string.ascii_letters + string.digits + "-" - - if sys.stdin.isatty(): - self.prompt = "chip-device-ctrl > " - else: - self.use_rawinput = 0 - self.prompt = "" - - DeviceMgrCmd.command_names.sort() - - self.bleMgr = None - - self.chipStack = ChipStack.ChipStack( - bluetoothAdapter=bluetoothAdapter, persistentStoragePath='/tmp/chip-device-ctrl-storage.json') - self.certificateAuthorityManager = chip.CertificateAuthority.CertificateAuthorityManager(chipStack=self.chipStack) - self.certificateAuthority = self.certificateAuthorityManager.NewCertificateAuthority() - self.fabricAdmin = self.certificateAuthority.NewFabricAdmin(vendorId=0xFFF1, fabricId=1) - self.devCtrl = self.fabricAdmin.NewController( - nodeId=controllerNodeId, useTestCommissioner=True) - - self.commissionableNodeCtrl = ChipCommissionableNodeCtrl.ChipCommissionableNodeController( - self.chipStack) - - # If we are on Linux and user selects non-default bluetooth adapter. - if sys.platform.startswith("linux") and (bluetoothAdapter is not None): - try: - self.bleMgr = BleManager(self.devCtrl) - self.bleMgr.ble_adapter_select( - "hci{}".format(bluetoothAdapter)) - except Exception as ex: - traceback.print_exc() - print( - "Failed to initialize BLE, if you don't have BLE, run chip-device-ctrl with --no-ble") - raise ex - - self.historyFileName = os.path.expanduser( - "~/.chip-device-ctrl-history") - - try: - import readline - - if "libedit" in readline.__doc__: - readline.parse_and_bind("bind ^I rl_complete") - readline.set_completer_delims(" ") - try: - readline.read_history_file(self.historyFileName) - except IOError: - pass - except ImportError: - pass - - command_names = [ - "setup-payload", - - "ble-scan", - "ble-adapter-select", - "ble-adapter-print", - "ble-debug-log", - - "connect", - "close-ble", - "close-session", - "resolve", - "paseonly", - "commission", - "zcl", - "zclread", - "zclsubscribe", - - "discover", - - "set-pairing-wifi-credential", - "set-pairing-thread-credential", - - "open-commissioning-window", - - "get-fabricid", - ] - - def parseline(self, line): - cmd, arg, line = Cmd.parseline(self, line) - if cmd: - cmd = self.shortCommandName(cmd) - line = cmd + " " + arg - return cmd, arg, line - - def completenames(self, text, *ignored): - return [ - name + " " - for name in DeviceMgrCmd.command_names - if name.startswith(text) or self.shortCommandName(name).startswith(text) - ] - - def shortCommandName(self, cmd): - return cmd.replace("-", "") - - def precmd(self, line): - if not self.use_rawinput and line != "EOF" and line != "": - print(">>> " + line) - return line - - def postcmd(self, stop, line): - if self.replHint is not None: - print("Try the following command in repl: ") - print(self.replHint) - print("") - self.replHint = None - if not stop and self.use_rawinput: - self.prompt = "chip-device-ctrl > " - return stop - - def postloop(self): - try: - import readline - - try: - readline.write_history_file(self.historyFileName) - except IOError: - pass - except ImportError: - pass - - def do_help(self, line): - if line: - cmd, arg, unused = self.parseline(line) - try: - doc = getattr(self, "do_" + cmd).__doc__ - except AttributeError: - doc = None - if doc: - self.stdout.write("%s\n" % textwrap.dedent(doc)) - else: - self.stdout.write("No help on %s\n" % (line)) - else: - self.print_topics( - "\nAvailable commands (type help for more information):", - DeviceMgrCmd.command_names, - 15, - 80, - ) - - def do_closeble(self, line): - """ - close-ble - - Close the ble connection to the device. - """ - - warnings.warn( - "This method is being deprecated. " - "Please use the DeviceController.CloseBLEConnection method directly in the REPL", DeprecationWarning) - - args = shlex.split(line) - - if len(args) != 0: - print("Usage:") - self.do_help("close") - return - - try: - self.devCtrl.CloseBLEConnection() - except exceptions.ChipStackException as ex: - print(str(ex)) - - def do_setlogoutput(self, line): - """ - set-log-output [ none | error | progress | detail ] - - Set the level of Chip logging output. - """ - - warnings.warn( - "This method is being deprecated. " - "Please use the DeviceController.SetLogFilter method directly in the REPL", DeprecationWarning) - - args = shlex.split(line) - - if len(args) == 0: - print("Usage:") - self.do_help("set-log-output") - return - if len(args) > 1: - print("Unexpected argument: " + args[1]) - return - - category = args[0].lower() - if category == "none": - category = 0 - elif category == "error": - category = 1 - elif category == "progress": - category = 2 - elif category == "detail": - category = 3 - else: - print("Invalid argument: " + args[0]) - return - - try: - self.devCtrl.SetLogFilter(category) - except exceptions.ChipStackException as ex: - print(str(ex)) - return - - def do_setuppayload(self, line): - """ - setup-payload generate [options] - - Options: - -vr Version - -vi Vendor ID - -pi Product ID - -cf Custom Flow [Standard = 0, UserActionRequired = 1, Custom = 2] - -dc Discovery Capabilities [SoftAP = 1 | BLE = 2 | OnNetwork = 4] - -dv Discriminator Value - -ps Passcode - - setup-payload parse-manual - setup-payload parse-qr - """ - - warnings.warn( - "This method is being deprecated. " - "Please use the SetupPayload function in the chip.setup_payload package directly", DeprecationWarning) - - try: - arglist = shlex.split(line) - if arglist[0] not in ("generate", "parse-manual", "parse-qr"): - self.do_help("setup-payload") - return - - if arglist[0] == "generate": - parser = argparse.ArgumentParser() - parser.add_argument("-vr", type=int, default=0, dest='version') - parser.add_argument( - "-pi", type=int, default=0, dest='productId') - parser.add_argument( - "-vi", type=int, default=0, dest='vendorId') - parser.add_argument( - '-cf', type=int, default=0, dest='customFlow') - parser.add_argument( - "-dc", type=int, default=0, dest='capabilities') - parser.add_argument( - "-dv", type=int, default=0, dest='discriminator') - parser.add_argument("-ps", type=int, dest='passcode') - args = parser.parse_args(arglist[1:]) - - SetupPayload().PrintOnboardingCodes(args.passcode, args.vendorId, args.productId, - args.discriminator, args.customFlow, args.capabilities, args.version) - - if arglist[0] == "parse-manual": - SetupPayload().ParseManualPairingCode(arglist[1]).Print() - - if arglist[0] == "parse-qr": - SetupPayload().ParseQrCode(arglist[1]).Print() - - except exceptions.ChipStackException as ex: - print(str(ex)) - return - - def do_bleadapterselect(self, line): - """ - ble-adapter-select - - Start BLE adapter select, deprecated, you can select adapter by command line arguments. - """ - if sys.platform.startswith("linux"): - if not self.bleMgr: - self.bleMgr = BleManager(self.devCtrl) - - self.bleMgr.ble_adapter_select(line) - print( - "This change only applies to ble-scan\n" - "Please run device controller with --bluetooth-adapter= to select adapter\n" + - "e.g. chip-device-ctrl --bluetooth-adapter hci0" - ) - else: - print( - "ble-adapter-select only works in Linux, ble-adapter-select mac_address" - ) - - return - - def do_bleadapterprint(self, line): - """ - ble-adapter-print - - Print attached BLE adapter. - """ - if sys.platform.startswith("linux"): - if not self.bleMgr: - self.bleMgr = BleManager(self.devCtrl) - - self.bleMgr.ble_adapter_print() - else: - print("ble-adapter-print only works in Linux") - - return - - def do_bledebuglog(self, line): - """ - ble-debug-log 0:1 - 0: disable BLE debug log - 1: enable BLE debug log - """ - if not self.bleMgr: - self.bleMgr = BleManager(self.devCtrl) - - self.bleMgr.ble_debug_log(line) - - return - - def do_blescan(self, line): - """ - ble-scan - - Start BLE scanning operations. - """ - - if not self.bleMgr: - self.bleMgr = BleManager(self.devCtrl) - - self.bleMgr.scan(line) - - return - - def ConnectFromSetupPayload(self, setupPayload, nodeid): - # TODO(cecille): Get this from the C++ code? - ble = 1 << 1 - # Devices may be uncommissioned, or may already be on the network. Need to check both ways. - # TODO(cecille): implement soft-ap connection. - - # Any device that is already commissioned into a fabric needs to use on-network - # pairing, so look first on the network regardless of the QR code contents. - print("Attempting to find device on Network") - longDiscriminator = ctypes.c_uint16( - int(setupPayload.attributes['Discriminator'])) - self.devCtrl.DiscoverCommissionableNodesLongDiscriminator( - longDiscriminator) - print("Waiting for device responses...") - strlen = 100 - addrStrStorage = ctypes.create_string_buffer(strlen) - # If this device is on the network and we're looking specifically for 1 device, - # expect a quick response. - if self.wait_for_one_discovered_device(): - self.devCtrl.GetIPForDiscoveredDevice( - 0, addrStrStorage, strlen) - addrStr = addrStrStorage.value.decode('utf-8') - print("Connecting to device at " + addrStr) - pincode = ctypes.c_uint32( - int(setupPayload.attributes['SetUpPINCode'])) - try: - self.devCtrl.CommissionIP(addrStrStorage, pincode, nodeid) - print("Connected") - return 0 - except Exception as ex: - print(f"Unable to connect on network: {ex}") - else: - print("Unable to locate device on network") - - if int(setupPayload.attributes["RendezvousInformation"]) & ble: - print("Attempting to connect via BLE") - longDiscriminator = ctypes.c_uint16( - int(setupPayload.attributes['Discriminator'])) - pincode = ctypes.c_uint32( - int(setupPayload.attributes['SetUpPINCode'])) - try: - self.devCtrl.ConnectBLE(longDiscriminator, pincode, nodeid) - print("Connected") - return 0 - except Exception as ex: - print(f"Unable to connect: {ex}") - return -1 - - def do_paseonly(self, line): - """ - paseonly -ip [] - - TODO: Add more methods to connect to device (like cert for auth, and IP - for connection) - """ - - try: - args = shlex.split(line) - if len(args) <= 1: - print("Usage:") - self.do_help("paseonly") - return - nodeid = random.randint(1, 1000000) # Just a random number - if len(args) == 4: - nodeid = int(args[3]) - print("Device is assigned with nodeid = {}".format(nodeid)) - self.replHint = f"devCtrl.EstablishPASESessionIP({repr(args[1])}, {int(args[2])}, {nodeid})" - if args[0] == "-ip" and len(args) >= 3: - self.devCtrl.EstablishPASESessionIP(args[1], int(args[2]), nodeid) - else: - print("Usage:") - self.do_help("paseonly") - return - print( - "Device temporary node id (**this does not match spec**): {}".format(nodeid)) - except Exception as ex: - print(str(ex)) - return - - def do_commission(self, line): - """ - commission nodeid - - Runs commissioning on a device that has been connected with paseonly - """ - try: - args = shlex.split(line) - if len(args) != 1: - print("Usage:") - self.do_help("commission") - return - nodeid = int(args[0]) - self.replHint = f"devCtrl.Commission({nodeid})" - self.devCtrl.Commission(nodeid) - except Exception as ex: - print(str(ex)) - return - - def do_connect(self, line): - """ - connect -ip [] - connect -ble [] - connect -qr [] - connect -code [] - - connect command is used for establishing a rendezvous session to the device. - currently, only connect using setupPinCode is supported. - -qr option will connect to the first device with a matching long discriminator. - - TODO: Add more methods to connect to device (like cert for auth, and IP - for connection) - """ - - warnings.warn( - "This method is being deprecated. " - "Please use the DeviceController.[ConnectBLE|CommissionIP] methods directly in the REPL", DeprecationWarning) - - try: - args = shlex.split(line) - if len(args) <= 1: - print("Usage:") - self.do_help("connect SetupPinCode") - return - - nodeid = random.randint(1, 1000000) # Just a random number - if len(args) == 4: - nodeid = int(args[3]) - print("Device is assigned with nodeid = {}".format(nodeid)) - - if args[0] == "-ip" and len(args) >= 3: - self.replHint = f"devCtrl.CommissionIP({repr(args[1])}, {int(args[2])}, {nodeid})" - self.devCtrl.CommissionIP(args[1], int(args[2]), nodeid) - elif args[0] == "-ble" and len(args) >= 3: - self.replHint = f"devCtrl.ConnectBLE({int(args[1])}, {int(args[2])}, {nodeid})" - self.devCtrl.ConnectBLE(int(args[1]), int(args[2]), nodeid) - elif args[0] in ['-qr', '-code'] and len(args) >= 2: - if len(args) == 3: - nodeid = int(args[2]) - print("Parsing QR code {}".format(args[1])) - - setupPayload = None - if args[0] == '-qr': - setupPayload = SetupPayload().ParseQrCode(args[1]) - elif args[0] == '-code': - setupPayload = SetupPayload( - ).ParseManualPairingCode(args[1]) - - if not int(setupPayload.attributes.get("RendezvousInformation", 0)): - print("No rendezvous information provided, default to all.") - setupPayload.attributes["RendezvousInformation"] = 0b111 - setupPayload.Print() - self.replHint = f"devCtrl.CommissionWithCode(setupPayload={repr(setupPayload)}, nodeid={nodeid})" - self.ConnectFromSetupPayload(setupPayload, nodeid) - else: - print("Usage:") - self.do_help("connect SetupPinCode") - return - print( - "Device temporary node id (**this does not match spec**): {}".format(nodeid)) - except exceptions.ChipStackException as ex: - print(str(ex)) - return - - def do_closesession(self, line): - """ - close-session - - Close any session associated with a given node ID. - """ - try: - parser = argparse.ArgumentParser() - parser.add_argument('nodeid', type=int, help='Peer node ID') - args = parser.parse_args(shlex.split(line)) - self.replHint = f"devCtrl.CloseSession({args.nodeid})" - self.devCtrl.CloseSession(args.nodeid) - except exceptions.ChipStackException as ex: - print(str(ex)) - except Exception: - self.do_help("close-session") - - def do_resolve(self, line): - """ - resolve - - Resolve DNS-SD name corresponding with the given node ID and - update address of the node in the device controller. - """ - try: - args = shlex.split(line) - if len(args) == 1: - try: - self.replHint = f"devCtrl.ResolveNode({int(args[0])});devCtrl.GetAddressAndPort({int(args[0])})" - self.devCtrl.ResolveNode(int(args[0])) - address = self.devCtrl.GetAddressAndPort(int(args[0])) - address = "{}:{}".format( - *address) if address else "unknown" - print("Current address: " + address) - except exceptions.ChipStackException as ex: - print(str(ex)) - else: - self.do_help("resolve") - except exceptions.ChipStackException as ex: - print(str(ex)) - return - - def wait_for_one_discovered_device(self): - print("Waiting for device responses...") - strlen = 100 - addrStrStorage = ctypes.create_string_buffer(strlen) - count = 0 - maxWaitTime = 2 - while (not self.devCtrl.GetIPForDiscoveredDevice(0, addrStrStorage, strlen) and count < maxWaitTime): - time.sleep(0.2) - count = count + 0.2 - return count < maxWaitTime - - def wait_for_many_discovered_devices(self): - # Discovery happens through mdns, which means we need to wait for responses to come back. - # TODO(cecille): I suppose we could make this a command line arg. Or Add a callback when - # x number of responses are received. For now, just 2 seconds. We can all wait that long. - print("Waiting for device responses...") - time.sleep(2) - - def do_discover(self, line): - """ - discover -qr qrcode - discover -all - discover -l long_discriminator - discover -s short_discriminator - discover -v vendor_id - discover -t device_type - discover -c - - discover command is used to discover available devices. - """ - try: - arglist = shlex.split(line) - if len(arglist) < 1: - print("Usage:") - self.do_help("discover") - return - parser = argparse.ArgumentParser() - group = parser.add_mutually_exclusive_group() - group.add_argument( - '-all', help='discover all commissionable nodes and commissioners', action='store_true') - group.add_argument( - '-qr', help='discover commissionable nodes matching provided QR code', type=str) - group.add_argument( - '-l', help='discover commissionable nodes with given long discriminator', type=int) - group.add_argument( - '-s', help='discover commissionable nodes with given short discriminator', type=int) - group.add_argument( - '-v', help='discover commissionable nodes with given vendor ID', type=int) - group.add_argument( - '-t', help='discover commissionable nodes with given device type', type=int) - group.add_argument( - '-c', help='discover commissionable nodes in commissioning mode', action='store_true') - args = parser.parse_args(arglist) - if args.all: - self.commissionableNodeCtrl.DiscoverCommissioners() - self.wait_for_many_discovered_devices() - self.commissionableNodeCtrl.PrintDiscoveredCommissioners() - self.devCtrl.DiscoverAllCommissioning() - self.wait_for_many_discovered_devices() - elif args.qr is not None: - setupPayload = SetupPayload().ParseQrCode(args.qr) - longDiscriminator = ctypes.c_uint16( - int(setupPayload.attributes['Discriminator'])) - self.devCtrl.DiscoverCommissionableNodesLongDiscriminator( - longDiscriminator) - self.wait_for_one_discovered_device() - elif args.l is not None: - self.devCtrl.DiscoverCommissionableNodesLongDiscriminator( - ctypes.c_uint16(args.l)) - self.wait_for_one_discovered_device() - elif args.s is not None: - self.devCtrl.DiscoverCommissionableNodesShortDiscriminator( - ctypes.c_uint16(args.s)) - self.wait_for_one_discovered_device() - elif args.v is not None: - self.devCtrl.DiscoverCommissionableNodesVendor( - ctypes.c_uint16(args.v)) - self.wait_for_many_discovered_devices() - elif args.t is not None: - self.devCtrl.DiscoverCommissionableNodesDeviceType( - ctypes.c_uint16(args.t)) - self.wait_for_many_discovered_devices() - elif args.c is not None: - self.devCtrl.DiscoverCommissionableNodesCommissioningEnabled() - self.wait_for_many_discovered_devices() - else: - self.do_help("discover") - return - self.devCtrl.PrintDiscoveredDevices() - except exceptions.ChipStackException as ex: - print('exception') - print(str(ex)) - return - except Exception: - self.do_help("discover") - return - - def do_zcl(self, line): - """ - To send ZCL message to device: - zcl [key=value]... - To get a list of clusters: - zcl ? - To get a list of commands in cluster: - zcl ? - - Send ZCL command to device nodeid - """ - try: - args = shlex.split(line) - all_commands = self.devCtrl.ZCLCommandList() - if len(args) == 1 and args[0] == '?': - print('\n'.join(all_commands.keys())) - elif len(args) == 2 and args[0] == '?': - if args[1] not in all_commands: - raise exceptions.UnknownCluster(args[1]) - for commands in all_commands.get(args[1]).items(): - args = ", ".join(["{}: {}".format(argName, argType) - for argName, argType in commands[1].items()]) - print(commands[0]) - if commands[1]: - print(" ", args) - else: - print(" ") - elif len(args) > 4: - if args[0] not in all_commands: - raise exceptions.UnknownCluster(args[0]) - command = all_commands.get(args[0]).get(args[1], None) - # When command takes no arguments, (not command) is True - if command is None: - raise exceptions.UnknownCommand(args[0], args[1]) - req = eval(f"Clusters.{args[0]}.Commands.{args[1]}")(**FormatZCLArguments(args[5:], command)) - self.replHint = f"await devCtrl.SendCommand({int(args[2])}, {int(args[3])}, Clusters.{repr(req)})" - err, res = self.devCtrl.ZCLSend(args[0], args[1], int( - args[2]), int(args[3]), int(args[4]), FormatZCLArguments(args[5:], command), blocking=True) - if err != 0: - print("Failed to receive command response: {}".format(res)) - elif res is not None: - print("Received command status response:") - print(res) - else: - print("Success, no status code is attached with response.") - else: - self.do_help("zcl") - except exceptions.ChipStackException as ex: - print("An exception occurred during process ZCL command:") - print(str(ex)) - except Exception as ex: - print("An exception occurred during processing input:") - traceback.print_exc() - print(str(ex)) - - def do_zclread(self, line): - """ - To read ZCL attribute: - zclread - """ - try: - args = shlex.split(line) - all_attrs = self.devCtrl.ZCLAttributeList() - if len(args) == 1 and args[0] == '?': - print('\n'.join(all_attrs.keys())) - elif len(args) == 2 and args[0] == '?': - if args[1] not in all_attrs: - raise exceptions.UnknownCluster(args[1]) - print('\n'.join(all_attrs.get(args[1]).keys())) - elif len(args) == 5: - if args[0] not in all_attrs: - raise exceptions.UnknownCluster(args[0]) - self.replHint = (f"await devCtrl.ReadAttribute({int(args[2])}, [({int(args[3])}, " - f"Clusters.{args[0]}.Attributes.{args[1]})])") - res = self.devCtrl.ZCLReadAttribute(args[0], args[1], int( - args[2]), int(args[3]), int(args[4])) - if res is not None: - print(repr(res)) - else: - self.do_help("zclread") - except exceptions.ChipStackException as ex: - print("An exception occurred during reading ZCL attribute:") - print(str(ex)) - except Exception as ex: - print("An exception occurred during processing input:") - print(str(ex)) - - def do_zclwrite(self, line): - """ - To write ZCL attribute: - zclwrite - """ - try: - args = shlex.split(line) - all_attrs = self.devCtrl.ZCLAttributeList() - if len(args) == 1 and args[0] == '?': - print('\n'.join(all_attrs.keys())) - elif len(args) == 2 and args[0] == '?': - if args[1] not in all_attrs: - raise exceptions.UnknownCluster(args[1]) - cluster_attrs = all_attrs.get(args[1], {}) - print('\n'.join(["{}: {}".format(key, cluster_attrs[key]["type"]) - for key in cluster_attrs.keys() if cluster_attrs[key].get("writable", False)])) - elif len(args) == 6: - if args[0] not in all_attrs: - raise exceptions.UnknownCluster(args[0]) - attribute_type = all_attrs.get(args[0], {}).get( - args[1], {}).get("type", None) - self.replHint = ( - f"await devCtrl.WriteAttribute({int(args[2])}, [({int(args[3])}, " - f"Clusters.{args[0]}.Attributes.{args[1]}(value={repr(ParseValueWithType(args[5], attribute_type))}))])") - res = self.devCtrl.ZCLWriteAttribute(args[0], args[1], int( - args[2]), int(args[3]), int(args[4]), ParseValueWithType(args[5], attribute_type)) - print(repr(res)) - else: - self.do_help("zclwrite") - except exceptions.ChipStackException as ex: - print("An exception occurred during writing ZCL attribute:") - print(str(ex)) - except Exception as ex: - print("An exception occurred during processing input:") - print(str(ex)) - - def do_zclsubscribe(self, line): - """ - To subscribe ZCL attribute reporting: - zclsubscribe - - To shut down a subscription: - zclsubscribe -shutdown - """ - try: - args = shlex.split(line) - all_attrs = self.devCtrl.ZCLAttributeList() - if len(args) == 1 and args[0] == '?': - print('\n'.join(all_attrs.keys())) - elif len(args) == 2 and args[0] == '?': - if args[1] not in all_attrs: - raise exceptions.UnknownCluster(args[1]) - cluster_attrs = all_attrs.get(args[1], {}) - print('\n'.join([key for key in cluster_attrs.keys( - ) if cluster_attrs[key].get("reportable", False)])) - elif len(args) == 6: - if args[0] not in all_attrs: - raise exceptions.UnknownCluster(args[0]) - res = self.devCtrl.ZCLSubscribeAttribute(args[0], args[1], int( - args[2]), int(args[3]), int(args[4]), int(args[5])) - self.replHint = (f"sub = await devCtrl.ReadAttribute({int(args[2])}, [({int(args[3])}, " - f"Clusters.{args[0]}.Attributes.{args[1]})], reportInterval=({int(args[4])}, {int(args[5])}))") - print(res.GetAllValues()) - print(f"Subscription Established: {res}") - elif len(args) == 2 and args[0] == '-shutdown': - subscriptionId = int(args[1], base=0) - self.replHint = "You can call sub.Shutdown() (sub is the return value of ReadAttribute() called before)" - self.devCtrl.ZCLShutdownSubscription(subscriptionId) - else: - self.do_help("zclsubscribe") - except exceptions.ChipStackException as ex: - print("An exception occurred during configuring reporting of ZCL attribute:") - print(str(ex)) - except Exception as ex: - print("An exception occurred during processing input:") - print(str(ex)) - - def do_setpairingwificredential(self, line): - """ - set-pairing-wifi-credential ssid credentials - """ - try: - args = shlex.split(line) - if len(args) < 2: - print("Usage:") - self.do_help("set-pairing-wifi-credential") - return - self.devCtrl.SetWiFiCredentials( - args[0], args[1]) - self.replHint = f"devCtrl.SetWiFiCredentials({repr(args[0])}, {repr(args[1])})" - except Exception as ex: - print(str(ex)) - return - - def do_setpairingthreadcredential(self, line): - """ - set-pairing-thread-credential threadOperationalDataset - """ - try: - args = shlex.split(line) - if len(args) < 1: - print("Usage:") - self.do_help("set-pairing-thread-credential") - return - self.replHint = f"devCtrl.SetThreadOperationalDataset(bytes.fromhex({repr(args[0])}))" - self.devCtrl.SetThreadOperationalDataset(bytes.fromhex(args[0])) - except Exception as ex: - print(str(ex)) - return - - def do_opencommissioningwindow(self, line): - """ - open-commissioning-window [options] - - Options: - -t Timeout (in seconds) - -o Option [TokenWithRandomPIN = 1, TokenWithProvidedPIN = 2] - -d Discriminator Value - -i Iteration - - This command is used by a current Administrator to instruct a Node to go into commissioning mode - """ - try: - arglist = shlex.split(line) - - if len(arglist) <= 1: - print("Usage:") - self.do_help("open-commissioning-window") - return - parser = argparse.ArgumentParser() - parser.add_argument( - "-t", type=int, default=0, dest='timeout') - parser.add_argument( - "-o", type=int, default=1, dest='option') - parser.add_argument( - "-i", type=int, default=0, dest='iteration') - parser.add_argument( - "-d", type=int, default=0, dest='discriminator') - args = parser.parse_args(arglist[1:]) - - if args.option < 1 or args.option > 2: - print("Invalid option specified!") - raise ValueError("Invalid option specified") - - self.replHint = (f"devCtrl.OpenCommissioningWindow(nodeid={int(arglist[0])}, timeout={args.timeout}, " - f"iteration={args.iteration}, discriminator={args.discriminator}, option={args.option})") - - self.devCtrl.OpenCommissioningWindow( - int(arglist[0]), args.timeout, args.iteration, args.discriminator, args.option) - - except exceptions.ChipStackException as ex: - print(str(ex)) - return - except Exception: - self.do_help("open-commissioning-window") - return - - def do_getfabricid(self, line): - """ - get-fabricid - - Read the current Compressed Fabric Id of the controller device, return 0 if not available. - """ - try: - args = shlex.split(line) - - if (len(args) > 0): - print("Unexpected argument: " + args[1]) - return - - compressed_fabricid = self.devCtrl.GetCompressedFabricId() - raw_fabricid = self.devCtrl.fabricId - - self.replHint = "devCtrl.GetCompressedFabricId(), devCtrl.fabricId" - except exceptions.ChipStackException as ex: - print("An exception occurred during reading FabricID:") - print(str(ex)) - return - - print("Get fabric ID complete") - - print("Raw Fabric ID: 0x{:016x}".format(raw_fabricid) - + " (" + str(raw_fabricid) + ")") - - print("Compressed Fabric ID: 0x{:016x}".format(compressed_fabricid) - + " (" + str(compressed_fabricid) + ")") - - def do_history(self, line): - """ - history - - Show previously executed commands. - """ - - try: - import readline - - h = readline.get_current_history_length() - for n in range(1, h + 1): - print(readline.get_history_item(n)) - except ImportError: - pass - - def do_h(self, line): - self.do_history(line) - - def do_exit(self, line): - return True - - def do_quit(self, line): - return True - - def do_q(self, line): - return True - - def do_EOF(self, line): - print() - return True - - def emptyline(self): - pass - - -def main(): - optParser = OptionParser() - optParser.add_option( - "-r", - "--rendezvous-addr", - action="store", - dest="rendezvousAddr", - help="Device rendezvous address", - metavar="", - ) - optParser.add_option( - "-n", - "--controller-nodeid", - action="store", - dest="controllerNodeId", - default=1, - type='int', - help="Controller node ID", - metavar="", - ) - - if sys.platform.startswith("linux"): - optParser.add_option( - "-b", - "--bluetooth-adapter", - action="store", - dest="bluetoothAdapter", - default="hci0", - type="str", - help="Controller bluetooth adapter ID, use --no-ble to disable bluetooth functions.", - metavar="", - ) - optParser.add_option( - "--no-ble", - action="store_true", - dest="disableBluetooth", - help="Disable bluetooth, calling BLE related feature with this flag results in undefined behavior.", - ) - (options, remainingArgs) = optParser.parse_args(sys.argv[1:]) - - if len(remainingArgs) != 0: - print("Unexpected argument: %s" % remainingArgs[0]) - sys.exit(-1) - - adapterId = None - if sys.platform.startswith("linux"): - if options.disableBluetooth: - adapterId = None - elif not options.bluetoothAdapter.startswith("hci"): - print( - "Invalid bluetooth adapter: {}, adapter name looks like hci0, hci1 etc.") - sys.exit(-1) - else: - try: - adapterId = int(options.bluetoothAdapter[3:]) - except ValueError: - print( - "Invalid bluetooth adapter: {}, adapter name looks like hci0, hci1 etc.") - sys.exit(-1) - native.Init(bluetoothAdapter=adapterId) - try: - devMgrCmd = DeviceMgrCmd(rendezvousAddr=options.rendezvousAddr, - controllerNodeId=options.controllerNodeId, bluetoothAdapter=adapterId) - except Exception as ex: - print(ex) - print("Failed to bringup CHIPDeviceController CLI") - sys.exit(1) - - print("Chip Device Controller Shell") - if options.rendezvousAddr: - print("Rendezvous address set to %s" % options.rendezvousAddr) - - # Adapter ID will always be 0 - if adapterId != 0: - print("Bluetooth adapter set to hci{}".format(adapterId)) - print() - - try: - devMgrCmd.cmdloop() - except KeyboardInterrupt: - print("\nQuitting") - - sys.exit(0) - - -if __name__ == "__main__": - print(""" - chip-device-ctrl will be deprecated and will be removed in the future. Please try chip-repl, which provides a lot of features. - - - Multi-fabric support, - - Better complex type support for sending commands, - - Native command highlight, - - Parallel commands with asyncio, - - Writing complex logic inline. - - You can still use chip-device-ctrl as usual for now, and you will learn how to do the same thing in chip-repl. - - Feel free to file an issue if some features are not supported by chip-repl yet. - """) - main() diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index d63a3772e62dc6..2ba7c584db927b 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -35,11 +35,12 @@ import enum import json import logging +import secrets import threading import time import typing -from ctypes import (CDLL, CFUNCTYPE, POINTER, byref, c_bool, c_char, c_char_p, c_int, c_int32, c_size_t, c_uint8, c_uint16, - c_uint32, c_uint64, c_void_p, create_string_buffer, pointer, py_object, resize, string_at) +from ctypes import (CDLL, CFUNCTYPE, POINTER, Structure, byref, c_bool, c_char, c_char_p, c_int, c_int32, c_size_t, c_uint8, + c_uint16, c_uint32, c_uint64, c_void_p, create_string_buffer, pointer, py_object, resize, string_at) from dataclasses import dataclass import dacite @@ -50,12 +51,9 @@ from .clusters import Attribute as ClusterAttribute from .clusters import ClusterObjects as ClusterObjects from .clusters import Command as ClusterCommand -from .clusters import Objects as GeneratedObjects from .clusters.CHIPClusters import ChipClusters from .crypto import p256keypair -from .exceptions import UnknownAttribute, UnknownCommand -from .interaction_model import InteractionModelError, SessionParameters, SessionParametersStruct -from .interaction_model import delegate as im +from .interaction_model import SessionParameters, SessionParametersStruct from .native import PyChipError __all__ = ["ChipDeviceController", "CommissioningParameters"] @@ -101,6 +99,21 @@ class NOCChain: adminSubject: int +@dataclass +class ICDRegistrationParameters: + symmetricKey: typing.Optional[bytes] + checkInNodeId: typing.Optional[int] + monitoredSubject: typing.Optional[int] + stayActiveMs: typing.Optional[int] + + class CStruct(Structure): + _fields_ = [('symmetricKey', c_char_p), ('symmetricKeyLength', c_size_t), ('checkInNodeId', + c_uint64), ('monitoredSubject', c_uint64), ('stayActiveMsec', c_uint32)] + + def to_c(self): + return ICDRegistrationParameters.CStruct(self.symmetricKey, len(self.symmetricKey), self.checkInNodeId, self.monitoredSubject, self.stayActiveMs) + + @_DeviceAvailableCallbackFunct def _DeviceAvailableCallback(closure, device, err): closure.deviceAvailable(device, err) @@ -126,6 +139,77 @@ def _IssueNOCChainCallbackPythonCallback(devCtrl, status: PyChipError, noc: c_vo nocChain = NOCChain(nocBytes, icacBytes, rcacBytes, ipkBytes, adminSubject) devCtrl.NOCChainCallback(nocChain) + +# Methods for ICD +class ScopedNodeId(Structure): + _fields_ = [("nodeId", c_uint64), ("fabricIndex", c_uint8)] + + def __hash__(self): + return self.nodeId << 8 | self.fabricIndex + + def __str__(self): + return f"({self.fabricIndex}:{self.nodeId:16x})" + + def __eq__(self, other): + return self.nodeId == other.nodeId and self.fabricIndex == other.fabricIndex + + +_OnCheckInCompleteFunct = CFUNCTYPE(None, ScopedNodeId) + +_OnCheckInCompleteWaitListLock = threading.Lock() +_OnCheckInCompleteWaitList = dict() + + +@_OnCheckInCompleteFunct +def _OnCheckInComplete(scopedNodeId: ScopedNodeId): + callbacks = [] + with _OnCheckInCompleteWaitListLock: + callbacks = list(_OnCheckInCompleteWaitList.get(scopedNodeId, set())) + + for callback in callbacks: + callback(scopedNodeId) + + +def RegisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callable[None, [ScopedNodeId]]): + ''' Registers a callback when the device with given (fabric index, node id) becomes active. + + Does nothing if the callback is already registered. + ''' + with _OnCheckInCompleteWaitListLock: + waitList = _OnCheckInCompleteWaitList.get(scopedNodeId, set()) + waitList.add(callback) + _OnCheckInCompleteWaitList[scopedNodeId] = waitList + + +def UnregisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callable[None, [ScopedNodeId]]): + ''' Unregisters a callback when the device with given (fabric index, node id) becomes active. + + Does nothing if the callback has not been registered. + ''' + with _OnCheckInCompleteWaitListLock: + _OnCheckInCompleteWaitList.get(scopedNodeId, set()).remove(callback) + + +async def WaitForCheckIn(scopedNodeId: ScopedNodeId, timeoutSeconds: float): + ''' Waits for a device becomes active. + + Returns: + - A future, completes when the device becomes active. + ''' + eventLoop = asyncio.get_running_loop() + future = eventLoop.create_future() + + def OnCheckInCallback(nodeid): + eventLoop.call_soon_threadsafe(lambda: future.done() or future.set_result(None)) + + RegisterOnActiveCallback(scopedNodeId, OnCheckInCallback) + + try: + async with asyncio.timeout(timeoutSeconds): + await future + finally: + UnregisterOnActiveCallback(scopedNodeId, OnCheckInCallback) + # This is a fix for WEAV-429. Jay Logue recommends revisiting this at a later # date to allow for truly multiple instances so this is temporary. @@ -272,6 +356,7 @@ def HandleCommissioningComplete(nodeid, err): else: logging.warning("Failed to commission: {}".format(err)) + self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters(False, None) self.state = DCState.IDLE self._ChipStack.callbackRes = err self._ChipStack.commissioningEventRes = err @@ -350,6 +435,7 @@ def HandlePASEEstablishmentComplete(err: PyChipError): self._isActive = True # Validate FabricID/NodeID followed from NOC Chain self._fabricId = self.GetFabricIdInternal() + self._fabricIndex = self.GetFabricIndexInternal() self._nodeId = self.GetNodeIdInternal() def _finish_init(self): @@ -769,6 +855,19 @@ def GetFabricIdInternal(self): return fabricid.value + def GetFabricIndexInternal(self): + """Get the fabric index from the object. Only used to validate cached value from property.""" + self.CheckIsActive() + + fabricindex = c_uint8(0) + + self._ChipStack.Call( + lambda: self._dmLib.pychip_DeviceController_GetFabricIndex( + self.devCtrl, pointer(fabricindex)) + ).raise_on_error() + + return fabricindex.value + def GetNodeIdInternal(self) -> int: """Get the node ID from the object. Only used to validate cached value from property.""" self.CheckIsActive() @@ -844,6 +943,18 @@ def deviceAvailable(self, device, err): return DeviceProxyWrapper(returnDevice, self._dmLib) + async def WaitForActive(self, nodeid, *, timeoutSeconds=30.0, stayActiveDurationMs=30000): + ''' Waits a LIT ICD device to become active. Will send a StayActive command to the device on active to allow human operations. + + nodeId: Node ID of the LID ICD + stayActiveDurationMs: The duration in the StayActive command, in milliseconds + + Returns: + - StayActiveResponse on success + ''' + await WaitForCheckIn(ScopedNodeId(nodeid, self._fabricIndex), timeoutSeconds=timeoutSeconds) + return await self.SendCommand(nodeid, 0, Clusters.IcdManagement.Commands.StayActiveRequest(stayActiveDuration=stayActiveDurationMs)) + async def GetConnectedDevice(self, nodeid, allowPASE: bool = True, timeoutMs: int = None): ''' Gets an OperationalDeviceProxy or CommissioneeDeviceProxy for the specified Node. @@ -1170,33 +1281,26 @@ def _parseAttributePathTuple(self, pathTuple: typing.Union[ # Concrete path typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]] ]): - endpoint = None - cluster = None - attribute = None - if pathTuple == ('*') or pathTuple == (): # Wildcard - pass + return ClusterAttribute.AttributePath() elif not isinstance(pathTuple, tuple): if isinstance(pathTuple, int): - endpoint = pathTuple + return ClusterAttribute.AttributePath(EndpointId=pathTuple) elif issubclass(pathTuple, ClusterObjects.Cluster): - cluster = pathTuple + return ClusterAttribute.AttributePath.from_cluster(EndpointId=None, Cluster=pathTuple) elif issubclass(pathTuple, ClusterObjects.ClusterAttributeDescriptor): - attribute = pathTuple + return ClusterAttribute.AttributePath.from_attribute(EndpointId=None, Attribute=pathTuple) else: raise ValueError("Unsupported Attribute Path") else: # endpoint + (cluster) attribute / endpoint + cluster - endpoint = pathTuple[0] if issubclass(pathTuple[1], ClusterObjects.Cluster): - cluster = pathTuple[1] + return ClusterAttribute.AttributePath.from_cluster(EndpointId=pathTuple[0], Cluster=pathTuple[1]) elif issubclass(pathTuple[1], ClusterAttribute.ClusterAttributeDescriptor): - attribute = pathTuple[1] + return ClusterAttribute.AttributePath.from_attribute(EndpointId=pathTuple[0], Attribute=pathTuple[1]) else: raise ValueError("Unsupported Attribute Path") - return ClusterAttribute.AttributePath( - EndpointId=endpoint, Cluster=cluster, Attribute=attribute) def _parseDataVersionFilterTuple(self, pathTuple: typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]]): endpoint = None @@ -1209,7 +1313,7 @@ def _parseDataVersionFilterTuple(self, pathTuple: typing.List[typing.Tuple[int, else: raise ValueError("Unsupported Cluster Path") dataVersion = pathTuple[2] - return ClusterAttribute.DataVersionFilter( + return ClusterAttribute.DataVersionFilter.from_cluster( EndpointId=endpoint, Cluster=cluster, DataVersion=dataVersion) def _parseEventPathTuple(self, pathTuple: typing.Union[ @@ -1226,39 +1330,31 @@ def _parseEventPathTuple(self, pathTuple: typing.Union[ typing.Tuple[int, typing.Type[ClusterObjects.ClusterEvent], int] ]): - endpoint = None - cluster = None - event = None - urgent = False if pathTuple in [('*'), ()]: # Wildcard - pass + return ClusterAttribute.EventPath() elif not isinstance(pathTuple, tuple): logging.debug(type(pathTuple)) if isinstance(pathTuple, int): - endpoint = pathTuple + return ClusterAttribute.EventPath(EndpointId=pathTuple) elif issubclass(pathTuple, ClusterObjects.Cluster): - cluster = pathTuple + return ClusterAttribute.EventPath.from_cluster(EndpointId=None, Cluster=pathTuple) elif issubclass(pathTuple, ClusterObjects.ClusterEvent): - event = pathTuple + return ClusterAttribute.EventPath.from_event(EndpointId=None, Event=pathTuple) else: raise ValueError("Unsupported Event Path") else: if pathTuple[0] == '*': - urgent = pathTuple[-1] - pass + return ClusterAttribute.EventPath(Urgent=pathTuple[-1]) else: + urgent = bool(pathTuple[-1]) if len(pathTuple) > 2 else False # endpoint + (cluster) event / endpoint + cluster - endpoint = pathTuple[0] if issubclass(pathTuple[1], ClusterObjects.Cluster): - cluster = pathTuple[1] + return ClusterAttribute.EventPath.from_cluster(EndpointId=pathTuple[0], Cluster=pathTuple[1], Urgent=urgent) elif issubclass(pathTuple[1], ClusterAttribute.ClusterEvent): - event = pathTuple[1] + return ClusterAttribute.EventPath.from_event(EndpointId=pathTuple[0], Event=pathTuple[1], Urgent=urgent) else: raise ValueError("Unsupported Attribute Path") - urgent = bool(pathTuple[-1]) if len(pathTuple) > 2 else False - return ClusterAttribute.EventPath( - EndpointId=endpoint, Cluster=cluster, Event=event, Urgent=urgent) async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ None, # Empty tuple, all wildcard @@ -1495,83 +1591,6 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ else: return res.events - def ZCLSend(self, cluster, command, nodeid, endpoint, groupid, args, blocking=False): - ''' Wrapper over SendCommand that catches the exceptions - Returns a tuple of (errorCode, CommandResponse) - ''' - self.CheckIsActive() - - req = None - try: - req = eval( - f"GeneratedObjects.{cluster}.Commands.{command}")(**args) - except BaseException: - raise UnknownCommand(cluster, command) - try: - res = asyncio.run(self.SendCommand(nodeid, endpoint, req)) - logging.debug(f"CommandResponse {res}") - return (0, res) - except InteractionModelError as ex: - return (int(ex.status), None) - - def ZCLReadAttribute(self, cluster, attribute, nodeid, endpoint, groupid, blocking=True): - ''' Wrapper over ReadAttribute for a single attribute - Returns an AttributeReadResult - ''' - self.CheckIsActive() - - clusterType = getattr(GeneratedObjects, cluster) - - try: - attributeType = eval( - f"GeneratedObjects.{cluster}.Attributes.{attribute}") - except BaseException: - raise UnknownAttribute(cluster, attribute) - - result = asyncio.run(self.ReadAttribute( - nodeid, [(endpoint, attributeType)])) - path = ClusterAttribute.AttributePath( - EndpointId=endpoint, Attribute=attributeType) - return im.AttributeReadResult(path=im.AttributePath(nodeId=nodeid, endpointId=path.EndpointId, clusterId=path.ClusterId, attributeId=path.AttributeId), - status=0, value=result[endpoint][clusterType][attributeType], dataVersion=result[endpoint][clusterType][ClusterAttribute.DataVersion]) - - def ZCLWriteAttribute(self, cluster: str, attribute: str, nodeid, endpoint, groupid, value, dataVersion=0, blocking=True): - ''' Wrapper over WriteAttribute for a single attribute - return PyChipError - ''' - req = None - try: - req = eval( - f"GeneratedObjects.{cluster}.Attributes.{attribute}")(value) - except BaseException: - raise UnknownAttribute(cluster, attribute) - - return asyncio.run(self.WriteAttribute(nodeid, [(endpoint, req, dataVersion)])) - - def ZCLSubscribeAttribute(self, cluster, attribute, nodeid, endpoint, minInterval, maxInterval, blocking=True, - keepSubscriptions=False, autoResubscribe=True): - ''' Wrapper over ReadAttribute for a single attribute - Returns a SubscriptionTransaction. See ReadAttribute for more information. - ''' - self.CheckIsActive() - - req = None - try: - req = eval(f"GeneratedObjects.{cluster}.Attributes.{attribute}") - except BaseException: - raise UnknownAttribute(cluster, attribute) - return asyncio.run(self.ReadAttribute(nodeid, [(endpoint, req)], None, False, reportInterval=(minInterval, maxInterval), - keepSubscriptions=keepSubscriptions, autoResubscribe=autoResubscribe)) - - def ZCLCommandList(self): - self.CheckIsActive() - return self._Cluster.ListClusterCommands() - - def ZCLAttributeList(self): - self.CheckIsActive() - - return self._Cluster.ListClusterAttributes() - def SetBlockingCB(self, blockingCB): self.CheckIsActive() @@ -1631,6 +1650,11 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_SetCheckMatchingFabric.restype = PyChipError self._dmLib.pychip_DeviceController_SetCheckMatchingFabric.argtypes = [c_bool] + self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters.restype = PyChipError + self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters.argtypes = [ + c_bool, c_void_p + ] + self._dmLib.pychip_DeviceController_ResetCommissioningParameters.restype = PyChipError self._dmLib.pychip_DeviceController_ResetCommissioningParameters.argtypes = [] @@ -1817,6 +1841,9 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_GetFabricId.argtypes = [c_void_p, POINTER(c_uint64)] self._dmLib.pychip_DeviceController_GetFabricId.restype = PyChipError + self._dmLib.pychip_DeviceController_GetFabricIndex.argtypes = [c_void_p, POINTER(c_uint8)] + self._dmLib.pychip_DeviceController_GetFabricIndex.restype = PyChipError + self._dmLib.pychip_DeviceController_GetLogFilter = [None] self._dmLib.pychip_DeviceController_GetLogFilter = c_uint8 @@ -1831,6 +1858,11 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_SetIpk.argtypes = [c_void_p, POINTER(c_char), c_size_t] self._dmLib.pychip_DeviceController_SetIpk.restype = PyChipError + self._dmLib.pychip_CheckInDelegate_SetOnCheckInCompleteCallback.restype = None + self._dmLib.pychip_CheckInDelegate_SetOnCheckInCompleteCallback.argtypes = [_OnCheckInCompleteFunct] + + self._dmLib.pychip_CheckInDelegate_SetOnCheckInCompleteCallback(_OnCheckInComplete) + class ChipDeviceController(ChipDeviceControllerBase): ''' The ChipDeviceCommissioner binding, named as ChipDeviceController @@ -1979,6 +2011,38 @@ def SetCheckMatchingFabric(self, check: bool): lambda: self._dmLib.pychip_DeviceController_SetCheckMatchingFabric(check) ).raise_on_error() + def GenerateICDRegistrationParameters(self): + ''' Generates ICD registration parameters for this controller. ''' + return ICDRegistrationParameters( + secrets.token_bytes(16), + self._nodeId, + self._nodeId, + 30) + + def EnableICDRegistration(self, parameters: ICDRegistrationParameters): + ''' Enables ICD registration for the following commissioning session. + + Args: + parameters: A ICDRegistrationParameters for the parameters used for ICD registration, or None for default arguments. + ''' + if parameters is None: + raise ValueError("ICD registration parameter required.") + if len(parameters.symmetricKey) != 16: + raise ValueError("symmetricKey should be 16 bytes") + + self.CheckIsActive() + self._ChipStack.Call( + lambda: self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters( + True, pointer(parameters.to_c())) + ).raise_on_error() + + def DisableICDRegistration(self): + ''' Disables ICD registration. ''' + self.CheckIsActive() + self._ChipStack.Call( + lambda: self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters(False, None) + ).raise_on_error() + def GetFabricCheckResult(self) -> int: ''' Returns the fabric check result if SetCheckMatchingFabric was used.''' return self.fabricCheckNodeId diff --git a/src/controller/python/chip/ChipReplStartup.py b/src/controller/python/chip/ChipReplStartup.py index a49638cb99e56d..13a93a1efb453b 100644 --- a/src/controller/python/chip/ChipReplStartup.py +++ b/src/controller/python/chip/ChipReplStartup.py @@ -94,6 +94,10 @@ def main(): "-d", "--debug", help="Set default logging level to debug.", action="store_true") parser.add_argument( "-t", "--trust-store", help="Path to the PAA trust store.", action="store", default="./credentials/development/paa-root-certs") + parser.add_argument( + "-b", "--ble-adapter", help="Set the Bluetooth adapter index.", type=int, default=None) + parser.add_argument( + "-s", "--server-interactions", help="Enable server interactions.", action="store_true") args = parser.parse_args() if not os.path.exists(args.trust_store): @@ -128,7 +132,7 @@ def main(): # nothing we can do ... things will NOT work return - chip.native.Init() + chip.native.Init(bluetoothAdapter=args.ble_adapter) global certificateAuthorityManager global chipStack @@ -137,7 +141,7 @@ def main(): ReplInit(args.debug) - chipStack = ChipStack(persistentStoragePath=args.storagepath, enableServerInteractions=False) + chipStack = ChipStack(persistentStoragePath=args.storagepath, enableServerInteractions=args.server_interactions) certificateAuthorityManager = chip.CertificateAuthority.CertificateAuthorityManager(chipStack, chipStack.GetStorageManager()) certificateAuthorityManager.LoadAuthoritiesFromStorage() diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py index 35f9e24ef4db25..06afff3ef3c380 100644 --- a/src/controller/python/chip/ChipStack.py +++ b/src/controller/python/chip/ChipStack.py @@ -28,12 +28,8 @@ import asyncio import builtins -import logging import os -import sys -import time -from ctypes import (CFUNCTYPE, POINTER, Structure, c_bool, c_char_p, c_int64, c_uint8, c_uint16, c_uint32, c_ulong, c_void_p, - py_object, pythonapi) +from ctypes import CFUNCTYPE, Structure, c_bool, c_char_p, c_uint16, c_uint32, c_void_p, py_object, pythonapi from threading import Condition, Event, Lock import chip.native @@ -76,60 +72,6 @@ class DeviceStatusStruct(Structure): ] -class LogCategory(object): - """Debug logging categories used by chip.""" - - # NOTE: These values must correspond to those used in the chip C++ code. - Disabled = 0 - Error = 1 - Progress = 2 - Detail = 3 - Retain = 4 - - @staticmethod - def categoryToLogLevel(cat): - if cat == LogCategory.Error: - return logging.ERROR - elif cat == LogCategory.Progress: - return logging.INFO - elif cat == LogCategory.Detail: - return logging.DEBUG - elif cat == LogCategory.Retain: - return logging.CRITICAL - else: - return logging.NOTSET - - -class ChipLogFormatter(logging.Formatter): - """A custom logging.Formatter for logging chip library messages.""" - - def __init__( - self, - datefmt=None, - logModulePrefix=False, - logLevel=False, - logTimestamp=False, - logMSecs=True, - ): - fmt = "%(message)s" - if logModulePrefix: - fmt = "CHIP:%(chip-module)s: " + fmt - if logLevel: - fmt = "%(levelname)s:" + fmt - if datefmt is not None or logTimestamp: - fmt = "%(asctime)s " + fmt - super(ChipLogFormatter, self).__init__(fmt=fmt, datefmt=datefmt) - self.logMSecs = logMSecs - - def formatTime(self, record, datefmt=None): - if datefmt is None: - timestampStr = time.strftime("%Y-%m-%d %H:%M:%S%z") - if self.logMSecs: - timestampUS = record.__dict__.get("timestamp-usec", 0) - timestampStr = "%s.%03ld" % (timestampStr, timestampUS / 1000) - return timestampStr - - class AsyncCallableHandle: def __init__(self, callback): self._callback = callback @@ -194,18 +136,12 @@ def __call__(self): pythonapi.Py_DecRef(py_object(self)) -_CompleteFunct = CFUNCTYPE(None, c_void_p, c_void_p) -_ErrorFunct = CFUNCTYPE(None, c_void_p, c_void_p, - c_ulong, POINTER(DeviceStatusStruct)) -_LogMessageFunct = CFUNCTYPE( - None, c_int64, c_int64, c_char_p, c_uint8, c_char_p) _ChipThreadTaskRunnerFunct = CFUNCTYPE(None, py_object) @_singleton class ChipStack(object): - def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, - bluetoothAdapter=None, enableServerInteractions=True): + def __init__(self, persistentStoragePath: str, enableServerInteractions=True): builtins.enableDebugMode = False # TODO: Probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321. @@ -218,8 +154,6 @@ def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, self.callbackRes = None self.commissioningEventRes = None self.openCommissioningWindowPincode = {} - self._activeLogFunct = None - self.addModulePrefixToLogMessage = True self._enableServerInteractions = enableServerInteractions # @@ -228,65 +162,11 @@ def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, # self._loadLib() - # Arrange to log output from the chip library to a python logger object with the - # name 'chip.ChipStack'. If desired, applications can override this behavior by - # setting self.logger to a different python logger object, or by calling setLogFunct() - # with their own logging function. - self.logger = logging.getLogger(__name__) - self.setLogFunct(self.defaultLogFunct) - - # Determine if there are already handlers installed for the logger. Python 3.5+ - # has a method for this; on older versions the check has to be done manually. - if hasattr(self.logger, "hasHandlers"): - hasHandlers = self.logger.hasHandlers() - else: - hasHandlers = False - logger = self.logger - while logger is not None: - if len(logger.handlers) > 0: - hasHandlers = True - break - if not logger.propagate: - break - logger = logger.parent - - # If a logging handler has not already been initialized for 'chip.ChipStack', - # or any one of its parent loggers, automatically configure a handler to log to - # stdout. This maintains compatibility with a number of applications which expect - # chip log output to go to stdout by default. - # - # This behavior can be overridden in a variety of ways: - # - Initialize a different log handler before ChipStack is initialized. - # - Pass installDefaultLogHandler=False when initializing ChipStack. - # - Replace the StreamHandler on self.logger with a different handler object. - # - Set a different Formatter object on the existing StreamHandler object. - # - Reconfigure the existing ChipLogFormatter object. - # - Configure chip to call an application-specific logging function by - # calling self.setLogFunct(). - # - Call self.setLogFunct(None), which will configure the chip library - # to log directly to stdout, bypassing python altogether. - # - if installDefaultLogHandler and not hasHandlers: - logHandler = logging.StreamHandler(stream=sys.stdout) - logHandler.setFormatter(ChipLogFormatter()) - self.logger.addHandler(logHandler) - self.logger.setLevel(logging.DEBUG) - - def HandleComplete(appState, reqState): - self.callbackRes = True - self.completeEvent.set() - - def HandleError(appState, reqState, err, devStatusPtr): - self.callbackRes = self.ErrorToException(err, devStatusPtr) - self.completeEvent.set() - @_ChipThreadTaskRunnerFunct def HandleChipThreadRun(callback): callback() self.cbHandleChipThreadRun = HandleChipThreadRun - self.cbHandleComplete = _CompleteFunct(HandleComplete) - self.cbHandleError = _ErrorFunct(HandleError) # set by other modules(BLE) that require service by thread while thread blocks. self.blockingCB = None @@ -314,49 +194,6 @@ def GetStorageManager(self): def enableServerInteractions(self): return self._enableServerInteractions - @property - def defaultLogFunct(self): - """Returns a python callable which, when called, logs a message to the python logger object - currently associated with the ChipStack object. - The returned function is suitable for passing to the setLogFunct() method.""" - - def logFunct(timestamp, timestampUSec, moduleName, logCat, message): - moduleName = ChipUtility.CStringToString(moduleName) - message = ChipUtility.CStringToString(message) - if self.addModulePrefixToLogMessage: - message = "CHIP:%s: %s" % (moduleName, message) - logLevel = LogCategory.categoryToLogLevel(logCat) - msgAttrs = { - "chip-module": moduleName, - "timestamp": timestamp, - "timestamp-usec": timestampUSec, - } - self.logger.log(logLevel, message, extra=msgAttrs) - - return logFunct - - def setLogFunct(self, logFunct): - """Set the function used by the chip library to log messages. - The supplied object must be a python callable that accepts the following - arguments: - timestamp (integer) - timestampUS (integer) - module name (encoded UTF-8 string) - log category (integer) - message (encoded UTF-8 string) - Specifying None configures the chip library to log directly to stdout.""" - if logFunct is None: - logFunct = 0 - if not isinstance(logFunct, _LogMessageFunct): - logFunct = _LogMessageFunct(logFunct) - # TODO: Lock probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321. - with self.networkLock: - # NOTE: ChipStack must hold a reference to the CFUNCTYPE object while it is - # set. Otherwise it may get garbage collected, and logging calls from the - # chip library will fail. - self._activeLogFunct = logFunct - self._ChipStackLib.pychip_Stack_SetLogFunct(logFunct) - def Shutdown(self): # # Terminate Matter thread and shutdown the stack. @@ -389,15 +226,9 @@ def Call(self, callFunct, timeoutMs: int = None): This function is a wrapper of PostTaskOnChipThread, which includes some handling of application specific logics. Calling this function on CHIP on CHIP mainloop thread will cause deadlock. ''' - # throw error if op in progress - self.callbackRes = None - self.completeEvent.clear() # TODO: Lock probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321. with self.networkLock: res = self.PostTaskOnChipThread(callFunct).Wait(timeoutMs) - self.completeEvent.set() - if res == 0 and self.callbackRes is not None: - return self.callbackRes return res async def CallAsync(self, callFunct, timeoutMs: int = None): @@ -512,9 +343,6 @@ def _loadLib(self): self._ChipStackLib.pychip_Stack_StatusReportToString.restype = c_char_p self._ChipStackLib.pychip_Stack_ErrorToString.argtypes = [c_uint32] self._ChipStackLib.pychip_Stack_ErrorToString.restype = c_char_p - self._ChipStackLib.pychip_Stack_SetLogFunct.argtypes = [ - _LogMessageFunct] - self._ChipStackLib.pychip_Stack_SetLogFunct.restype = PyChipError self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread.argtypes = [ _ChipThreadTaskRunnerFunct, py_object] diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py index 9e46eed469d39f..a1a341ed46614a 100644 --- a/src/controller/python/chip/clusters/Attribute.py +++ b/src/controller/python/chip/clusters/Attribute.py @@ -54,62 +54,43 @@ class EventPriority(Enum): CRITICAL = 2 -@dataclass +@dataclass(frozen=True) class AttributePath: EndpointId: int = None ClusterId: int = None AttributeId: int = None - def __init__(self, EndpointId: int = None, Cluster=None, Attribute=None, ClusterId=None, AttributeId=None): - self.EndpointId = EndpointId - if Cluster is not None: - # Wildcard read for a specific cluster - if (Attribute is not None) or (ClusterId is not None) or (AttributeId is not None): - raise Warning( - "Attribute, ClusterId and AttributeId is ignored when Cluster is specified") - self.ClusterId = Cluster.id - return - if Attribute is not None: - if (ClusterId is not None) or (AttributeId is not None): - raise Warning( - "ClusterId and AttributeId is ignored when Attribute is specified") - self.ClusterId = Attribute.cluster_id - self.AttributeId = Attribute.attribute_id - return - self.ClusterId = ClusterId - self.AttributeId = AttributeId + @staticmethod + def from_cluster(EndpointId: int, Cluster: Cluster) -> AttributePath: + if Cluster is None: + raise ValueError("Cluster cannot be None") + return AttributePath(EndpointId=EndpointId, ClusterId=Cluster.id) + + @staticmethod + def from_attribute(EndpointId: int, Attribute: ClusterAttributeDescriptor) -> AttributePath: + if Attribute is None: + raise ValueError("Attribute cannot be None") + return AttributePath(EndpointId=EndpointId, ClusterId=Attribute.cluster_id, AttributeId=Attribute.attribute_id) def __str__(self) -> str: return f"{self.EndpointId}/{self.ClusterId}/{self.AttributeId}" - def __hash__(self): - return str(self).__hash__() - -@dataclass +@dataclass(frozen=True) class DataVersionFilter: EndpointId: int = None ClusterId: int = None DataVersion: int = None - def __init__(self, EndpointId: int = None, Cluster=None, ClusterId=None, DataVersion=None): - self.EndpointId = EndpointId - if Cluster is not None: - # Wildcard read for a specific cluster - if (ClusterId is not None): - raise Warning( - "Attribute, ClusterId and AttributeId is ignored when Cluster is specified") - self.ClusterId = Cluster.id - else: - self.ClusterId = ClusterId - self.DataVersion = DataVersion + @staticmethod + def from_cluster(EndpointId: int, Cluster: Cluster, DataVersion: int = None) -> AttributePath: + if Cluster is None: + raise ValueError("Cluster cannot be None") + return DataVersionFilter(EndpointId=EndpointId, ClusterId=Cluster.id, DataVersion=DataVersion) def __str__(self) -> str: return f"{self.EndpointId}/{self.ClusterId}/{self.DataVersion}" - def __hash__(self): - return str(self).__hash__() - @dataclass class TypedAttributePath: @@ -165,44 +146,28 @@ def __init__(self, ClusterType: Cluster = None, AttributeType: ClusterAttributeD self.AttributeId = self.AttributeType.attribute_id -@dataclass +@dataclass(frozen=True) class EventPath: EndpointId: int = None ClusterId: int = None EventId: int = None Urgent: int = None - def __init__(self, EndpointId: int = None, Cluster=None, Event=None, ClusterId=None, EventId=None, Urgent=None): - self.EndpointId = EndpointId - self.Urgent = Urgent - if Cluster is not None: - # Wildcard read for a specific cluster - if (Event is not None) or (ClusterId is not None) or (EventId is not None): - raise Warning( - "Event, ClusterId and AttributeId is ignored when Cluster is specified") - self.ClusterId = Cluster.id - return - if Event is not None: - if (ClusterId is not None) or (EventId is not None): - raise Warning( - "ClusterId and EventId is ignored when Event is specified") - self.ClusterId = Event.cluster_id - self.EventId = Event.event_id - return - self.ClusterId = ClusterId - self.EventId = EventId + @staticmethod + def from_cluster(EndpointId: int, Cluster: Cluster, EventId: int = None, Urgent: int = None) -> "EventPath": + if Cluster is None: + raise ValueError("Cluster cannot be None") + return EventPath(EndpointId=EndpointId, ClusterId=Cluster.id, EventId=EventId, Urgent=Urgent) + + @staticmethod + def from_event(EndpointId: int, Event: ClusterEvent, Urgent: int = None) -> "EventPath": + if Event is None: + raise ValueError("Event cannot be None") + return EventPath(EndpointId=EndpointId, ClusterId=Event.cluster_id, EventId=Event.event_id, Urgent=Urgent) def __str__(self) -> str: return f"{self.EndpointId}/{self.ClusterId}/{self.EventId}/{self.Urgent}" - def __hash__(self): - return str(self).__hash__() - - -@dataclass -class AttributePathWithListIndex(AttributePath): - ListIndex: int = None - @dataclass class EventHeader: @@ -688,7 +653,7 @@ def SetClientObjPointers(self, pReadClient, pReadCallback): def GetAllEventValues(self): return self._events - def handleAttributeData(self, path: AttributePathWithListIndex, dataVersion: int, status: int, data: bytes): + def handleAttributeData(self, path: AttributePath, dataVersion: int, status: int, data: bytes): try: imStatus = chip.interaction_model.Status(status) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 3bc715829f27db..24b35747203355 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -11535,6 +11535,146 @@ class ChipClusters: }, }, } + _WI_FI_NETWORK_MANAGEMENT_CLUSTER_INFO = { + "clusterName": "WiFiNetworkManagement", + "clusterId": 0x00000451, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "NetworkPassphraseRequest", + "args": { + }, + }, + }, + "attributes": { + 0x00000001: { + "attributeName": "Ssid", + "attributeId": 0x00000001, + "type": "bytes", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } + _THREAD_NETWORK_DIRECTORY_CLUSTER_INFO = { + "clusterName": "ThreadNetworkDirectory", + "clusterId": 0x00000453, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "AddNetwork", + "args": { + "operationalDataset": "bytes", + }, + }, + 0x00000001: { + "commandId": 0x00000001, + "commandName": "RemoveNetwork", + "args": { + "extendedPanID": "int", + }, + }, + 0x00000002: { + "commandId": 0x00000002, + "commandName": "GetOperationalDataset", + "args": { + "extendedPanID": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "PreferredExtendedPanID", + "attributeId": 0x00000000, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00000001: { + "attributeName": "ThreadNetworks", + "attributeId": 0x00000001, + "type": "", + "reportable": True, + }, + 0x00000002: { + "attributeName": "ThreadNetworkTableSize", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _WAKE_ON_LAN_CLUSTER_INFO = { "clusterName": "WakeOnLan", "clusterId": 0x00000503, @@ -14638,6 +14778,8 @@ class ChipClusters: 0x0000042D: _PM10_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, 0x0000042E: _TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, 0x0000042F: _RADON_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, + 0x00000451: _WI_FI_NETWORK_MANAGEMENT_CLUSTER_INFO, + 0x00000453: _THREAD_NETWORK_DIRECTORY_CLUSTER_INFO, 0x00000503: _WAKE_ON_LAN_CLUSTER_INFO, 0x00000504: _CHANNEL_CLUSTER_INFO, 0x00000505: _TARGET_NAVIGATOR_CLUSTER_INFO, @@ -14759,6 +14901,8 @@ class ChipClusters: "Pm10ConcentrationMeasurement": _PM10_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, "TotalVolatileOrganicCompoundsConcentrationMeasurement": _TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, "RadonConcentrationMeasurement": _RADON_CONCENTRATION_MEASUREMENT_CLUSTER_INFO, + "WiFiNetworkManagement": _WI_FI_NETWORK_MANAGEMENT_CLUSTER_INFO, + "ThreadNetworkDirectory": _THREAD_NETWORK_DIRECTORY_CLUSTER_INFO, "WakeOnLan": _WAKE_ON_LAN_CLUSTER_INFO, "Channel": _CHANNEL_CLUSTER_INFO, "TargetNavigator": _TARGET_NAVIGATOR_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index cd411b93d43301..527bc943019cbb 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -40230,6 +40230,463 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class WiFiNetworkManagement(Cluster): + id: typing.ClassVar[int] = 0x00000451 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="ssid", Tag=0x00000001, Type=typing.Union[Nullable, bytes]), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + ssid: 'typing.Union[Nullable, bytes]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Commands: + @dataclass + class NetworkPassphraseRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000451 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'NetworkPassphraseResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ]) + + @dataclass + class NetworkPassphraseResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000451 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="passphrase", Tag=0, Type=bytes), + ]) + + passphrase: 'bytes' = b"" + + class Attributes: + @dataclass + class Ssid(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) + + value: 'typing.Union[Nullable, bytes]' = NullValue + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + +@dataclass +class ThreadNetworkDirectory(Cluster): + id: typing.ClassVar[int] = 0x00000453 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="preferredExtendedPanID", Tag=0x00000000, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="threadNetworks", Tag=0x00000001, Type=typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]), + ClusterObjectFieldDescriptor(Label="threadNetworkTableSize", Tag=0x00000002, Type=uint), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + preferredExtendedPanID: 'typing.Union[Nullable, uint]' = None + threadNetworks: 'typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]' = None + threadNetworkTableSize: 'uint' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Structs: + @dataclass + class ThreadNetworkStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="networkName", Tag=1, Type=str), + ClusterObjectFieldDescriptor(Label="channel", Tag=2, Type=uint), + ]) + + extendedPanID: 'uint' = 0 + networkName: 'str' = "" + channel: 'uint' = 0 + + class Commands: + @dataclass + class AddNetwork(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000453 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="operationalDataset", Tag=0, Type=bytes), + ]) + + @ChipUtility.classproperty + def must_use_timed_invoke(cls) -> bool: + return True + + operationalDataset: 'bytes' = b"" + + @dataclass + class RemoveNetwork(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000453 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint), + ]) + + @ChipUtility.classproperty + def must_use_timed_invoke(cls) -> bool: + return True + + extendedPanID: 'uint' = 0 + + @dataclass + class GetOperationalDataset(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000453 + command_id: typing.ClassVar[int] = 0x00000002 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'OperationalDatasetResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint), + ]) + + @ChipUtility.classproperty + def must_use_timed_invoke(cls) -> bool: + return True + + extendedPanID: 'uint' = 0 + + @dataclass + class OperationalDatasetResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000453 + command_id: typing.ClassVar[int] = 0x00000003 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="operationalDataset", Tag=0, Type=bytes), + ]) + + operationalDataset: 'bytes' = b"" + + class Attributes: + @dataclass + class PreferredExtendedPanID(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) + + value: 'typing.Union[Nullable, uint]' = NullValue + + @dataclass + class ThreadNetworks(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]) + + value: 'typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]' = field(default_factory=lambda: []) + + @dataclass + class ThreadNetworkTableSize(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + class Events: + @dataclass + class NetworkChanged(ClusterEvent): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000453 + + @ChipUtility.classproperty + def event_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=uint), + ]) + + extendedPanID: 'uint' = 0 + + @dataclass class WakeOnLan(Cluster): id: typing.ClassVar[int] = 0x00000503 diff --git a/src/controller/python/chip/clusters/__init__.py b/src/controller/python/chip/clusters/__init__.py index 44d9910c670098..76a37b84abbc87 100644 --- a/src/controller/python/chip/clusters/__init__.py +++ b/src/controller/python/chip/clusters/__init__.py @@ -27,23 +27,24 @@ ApplicationBasic, ApplicationLauncher, AudioOutput, BallastConfiguration, BarrierControl, BasicInformation, BinaryInputBasic, Binding, BooleanState, BooleanStateConfiguration, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, Channel, ColorControl, - ContentControl, ContentLauncher, Descriptor, DeviceEnergyManagement, DeviceEnergyManagementMode, - DiagnosticLogs, DishwasherAlarm, DishwasherMode, DoorLock, ElectricalEnergyMeasurement, ElectricalMeasurement, - ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, EnergyPreference, EthernetNetworkDiagnostics, - FanControl, FaultInjection, FixedLabel, FlowMeasurement, FormaldehydeConcentrationMeasurement, - GeneralCommissioning, GeneralDiagnostics, GroupKeyManagement, Groups, HepaFilterMonitoring, IcdManagement, - Identify, IlluminanceMeasurement, KeypadInput, LaundryDryerControls, LaundryWasherControls, LaundryWasherMode, - LevelControl, LocalizationConfiguration, LowPower, MediaInput, MediaPlayback, MicrowaveOvenControl, - MicrowaveOvenMode, ModeSelect, NetworkCommissioning, NitrogenDioxideConcentrationMeasurement, - OccupancySensing, OnOff, OnOffSwitchConfiguration, OperationalCredentials, OperationalState, - OtaSoftwareUpdateProvider, OtaSoftwareUpdateRequestor, OvenCavityOperationalState, OvenMode, - OzoneConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm10ConcentrationMeasurement, - Pm25ConcentrationMeasurement, PowerSource, PowerSourceConfiguration, PowerTopology, PressureMeasurement, - ProxyConfiguration, ProxyDiscovery, ProxyValid, PulseWidthModulation, PumpConfigurationAndControl, - RadonConcentrationMeasurement, RefrigeratorAlarm, RefrigeratorAndTemperatureControlledCabinetMode, - RelativeHumidityMeasurement, RvcCleanMode, RvcOperationalState, RvcRunMode, ScenesManagement, SmokeCoAlarm, - SoftwareDiagnostics, Switch, TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, - ThermostatUserInterfaceConfiguration, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, + ContentControl, ContentLauncher, DemandResponseLoadControl, Descriptor, DeviceEnergyManagement, + DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, DoorLock, + ElectricalEnergyMeasurement, ElectricalMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, + EnergyPreference, EthernetNetworkDiagnostics, FanControl, FaultInjection, FixedLabel, FlowMeasurement, + FormaldehydeConcentrationMeasurement, GeneralCommissioning, GeneralDiagnostics, GroupKeyManagement, Groups, + HepaFilterMonitoring, IcdManagement, Identify, IlluminanceMeasurement, KeypadInput, LaundryDryerControls, + LaundryWasherControls, LaundryWasherMode, LevelControl, LocalizationConfiguration, LowPower, MediaInput, + MediaPlayback, MicrowaveOvenControl, MicrowaveOvenMode, ModeSelect, NetworkCommissioning, + NitrogenDioxideConcentrationMeasurement, OccupancySensing, OnOff, OnOffSwitchConfiguration, + OperationalCredentials, OperationalState, OtaSoftwareUpdateProvider, OtaSoftwareUpdateRequestor, + OvenCavityOperationalState, OvenMode, OzoneConcentrationMeasurement, Pm1ConcentrationMeasurement, + Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PowerSource, PowerSourceConfiguration, + PowerTopology, PressureMeasurement, ProxyConfiguration, ProxyDiscovery, ProxyValid, PulseWidthModulation, + PumpConfigurationAndControl, RadonConcentrationMeasurement, RefrigeratorAlarm, + RefrigeratorAndTemperatureControlledCabinetMode, RelativeHumidityMeasurement, RvcCleanMode, + RvcOperationalState, RvcRunMode, ScenesManagement, SmokeCoAlarm, SoftwareDiagnostics, Switch, TargetNavigator, + TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, + ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering) @@ -51,7 +52,7 @@ ApplicationBasic, ApplicationLauncher, AudioOutput, BallastConfiguration, BarrierControl, BasicInformation, BinaryInputBasic, Binding, BooleanState, BooleanStateConfiguration, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, Channel, - ColorControl, ContentControl, ContentLauncher, Descriptor, DeviceEnergyManagementMode, DeviceEnergyManagement, DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, + ColorControl, ContentControl, ContentLauncher, DemandResponseLoadControl, Descriptor, DeviceEnergyManagementMode, DeviceEnergyManagement, DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, DoorLock, ElectricalEnergyMeasurement, ElectricalMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, EnergyPreference, EthernetNetworkDiagnostics, FanControl, FaultInjection, FixedLabel, FlowMeasurement, FormaldehydeConcentrationMeasurement, GeneralCommissioning, GeneralDiagnostics, GroupKeyManagement, Groups, diff --git a/src/controller/python/chip/icd/PyChipCheckInDelegate.cpp b/src/controller/python/chip/icd/PyChipCheckInDelegate.cpp new file mode 100644 index 00000000000000..03f6b7de1003e6 --- /dev/null +++ b/src/controller/python/chip/icd/PyChipCheckInDelegate.cpp @@ -0,0 +1,33 @@ +/* + * + * 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 "PyChipCheckInDelegate.h" + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Controller; + +void PyChipCheckInDelegate::OnCheckInComplete(const ICDClientInfo & clientInfo) +{ + DefaultCheckInDelegate::OnCheckInComplete(clientInfo); + + if (mCallback != nullptr) + { + mCallback(clientInfo.peer_node); + } +} diff --git a/src/controller/python/chip/icd/PyChipCheckInDelegate.h b/src/controller/python/chip/icd/PyChipCheckInDelegate.h new file mode 100644 index 00000000000000..3e3a3d9871af24 --- /dev/null +++ b/src/controller/python/chip/icd/PyChipCheckInDelegate.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace Controller { + +class PyChipCheckInDelegate : public chip::app::DefaultCheckInDelegate +{ +public: + using OnCheckInCompleteCallback = void(chip::ScopedNodeId); + + virtual ~PyChipCheckInDelegate() = default; + + void OnCheckInComplete(const chip::app::ICDClientInfo & clientInfo) override; + + void SetOnCheckInCompleteCallback(OnCheckInCompleteCallback * callback) { mCallback = callback; } + +private: + OnCheckInCompleteCallback * mCallback; +}; + +} // namespace Controller +} // namespace chip diff --git a/src/controller/python/chip/internal/types.py b/src/controller/python/chip/internal/types.py index 190456969b2006..34c14737a47ff7 100644 --- a/src/controller/python/chip/internal/types.py +++ b/src/controller/python/chip/internal/types.py @@ -14,7 +14,7 @@ # limitations under the License. # -from ctypes import CFUNCTYPE, c_size_t, c_uint32, c_void_p +from ctypes import CFUNCTYPE, Structure, c_size_t, c_uint32, c_uint64, c_void_p # General callback of 'network credentials requested. No python-data # is available as the underlying callback is used internally @@ -26,3 +26,7 @@ # Notification that pairing has been coompleted PairingComplete = CFUNCTYPE(None, c_uint32) + + +class ScopedNodeId(Structure): + _fields_ = [("node_id", c_uint64), ("fabric_index", "c_uint8")] diff --git a/src/controller/python/chip/logging/__init__.py b/src/controller/python/chip/logging/__init__.py index 047d3f4f8e97f5..aca671997d7299 100644 --- a/src/controller/python/chip/logging/__init__.py +++ b/src/controller/python/chip/logging/__init__.py @@ -19,11 +19,12 @@ from chip.logging.library_handle import _GetLoggingLibraryHandle from chip.logging.types import LogRedirectCallback_t -# Defines match support/logging/Constants.h (LogCategory enum) -ERROR_CATEGORY_NONE = 0 -ERROR_CATEGORY_ERROR = 1 -ERROR_CATEGORY_PROGRESS = 2 -ERROR_CATEGORY_DETAIL = 3 +# Defines match src/lib/support/logging/Constants.h (LogCategory enum) +LOG_CATEGORY_NONE = 0 +LOG_CATEGORY_ERROR = 1 +LOG_CATEGORY_PROGRESS = 2 +LOG_CATEGORY_DETAIL = 3 +LOG_CATEGORY_AUTOMATION = 4 @LogRedirectCallback_t @@ -34,11 +35,11 @@ def _RedirectToPythonLogging(category, module, message): logger = logging.getLogger('chip.native.%s' % module) - if category == ERROR_CATEGORY_ERROR: + if category == LOG_CATEGORY_ERROR: logger.error("%s", message) - elif category == ERROR_CATEGORY_PROGRESS: + elif category == LOG_CATEGORY_PROGRESS: logger.info("%s", message) - elif category == ERROR_CATEGORY_DETAIL: + elif category in (LOG_CATEGORY_DETAIL, LOG_CATEGORY_AUTOMATION): logger.debug("%s", message) else: # All logs are expected to have some reasonable category. This treats diff --git a/src/controller/python/test/test_scripts/cluster_objects.py b/src/controller/python/test/test_scripts/cluster_objects.py index 53516c1dc75e9b..37f6819cbe66a4 100644 --- a/src/controller/python/test/test_scripts/cluster_objects.py +++ b/src/controller/python/test/test_scripts/cluster_objects.py @@ -164,7 +164,7 @@ async def TestWriteRequest(cls, devCtrl): ] ) expectedRes = [ - AttributeStatus(Path=AttributePath( + AttributeStatus(Path=AttributePath.from_attribute( EndpointId=1, Attribute=Clusters.UnitTesting.Attributes.ListLongOctetString), Status=chip.interaction_model.Status.Success), ] diff --git a/src/credentials/FabricTable.cpp b/src/credentials/FabricTable.cpp index ade5189a738f27..b847addbe10773 100644 --- a/src/credentials/FabricTable.cpp +++ b/src/credentials/FabricTable.cpp @@ -2124,4 +2124,16 @@ CHIP_ERROR FabricTable::PeekFabricIndexForNextAddition(FabricIndex & outIndex) return CHIP_NO_ERROR; } +CHIP_ERROR FabricTable::SetFabricIndexForNextAddition(FabricIndex fabricIndex) +{ + VerifyOrReturnError(!mStateFlags.Has(StateFlags::kIsPendingFabricDataPresent), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + + const FabricInfo * fabricInfo = FindFabricWithIndex(fabricIndex); + VerifyOrReturnError(fabricInfo == nullptr, CHIP_ERROR_FABRIC_EXISTS); + + mNextAvailableFabricIndex.SetValue(fabricIndex); + return CHIP_NO_ERROR; +} + } // namespace chip diff --git a/src/credentials/FabricTable.h b/src/credentials/FabricTable.h index 55c1f6965e8c32..aef60f6a17fbbe 100644 --- a/src/credentials/FabricTable.h +++ b/src/credentials/FabricTable.h @@ -1003,6 +1003,13 @@ class DLL_EXPORT FabricTable */ CHIP_ERROR PeekFabricIndexForNextAddition(FabricIndex & outIndex); + /** + * Set the fabric index that will be used fo the next fabric added. + * + * Returns an error if the |fabricIndex| is already in use. + */ + CHIP_ERROR SetFabricIndexForNextAddition(FabricIndex fabricIndex); + private: enum class StateFlags : uint16_t { diff --git a/src/credentials/tests/CHIPCert_test_vectors.h b/src/credentials/tests/CHIPCert_test_vectors.h index 104436e5acc107..ef6ce7bb46c049 100644 --- a/src/credentials/tests/CHIPCert_test_vectors.h +++ b/src/credentials/tests/CHIPCert_test_vectors.h @@ -140,6 +140,8 @@ extern const ByteSpan sTestCert_Node01_01_PublicKey; extern const ByteSpan sTestCert_Node01_01_PrivateKey; extern const ByteSpan sTestCert_Node01_01_SubjectKeyId; extern const ByteSpan sTestCert_Node01_01_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node01_01_NodeId = 0xDEDEDEDE00010001; +inline constexpr FabricId kTestCert_Node01_01_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node01_01_Err01_Chip; @@ -149,6 +151,8 @@ extern const ByteSpan sTestCert_Node01_02_PublicKey; extern const ByteSpan sTestCert_Node01_02_PrivateKey; extern const ByteSpan sTestCert_Node01_02_SubjectKeyId; extern const ByteSpan sTestCert_Node01_02_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node01_02_NodeId = 0xDEDEDEDE00010002; +inline constexpr FabricId kTestCert_Node01_02_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_01_Chip; extern const ByteSpan sTestCert_Node02_01_DER; @@ -156,6 +160,8 @@ extern const ByteSpan sTestCert_Node02_01_PublicKey; extern const ByteSpan sTestCert_Node02_01_PrivateKey; extern const ByteSpan sTestCert_Node02_01_SubjectKeyId; extern const ByteSpan sTestCert_Node02_01_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_01_NodeId = 0xDEDEDEDE00020001; +inline constexpr FabricId kTestCert_Node02_01_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_02_Chip; extern const ByteSpan sTestCert_Node02_02_DER; @@ -163,6 +169,8 @@ extern const ByteSpan sTestCert_Node02_02_PublicKey; extern const ByteSpan sTestCert_Node02_02_PrivateKey; extern const ByteSpan sTestCert_Node02_02_SubjectKeyId; extern const ByteSpan sTestCert_Node02_02_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_02_NodeId = 0xDEDEDEDE00020002; +inline constexpr FabricId kTestCert_Node02_02_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_03_Chip; extern const ByteSpan sTestCert_Node02_03_DER; @@ -170,6 +178,8 @@ extern const ByteSpan sTestCert_Node02_03_PublicKey; extern const ByteSpan sTestCert_Node02_03_PrivateKey; extern const ByteSpan sTestCert_Node02_03_SubjectKeyId; extern const ByteSpan sTestCert_Node02_03_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_03_NodeId = 0xDEDEDEDE00020003; +inline constexpr FabricId kTestCert_Node02_03_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_04_Chip; extern const ByteSpan sTestCert_Node02_04_DER; @@ -177,6 +187,8 @@ extern const ByteSpan sTestCert_Node02_04_PublicKey; extern const ByteSpan sTestCert_Node02_04_PrivateKey; extern const ByteSpan sTestCert_Node02_04_SubjectKeyId; extern const ByteSpan sTestCert_Node02_04_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_04_NodeId = 0xDEDEDEDE00020004; +inline constexpr FabricId kTestCert_Node02_04_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_05_Chip; extern const ByteSpan sTestCert_Node02_05_DER; @@ -184,6 +196,8 @@ extern const ByteSpan sTestCert_Node02_05_PublicKey; extern const ByteSpan sTestCert_Node02_05_PrivateKey; extern const ByteSpan sTestCert_Node02_05_SubjectKeyId; extern const ByteSpan sTestCert_Node02_05_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_05_NodeId = 0xDEDEDEDE00020005; +inline constexpr FabricId kTestCert_Node02_05_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_06_Chip; extern const ByteSpan sTestCert_Node02_06_DER; @@ -191,6 +205,8 @@ extern const ByteSpan sTestCert_Node02_06_PublicKey; extern const ByteSpan sTestCert_Node02_06_PrivateKey; extern const ByteSpan sTestCert_Node02_06_SubjectKeyId; extern const ByteSpan sTestCert_Node02_06_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_06_NodeId = 0xDEDEDEDE00020006; +inline constexpr FabricId kTestCert_Node02_06_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_07_Chip; extern const ByteSpan sTestCert_Node02_07_DER; @@ -198,6 +214,8 @@ extern const ByteSpan sTestCert_Node02_07_PublicKey; extern const ByteSpan sTestCert_Node02_07_PrivateKey; extern const ByteSpan sTestCert_Node02_07_SubjectKeyId; extern const ByteSpan sTestCert_Node02_07_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_07_NodeId = 0xDEDEDEDE00020007; +inline constexpr FabricId kTestCert_Node02_07_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_Node02_08_Chip; extern const ByteSpan sTestCert_Node02_08_DER; @@ -205,6 +223,8 @@ extern const ByteSpan sTestCert_Node02_08_PublicKey; extern const ByteSpan sTestCert_Node02_08_PrivateKey; extern const ByteSpan sTestCert_Node02_08_SubjectKeyId; extern const ByteSpan sTestCert_Node02_08_AuthorityKeyId; +inline constexpr NodeId kTestCert_Node02_08_NodeId = 0xDEDEDEDE00020008; +inline constexpr FabricId kTestCert_Node02_08_FabricId = 0xFAB000000000001D; extern const ByteSpan sTestCert_PDCID01_Chip; extern const ByteSpan sTestCert_PDCID01_ChipCompact; diff --git a/src/credentials/tests/TestFabricTable.cpp b/src/credentials/tests/TestFabricTable.cpp index a6b9f2ee6bc467..75f51c1c2cb402 100644 --- a/src/credentials/tests/TestFabricTable.cpp +++ b/src/credentials/tests/TestFabricTable.cpp @@ -183,6 +183,18 @@ static CHIP_ERROR LoadTestFabric_Node02_01(FabricTable & fabricTable, bool doCom return err; } +const FabricInfo * FindFabric(FabricTable & fabricTable, ByteSpan rootPublicKey, FabricId fabricId) +{ + Crypto::P256PublicKey key; + EXPECT_GE(key.Length(), rootPublicKey.size()); + if (key.Length() < rootPublicKey.size()) + { + return nullptr; + } + memcpy(key.Bytes(), rootPublicKey.data(), rootPublicKey.size()); + return fabricTable.FindFabric(key, fabricId); +} + struct TestFabricTable : public ::testing::Test { @@ -2279,16 +2291,13 @@ TEST_F(TestFabricTable, TestFabricLookup) EXPECT_EQ(LoadTestFabric_Node01_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR); EXPECT_EQ(LoadTestFabric_Node02_01(fabricTable, /* doCommit = */ true, FabricTable::AdvertiseIdentity::No), CHIP_NO_ERROR); + // These two NOCs have the same fabric id on purpose; only the trust root is + // different. + constexpr FabricId kNode01_01_and_02_01_FabricId = 0xFAB000000000001D; + // Attempt lookup of the Root01 fabric. { - Crypto::P256PublicKey key; - EXPECT_GE(key.Length(), TestCerts::sTestCert_Root01_PublicKey.size()); - if (key.Length() < TestCerts::sTestCert_Root01_PublicKey.size()) - { - return; - } - memcpy(key.Bytes(), TestCerts::sTestCert_Root01_PublicKey.data(), TestCerts::sTestCert_Root01_PublicKey.size()); - auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D); + auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root01_PublicKey, kNode01_01_and_02_01_FabricId); ASSERT_NE(fabricInfo, nullptr); EXPECT_EQ(fabricInfo->GetFabricIndex(), 1); @@ -2297,14 +2306,7 @@ TEST_F(TestFabricTable, TestFabricLookup) // Attempt lookup of the Root02 fabric. { - Crypto::P256PublicKey key; - EXPECT_GE(key.Length(), TestCerts::sTestCert_Root02_PublicKey.size()); - if (key.Length() < TestCerts::sTestCert_Root02_PublicKey.size()) - { - return; - } - memcpy(key.Bytes(), TestCerts::sTestCert_Root02_PublicKey.data(), TestCerts::sTestCert_Root02_PublicKey.size()); - auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D); + auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root02_PublicKey, kNode01_01_and_02_01_FabricId); ASSERT_NE(fabricInfo, nullptr); EXPECT_EQ(fabricInfo->GetFabricIndex(), 2); @@ -2317,6 +2319,69 @@ TEST_F(TestFabricTable, TestFabricLookup) } } +TEST_F(TestFabricTable, ShouldFailSetFabricIndexWithInvalidIndex) +{ + chip::TestPersistentStorageDelegate testStorage; + ScopedFabricTable fabricTableHolder; + EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR); + FabricTable & fabricTable = fabricTableHolder.GetFabricTable(); + + EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(kUndefinedFabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); +} + +TEST_F(TestFabricTable, ShouldFailSetFabricIndexWithPendingFabric) +{ + chip::TestPersistentStorageDelegate testStorage; + ScopedFabricTable fabricTableHolder; + EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR); + FabricTable & fabricTable = fabricTableHolder.GetFabricTable(); + + EXPECT_EQ(fabricTable.AddNewPendingTrustedRootCert(ByteSpan(TestCerts::sTestCert_Root01_Chip)), CHIP_NO_ERROR); + + EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(1), CHIP_ERROR_INCORRECT_STATE); +} + +TEST_F(TestFabricTable, ShouldFailSetFabricIndexWhenInUse) +{ + chip::TestPersistentStorageDelegate testStorage; + ScopedFabricTable fabricTableHolder; + EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR); + FabricTable & fabricTable = fabricTableHolder.GetFabricTable(); + + EXPECT_EQ(LoadTestFabric_Node01_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR); + EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(1), CHIP_ERROR_FABRIC_EXISTS); +} + +TEST_F(TestFabricTable, ShouldAddFabricAtRequestedIndex) +{ + chip::TestPersistentStorageDelegate testStorage; + ScopedFabricTable fabricTableHolder; + EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR); + FabricTable & fabricTable = fabricTableHolder.GetFabricTable(); + + EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(2), CHIP_NO_ERROR); + EXPECT_EQ(LoadTestFabric_Node02_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR); + + EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(1), CHIP_NO_ERROR); + EXPECT_EQ(LoadTestFabric_Node01_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR); + + { + auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root01_PublicKey, TestCerts::kTestCert_Node01_01_FabricId); + ASSERT_NE(fabricInfo, nullptr); + EXPECT_EQ(fabricInfo->GetFabricIndex(), 1); + EXPECT_EQ(fabricInfo->GetNodeId(), TestCerts::kTestCert_Node01_01_NodeId); + EXPECT_EQ(fabricInfo->GetFabricId(), TestCerts::kTestCert_Node01_01_FabricId); + } + + { + auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root02_PublicKey, TestCerts::kTestCert_Node02_01_FabricId); + ASSERT_NE(fabricInfo, nullptr); + EXPECT_EQ(fabricInfo->GetFabricIndex(), 2); + EXPECT_EQ(fabricInfo->GetNodeId(), TestCerts::kTestCert_Node02_01_NodeId); + EXPECT_EQ(fabricInfo->GetFabricId(), TestCerts::kTestCert_Node02_01_FabricId); + } +} + TEST_F(TestFabricTable, TestFetchCATs) { // Initialize a fabric table. diff --git a/src/crypto/tests/TestChipCryptoPAL.cpp b/src/crypto/tests/TestChipCryptoPAL.cpp index c7ad4f3f290522..b4e0fbb2558057 100644 --- a/src/crypto/tests/TestChipCryptoPAL.cpp +++ b/src/crypto/tests/TestChipCryptoPAL.cpp @@ -2804,8 +2804,8 @@ TEST_F(TestChipCryptoPAL, TestVIDPID_x509Extraction) AttestationCertVidPid vidpid; CHIP_ERROR result = ExtractVIDPIDFromX509Cert(testCase.cert, vidpid); EXPECT_EQ(result, testCase.expectedResult); - EXPECT_EQ(vidpid.mVendorId.HasValue(), testCase.expectedVidPresent); - EXPECT_EQ(vidpid.mProductId.HasValue(), testCase.expectedPidPresent); + ASSERT_EQ(vidpid.mVendorId.HasValue(), testCase.expectedVidPresent); + ASSERT_EQ(vidpid.mProductId.HasValue(), testCase.expectedPidPresent); // If present, make sure the VID matches expectation. if (testCase.expectedVidPresent) diff --git a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm index 1e44b4a04ef702..62deb58f5008e6 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm +++ b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm @@ -77,7 +77,7 @@ - (NSString *)description std::lock_guard lock(_lock); return [NSString - stringWithFormat:@"MTRAsyncCallbackWorkQueue context: %@ items count: %lu", self.context, (unsigned long) self.items.count]; + stringWithFormat:@"MTRAsyncCallbackWorkQueue context: %@ items count: %lu", self.context, static_cast(self.items.count)]; } - (void)enqueueWorkItem:(MTRAsyncCallbackQueueWorkItem *)item diff --git a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm index 53a719502306bd..4d82fded930b87 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm +++ b/src/darwin/Framework/CHIP/MTRAsyncWorkQueue.mm @@ -84,7 +84,7 @@ - (void)setDuplicateTypeID:(NSUInteger)opaqueDuplicateTypeID handler:(MTRAsyncWo - (void)assertMutable { - NSAssert(_state == MTRAsyncWorkItemMutable, @"work item is not mutable (%ld)", (long) _state); + NSAssert(_state == MTRAsyncWorkItemMutable, @"work item is not mutable (%ld)", static_cast(_state)); } #pragma mark Management by the work queue (queue lock held) @@ -109,7 +109,7 @@ - (NSInteger)retryCount - (void)callReadyHandlerWithContext:(id)context completion:(MTRAsyncWorkCompletionBlock)completion { - NSAssert(_state >= MTRAsyncWorkItemEnqueued, @"work item is not enqueued (%ld)", (long) _state); + NSAssert(_state >= MTRAsyncWorkItemEnqueued, @"work item is not enqueued (%ld)", static_cast(_state)); NSInteger retryCount = 0; if (_state == MTRAsyncWorkItemEnqueued) { _state = MTRAsyncWorkItemRunning; @@ -126,9 +126,9 @@ - (void)callReadyHandlerWithContext:(id)context completion:(MTRAsyncWorkCompleti auto readyHandler = _readyHandler; dispatch_async(_queue, ^{ if (!retryCount) { - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> executing work item [%llu]", context, uniqueID); + MTR_LOG("MTRAsyncWorkQueue<%@> executing work item [%llu]", context, uniqueID); } else { - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> executing work item [%llu] (retry %zd)", context, uniqueID, retryCount); + MTR_LOG("MTRAsyncWorkQueue<%@> executing work item [%llu] (retry %zd)", context, uniqueID, retryCount); } if (readyHandler) { readyHandler(context, retryCount, completion); @@ -161,7 +161,7 @@ - (BOOL)isComplete - (void)markComplete { - NSAssert(_state >= MTRAsyncWorkItemEnqueued, @"work item was not enqueued (%ld)", (long) _state); + NSAssert(_state >= MTRAsyncWorkItemEnqueued, @"work item was not enqueued (%ld)", static_cast(_state)); _state = MTRAsyncWorkItemComplete; // Clear all handlers in case any of them captured this object. @@ -185,7 +185,7 @@ - (NSString *)description state = @"enqueued"; break; default: - return [NSString stringWithFormat:@"<%@ %llu running retry: %tu>", self.class, _uniqueID, self.retryCount]; + return [NSString stringWithFormat:@"<%@ %llu running retry: %ld>", self.class, _uniqueID, static_cast(self.retryCount)]; } return [NSString stringWithFormat:@"<%@ %llu %@>", self.class, _uniqueID, state]; } @@ -236,7 +236,7 @@ - (NSString *)description { ContextSnapshot context(self); std::lock_guard lock(_lock); - return [NSString stringWithFormat:@"<%@ context: %@, items count: %tu>", self.class, context.description, _items.count]; + return [NSString stringWithFormat:@"<%@ context: %@, items count: %lu>", self.class, context.description, static_cast(_items.count)]; } - (void)enqueueWorkItem:(MTRAsyncWorkItem *)item @@ -268,9 +268,9 @@ - (void)enqueueWorkItem:(MTRAsyncWorkItem *)item // Logging the description once is enough because other log messages // related to the work item (execution, completion etc) can easily be // correlated using the unique id. - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@, items count: %tu> enqueued work item [%llu]: %@", context.description, _items.count, item.uniqueID, description); + MTR_LOG("MTRAsyncWorkQueue<%@, items count: %lu> enqueued work item [%llu]: %@", context.description, static_cast(_items.count), item.uniqueID, description); } else { - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@, items count: %tu> enqueued work item [%llu]", context.description, _items.count, item.uniqueID); + MTR_LOG("MTRAsyncWorkQueue<%@, items count: %lu> enqueued work item [%llu]", context.description, static_cast(_items.count), item.uniqueID); } [self _callNextReadyWorkItemWithContext:context]; @@ -280,7 +280,7 @@ - (void)invalidate { ContextSnapshot context(self); // outside of lock std::lock_guard lock(_lock); - MTR_LOG_INFO("MTRAsyncWorkQueue<%@> invalidate %tu items", context.description, _items.count); + MTR_LOG("MTRAsyncWorkQueue<%@> invalidate %lu items", context.description, static_cast(_items.count)); for (MTRAsyncWorkItem * item in _items) { [item cancel]; } @@ -309,14 +309,14 @@ - (void)_postProcessWorkItem:(MTRAsyncWorkItem *)workItem // already part of the running work items allowed by width - retry directly if (retry) { - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> retry needed for work item [%llu]", context.description, workItem.uniqueID); + MTR_LOG("MTRAsyncWorkQueue<%@> retry needed for work item [%llu]", context.description, workItem.uniqueID); [self _callWorkItem:workItem withContext:context]; return; } [workItem markComplete]; [_items removeObjectAtIndex:indexOfWorkItem]; - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@, items count: %tu> completed work item [%llu]", context.description, _items.count, workItem.uniqueID); + MTR_LOG("MTRAsyncWorkQueue<%@, items count: %lu> completed work item [%llu]", context.description, static_cast(_items.count), workItem.uniqueID); // sanity check running work item count is positive if (_runningWorkItemCount == 0) { @@ -398,11 +398,11 @@ - (void)_callNextReadyWorkItemWithContext:(ContextSnapshot const &)context case MTRNotBatched: goto done; // can't merge anything else case MTRBatchedPartially: - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> partially merged work item [%llu] into %llu", + MTR_LOG("MTRAsyncWorkQueue<%@> partially merged work item [%llu] into %llu", context.description, nextWorkItem.uniqueID, workItem.uniqueID); goto done; // can't merge anything else case MTRBatchedFully: - MTR_LOG_DEFAULT("MTRAsyncWorkQueue<%@> fully merged work item [%llu] into %llu", + MTR_LOG("MTRAsyncWorkQueue<%@> fully merged work item [%llu] into %llu", context.description, nextWorkItem.uniqueID, workItem.uniqueID); [_items removeObjectAtIndex:1]; continue; // try to batch the next item (if any) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0712e779c525e6..331d61129b9daf 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -571,7 +571,7 @@ - (void)subscribeWithQueue:(dispatch_queue_t)queue return _MakeDataValueDictionary(typeName, array, dataVersion); } default: - MTR_LOG_ERROR("Error: Unsupported TLV type for conversion: %u", (unsigned) data->GetType()); + MTR_LOG_ERROR("Error: Unsupported TLV type for conversion: %u", static_cast(data->GetType())); return nil; } } diff --git a/src/darwin/Framework/CHIP/MTRCertificates.mm b/src/darwin/Framework/CHIP/MTRCertificates.mm index 9444ae920cc44c..5837a50a3fe21a 100644 --- a/src/darwin/Framework/CHIP/MTRCertificates.mm +++ b/src/darwin/Framework/CHIP/MTRCertificates.mm @@ -42,7 +42,7 @@ + (MTRCertificateDERBytes _Nullable)createRootCertificate:(id)keypai validityPeriod:(NSDateInterval *)validityPeriod error:(NSError * __autoreleasing *)error { - MTR_LOG_DEFAULT("Generating root certificate"); + MTR_LOG("Generating root certificate"); NSData * rootCert = nil; CHIP_ERROR err = MTROperationalCredentialsDelegate::GenerateRootCertificate(keypair, issuerID, fabricID, validityPeriod, &rootCert); @@ -74,7 +74,7 @@ + (MTRCertificateDERBytes _Nullable)createIntermediateCertificate:(id validityPeriod:(NSDateInterval *)validityPeriod error:(NSError * __autoreleasing _Nullable * _Nullable)error { - MTR_LOG_DEFAULT("Generating operational certificate"); + MTR_LOG("Generating operational certificate"); NSData * opcert = nil; CHIP_ERROR err = MTROperationalCredentialsDelegate::GenerateOperationalCertificate( signingKeypair, signingCertificate, operationalPublicKey, fabricID, nodeID, caseAuthenticatedTags, validityPeriod, &opcert); @@ -250,7 +250,7 @@ + (MTRCertificateTLVBytes _Nullable)convertX509Certificate:(MTRCertificateDERByt return nil; } - MTR_LOG_INFO("convertX509Certificate: Success"); + MTR_LOG_DEBUG("convertX509Certificate: Success"); return AsData(chipCertBytes); } diff --git a/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm b/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm index 2b3e2814ecd220..276fb5e3460682 100644 --- a/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm +++ b/src/darwin/Framework/CHIP/MTRCommissionableBrowser.mm @@ -61,6 +61,10 @@ @implementation MTRCommissionableBrowserResult #endif // CONFIG_NETWORK_LAYER_BLE { public: +#if CONFIG_NETWORK_LAYER_BLE + id mBleScannerDelegateOwner; +#endif // CONFIG_NETWORK_LAYER_BLE + CHIP_ERROR Start(id delegate, MTRDeviceController * controller, dispatch_queue_t queue) { assertChipStackLockedByCurrentThread(); @@ -90,7 +94,7 @@ CHIP_ERROR Start(id delegate, MTRDeviceControl chip::Inet::InterfaceId::Null(), this); } - CHIP_ERROR Stop() + CHIP_ERROR Stop(id owner) { assertChipStackLockedByCurrentThread(); @@ -109,7 +113,10 @@ CHIP_ERROR Stop() mDiscoveredResults = nil; #if CONFIG_NETWORK_LAYER_BLE - ReturnErrorOnFailure(PlatformMgrImpl().StopBleScan()); + mBleScannerDelegateOwner = owner; // retain the owner until OnBleScanStopped is called + PlatformMgrImpl().StopBleScan(); // doesn't actually fail, and if it did we'd want to carry on regardless +#else + (void) owner; #endif // CONFIG_NETWORK_LAYER_BLE return ChipDnssdStopBrowse(this); @@ -281,6 +288,7 @@ void OnBrowseStop(CHIP_ERROR error) override void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info) override { assertChipStackLockedByCurrentThread(); + VerifyOrReturn(mDelegate != nil); auto result = [[MTRCommissionableBrowserResult alloc] init]; result.instanceName = [NSString stringWithUTF8String:kBleKey]; @@ -303,6 +311,7 @@ void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificati void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override { assertChipStackLockedByCurrentThread(); + VerifyOrReturn(mDelegate != nil); auto key = [NSString stringWithFormat:@"%@", connObj]; if ([mDiscoveredResults objectForKey:key] == nil) { @@ -319,6 +328,12 @@ void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override [mDelegate controller:mController didFindCommissionableDevice:result]; }); } + + void OnBleScanStopped() override + { + mBleScannerDelegateOwner = nil; + } + #endif // CONFIG_NETWORK_LAYER_BLE private: @@ -360,7 +375,7 @@ - (BOOL)start - (BOOL)stop { - VerifyOrReturnValue(CHIP_NO_ERROR == _browser.Stop(), NO); + VerifyOrReturnValue(CHIP_NO_ERROR == _browser.Stop(self), NO); _delegate = nil; _controller = nil; _queue = nil; diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 61dbc643f5ccd1..4014bd5f6924bf 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -101,6 +101,14 @@ - (id)strongObject return aNumber; } +/* BEGIN DRAGONS: Note methods here cannot be renamed, and are used by private callers, do not rename, remove or modify behavior here */ + +@interface NSObject (MatterPrivateForInternalDragonsDoNotFeed) +- (void)_deviceInternalStateChanged:(MTRDevice *)device; +@end + +/* END DRAGONS */ + #pragma mark - SubscriptionCallback class declaration using namespace chip; using namespace chip::app; @@ -141,25 +149,6 @@ - (id)strongObject } // anonymous namespace #pragma mark - MTRDevice -typedef NS_ENUM(NSUInteger, MTRInternalDeviceState) { - // Unsubscribed means we do not have a subscription and are not trying to set one up. - MTRInternalDeviceStateUnsubscribed = 0, - // Subscribing means we are actively trying to establish our initial subscription (e.g. doing - // DNS-SD discovery, trying to establish CASE to the peer, getting priming reports, etc). - MTRInternalDeviceStateSubscribing = 1, - // InitialSubscriptionEstablished means we have at some point finished setting up a - // subscription. That subscription may have dropped since then, but if so it's the ReadClient's - // responsibility to re-establish it. - MTRInternalDeviceStateInitialSubscriptionEstablished = 2, - // Resubscribing means we had established a subscription, but then - // detected a subscription drop due to not receiving a report on time. This - // covers all the actions that happen when re-subscribing (discovery, CASE, - // getting priming reports, etc). - MTRInternalDeviceStateResubscribing = 3, - // LaterSubscriptionEstablished meant that we had a subscription drop and - // then re-created a subscription. - MTRInternalDeviceStateLaterSubscriptionEstablished = 4, -}; // Utility methods for working with MTRInternalDeviceState, located near the // enum so it's easier to notice that they need to stay in sync. @@ -220,6 +209,11 @@ - (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(N _attributes[attribute] = value; } +- (void)removeValueForAttribute:(NSNumber *)attribute +{ + [_attributes removeObjectForKey:attribute]; +} + - (NSDictionary *)attributes { return _attributes; @@ -379,6 +373,7 @@ - (BOOL)unitTestForceAttributeReportsIfMatchingCache:(MTRDevice *)device; - (BOOL)unitTestPretendThreadEnabled:(MTRDevice *)device; - (void)unitTestSubscriptionPoolDequeue:(MTRDevice *)device; - (void)unitTestSubscriptionPoolWorkComplete:(MTRDevice *)device; +- (void)unitTestClusterDataPersisted:(MTRDevice *)device; @end #endif @@ -386,7 +381,11 @@ @implementation MTRDevice { #ifdef DEBUG NSUInteger _unitTestAttributesReportedSinceLastCheck; #endif - BOOL _delegateDeviceCachePrimedCalled; + + // _deviceCachePrimed is true if we have the data that comes from an initial + // subscription priming report (whether it came from storage or from our + // subscription). + BOOL _deviceCachePrimed; // _persistedClusterData stores data that we have already persisted (when we have // cluster data persistence enabled). Nil when we have no persistence enabled. @@ -401,8 +400,8 @@ @implementation MTRDevice { NSMutableSet * _persistedClusters; // When we last failed to subscribe to the device (either via - // _setupSubscription or via the auto-resubscribe behavior of the - // ReadClient). Nil if we have had no such failures. + // _setupSubscriptionWithReason or via the auto-resubscribe behavior + // of the ReadClient). Nil if we have had no such failures. NSDate * _Nullable _lastSubscriptionFailureTime; MTRDeviceConnectivityMonitor * _connectivityMonitor; @@ -419,6 +418,23 @@ @implementation MTRDevice { // Tracking of initial subscribe latency. When _initialSubscribeStart is // nil, we are not tracking the latency. NSDate * _Nullable _initialSubscribeStart; + + // Storage behavior configuration and variables to keep track of the logic + // _clusterDataPersistenceFirstScheduledTime is used to track the start time of the delay between + // report and persistence. + // _mostRecentReportTimes is a list of the most recent report timestamps used for calculating + // the running average time between reports. + // _deviceReportingExcessivelyStartTime tracks when a device starts reporting excessively. + // _reportToPersistenceDelayCurrentMultiplier is the current multiplier that is calculated when a + // report comes in. + MTRDeviceStorageBehaviorConfiguration * _storageBehaviorConfiguration; + NSDate * _Nullable _clusterDataPersistenceFirstScheduledTime; + NSMutableArray * _mostRecentReportTimes; + NSDate * _Nullable _deviceReportingExcessivelyStartTime; + double _reportToPersistenceDelayCurrentMultiplier; + + // System time change observer reference + id _systemTimeChangeObserverToken; } - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceController *)controller @@ -442,11 +458,27 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle } _clusterDataToPersist = nil; _persistedClusters = [NSMutableSet set]; - MTR_LOG_INFO("%@ init with hex nodeID 0x%016llX", self, _nodeID.unsignedLongLongValue); + + // If there is a data store, make sure we have an observer to + if (_persistedClusterData) { + mtr_weakify(self); + _systemTimeChangeObserverToken = [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemClockDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) { + mtr_strongify(self); + std::lock_guard lock(self->_lock); + [self _resetStorageBehaviorState]; + }]; + } + + MTR_LOG_DEBUG("%@ init with hex nodeID 0x%016llX", self, _nodeID.unsignedLongLongValue); } return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:_systemTimeChangeObserverToken]; +} + - (NSString *)description { return [NSString @@ -486,7 +518,7 @@ - (void)_setTimeOnDevice auto dstOffsetsMaxSize = [self readAttributeWithEndpointID:dstOffsetsMaxSizePath.endpoint clusterID:dstOffsetsMaxSizePath.cluster attributeID:dstOffsetsMaxSizePath.attribute params:nil]; if (dstOffsetsMaxSize == nil) { // This endpoint does not support TZ, so won't support SetDSTOffset. - MTR_LOG_DEFAULT("%@ Unable to SetDSTOffset on endpoint %@, since it does not support the TZ feature", self, endpoint); + MTR_LOG("%@ Unable to SetDSTOffset on endpoint %@, since it does not support the TZ feature", self, endpoint); continue; } auto attrReport = [[MTRAttributeReport alloc] initWithResponseValue:@{ @@ -643,7 +675,7 @@ - (void)_setDSTOffsets:(NSArray completion:setDSTOffsetResponseHandler]; } -- (NSMutableArray *)arrayOfNumbersFromAttributeValue:(NSDictionary *)dataDictionary +- (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary { if (![MTRArrayValueType isEqual:dataDictionary[MTRTypeKey]]) { return nil; @@ -682,16 +714,27 @@ - (void)_setDSTOffsets:(NSArray #pragma mark Subscription and delegate handling // subscription intervals are in seconds -#define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN (1 * 60) // 1 minute (for now) +#define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN (10 * 60) // 10 minutes (for now) #define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX (60 * 60) // 60 minutes +- (BOOL)_subscriptionsAllowed +{ + os_unfair_lock_assert_owner(&self->_lock); + + // We should not allow a subscription for device controllers over XPC. + return ![_deviceController isKindOfClass:MTRDeviceControllerOverXPC.class]; +} + - (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue { - MTR_LOG_INFO("%@ setDelegate %@", self, delegate); + MTR_LOG("%@ setDelegate %@", self, delegate); + + std::lock_guard lock(_lock); - BOOL setUpSubscription = YES; + BOOL setUpSubscription = [self _subscriptionsAllowed]; - // For unit testing only + // For unit testing only. If this ever changes to not being for unit testing purposes, + // we would need to move the code outside of where we acquire the lock above. #ifdef DEBUG id testDelegate = delegate; if ([testDelegate respondsToSelector:@selector(unitTestShouldSetUpSubscriptionForDevice:)]) { @@ -699,32 +742,25 @@ - (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queu } #endif - std::lock_guard lock(_lock); - _weakDelegate = [MTRWeakReference weakReferenceWithObject:delegate]; _delegateQueue = queue; - // If Check if cache is already primed and client hasn't been informed yet, call the -deviceCachePrimed: callback - if (!_delegateDeviceCachePrimedCalled && [self _isCachePrimedWithInitialConfigurationData]) { - [self _callDelegateDeviceCachePrimed]; - } - if (setUpSubscription) { _initialSubscribeStart = [NSDate now]; if ([self _deviceUsesThread]) { [self _scheduleSubscriptionPoolWork:^{ std::lock_guard lock(self->_lock); - [self _setupSubscription]; + [self _setupSubscriptionWithReason:@"delegate is set and scheduled subscription is happening"]; } inNanoseconds:0 description:@"MTRDevice setDelegate first subscription"]; } else { - [self _setupSubscription]; + [self _setupSubscriptionWithReason:@"delegate is set and subscription is needed"]; } } } - (void)invalidate { - MTR_LOG_INFO("%@ invalidate", self); + MTR_LOG("%@ invalidate", self); [_asyncWorkQueue invalidate]; @@ -755,16 +791,16 @@ - (void)nodeMayBeAdvertisingOperational { assertChipStackLockedByCurrentThread(); - MTR_LOG_DEFAULT("%@ saw new operational advertisement", self); + MTR_LOG("%@ saw new operational advertisement", self); - [self _triggerResubscribeWithReason:"operational advertisement seen" + [self _triggerResubscribeWithReason:@"operational advertisement seen" nodeLikelyReachable:YES]; } // Trigger a resubscribe as needed. nodeLikelyReachable should be YES if we // have reason to suspect the node is now reachable, NO if we have no idea // whether it might be. -- (void)_triggerResubscribeWithReason:(const char *)reason nodeLikelyReachable:(BOOL)nodeLikelyReachable +- (void)_triggerResubscribeWithReason:(NSString *)reason nodeLikelyReachable:(BOOL)nodeLikelyReachable { assertChipStackLockedByCurrentThread(); @@ -783,7 +819,7 @@ - (void)_triggerResubscribeWithReason:(const char *)reason nodeLikelyReachable:( // establish a CASE session. And at that point, our subscription will // trigger the state change as needed. if (self.reattemptingSubscription) { - [self _reattemptSubscriptionNowIfNeeded]; + [self _reattemptSubscriptionNowIfNeededWithReason:reason]; } else { readClientToResubscribe = self->_currentReadClient; subscriptionCallback = self->_currentSubscriptionCallback; @@ -798,7 +834,7 @@ - (void)_triggerResubscribeWithReason:(const char *)reason nodeLikelyReachable:( // here (e.g. still booting up), but should try again reasonably quickly. subscriptionCallback->ResetResubscriptionBackoff(); } - readClientToResubscribe->TriggerResubscribeIfScheduled(reason); + readClientToResubscribe->TriggerResubscribeIfScheduled(reason.UTF8String); } } @@ -823,13 +859,8 @@ - (BOOL)_subscriptionAbleToReport } #endif - // Unfortunately, we currently have no subscriptions over our hacked-up XPC - // setup. Try to detect that situation. - if ([_deviceController isKindOfClass:MTRDeviceControllerOverXPC.class]) { - return NO; - } - - return YES; + // Subscriptions are not able to report if they are not allowed. + return [self _subscriptionsAllowed]; } // Notification that read-through was skipped for an attribute read. @@ -867,7 +898,7 @@ - (void)_readThroughSkipped // ReadClient in there. If the dispatch fails, that's fine; it means our // controller has shut down, so nothing to be done. [_deviceController asyncDispatchToMatterQueue:^{ - [self _triggerResubscribeWithReason:"read-through skipped while not subscribed" nodeLikelyReachable:NO]; + [self _triggerResubscribeWithReason:@"read-through skipped while not subscribed" nodeLikelyReachable:NO]; } errorHandler:nil]; } @@ -888,7 +919,7 @@ - (BOOL)_callDelegateWithBlock:(void (^)(id))block - (void)_callDelegateDeviceCachePrimed { os_unfair_lock_assert_owner(&self->_lock); - _delegateDeviceCachePrimedCalled = [self _callDelegateWithBlock:^(id delegate) { + [self _callDelegateWithBlock:^(id delegate) { if ([delegate respondsToSelector:@selector(deviceCachePrimed:)]) { [delegate deviceCachePrimed:self]; } @@ -903,12 +934,12 @@ - (void)_changeState:(MTRDeviceState)state _state = state; if (lastState != state) { if (state != MTRDeviceStateReachable) { - MTR_LOG_INFO("%@ reachability state change %lu => %lu, set estimated start time to nil", self, static_cast(lastState), + MTR_LOG("%@ reachability state change %lu => %lu, set estimated start time to nil", self, static_cast(lastState), static_cast(state)); _estimatedStartTime = nil; _estimatedStartTimeFromGeneralDiagnosticsUpTime = nil; } else { - MTR_LOG_INFO( + MTR_LOG( "%@ reachability state change %lu => %lu", self, static_cast(lastState), static_cast(state)); } id delegate = _weakDelegate.strongObject; @@ -918,7 +949,7 @@ - (void)_changeState:(MTRDeviceState)state }); } } else { - MTR_LOG_INFO( + MTR_LOG( "%@ Not reporting reachability state change, since no change in state %lu => %lu", self, static_cast(lastState), static_cast(state)); } } @@ -929,10 +960,28 @@ - (void)_changeInternalState:(MTRInternalDeviceState)state MTRInternalDeviceState lastState = _internalDeviceState; _internalDeviceState = state; if (lastState != state) { - MTR_LOG_DEFAULT("%@ internal state change %lu => %lu", self, static_cast(lastState), static_cast(state)); + MTR_LOG("%@ internal state change %lu => %lu", self, static_cast(lastState), static_cast(state)); + + /* BEGIN DRAGONS: This is a huge hack for a specific use case, do not rename, remove or modify behavior here */ + // TODO: This should only be called for thread devices + id delegate = _weakDelegate.strongObject; + if ([delegate respondsToSelector:@selector(_deviceInternalStateChanged:)]) { + dispatch_async(_delegateQueue, ^{ + [(id) delegate _deviceInternalStateChanged:self]; + }); + } + /* END DRAGONS */ } } +#ifdef DEBUG +- (MTRInternalDeviceState)_getInternalState +{ + std::lock_guard lock(self->_lock); + return _internalDeviceState; +} +#endif + // First Time Sync happens 2 minutes after reachability (this can be changed in the future) #define MTR_DEVICE_TIME_UPDATE_INITIAL_WAIT_TIME_SEC (60 * 2) - (void)_handleSubscriptionEstablished @@ -950,11 +999,6 @@ - (void)_handleSubscriptionEstablished [self _changeInternalState:MTRInternalDeviceStateInitialSubscriptionEstablished]; } - // As subscription is established, check if the delegate needs to be informed - if (!_delegateDeviceCachePrimedCalled) { - [self _callDelegateDeviceCachePrimed]; - } - [self _changeState:MTRDeviceStateReachable]; // No need to monitor connectivity after subscription establishment @@ -1077,7 +1121,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: #endif if (self->_subscriptionPoolWorkCompletionBlock) { // This means a resubscription triggering event happened and is now in-progress - MTR_LOG_DEFAULT("%@ timer fired but already running in subscription pool - ignoring: %@", self, description); + MTR_LOG("%@ timer fired but already running in subscription pool - ignoring: %@", self, description); os_unfair_lock_unlock(&self->_lock); // call completion as complete to remove from queue @@ -1122,10 +1166,10 @@ - (void)_handleResubscriptionNeededWithDelay:(NSNumber *)resubscriptionDelayMs // this block is run -- if other triggering events had happened, this would become a no-op. auto resubscriptionBlock = ^{ [self->_deviceController asyncDispatchToMatterQueue:^{ - [self _triggerResubscribeWithReason:"ResubscriptionNeeded timer fired" nodeLikelyReachable:NO]; + [self _triggerResubscribeWithReason:@"ResubscriptionNeeded timer fired" nodeLikelyReachable:NO]; } errorHandler:^(NSError * _Nonnull error) { // If controller is not running, clear work item from the subscription queue - MTR_LOG_INFO("%@ could not dispatch to matter queue for resubscription - error %@", self, error); + MTR_LOG_ERROR("%@ could not dispatch to matter queue for resubscription - error %@", self, error); std::lock_guard lock(self->_lock); [self _clearSubscriptionPoolWork]; }]; @@ -1165,7 +1209,7 @@ - (void)_handleSubscriptionReset:(NSNumber * _Nullable)retryDelay // don't schedule multiple retries if (self.reattemptingSubscription) { - MTR_LOG_DEFAULT("%@ already reattempting subscription", self); + MTR_LOG("%@ already reattempting subscription", self); return; } @@ -1182,7 +1226,7 @@ - (void)_handleSubscriptionReset:(NSNumber * _Nullable)retryDelay // the device told us to use. _lastSubscriptionAttemptWait = 0; secondsToWait = retryDelay.doubleValue; - MTR_LOG_INFO("%@ resetting resubscribe attempt counter, and delaying by the server-provided delay: %f", + MTR_LOG("%@ resetting resubscribe attempt counter, and delaying by the server-provided delay: %f", self, secondsToWait); } else { _lastSubscriptionAttemptWait *= 2; @@ -1192,22 +1236,22 @@ - (void)_handleSubscriptionReset:(NSNumber * _Nullable)retryDelay secondsToWait = _lastSubscriptionAttemptWait; } - MTR_LOG_DEFAULT("%@ scheduling to reattempt subscription in %f seconds", self, secondsToWait); + MTR_LOG("%@ scheduling to reattempt subscription in %f seconds", self, secondsToWait); // If we started subscription or session establishment but failed, remove item from the subscription pool so we can re-queue. [self _clearSubscriptionPoolWork]; - // Call _reattemptSubscriptionNowIfNeeded when timer fires - if subscription is + // Call _reattemptSubscriptionNowIfNeededWithReason when timer fires - if subscription is // in a better state at that time this will be a no-op. auto resubscriptionBlock = ^{ os_unfair_lock_lock(&self->_lock); - [self _reattemptSubscriptionNowIfNeeded]; + [self _reattemptSubscriptionNowIfNeededWithReason:@"got subscription reset"]; os_unfair_lock_unlock(&self->_lock); }; int64_t resubscriptionDelayNs = static_cast(secondsToWait * NSEC_PER_SEC); if ([self _deviceUsesThread]) { - // For Thread-enabled devices, schedule the _reattemptSubscriptionNowIfNeeded call to run in the subscription pool + // For Thread-enabled devices, schedule the _reattemptSubscriptionNowIfNeededWithReason call to run in the subscription pool [self _scheduleSubscriptionPoolWork:resubscriptionBlock inNanoseconds:resubscriptionDelayNs description:@"MTRDevice resubscription"]; } else { // For non-Thread-enabled devices, just call the resubscription block after the specified time @@ -1215,16 +1259,16 @@ - (void)_handleSubscriptionReset:(NSNumber * _Nullable)retryDelay } } -- (void)_reattemptSubscriptionNowIfNeeded +- (void)_reattemptSubscriptionNowIfNeededWithReason:(NSString *)reason { os_unfair_lock_assert_owner(&self->_lock); if (!self.reattemptingSubscription) { return; } - MTR_LOG_DEFAULT("%@ reattempting subscription", self); + MTR_LOG("%@ reattempting subscription", self); self.reattemptingSubscription = NO; - [self _setupSubscription]; + [self _setupSubscriptionWithReason:reason]; } - (void)_handleUnsolicitedMessageFromPublisher @@ -1246,8 +1290,8 @@ - (void)_handleUnsolicitedMessageFromPublisher // reestablishment, this starts the attempt right away // TODO: This doesn't really make sense. If we _don't_ have a live // ReadClient how did we get this notification and if we _do_ have an active - // ReadClient, this call or _setupSubscription would be no-ops. - [self _reattemptSubscriptionNowIfNeeded]; + // ReadClient, this call or _setupSubscriptionWithReason would be no-ops. + [self _reattemptSubscriptionNowIfNeededWithReason:@"got unsolicited message from publisher"]; } - (void)_markDeviceAsUnreachableIfNeverSubscribed @@ -1258,7 +1302,7 @@ - (void)_markDeviceAsUnreachableIfNeverSubscribed return; } - MTR_LOG_DEFAULT("%@ still not subscribed, marking the device as unreachable", self); + MTR_LOG("%@ still not subscribed, marking the device as unreachable", self); [self _changeState:MTRDeviceStateUnreachable]; } @@ -1287,6 +1331,261 @@ - (void)_handleReportBegin return clusterDataToReturn; } +- (NSTimeInterval)_reportToPersistenceDelayTimeAfterMutiplier +{ + return _storageBehaviorConfiguration.reportToPersistenceDelayTime * _reportToPersistenceDelayCurrentMultiplier; +} + +- (NSTimeInterval)_reportToPersistenceDelayTimeMaxAfterMutiplier +{ + return _storageBehaviorConfiguration.reportToPersistenceDelayTimeMax * _reportToPersistenceDelayCurrentMultiplier; +} + +- (BOOL)_dataStoreExists +{ + os_unfair_lock_assert_owner(&self->_lock); + return _persistedClusterData != nil; +} + +- (void)_persistClusterData +{ + os_unfair_lock_assert_owner(&self->_lock); + + // Nothing to persist + if (!_clusterDataToPersist.count) { + return; + } + + MTR_LOG("%@ Storing cluster information (data version and attributes) count: %lu", self, static_cast(_clusterDataToPersist.count)); + // We're going to hand out these MTRDeviceClusterData objects to our + // storage implementation, which will try to read them later. Make sure + // we snapshot the state here instead of handing out live copies. + NSDictionary * clusterData = [self _clusterDataToPersistSnapshot]; + [_deviceController.controllerDataStore storeClusterData:clusterData forNodeID:_nodeID]; + for (MTRClusterPath * clusterPath in _clusterDataToPersist) { + [_persistedClusterData setObject:_clusterDataToPersist[clusterPath] forKey:clusterPath]; + [_persistedClusters addObject:clusterPath]; + } + + // TODO: There is one edge case not handled well here: if the + // storeClusterData call above fails somehow, and then the data gets + // evicted from _persistedClusterData, we could end up in a situation + // where when we page things in from storage we have stale values and + // hence effectively lose the delta that we failed to persist. + // + // The only way to handle this would be to detect it when it happens, + // then re-subscribe at that point, which would cause the relevant data + // to be sent to us via the priming read. + _clusterDataToPersist = nil; + +#ifdef DEBUG + id delegate = _weakDelegate.strongObject; + if (delegate) { + dispatch_async(_delegateQueue, ^{ + if ([delegate respondsToSelector:@selector(unitTestClusterDataPersisted:)]) { + [delegate unitTestClusterDataPersisted:self]; + } + }); + } +#endif +} + +- (BOOL)_deviceIsReportingExcessively +{ + os_unfair_lock_assert_owner(&self->_lock); + + if (!_deviceReportingExcessivelyStartTime) { + return NO; + } + + NSTimeInterval intervalSinceDeviceReportingExcessively = -[_deviceReportingExcessivelyStartTime timeIntervalSinceNow]; + BOOL deviceIsReportingExcessively = intervalSinceDeviceReportingExcessively > _storageBehaviorConfiguration.deviceReportingExcessivelyIntervalThreshold; + if (deviceIsReportingExcessively) { + MTR_LOG("%@ storage behavior: device has been reporting excessively for %.3lf seconds", self, intervalSinceDeviceReportingExcessively); + } + return deviceIsReportingExcessively; +} + +- (void)_persistClusterDataAsNeeded +{ + std::lock_guard lock(_lock); + + // Nothing to persist + if (!_clusterDataToPersist.count) { + return; + } + + // This is run with a dispatch_after, and need to check again if this device is reporting excessively + if ([self _deviceIsReportingExcessively]) { + return; + } + + NSDate * lastReportTime = [_mostRecentReportTimes lastObject]; + NSTimeInterval intervalSinceLastReport = -[lastReportTime timeIntervalSinceNow]; + if (intervalSinceLastReport < [self _reportToPersistenceDelayTimeAfterMutiplier]) { + // A report came in after this call was scheduled + + if (!_clusterDataPersistenceFirstScheduledTime) { + MTR_LOG_ERROR("%@ storage behavior: expects _clusterDataPersistenceFirstScheduledTime if _clusterDataToPersist exists", self); + return; + } + + NSTimeInterval intervalSinceFirstScheduledPersistence = -[_clusterDataPersistenceFirstScheduledTime timeIntervalSinceNow]; + if (intervalSinceFirstScheduledPersistence < [self _reportToPersistenceDelayTimeMaxAfterMutiplier]) { + MTR_LOG("%@ storage behavior: not persisting: intervalSinceLastReport %lf intervalSinceFirstScheduledPersistence %lf", self, intervalSinceLastReport, intervalSinceFirstScheduledPersistence); + // The max delay is also not reached - do not persist yet + return; + } + } + + // At this point, there is data to persist, and either _reportToPersistenceDelayTime was + // reached, or _reportToPersistenceDelayTimeMax was reached. Time to persist: + [self _persistClusterData]; + + _clusterDataPersistenceFirstScheduledTime = nil; +} + +#ifdef DEBUG +- (void)unitTestSetMostRecentReportTimes:(NSMutableArray *)mostRecentReportTimes +{ + _mostRecentReportTimes = mostRecentReportTimes; +} +#endif + +- (void)_scheduleClusterDataPersistence +{ + os_unfair_lock_assert_owner(&self->_lock); + + // No persisted data / lack of controller data store + if (![self _dataStoreExists]) { + MTR_LOG_DEBUG("%@ storage behavior: no data store", self); + return; + } + + // Nothing to persist + if (!_clusterDataToPersist.count) { + MTR_LOG_DEBUG("%@ storage behavior: nothing to persist", self); + return; + } + + // If there is no storage behavior configuration, make a default one + if (!_storageBehaviorConfiguration) { + _storageBehaviorConfiguration = [[MTRDeviceStorageBehaviorConfiguration alloc] init]; + [_storageBehaviorConfiguration checkValuesAndResetToDefaultIfNecessary]; + } + + // Directly store if the storage behavior optimization is disabled + if (_storageBehaviorConfiguration.disableStorageBehaviorOptimization) { + [self _persistClusterData]; + return; + } + + // If we have nothing stored at all yet, store directly, so we move into a + // primed state. + if (!_deviceCachePrimed) { + [self _persistClusterData]; + return; + } + + // Ensure there is an array to keep the most recent report times + if (!_mostRecentReportTimes) { + _mostRecentReportTimes = [NSMutableArray array]; + } + + // Mark when first report comes in to know when _reportToPersistenceDelayTimeMax is hit + if (!_clusterDataPersistenceFirstScheduledTime) { + _clusterDataPersistenceFirstScheduledTime = [NSDate now]; + } + + // Make sure there is space in the array, and note report time + while (_mostRecentReportTimes.count >= _storageBehaviorConfiguration.recentReportTimesMaxCount) { + [_mostRecentReportTimes removeObjectAtIndex:0]; + } + [_mostRecentReportTimes addObject:[NSDate now]]; + + // Calculate running average and update multiplier - need at least 2 items to calculate intervals + if (_mostRecentReportTimes.count > 2) { + NSTimeInterval cumulativeIntervals = 0; + for (int i = 1; i < _mostRecentReportTimes.count; i++) { + NSDate * lastDate = [_mostRecentReportTimes objectAtIndex:i - 1]; + NSDate * currentDate = [_mostRecentReportTimes objectAtIndex:i]; + NSTimeInterval intervalSinceLastReport = [currentDate timeIntervalSinceDate:lastDate]; + // Check to guard against clock change + if (intervalSinceLastReport > 0) { + cumulativeIntervals += intervalSinceLastReport; + } + } + NSTimeInterval averageTimeBetweenReports = cumulativeIntervals / (_mostRecentReportTimes.count - 1); + + if (averageTimeBetweenReports < _storageBehaviorConfiguration.timeBetweenReportsTooShortThreshold) { + // Multiplier goes from 1 to _reportToPersistenceDelayMaxMultiplier uniformly, as + // averageTimeBetweenReports go from timeBetweenReportsTooShortThreshold to + // timeBetweenReportsTooShortMinThreshold + + double intervalAmountBelowThreshold = _storageBehaviorConfiguration.timeBetweenReportsTooShortThreshold - averageTimeBetweenReports; + double intervalAmountBetweenThresholdAndMinThreshold = _storageBehaviorConfiguration.timeBetweenReportsTooShortThreshold - _storageBehaviorConfiguration.timeBetweenReportsTooShortMinThreshold; + double proportionTowardMinThreshold = intervalAmountBelowThreshold / intervalAmountBetweenThresholdAndMinThreshold; + if (proportionTowardMinThreshold > 1) { + // Clamp to 100% + proportionTowardMinThreshold = 1; + } + + // Set current multiplier to [1, MaxMultiplier] + _reportToPersistenceDelayCurrentMultiplier = 1 + (proportionTowardMinThreshold * (_storageBehaviorConfiguration.reportToPersistenceDelayMaxMultiplier - 1)); + MTR_LOG("%@ storage behavior: device reporting frequently - setting delay multiplier to %lf", self, _reportToPersistenceDelayCurrentMultiplier); + } else { + _reportToPersistenceDelayCurrentMultiplier = 1; + } + + // Also note when the running average first dips below the min threshold + if (averageTimeBetweenReports < _storageBehaviorConfiguration.timeBetweenReportsTooShortMinThreshold) { + if (!_deviceReportingExcessivelyStartTime) { + _deviceReportingExcessivelyStartTime = [NSDate now]; + MTR_LOG_DEBUG("%@ storage behavior: device is reporting excessively @%@", self, _deviceReportingExcessivelyStartTime); + } + } else { + _deviceReportingExcessivelyStartTime = nil; + } + } + + // Do not schedule persistence if device is reporting excessively + if ([self _deviceIsReportingExcessively]) { + return; + } + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) ([self _reportToPersistenceDelayTimeAfterMutiplier] * NSEC_PER_SEC)), self.queue, ^{ + [self _persistClusterDataAsNeeded]; + }); +} + +// Used to clear the storage behavior state when needed (system time change, or when new +// configuration is set. +// +// Also flushes unwritten cluster data to storage, if data store exists. +- (void)_resetStorageBehaviorState +{ + os_unfair_lock_assert_owner(&self->_lock); + + _clusterDataPersistenceFirstScheduledTime = nil; + _mostRecentReportTimes = nil; + _deviceReportingExcessivelyStartTime = nil; + _reportToPersistenceDelayCurrentMultiplier = 1; + + if (_persistedClusters) { + [self _persistClusterData]; + } +} + +- (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration +{ + MTR_LOG("%@ storage behavior: setStorageBehaviorConfiguration %@", self, storageBehaviorConfiguration); + std::lock_guard lock(_lock); + _storageBehaviorConfiguration = storageBehaviorConfiguration; + // Make sure the values are sane + [_storageBehaviorConfiguration checkValuesAndResetToDefaultIfNecessary]; + [self _resetStorageBehaviorState]; +} + - (void)_handleReportEnd { std::lock_guard lock(_lock); @@ -1294,30 +1593,7 @@ - (void)_handleReportEnd _receivingPrimingReport = NO; _estimatedStartTimeFromGeneralDiagnosticsUpTime = nil; - BOOL dataStoreExists = _deviceController.controllerDataStore != nil; - if (dataStoreExists && _clusterDataToPersist != nil && _clusterDataToPersist.count) { - MTR_LOG_DEFAULT("%@ Storing cluster information (data version and attributes) count: %lu", self, static_cast(_clusterDataToPersist.count)); - // We're going to hand out these MTRDeviceClusterData objects to our - // storage implementation, which will try to read them later. Make sure - // we snapshot the state here instead of handing out live copies. - NSDictionary * clusterData = [self _clusterDataToPersistSnapshot]; - [_deviceController.controllerDataStore storeClusterData:clusterData forNodeID:_nodeID]; - for (MTRClusterPath * clusterPath in _clusterDataToPersist) { - [_persistedClusterData setObject:_clusterDataToPersist[clusterPath] forKey:clusterPath]; - [_persistedClusters addObject:clusterPath]; - } - - // TODO: There is one edge case not handled well here: if the - // storeClusterData call above fails somehow, and then the data gets - // evicted from _persistedClusterData, we could end up in a situation - // where when we page things in from storage we have stale values and - // hence effectively lose the delta that we failed to persist. - // - // The only way to handle this would be to detect it when it happens, - // then re-subscribe at that point, which would cause the relevant data - // to be sent to us via the priming read. - _clusterDataToPersist = nil; - } + [self _scheduleClusterDataPersistence]; // After the handling of the report, if we detected a device configuration change, notify the delegate // of the same. @@ -1332,6 +1608,19 @@ - (void)_handleReportEnd _deviceConfigurationChanged = NO; } + // Do this after the _deviceConfigurationChanged check, so that we don't + // call deviceConfigurationChanged: immediately after telling our delegate + // we are now primed. + // + // TODO: Maybe we shouldn't dispatch deviceConfigurationChanged: for the + // initial priming bits? + if (!_deviceCachePrimed) { + // This is the end of the priming sequence of data reports, so we have + // all the data for the device now. + _deviceCachePrimed = YES; + [self _callDelegateDeviceCachePrimed]; + } + // For unit testing only #ifdef DEBUG id delegate = _weakDelegate.strongObject; @@ -1428,12 +1717,12 @@ - (void)_handleEventReport:(NSArray *> *)eventRepor if (isStartUpEvent) { if (_estimatedStartTimeFromGeneralDiagnosticsUpTime) { // If UpTime was received, make use of it as mark of system start time - MTR_LOG_INFO("%@ StartUp event: set estimated start time forward to %@", self, + MTR_LOG("%@ StartUp event: set estimated start time forward to %@", self, _estimatedStartTimeFromGeneralDiagnosticsUpTime); _estimatedStartTime = _estimatedStartTimeFromGeneralDiagnosticsUpTime; } else { // If UpTime was not received, reset estimated start time in case of reboot - MTR_LOG_INFO("%@ StartUp event: set estimated start time to nil", self); + MTR_LOG("%@ StartUp event: set estimated start time to nil", self); _estimatedStartTime = nil; } } @@ -1468,7 +1757,7 @@ - (void)_handleEventReport:(NSArray *> *)eventRepor [reportToReturn addObject:eventToReturn]; } if (oldEstimatedStartTime != _estimatedStartTime) { - MTR_LOG_DEFAULT("%@ updated estimated start time to %@", self, _estimatedStartTime); + MTR_LOG("%@ updated estimated start time to %@", self, _estimatedStartTime); } id delegate = _weakDelegate.strongObject; @@ -1487,7 +1776,7 @@ - (void)_handleEventReport:(NSArray *> *)eventRepor - (void)unitTestClearClusterData { std::lock_guard lock(_lock); - NSAssert(_persistedClusterData != nil, @"Test is not going to test what it thinks is testing!"); + NSAssert([self _dataStoreExists], @"Test is not going to test what it thinks is testing!"); [_persistedClusterData removeAllObjects]; } #endif @@ -1504,7 +1793,7 @@ - (nullable MTRDeviceClusterData *)_clusterDataForPath:(MTRClusterPath *)cluster } } - if (_persistedClusterData != nil) { + if ([self _dataStoreExists]) { MTRDeviceClusterData * data = [_persistedClusterData objectForKey:clusterPath]; if (data != nil) { return data; @@ -1554,7 +1843,7 @@ - (nullable MTRDeviceClusterData *)_clusterDataForPath:(MTRClusterPath *)cluster dataVersions[path] = [self _clusterDataForPath:path].dataVersion; } - MTR_LOG_INFO("%@ _getCachedDataVersions dataVersions count: %lu", self, static_cast(dataVersions.count)); + MTR_LOG_DEBUG("%@ _getCachedDataVersions dataVersions count: %lu", self, static_cast(dataVersions.count)); return dataVersions; } @@ -1609,6 +1898,17 @@ - (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value f _clusterDataToPersist[clusterPath] = clusterData; } +- (void)_removeCachedAttribute:(NSNumber *)attributeID fromCluster:(MTRClusterPath *)clusterPath +{ + os_unfair_lock_assert_owner(&self->_lock); + + if (_clusterDataToPersist == nil) { + return; + } + auto * clusterData = _clusterDataToPersist[clusterPath]; + [clusterData removeValueForAttribute:attributeID]; +} + - (void)_createDataVersionFilterListFromDictionary:(NSDictionary *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count sizeReduction:(size_t)sizeReduction { size_t maxDataVersionFilterSize = dataVersions.count; @@ -1644,7 +1944,7 @@ - (void)_setupConnectivityMonitoring // Get the required info before setting up the connectivity monitor NSNumber * compressedFabricID = [self->_deviceController syncGetCompressedFabricID]; if (!compressedFabricID) { - MTR_LOG_INFO("%@ could not get compressed fabricID", self); + MTR_LOG_ERROR("%@ could not get compressed fabricID", self); return; } @@ -1658,7 +1958,7 @@ - (void)_setupConnectivityMonitoring self->_connectivityMonitor = [[MTRDeviceConnectivityMonitor alloc] initWithCompressedFabricID:compressedFabricID nodeID:self.nodeID]; [self->_connectivityMonitor startMonitoringWithHandler:^{ [self->_deviceController asyncDispatchToMatterQueue:^{ - [self _triggerResubscribeWithReason:"device connectivity changed" nodeLikelyReachable:YES]; + [self _triggerResubscribeWithReason:@"device connectivity changed" nodeLikelyReachable:YES]; } errorHandler:nil]; } queue:self.queue]; @@ -1676,10 +1976,15 @@ - (void)_stopConnectivityMonitoring } // assume lock is held -- (void)_setupSubscription +- (void)_setupSubscriptionWithReason:(NSString *)reason { os_unfair_lock_assert_owner(&self->_lock); + if (![self _subscriptionsAllowed]) { + MTR_LOG("%@ _setupSubscription: Subscriptions not allowed. Do not set up subscription", self); + return; + } + #ifdef DEBUG id delegate = _weakDelegate.strongObject; Optional maxIntervalOverride; @@ -1698,6 +2003,8 @@ - (void)_setupSubscription [self _changeInternalState:MTRInternalDeviceStateSubscribing]; + MTR_LOG("%@ setting up subscription with reason: %@", self, reason); + // Set up a timer to mark as not reachable if it takes too long to set up a subscription MTRWeakReference * weakSelf = [MTRWeakReference weakReferenceWithObject:self]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, static_cast(kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription) * static_cast(NSEC_PER_SEC)), self.queue, ^{ @@ -1724,7 +2031,7 @@ - (void)_setupSubscription auto callback = std::make_unique( ^(NSArray * value) { - MTR_LOG_INFO("%@ got attribute report %@", self, value); + MTR_LOG("%@ got attribute report %@", self, value); dispatch_async(self.queue, ^{ // OnAttributeData [self _handleAttributeReport:value fromSubscription:YES]; @@ -1734,7 +2041,7 @@ - (void)_setupSubscription }); }, ^(NSArray * value) { - MTR_LOG_INFO("%@ got event report %@", self, value); + MTR_LOG("%@ got event report %@", self, value); dispatch_async(self.queue, ^{ // OnEventReport [self _handleEventReport:value]; @@ -1748,21 +2055,21 @@ - (void)_setupSubscription }); }, ^(NSError * error, NSNumber * resubscriptionDelayMs) { - MTR_LOG_DEFAULT("%@ got resubscription error %@ delay %@", self, error, resubscriptionDelayMs); + MTR_LOG_ERROR("%@ got resubscription error %@ delay %@", self, error, resubscriptionDelayMs); dispatch_async(self.queue, ^{ // OnResubscriptionNeeded [self _handleResubscriptionNeededWithDelay:resubscriptionDelayMs]; }); }, ^(void) { - MTR_LOG_DEFAULT("%@ got subscription established", self); + MTR_LOG("%@ got subscription established", self); dispatch_async(self.queue, ^{ // OnSubscriptionEstablished [self _handleSubscriptionEstablished]; }); }, ^(void) { - MTR_LOG_DEFAULT("%@ got subscription done", self); + MTR_LOG("%@ got subscription done", self); // Drop our pointer to the ReadClient immediately, since // it's about to be destroyed and we don't want to be // holding a dangling pointer. @@ -1776,20 +2083,20 @@ - (void)_setupSubscription }); }, ^(void) { - MTR_LOG_DEFAULT("%@ got unsolicited message from publisher", self); + MTR_LOG("%@ got unsolicited message from publisher", self); dispatch_async(self.queue, ^{ // OnUnsolicitedMessageFromPublisher [self _handleUnsolicitedMessageFromPublisher]; }); }, ^(void) { - MTR_LOG_DEFAULT("%@ got report begin", self); + MTR_LOG("%@ got report begin", self); dispatch_async(self.queue, ^{ [self _handleReportBegin]; }); }, ^(void) { - MTR_LOG_DEFAULT("%@ got report end", self); + MTR_LOG("%@ got report end", self); dispatch_async(self.queue, ^{ [self _handleReportEnd]; }); @@ -1884,7 +2191,7 @@ - (void)_setupSubscription return; } - MTR_LOG_DEFAULT("%@ Subscribe with data version list size %lu, reduced by %lu", self, (unsigned long) dataVersions.count, (unsigned long) dataVersionFilterListSizeReduction); + MTR_LOG("%@ Subscribe with data version list size %lu, reduced by %lu", self, static_cast(dataVersions.count), static_cast(dataVersionFilterListSizeReduction)); // Callback and ClusterStateCache and ReadClient will be deleted // when OnDone is called. @@ -2099,14 +2406,14 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) while (readRequestsNext.count) { // Can only read up to 9 paths at a time, per spec if (readRequestsCurrent.count >= 9) { - MTR_LOG_INFO("Batching read attribute work item [%llu]: cannot add more work, item is full [0x%016llX:%@:0x%llx:0x%llx]", workItemID, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); + MTR_LOG("Batching read attribute work item [%llu]: cannot add more work, item is full [0x%016llX:%@:0x%llx:0x%llx]", workItemID, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); return outcome; } // if params don't match then they cannot be merged if (![readRequestsNext[0][MTRDeviceReadRequestFieldParamsIndex] isEqual:readRequestsCurrent[0][MTRDeviceReadRequestFieldParamsIndex]]) { - MTR_LOG_INFO("Batching read attribute work item [%llu]: cannot add more work, parameter mismatch [0x%016llX:%@:0x%llx:0x%llx]", workItemID, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); + MTR_LOG("Batching read attribute work item [%llu]: cannot add more work, parameter mismatch [0x%016llX:%@:0x%llx:0x%llx]", workItemID, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); return outcome; } @@ -2114,8 +2421,8 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) auto readItem = readRequestsNext.firstObject; [readRequestsNext removeObjectAtIndex:0]; [readRequestsCurrent addObject:readItem]; - MTR_LOG_INFO("Batching read attribute work item [%llu]: added %@ (now %tu requests total) [0x%016llX:%@:0x%llx:0x%llx]", - workItemID, readItem, readRequestsCurrent.count, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); + MTR_LOG("Batching read attribute work item [%llu]: added %@ (now %lu requests total) [0x%016llX:%@:0x%llx:0x%llx]", + workItemID, readItem, static_cast(readRequestsCurrent.count), nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); outcome = MTRBatchedPartially; } NSCAssert(readRequestsNext.count == 0, @"should have batched everything or returned early"); @@ -2125,7 +2432,7 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) mtr_hide(self); // don't capture self accidentally for (NSArray * readItem in readRequests) { if ([readItem isEqual:opaqueItemData]) { - MTR_LOG_DEFAULT("Read attribute work item [%llu] report duplicate %@ [0x%016llX:%@:0x%llx:0x%llx]", workItemID, readItem, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); + MTR_LOG("Read attribute work item [%llu] report duplicate %@ [0x%016llX:%@:0x%llx:0x%llx]", workItemID, readItem, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); *isDuplicate = YES; *stop = YES; return; @@ -2162,7 +2469,7 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) if (values) { // Since the format is the same data-value dictionary, this looks like an // attribute report - MTR_LOG_INFO("Read attribute work item [%llu] result: %@ [0x%016llX:%@:0x%llX:0x%llX]", workItemID, values, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); + MTR_LOG("Read attribute work item [%llu] result: %@ [0x%016llX:%@:0x%llX:0x%llX]", workItemID, values, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); [self _handleAttributeReport:values fromSubscription:NO]; } @@ -2172,7 +2479,7 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) completion(MTRAsyncWorkNeedsRetry); } else { if (error) { - MTR_LOG_DEFAULT("Read attribute work item [%llu] failed (giving up): %@ [0x%016llX:%@:0x%llx:0x%llx]", workItemID, error, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); + MTR_LOG("Read attribute work item [%llu] failed (giving up): %@ [0x%016llX:%@:0x%llx:0x%llx]", workItemID, error, nodeID.unsignedLongLongValue, endpointID, clusterID.unsignedLongLongValue, attributeID.unsignedLongLongValue); } completion(MTRAsyncWorkComplete); } @@ -2242,7 +2549,7 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID if (writeRequestsCurrent.count != 1) { // Very unexpected! - MTR_LOG_ERROR("Batching write attribute work item [%llu]: Unexpected write request count %tu", workItemID, writeRequestsCurrent.count); + MTR_LOG_ERROR("Batching write attribute work item [%llu]: Unexpected write request count %lu", workItemID, static_cast(writeRequestsCurrent.count)); return MTRNotBatched; } @@ -2252,7 +2559,7 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID // with the later one. if (![writeRequestsNext[0][MTRDeviceWriteRequestFieldPathIndex] isEqual:writeRequestsCurrent[0][MTRDeviceWriteRequestFieldPathIndex]]) { - MTR_LOG_INFO("Batching write attribute work item [%llu]: cannot replace with next work item due to path mismatch", workItemID); + MTR_LOG("Batching write attribute work item [%llu]: cannot replace with next work item due to path mismatch", workItemID); return outcome; } @@ -2260,7 +2567,7 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID auto writeItem = writeRequestsNext.firstObject; [writeRequestsNext removeObjectAtIndex:0]; [writeRequestsCurrent replaceObjectAtIndex:0 withObject:writeItem]; - MTR_LOG_INFO("Batching write attribute work item [%llu]: replaced with new write value %@ [0x%016llX]", + MTR_LOG("Batching write attribute work item [%llu]: replaced with new write value %@ [0x%016llX]", workItemID, writeItem, nodeID.unsignedLongLongValue); outcome = MTRBatchedPartially; } @@ -2277,7 +2584,7 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID MTRBaseDevice * baseDevice = [self newBaseDevice]; // Make sure to use writeRequests here, because that's what our batching // handler will modify as needed. - NSCAssert(writeRequests.count == 1, @"Incorrect number of write requests: %tu", writeRequests.count); + NSCAssert(writeRequests.count == 1, @"Incorrect number of write requests: %lu", static_cast(writeRequests.count)); auto * request = writeRequests[0]; MTRAttributePath * path = request[MTRDeviceWriteRequestFieldPathIndex]; @@ -2444,7 +2751,7 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { // Log the data at the INFO level (not usually persisted permanently), // but make sure we log the work completion at the DEFAULT level. - MTR_LOG_INFO("Invoke work item [%llu] received command response: %@ error: %@", workItemID, values, error); + MTR_LOG("Invoke work item [%llu] received command response: %@ error: %@", workItemID, values, error); // TODO: This 5-retry cap is very arbitrary. // TODO: Should there be some sort of backoff here? if (error != nil && error.domain == MTRInteractionErrorDomain && error.code == MTRInteractionErrorCodeBusy && retryCount < 5) { @@ -2591,7 +2898,7 @@ - (void)_checkExpiredExpectedValues } // log attribute paths - MTR_LOG_INFO("%@ report from expired expected values %@", self, attributePathsToReport); + MTR_LOG("%@ report from expired expected values %@", self, attributePathsToReport); [self _reportAttributes:attributesToReport]; // Have a reasonable minimum wait time for expiration timers @@ -2642,7 +2949,7 @@ - (void)_performScheduledExpirationCheck return cachedAttributeValue; } else { // TODO: when not found in cache, generated default values should be used - MTR_LOG_INFO("%@ _attributeValueDictionaryForAttributePath: could not find cached attribute values for attribute %@", self, + MTR_LOG("%@ _attributeValueDictionaryForAttributePath: could not find cached attribute values for attribute %@", self, attributePath); } @@ -2666,7 +2973,7 @@ - (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary } // Utility to return data value dictionary without data version -- (NSDictionary *)_dataValueWithoutDataVersion:(NSDictionary *)attributeValue; +- (NSDictionary *)_dataValueWithoutDataVersion:(NSDictionary *)attributeValue { // Sanity check for nil - return the same input to fail gracefully if (!attributeValue || !attributeValue[MTRTypeKey]) { @@ -2728,6 +3035,117 @@ - (BOOL)_attributeAffectsDeviceConfiguration:(MTRAttributePath *)attributePath return NO; } +- (void)_removeClusters:(NSSet *)clusterPathsToRemove + doRemoveFromDataStore:(BOOL)doRemoveFromDataStore +{ + os_unfair_lock_assert_owner(&self->_lock); + + [_persistedClusters minusSet:clusterPathsToRemove]; + + for (MTRClusterPath * path in clusterPathsToRemove) { + [_persistedClusterData removeObjectForKey:path]; + [_clusterDataToPersist removeObjectForKey:path]; + if (doRemoveFromDataStore) { + [self.deviceController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:path.endpoint clusterID:path.cluster]; + } + } +} + +- (void)_removeAttributes:(NSSet *)attributes fromCluster:(MTRClusterPath *)clusterPath +{ + os_unfair_lock_assert_owner(&self->_lock); + + for (NSNumber * attribute in attributes) { + [self _removeCachedAttribute:attribute fromCluster:clusterPath]; + } + // Just clear out the NSCache entry for this cluster, so we'll load it from storage as needed. + [_persistedClusterData removeObjectForKey:clusterPath]; + [self.deviceController.controllerDataStore removeAttributes:attributes fromCluster:clusterPath forNodeID:self.nodeID]; +} + +- (void)_pruneEndpointsIn:(MTRDeviceDataValueDictionary)previousPartsListValue + missingFrom:(MTRDeviceDataValueDictionary)newPartsListValue +{ + // If the parts list changed and one or more endpoints were removed, remove all the + // clusters for all those endpoints from our data structures. + // Also remove those endpoints from the data store. + NSMutableSet * toBeRemovedEndpoints = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:previousPartsListValue]]; + NSSet * endpointsOnDevice = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newPartsListValue]]; + [toBeRemovedEndpoints minusSet:endpointsOnDevice]; + + for (NSNumber * endpoint in toBeRemovedEndpoints) { + NSMutableSet * clusterPathsToRemove = [[NSMutableSet alloc] init]; + for (MTRClusterPath * path in _persistedClusters) { + if ([path.endpoint isEqualToNumber:endpoint]) { + [clusterPathsToRemove addObject:path]; + } + } + [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:NO]; + [self.deviceController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:endpoint]; + } +} + +- (void)_pruneClustersIn:(MTRDeviceDataValueDictionary)previousServerListValue + missingFrom:(MTRDeviceDataValueDictionary)newServerListValue + forEndpoint:(NSNumber *)endpointID +{ + // If the server list changed and clusters were removed, remove those clusters from our data structures. + // Also remove them from the data store. + NSMutableSet * toBeRemovedClusters = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:previousServerListValue]]; + NSSet * clustersStillOnEndpoint = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newServerListValue]]; + [toBeRemovedClusters minusSet:clustersStillOnEndpoint]; + + NSMutableSet * clusterPathsToRemove = [[NSMutableSet alloc] init]; + for (MTRClusterPath * path in _persistedClusters) { + if ([path.endpoint isEqualToNumber:endpointID] && [toBeRemovedClusters containsObject:path.cluster]) { + [clusterPathsToRemove addObject:path]; + } + } + [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:YES]; +} + +- (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListValue + missingFrom:(MTRDeviceDataValueDictionary)newAttributeListValue + forCluster:(MTRClusterPath *)clusterPath +{ + // If the attribute list changed and attributes were removed, remove the attributes from our + // data structures. + NSMutableSet * toBeRemovedAttributes = [NSMutableSet setWithArray:[self arrayOfNumbersFromAttributeValue:previousAttributeListValue]]; + NSSet * attributesStillInCluster = [NSSet setWithArray:[self arrayOfNumbersFromAttributeValue:newAttributeListValue]]; + + [toBeRemovedAttributes minusSet:attributesStillInCluster]; + [self _removeAttributes:toBeRemovedAttributes fromCluster:clusterPath]; +} + +- (void)_pruneStoredDataForPath:(MTRAttributePath *)attributePath + missingFrom:(MTRDeviceDataValueDictionary)newAttributeDataValue +{ + os_unfair_lock_assert_owner(&self->_lock); + + if (![self _dataStoreExists] && !_clusterDataToPersist.count) { + MTR_LOG_DEBUG("%@ No data store to prune from", self); + return; + } + + // Check if parts list changed or server list changed for the descriptor cluster or the attribute list changed for a cluster. + // If yes, we might need to prune any deleted endpoints, clusters or attributes from the storage and persisted cluster data. + if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID) { + if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributePartsListID && [attributePath.endpoint isEqualToNumber:@(kRootEndpointId)]) { + [self _pruneEndpointsIn:[self _cachedAttributeValueForPath:attributePath] missingFrom:newAttributeDataValue]; + return; + } + + if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributeServerListID) { + [self _pruneClustersIn:[self _cachedAttributeValueForPath:attributePath] missingFrom:newAttributeDataValue forEndpoint:attributePath.endpoint]; + return; + } + } + + if (attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeGlobalAttributeAttributeListID) { + [self _pruneAttributesIn:[self _cachedAttributeValueForPath:attributePath] missingFrom:newAttributeDataValue forCluster:[MTRClusterPath clusterPathWithEndpointID:attributePath.endpoint clusterID:attributePath.cluster]]; + } +} + // assume lock is held - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray *> *)reportedAttributeValues fromSubscription:(BOOL)isFromSubscription { @@ -2743,7 +3161,7 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray %@", self, upTime, + MTR_LOG("%@ General Diagnostics UpTime %.3lf: estimated start time %@ => %@", self, upTime, oldSystemStartTime, potentialSystemStartTime); _estimatedStartTime = potentialSystemStartTime; } @@ -2854,7 +3275,7 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray *)clusterData { - MTR_LOG_INFO("%@ setPersistedClusterData count: %lu", self, static_cast(clusterData.count)); + MTR_LOG("%@ setPersistedClusterData count: %lu", self, static_cast(clusterData.count)); if (!clusterData.count) { return; } std::lock_guard lock(_lock); - NSAssert(_persistedClusterData != nil, @"Why is controller setting persisted data when we shouldn't have it?"); + NSAssert([self _dataStoreExists], @"Why is controller setting persisted data when we shouldn't have it?"); for (MTRClusterPath * clusterPath in clusterData) { // The caller has mutable references to MTRDeviceClusterData and @@ -2891,10 +3312,9 @@ - (void)setPersistedClusterData:(NSDictionary *)data { - MTR_LOG_INFO("%@ setPersistedDeviceData: %@", self, data); + MTR_LOG_DEBUG("%@ setPersistedDeviceData: %@", self, data); std::lock_guard lock(_lock); @@ -2941,10 +3361,26 @@ - (void)_storePersistedDeviceData [datastore storeDeviceData:[data copy] forNodeID:self.nodeID]; } +#ifdef DEBUG +- (MTRDeviceClusterData *)_getClusterDataForPath:(MTRClusterPath *)path +{ + std::lock_guard lock(_lock); + + return [[self _clusterDataForPath:path] copy]; +} + +- (BOOL)_clusterHasBeenPersisted:(MTRClusterPath *)path +{ + std::lock_guard lock(_lock); + + return [_persistedClusters containsObject:path]; +} +#endif + - (BOOL)deviceCachePrimed { std::lock_guard lock(_lock); - return [self _isCachePrimedWithInitialConfigurationData]; + return _deviceCachePrimed; } // If value is non-nil, associate with expectedValueID @@ -3044,7 +3480,7 @@ - (NSArray *)_getAttributesToReportWithNewExpectedValues:(NSArray *> *)values // since NSTimeInterval is in seconds, convert ms into seconds in double NSDate * expirationTime = [NSDate dateWithTimeIntervalSinceNow:expectedValueInterval.doubleValue / 1000]; - MTR_LOG_INFO( + MTR_LOG( "%@ Setting expected values %@ with expiration time %f seconds from now", self, values, [expirationTime timeIntervalSinceNow]); std::lock_guard lock(_lock); @@ -3107,7 +3543,7 @@ - (void)_removeExpectedValueForAttributePath:(MTRAttributePath *)attributePath e expectedValueID:expectedValueID previousValue:&previousValue]; - MTR_LOG_INFO("%@ remove expected value for path %@ should report %@", self, attributePath, shouldReportValue ? @"YES" : @"NO"); + MTR_LOG("%@ remove expected value for path %@ should report %@", self, attributePath, shouldReportValue ? @"YES" : @"NO"); if (shouldReportValue) { NSMutableDictionary * attribute = [NSMutableDictionary dictionaryWithObject:attributePath forKey:MTRAttributePathKey]; @@ -3121,47 +3557,6 @@ - (void)_removeExpectedValueForAttributePath:(MTRAttributePath *)attributePath e } } -// This method checks if there is a need to inform delegate that the attribute cache has been "primed" -- (BOOL)_isCachePrimedWithInitialConfigurationData -{ - os_unfair_lock_assert_owner(&self->_lock); - - // Check if root node descriptor exists - MTRDeviceDataValueDictionary rootDescriptorPartsListDataValue = [self _cachedAttributeValueForPath:[MTRAttributePath attributePathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)]]; - if (!rootDescriptorPartsListDataValue || ![MTRArrayValueType isEqualToString:rootDescriptorPartsListDataValue[MTRTypeKey]]) { - return NO; - } - NSArray * partsList = rootDescriptorPartsListDataValue[MTRValueKey]; - if (![partsList isKindOfClass:[NSArray class]] || !partsList.count) { - MTR_LOG_ERROR("%@ unexpected type %@ for parts list %@", self, [partsList class], partsList); - return NO; - } - - // Check if we have cached descriptor clusters for each listed endpoint - for (NSDictionary * endpointDictionary in partsList) { - NSDictionary * endpointDataValue = endpointDictionary[MTRDataKey]; - if (![endpointDataValue isKindOfClass:[NSDictionary class]]) { - MTR_LOG_ERROR("%@ unexpected parts list dictionary %@ data value class %@", self, endpointDictionary, [endpointDataValue class]); - continue; - } - if (![MTRUnsignedIntegerValueType isEqual:endpointDataValue[MTRTypeKey]]) { - MTR_LOG_ERROR("%@ unexpected parts list data value %@ item type %@", self, endpointDataValue, endpointDataValue[MTRTypeKey]); - continue; - } - NSNumber * endpoint = endpointDataValue[MTRValueKey]; - if (![endpoint isKindOfClass:[NSNumber class]]) { - MTR_LOG_ERROR("%@ unexpected parts list item value class %@", self, [endpoint class]); - continue; - } - MTRDeviceDataValueDictionary descriptorDeviceTypeListDataValue = [self _cachedAttributeValueForPath:[MTRAttributePath attributePathWithEndpointID:endpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)]]; - if (![MTRArrayValueType isEqualToString:descriptorDeviceTypeListDataValue[MTRTypeKey]] || !descriptorDeviceTypeListDataValue[MTRValueKey]) { - return NO; - } - } - - return YES; -} - - (MTRBaseDevice *)newBaseDevice { return [MTRBaseDevice deviceWithNodeID:self.nodeID controller:self.deviceController]; @@ -3249,6 +3644,32 @@ - (void)removeClientDataForKey:(NSString *)key endpointID:(NSNumber *)endpointID @end +/* BEGIN DRAGONS: Note methods here cannot be renamed, and are used by private callers, do not rename, remove or modify behavior here */ + +@implementation MTRDevice (MatterPrivateForInternalDragonsDoNotFeed) + +- (BOOL)_deviceHasActiveSubscription +{ + std::lock_guard lock(_lock); + + // TODO: This should always return YES for thread devices + return HaveSubscriptionEstablishedRightNow(_internalDeviceState); +} + +- (void)_deviceMayBeReachable +{ + MTR_LOG("%@ _deviceMayBeReachable called", self); + // TODO: This should only be allowed for thread devices + [_deviceController asyncDispatchToMatterQueue:^{ + [self _triggerResubscribeWithReason:@"SPI client indicated the device may now be reachable" + nodeLikelyReachable:YES]; + } errorHandler:nil]; +} + +/* END DRAGONS */ + +@end + @implementation MTRDevice (Deprecated) + (MTRDevice *)deviceWithNodeID:(uint64_t)nodeID deviceController:(MTRDeviceController *)deviceController diff --git a/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm b/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm index b044cb6502dceb..38e6ba08165fc0 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceAttestationDelegateBridge.mm @@ -28,7 +28,7 @@ chip::Credentials::AttestationVerificationResult attestationResult) { dispatch_async(mQueue, ^{ - MTR_LOG_DEFAULT("MTRDeviceAttestationDelegateBridge::OnDeviceAttestationFailed completed with result: %hu", + MTR_LOG("MTRDeviceAttestationDelegateBridge::OnDeviceAttestationFailed completed with result: %hu", chip::to_underlying(attestationResult)); mResult = attestationResult; diff --git a/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm b/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm index 80ad6f80d5be2b..6a9ac601d41b6f 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceConnectivityMonitor.mm @@ -154,7 +154,7 @@ - (void)handleResolvedHostname:(const char *)hostName port:(uint16_t)port error: if (self) { nw_path_status_t status = nw_path_get_status(path); if (status == nw_path_status_satisfied) { - MTR_LOG_INFO("%@ path is satisfied", self); + MTR_LOG("%@ path is satisfied", self); std::lock_guard lock(sConnectivityMonitorLock); [self _callHandler]; } @@ -165,7 +165,7 @@ - (void)handleResolvedHostname:(const char *)hostName port:(uint16_t)port error: if (self) { if (viable) { std::lock_guard lock(sConnectivityMonitorLock); - MTR_LOG_INFO("%@ connectivity now viable", self); + MTR_LOG("%@ connectivity now viable", self); [self _callHandler]; } } @@ -201,11 +201,11 @@ - (void)startMonitoringWithHandler:(MTRDeviceConnectivityMonitorHandler)handler // If there's already a resolver running, just return if (_resolvers.size() != 0) { - MTR_LOG_INFO("%@ connectivity monitor already running", self); + MTR_LOG("%@ connectivity monitor already running", self); return; } - MTR_LOG_INFO("%@ start connectivity monitoring for %@ (%lu monitoring objects)", self, _instanceName, static_cast(sConnectivityMonitorCount)); + MTR_LOG("%@ start connectivity monitoring for %@ (%lu monitoring objects)", self, _instanceName, static_cast(sConnectivityMonitorCount)); auto sharedConnection = [MTRDeviceConnectivityMonitor _sharedResolverConnection]; if (!sharedConnection) { @@ -258,8 +258,8 @@ - (void)_stopMonitoring dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kSharedConnectionLingerIntervalSeconds * NSEC_PER_SEC), sSharedResolverQueue, ^{ std::lock_guard lock(sConnectivityMonitorLock); - if (!sConnectivityMonitorCount) { - MTR_LOG_INFO("MTRDeviceConnectivityMonitor: Closing shared resolver connection"); + if (!sConnectivityMonitorCount && sSharedResolverConnection) { + MTR_LOG("MTRDeviceConnectivityMonitor: Closing shared resolver connection"); DNSServiceRefDeallocate(sSharedResolverConnection); sSharedResolverConnection = NULL; sSharedResolverQueue = nil; @@ -271,9 +271,14 @@ - (void)_stopMonitoring - (void)stopMonitoring { + MTR_LOG("%@ stop connectivity monitoring for %@", self, self->_instanceName); + std::lock_guard lock(sConnectivityMonitorLock); + if (!sSharedResolverConnection || !sSharedResolverQueue) { + MTR_LOG("%@ shared resolver connection already stopped - nothing to do", self); + } + // DNSServiceRefDeallocate must be called on the same queue set on the shared connection. dispatch_async(sSharedResolverQueue, ^{ - MTR_LOG_INFO("%@ stop connectivity monitoring for %@", self, self->_instanceName); std::lock_guard lock(sConnectivityMonitorLock); [self _stopMonitoring]; }); diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.h b/src/darwin/Framework/CHIP/MTRDeviceController.h index 09c480f0568754..eaae1fcf7d4c6a 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController.h @@ -54,7 +54,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * if it has not already been started. * 2) Return nil or a running controller. * - * Once this returns non-nil, it's the caller's resposibility to call shutdown + * Once this returns non-nil, it's the caller's responsibility to call shutdown * on the controller to avoid leaking it. */ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 16b4d7f385e3aa..303cc2679e60d1 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -128,6 +128,8 @@ @implementation MTRDeviceController { // _serverEndpoints is only touched on the Matter queue. NSMutableArray * _serverEndpoints; + + MTRDeviceStorageBehaviorConfiguration * _storageBehaviorConfiguration; } - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error @@ -145,9 +147,6 @@ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParamete return [MTRDeviceControllerFactory.sharedInstance initializeController:self withParameters:controllerParameters error:error]; } -static NSString * const kLocalTestUserDefaultDomain = @"org.csa-iot.matter.darwintest"; -static NSString * const kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey = @"subscriptionPoolSizeOverride"; - - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory queue:(dispatch_queue_t)queue storageDelegate:(id _Nullable)storageDelegate @@ -156,6 +155,7 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue uniqueIdentifier:(NSUUID *)uniqueIdentifier concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize + storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration { if (self = [super init]) { // Make sure our storage is all set up to work as early as possible, @@ -256,22 +256,29 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory } // Provide a way to test different subscription pool sizes without code change - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; - if ([defaults objectForKey:kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey]) { - NSInteger subscriptionPoolSizeOverride = [defaults integerForKey:kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey]; + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; + if ([defaults objectForKey:kDefaultSubscriptionPoolSizeOverrideKey]) { + NSInteger subscriptionPoolSizeOverride = [defaults integerForKey:kDefaultSubscriptionPoolSizeOverrideKey]; if (subscriptionPoolSizeOverride < 1) { concurrentSubscriptionPoolSize = 1; } else { concurrentSubscriptionPoolSize = static_cast(subscriptionPoolSizeOverride); } + + MTR_LOG(" *** Overriding pool size of MTRDeviceController with: %lu", static_cast(concurrentSubscriptionPoolSize)); } if (!concurrentSubscriptionPoolSize) { concurrentSubscriptionPoolSize = 1; } + + MTR_LOG("Setting up pool size of MTRDeviceController with: %lu", static_cast(concurrentSubscriptionPoolSize)); + _concurrentSubscriptionPool = [[MTRAsyncWorkQueue alloc] initWithContext:self width:concurrentSubscriptionPoolSize]; _storedFabricIndex = chip::kUndefinedFabricIndex; + + _storageBehaviorConfiguration = storageBehaviorConfiguration; } return self; } @@ -595,13 +602,13 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams if (_controllerDataStore) { // If the storage delegate supports the bulk read API, then a dictionary of nodeID => cluster data dictionary would be passed to the handler. Otherwise this would be a no-op, and stored attributes for MTRDevice objects will be loaded lazily in -deviceForNodeID:. [_controllerDataStore fetchAttributeDataForAllDevices:^(NSDictionary *> * _Nonnull clusterDataByNode) { - MTR_LOG_INFO("Loaded attribute values for %lu nodes from storage for controller uuid %@", static_cast(clusterDataByNode.count), self->_uniqueIdentifier); + MTR_LOG("Loaded attribute values for %lu nodes from storage for controller uuid %@", static_cast(clusterDataByNode.count), self->_uniqueIdentifier); std::lock_guard lock(self->_deviceMapLock); for (NSNumber * nodeID in clusterDataByNode) { NSDictionary * clusterData = clusterDataByNode[nodeID]; MTRDevice * device = [self _setupDeviceForNodeID:nodeID prefetchedClusterData:clusterData]; - MTR_LOG_INFO("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), device); + MTR_LOG("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), device); } }]; } @@ -631,7 +638,7 @@ - (BOOL)setupCommissioningSessionWithPayload:(MTRSetupPayload *)payload newNodeID:(NSNumber *)newNodeID error:(NSError * __autoreleasing *)error { - MTR_LOG_DEFAULT("Setting up commissioning session for device ID 0x%016llX with setup payload %@", newNodeID.unsignedLongLongValue, payload); + MTR_LOG("Setting up commissioning session for device ID 0x%016llX with setup payload %@", newNodeID.unsignedLongLongValue, payload); [[MTRMetricsCollector sharedInstance] resetMetrics]; @@ -684,7 +691,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR newNodeID:(NSNumber *)newNodeID error:(NSError * __autoreleasing *)error { - MTR_LOG_DEFAULT("Setting up commissioning session for already-discovered device %@ and device ID 0x%016llX with setup payload %@", discoveredDevice, newNodeID.unsignedLongLongValue, payload); + MTR_LOG("Setting up commissioning session for already-discovered device %@ and device ID 0x%016llX with setup payload %@", discoveredDevice, newNodeID.unsignedLongLongValue, payload); [[MTRMetricsCollector sharedInstance] resetMetrics]; @@ -942,7 +949,7 @@ - (MTRBaseDevice *)deviceBeingCommissionedWithNodeID:(NSNumber *)nodeID error:(N }; MTRBaseDevice * device = [self syncRunOnWorkQueueWithReturnValue:block error:error]; - MTR_LOG_DEFAULT("Getting device being commissioned with node ID 0x%016llX: %@ (error: %@)", + MTR_LOG("Getting device being commissioned with node ID 0x%016llX: %@ (error: %@)", nodeID.unsignedLongLongValue, device, (error ? *error : nil)); return device; } @@ -973,7 +980,7 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N } else if (_controllerDataStore) { // Load persisted cluster data if they exist. NSDictionary * clusterData = [_controllerDataStore getStoredClusterDataForNodeID:nodeID]; - MTR_LOG_INFO("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), deviceToReturn); + MTR_LOG("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), deviceToReturn); if (clusterData.count) { [deviceToReturn setPersistedClusterData:clusterData]; } @@ -987,6 +994,8 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N } } + [deviceToReturn setStorageBehaviorConfiguration:_storageBehaviorConfiguration]; + return deviceToReturn; } @@ -1126,7 +1135,7 @@ - (BOOL)addServerEndpoint:(MTRServerEndpoint *)endpoint [self asyncDispatchToMatterQueue:^() { [self->_serverEndpoints addObject:endpoint]; [endpoint registerMatterEndpoint]; - MTR_LOG_DEFAULT("Added server endpoint %u to controller %@", static_cast(endpoint.endpointID.unsignedLongLongValue), + MTR_LOG("Added server endpoint %u to controller %@", static_cast(endpoint.endpointID.unsignedLongLongValue), self->_uniqueIdentifier); } errorHandler:^(NSError * error) { @@ -1154,7 +1163,7 @@ - (void)removeServerEndpointInternal:(MTRServerEndpoint *)endpoint queue:(dispat // tearing it down. [self asyncDispatchToMatterQueue:^() { [self removeServerEndpointOnMatterQueue:endpoint]; - MTR_LOG_DEFAULT("Removed server endpoint %u from controller %@", static_cast(endpoint.endpointID.unsignedLongLongValue), + MTR_LOG("Removed server endpoint %u from controller %@", static_cast(endpoint.endpointID.unsignedLongLongValue), self->_uniqueIdentifier); if (queue != nil && completion != nil) { dispatch_async(queue, completion); @@ -1162,7 +1171,7 @@ - (void)removeServerEndpointInternal:(MTRServerEndpoint *)endpoint queue:(dispat } errorHandler:^(NSError * error) { // Error means we got shut down, so the endpoint is removed now. - MTR_LOG_DEFAULT("controller %@ already shut down, so endpoint %u has already been removed", self->_uniqueIdentifier, + MTR_LOG("controller %@ already shut down, so endpoint %u has already been removed", self->_uniqueIdentifier, static_cast(endpoint.endpointID.unsignedLongLongValue)); if (queue != nil && completion != nil) { dispatch_async(queue, completion); @@ -1833,7 +1842,7 @@ - (MTRBaseDevice *)getDeviceBeingCommissioned:(uint64_t)deviceId error:(NSError - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error:(NSError * __autoreleasing *)error { if (duration > UINT16_MAX) { - MTR_LOG_ERROR("Error: Duration %tu is too large. Max value %d", duration, UINT16_MAX); + MTR_LOG_ERROR("Error: Duration %lu is too large. Max value %d", static_cast(duration), UINT16_MAX); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE]; } @@ -1859,7 +1868,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID error:(NSError * __autoreleasing *)error { if (duration > UINT16_MAX) { - MTR_LOG_ERROR("Error: Duration %tu is too large. Max value %d", duration, UINT16_MAX); + MTR_LOG_ERROR("Error: Duration %lu is too large. Max value %d", static_cast(duration), UINT16_MAX); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE]; } @@ -1867,7 +1876,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID } if (discriminator > 0xfff) { - MTR_LOG_ERROR("Error: Discriminator %tu is too large. Max value %d", discriminator, 0xfff); + MTR_LOG_ERROR("Error: Discriminator %lu is too large. Max value %d", static_cast(discriminator), 0xfff); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE]; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h index e0cf9d0a26028b..826fd1821f7640 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h @@ -76,6 +76,9 @@ typedef void (^MTRDeviceControllerDataStoreClusterDataHandler)(NSDictionary *)clusterData forNodeID:(NSNumber *)nodeID; - (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID; +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID; +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; +- (void)removeAttributes:(NSSet *)attributes fromCluster:(MTRClusterPath *)path forNodeID:(NSNumber *)nodeID; - (void)clearAllStoredClusterData; /** diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm index 7b65f8e963dfa3..d38712c00a5151 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm @@ -446,6 +446,23 @@ - (BOOL)_storeEndpointIndex:(NSArray *)endpointIndex forNodeID:(NSNu return [self _storeAttributeCacheValue:endpointIndex forKey:[self _endpointIndexKeyForNodeID:nodeID]]; } +- (BOOL)_removeEndpointFromEndpointIndex:(NSNumber *)endpointID forNodeID:(NSNumber *)nodeID +{ + dispatch_assert_queue(_storageDelegateQueue); + if (!endpointID || !nodeID) { + MTR_LOG_ERROR("%s: unexpected nil input", __func__); + return NO; + } + + NSMutableArray * endpointIndex = [[self _fetchEndpointIndexForNodeID:nodeID] mutableCopy]; + if (endpointIndex == nil) { + return NO; + } + + [endpointIndex removeObject:endpointID]; + return [self _storeEndpointIndex:endpointIndex forNodeID:nodeID]; +} + - (BOOL)_deleteEndpointIndexForNodeID:(NSNumber *)nodeID { dispatch_assert_queue(_storageDelegateQueue); @@ -597,7 +614,7 @@ - (void)_pruneEmptyStoredClusterDataBranches } if (!success) { storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredClusterDataBranches for clusterIndex (%lu) @ node 0x%016llX endpoint %u", static_cast(clusterIndexCopy.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); + MTR_LOG_ERROR("Store failed in _pruneEmptyStoredClusterDataBranches for clusterIndex (%lu) @ node 0x%016llX endpoint %u", static_cast(clusterIndexCopy.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); } } } @@ -612,7 +629,7 @@ - (void)_pruneEmptyStoredClusterDataBranches } if (!success) { storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredClusterDataBranches for endpointIndex (%lu) @ node 0x%016llX", static_cast(endpointIndexCopy.count), nodeID.unsignedLongLongValue); + MTR_LOG_ERROR("Store failed in _pruneEmptyStoredClusterDataBranches for endpointIndex (%lu) @ node 0x%016llX", static_cast(endpointIndexCopy.count), nodeID.unsignedLongLongValue); } } } @@ -626,7 +643,7 @@ - (void)_pruneEmptyStoredClusterDataBranches } if (!success) { storeFailures++; - MTR_LOG_INFO("Store failed in _pruneEmptyStoredClusterDataBranches for nodeIndex (%lu)", static_cast(nodeIndexCopy.count)); + MTR_LOG_ERROR("Store failed in _pruneEmptyStoredClusterDataBranches for nodeIndex (%lu)", static_cast(nodeIndexCopy.count)); } } @@ -656,7 +673,7 @@ - (void)_clearStoredClusterDataForNodeID:(NSNumber *)nodeID for (NSNumber * clusterID in clusterIndex) { BOOL success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; if (!success) { - MTR_LOG_INFO("Delete failed for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); + MTR_LOG_ERROR("Delete failed for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); } else { clusterDataCleared++; } @@ -664,7 +681,7 @@ - (void)_clearStoredClusterDataForNodeID:(NSNumber *)nodeID BOOL success = [self _deleteClusterIndexForNodeID:nodeID endpointID:endpointID]; if (!success) { - MTR_LOG_INFO("Delete failed for clusterIndex @ node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); + MTR_LOG_ERROR("Delete failed for clusterIndex @ node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); } else { endpointsCleared++; } @@ -672,10 +689,10 @@ - (void)_clearStoredClusterDataForNodeID:(NSNumber *)nodeID BOOL success = [self _deleteEndpointIndexForNodeID:nodeID]; if (!success) { - MTR_LOG_INFO("Delete failed for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); + MTR_LOG_ERROR("Delete failed for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); } - MTR_LOG_INFO("clearStoredClusterDataForNodeID: deleted endpoints %lu/%lu clusters %lu/%lu", static_cast(endpointsCleared), static_cast(endpointsClearAttempts), static_cast(clusterDataCleared), static_cast(clusterDataClearAttempts)); + MTR_LOG("clearStoredClusterDataForNodeID: deleted endpoints %lu/%lu clusters %lu/%lu", static_cast(endpointsCleared), static_cast(endpointsClearAttempts), static_cast(clusterDataCleared), static_cast(clusterDataClearAttempts)); } - (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID @@ -693,9 +710,79 @@ - (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID success = [self _deleteNodeIndex]; } if (!success) { - MTR_LOG_INFO("Store failed in clearStoredAttributesForNodeID for nodeIndex (%lu)", static_cast(nodeIndexCopy.count)); + MTR_LOG_ERROR("Store failed in clearStoredAttributesForNodeID for nodeIndex (%lu)", static_cast(nodeIndexCopy.count)); + } + } + }); +} + +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID +{ + dispatch_async(_storageDelegateQueue, ^{ + NSArray * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID]; + NSMutableArray * clusterIndexCopy = [clusterIndex mutableCopy]; + [clusterIndexCopy removeObject:clusterID]; + + BOOL success; + if (clusterIndexCopy.count != clusterIndex.count) { + success = [self _storeClusterIndex:clusterIndexCopy forNodeID:nodeID endpointID:endpointID]; + if (!success) { + MTR_LOG_ERROR("clearStoredClusterDataForNodeID: _storeClusterIndex failed for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); } } + + success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; + if (!success) { + MTR_LOG_ERROR("clearStoredClusterDataForNodeID: _deleteClusterDataForNodeID failed for node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); + return; + } + + MTR_LOG("clearStoredClusterDataForNodeID: Deleted endpoint %u cluster 0x%08lX for node 0x%016llX successfully", endpointID.unsignedShortValue, clusterID.unsignedLongValue, nodeID.unsignedLongLongValue); + }); +} + +- (void)clearStoredClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID +{ + dispatch_async(_storageDelegateQueue, ^{ + BOOL success = [self _removeEndpointFromEndpointIndex:endpointID forNodeID:nodeID]; + if (!success) { + MTR_LOG_ERROR("removeEndpointFromEndpointIndex for endpointID %u failed for node 0x%016llX", endpointID.unsignedShortValue, nodeID.unsignedLongLongValue); + } + + NSArray * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID]; + + for (NSNumber * cluster in clusterIndex) { + success = [self _deleteClusterDataForNodeID:nodeID endpointID:endpointID clusterID:cluster]; + if (!success) { + MTR_LOG_ERROR("Delete failed for clusterData for node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, cluster.unsignedLongValue); + } + } + + success = [self _deleteClusterIndexForNodeID:nodeID endpointID:endpointID]; + if (!success) { + MTR_LOG_ERROR("Delete failed for clusterIndex for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); + } + + MTR_LOG("clearStoredClusterDataForNodeID: Deleted endpoint %u for node 0x%016llX successfully", endpointID.unsignedShortValue, nodeID.unsignedLongLongValue); + }); +} + +- (void)removeAttributes:(NSSet *)attributes fromCluster:(MTRClusterPath *)path forNodeID:(NSNumber *)nodeID +{ + MTRDeviceClusterData * clusterData = [self getStoredClusterDataForNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster]; + if (clusterData == nil) { + return; + } + for (NSNumber * attribute in attributes) { + [clusterData removeValueForAttribute:attribute]; + } + + dispatch_async(_storageDelegateQueue, ^{ + BOOL success = [self _storeClusterData:clusterData forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster]; + if (!success) { + MTR_LOG_ERROR("removeAttributes: _storeClusterData failed for node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue); + } + MTR_LOG("removeAttributes: Deleted attributes %@ from endpoint %u cluster 0x%08lX for node 0x%016llX successfully", attributes, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue, nodeID.unsignedLongLongValue); }); } @@ -711,7 +798,7 @@ - (void)clearAllStoredClusterData BOOL success = [self _deleteNodeIndex]; if (!success) { - MTR_LOG_INFO("Delete failed for nodeIndex"); + MTR_LOG_ERROR("Delete failed for nodeIndex"); } }); } @@ -729,7 +816,7 @@ - (void)clearAllStoredClusterData NSArray * nodeIndex = [self _fetchNodeIndex]; #if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for nodeIndex", static_cast(nodeIndex.count)); + MTR_LOG("Fetch got %lu values for nodeIndex", static_cast(nodeIndex.count)); #endif if (![nodeIndex containsObject:nodeID]) { @@ -743,7 +830,7 @@ - (void)clearAllStoredClusterData [self _clearStoredClusterDataForNodeID:nodeID]; } - MTR_LOG_INFO("Fetch got no value for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); + MTR_LOG("Fetch got no value for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); clusterDataToReturn = nil; return; } @@ -752,7 +839,7 @@ - (void)clearAllStoredClusterData NSArray * endpointIndex = [self _fetchEndpointIndexForNodeID:nodeID]; #if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for endpointIndex @ node 0x%016llX", static_cast(endpointIndex.count), nodeID.unsignedLongLongValue); + MTR_LOG("Fetch got %lu values for endpointIndex @ node 0x%016llX", static_cast(endpointIndex.count), nodeID.unsignedLongLongValue); #endif for (NSNumber * endpointID in endpointIndex) { @@ -760,19 +847,19 @@ - (void)clearAllStoredClusterData NSArray * clusterIndex = [self _fetchClusterIndexForNodeID:nodeID endpointID:endpointID]; #if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got %lu values for clusterIndex @ node 0x%016llX %u", static_cast(clusterIndex.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); + MTR_LOG("Fetch got %lu values for clusterIndex @ node 0x%016llX %u", static_cast(clusterIndex.count), nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); #endif for (NSNumber * clusterID in clusterIndex) { // Fetch cluster data MTRDeviceClusterData * clusterData = [self _fetchClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; if (!clusterData) { - MTR_LOG_INFO("Fetch got no value for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); + MTR_LOG("Fetch got no value for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); continue; } #if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Fetch got clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); + MTR_LOG("Fetch got clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue, clusterID.unsignedLongValue); #endif MTRClusterPath * path = [MTRClusterPath clusterPathWithEndpointID:endpointID clusterID:clusterID]; @@ -896,7 +983,7 @@ - (void)storeClusterData:(NSDictionary for (MTRClusterPath * path in clusterData) { MTRDeviceClusterData * data = clusterData[path]; #if ATTRIBUTE_CACHE_VERBOSE_LOGGING - MTR_LOG_INFO("Attempt to store clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue); + MTR_LOG("Attempt to store clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue); #endif if (bulkValuesToStore) { @@ -906,7 +993,7 @@ - (void)storeClusterData:(NSDictionary BOOL storeFailed = ![self _storeClusterData:data forNodeID:nodeID endpointID:path.endpoint clusterID:path.cluster]; if (storeFailed) { storeFailures++; - MTR_LOG_INFO("Store failed for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue); + MTR_LOG_ERROR("Store failed for clusterData @ node 0x%016llX endpoint %u cluster 0x%08lX", nodeID.unsignedLongLongValue, path.endpoint.unsignedShortValue, path.cluster.unsignedLongValue); } } @@ -962,7 +1049,7 @@ - (void)storeClusterData:(NSDictionary BOOL storeFailed = ![self _storeClusterIndex:clusterIndexToStore forNodeID:nodeID endpointID:endpointID]; if (storeFailed) { storeFailures++; - MTR_LOG_INFO("Store failed for clusterIndex @ node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); + MTR_LOG_ERROR("Store failed for clusterIndex @ node 0x%016llX endpoint %u", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); continue; } } @@ -977,7 +1064,7 @@ - (void)storeClusterData:(NSDictionary BOOL storeFailed = ![self _storeEndpointIndex:endpointIndexToStore forNodeID:nodeID]; if (storeFailed) { storeFailures++; - MTR_LOG_INFO("Store failed for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); + MTR_LOG_ERROR("Store failed for endpointIndex @ node 0x%016llX", nodeID.unsignedLongLongValue); } } } @@ -999,7 +1086,7 @@ - (void)storeClusterData:(NSDictionary BOOL storeFailed = ![self _storeNodeIndex:nodeIndexToStore]; if (storeFailed) { storeFailures++; - MTR_LOG_INFO("Store failed for nodeIndex"); + MTR_LOG_ERROR("Store failed for nodeIndex"); } } } @@ -1008,7 +1095,7 @@ - (void)storeClusterData:(NSDictionary BOOL storeFailed = ![self _bulkStoreAttributeCacheValues:bulkValuesToStore]; if (storeFailed) { storeFailures++; - MTR_LOG_INFO("Store failed for bulk values count %lu", static_cast(bulkValuesToStore.count)); + MTR_LOG_ERROR("Store failed for bulk values count %lu", static_cast(bulkValuesToStore.count)); } } diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm index 4c50f7fd2a7fa4..5972b17de804e2 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm @@ -62,7 +62,7 @@ void MTRDeviceControllerDelegateBridge::OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) { - MTR_LOG_DEFAULT("DeviceControllerDelegate status updated: %d", status); + MTR_LOG("DeviceControllerDelegate status updated: %d", status); // If pairing failed, PASE failed. However, since OnPairingComplete(failure_code) might not be invoked in all cases, mark // end of PASE with timeout as assumed failure. If OnPairingComplete is invoked, the right error code will be updated in @@ -94,7 +94,7 @@ void MTRDeviceControllerDelegateBridge::OnPairingComplete(CHIP_ERROR error) { if (error == CHIP_NO_ERROR) { - MTR_LOG_DEFAULT("MTRDeviceControllerDelegate PASE session establishment succeeded."); + MTR_LOG("MTRDeviceControllerDelegate PASE session establishment succeeded."); } else { MTR_LOG_ERROR("MTRDeviceControllerDelegate PASE session establishment failed: %" CHIP_ERROR_FORMAT, error.Format()); } @@ -114,7 +114,7 @@ void MTRDeviceControllerDelegateBridge::OnPairingDeleted(CHIP_ERROR error) { - MTR_LOG_DEFAULT("DeviceControllerDelegate Pairing deleted. Status %s", chip::ErrorStr(error)); + MTR_LOG("DeviceControllerDelegate Pairing deleted. Status %s", chip::ErrorStr(error)); // This is never actually called; just do nothing. } @@ -124,7 +124,7 @@ chip::VendorId vendorId = info.basic.vendorId; uint16_t productId = info.basic.productId; - MTR_LOG_DEFAULT("DeviceControllerDelegate Read Commissioning Info. VendorId %u ProductId %u", vendorId, productId); + MTR_LOG("DeviceControllerDelegate Read Commissioning Info. VendorId %u ProductId %u", vendorId, productId); id strongDelegate = mDelegate; MTRDeviceController * strongController = mController; @@ -140,7 +140,7 @@ void MTRDeviceControllerDelegateBridge::OnCommissioningComplete(chip::NodeId nodeId, CHIP_ERROR error) { - MTR_LOG_DEFAULT("DeviceControllerDelegate Commissioning complete. NodeId %llu Status %s", nodeId, chip::ErrorStr(error)); + MTR_LOG("DeviceControllerDelegate Commissioning complete. NodeId %llu Status %s", nodeId, chip::ErrorStr(error)); MATTER_LOG_METRIC_END(kMetricDeviceCommissioning, error); id strongDelegate = mDelegate; @@ -149,7 +149,7 @@ // Always collect the metrics to avoid unbounded growth of the stats in the collector MTRMetrics * metrics = [[MTRMetricsCollector sharedInstance] metricSnapshot:TRUE]; - MTR_LOG_INFO("Device commissioning complete with metrics %@", metrics); + MTR_LOG("Device commissioning complete with metrics %@", metrics); if ([strongDelegate respondsToSelector:@selector(controller:commissioningComplete:nodeID:)] || [strongDelegate respondsToSelector:@selector(controller:commissioningComplete:nodeID:metrics:)]) { diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 0ca254acb34115..662a228bdd994e 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -72,7 +72,7 @@ static bool sExitHandlerRegistered = false; static void ShutdownOnExit() { - MTR_LOG_INFO("ShutdownOnExit invoked on exit"); + MTR_LOG("ShutdownOnExit invoked on exit"); [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory]; } @@ -239,7 +239,7 @@ - (void)_assertCurrentQueueIsNotMatterQueue - (void)cleanupStartupObjects { assertChipStackLockedByCurrentThread(); - MTR_LOG_INFO("Cleaning startup objects in controller factory"); + MTR_LOG("Cleaning startup objects in controller factory"); // Make sure the deinit order here is the reverse of the init order in // startControllerFactory: @@ -441,7 +441,7 @@ - (void)stopControllerFactory dispatch_sync(_chipWorkQueue, ^{ VerifyOrReturn(_running); - MTR_LOG_INFO("Shutting down the Matter controller factory"); + MTR_LOG("Shutting down the Matter controller factory"); _controllerFactory->Shutdown(); [self cleanupStartupObjects]; _running = NO; @@ -473,6 +473,7 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController * id _Nullable otaProviderDelegate; dispatch_queue_t _Nullable otaProviderDelegateQueue; NSUInteger concurrentSubscriptionPoolSize = 0; + MTRDeviceStorageBehaviorConfiguration * storageBehaviorConfiguration = nil; if ([startupParams isKindOfClass:[MTRDeviceControllerParameters class]]) { MTRDeviceControllerParameters * params = startupParams; storageDelegate = params.storageDelegate; @@ -481,6 +482,7 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController * otaProviderDelegate = params.otaProviderDelegate; otaProviderDelegateQueue = params.otaProviderDelegateQueue; concurrentSubscriptionPoolSize = params.concurrentSubscriptionEstablishmentsAllowedOnThread; + storageBehaviorConfiguration = params.storageBehaviorConfiguration; } else if ([startupParams isKindOfClass:[MTRDeviceControllerStartupParams class]]) { MTRDeviceControllerStartupParams * params = startupParams; storageDelegate = nil; @@ -498,7 +500,7 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController * if (!_running) { // Note: reading _running from outside of the Matter work queue if (storageDelegate != nil) { - MTR_LOG_DEFAULT("Auto-starting Matter controller factory in per-controller storage mode"); + MTR_LOG("Auto-starting Matter controller factory in per-controller storage mode"); auto * params = [[MTRDeviceControllerFactoryParams alloc] initWithoutStorage]; if (![self _startControllerFactory:params startingController:YES error:error]) { return nil; @@ -542,7 +544,8 @@ - (MTRDeviceController * _Nullable)_startDeviceController:(MTRDeviceController * otaProviderDelegate:otaProviderDelegate otaProviderDelegateQueue:otaProviderDelegateQueue uniqueIdentifier:uniqueIdentifier - concurrentSubscriptionPoolSize:concurrentSubscriptionPoolSize]; + concurrentSubscriptionPoolSize:concurrentSubscriptionPoolSize + storageBehaviorConfiguration:storageBehaviorConfiguration]; if (controller == nil) { if (error != nil) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]; @@ -766,7 +769,7 @@ - (void)preWarmCommissioningSession if (!self->_running) { MTR_LOG_ERROR("Can't pre-warm, Matter controller factory is not running"); } else { - MTR_LOG_DEFAULT("Pre-warming commissioning session"); + MTR_LOG("Pre-warming commissioning session"); self->_controllerFactory->EnsureAndRetainSystemState(); err = DeviceLayer::PlatformMgrImpl().StartBleScan(&self->_preWarmingDelegate, DeviceLayer::BleScanMode::kPreWarm); if (err != CHIP_NO_ERROR) { @@ -781,7 +784,7 @@ - (void)preWarmCommissioningSession - (void)preWarmCommissioningSessionDone { assertChipStackLockedByCurrentThread(); - MTR_LOG_DEFAULT("Pre-warming done"); + MTR_LOG("Pre-warming done"); self->_controllerFactory->ReleaseSystemState(); } @@ -881,24 +884,21 @@ - (MTRDeviceController * _Nullable)maybeInitializeOTAProvider:(MTRDeviceControll - (void)resetOperationalAdvertising { - if (!_advertiseOperational) { - // No need to reset anything; we are not advertising the things that - // would need to get reset. - return; - } + assertChipStackLockedByCurrentThread(); - std::lock_guard lock(_controllersLock); - if (_controllers.count != 0) { - // We have a running controller. That means we likely need to reset - // operational advertising for that controller. - dispatch_async(_chipWorkQueue, ^{ - // StartServer() is the only API we have for resetting DNS-SD - // advertising. It sure would be nice if there were a "restart" - // that was a no-op if the DNS-SD server was not already - // running. - app::DnssdServer::Instance().StartServer(); - }); + // If we're not advertising, then there's no need to reset anything. + VerifyOrReturn(_advertiseOperational); + + // If there are no running controllers there will be no advertisements to reset. + { + std::lock_guard lock(_controllersLock); + VerifyOrReturn(_controllers.count > 0); } + + // StartServer() is the only API we have for resetting DNS-SD advertising. + // It sure would be nice if there were a "restart" that was a no-op if the + // DNS-SD server was not already running. + app::DnssdServer::Instance().StartServer(); } - (void)controllerShuttingDown:(MTRDeviceController *)controller @@ -1165,6 +1165,45 @@ - (MTRDeviceController * _Nullable)initializeController:(MTRDeviceController *)c error:error]; } +- (void)setMessageReliabilityProtocolIdleRetransmitMs:(nullable NSNumber *)idleRetransmitMs + activeRetransmitMs:(nullable NSNumber *)activeRetransmitMs + activeThresholdMs:(nullable NSNumber *)activeThresholdMs + additionalRetransmitDelayMs:(nullable NSNumber *)additionalRetransmitDelayMs +{ + [self _assertCurrentQueueIsNotMatterQueue]; + dispatch_async(_chipWorkQueue, ^{ + bool resetAdvertising; + if (idleRetransmitMs == nil && activeRetransmitMs == nil && activeThresholdMs == nil && additionalRetransmitDelayMs == nil) { + Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional); + resetAdvertising = ReliableMessageProtocolConfig::SetLocalMRPConfig(NullOptional); + } else { + if (additionalRetransmitDelayMs != nil) { + System::Clock::Timeout additionalBackoff(additionalRetransmitDelayMs.unsignedLongValue); + Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(additionalBackoff)); + } + + // Get current MRP parameters, then override the things we were asked to + // override. + ReliableMessageProtocolConfig mrpConfig = GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()); + if (idleRetransmitMs != nil) { + mrpConfig.mIdleRetransTimeout = System::Clock::Milliseconds32(idleRetransmitMs.unsignedLongValue); + } + if (activeRetransmitMs != nil) { + mrpConfig.mActiveRetransTimeout = System::Clock::Milliseconds32(activeRetransmitMs.unsignedLongValue); + } + if (activeThresholdMs != nil) { + mrpConfig.mActiveThresholdTime = System::Clock::Milliseconds32(activeThresholdMs.unsignedLongValue); + } + + resetAdvertising = ReliableMessageProtocolConfig::SetLocalMRPConfig(MakeOptional(mrpConfig)); + } + + if (resetAdvertising) { + [self resetOperationalAdvertising]; + } + }); +} + - (PersistentStorageDelegate *)storageDelegate { return _persistentStorageDelegate; @@ -1327,33 +1366,8 @@ void MTRSetMessageReliabilityParameters(NSNumber * _Nullable idleRetransmitMs, NSNumber * _Nullable activeThresholdMs, NSNumber * _Nullable additionalRetransmitDelayMs) { - bool resetAdvertising = false; - if (idleRetransmitMs == nil && activeRetransmitMs == nil && activeThresholdMs == nil && additionalRetransmitDelayMs == nil) { - Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional); - resetAdvertising = ReliableMessageProtocolConfig::SetLocalMRPConfig(NullOptional); - } else { - if (additionalRetransmitDelayMs != nil) { - System::Clock::Timeout additionalBackoff(additionalRetransmitDelayMs.unsignedLongValue); - Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(additionalBackoff)); - } - - // Get current MRP parameters, then override the things we were asked to - // override. - ReliableMessageProtocolConfig mrpConfig = GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()); - if (idleRetransmitMs != nil) { - mrpConfig.mIdleRetransTimeout = System::Clock::Milliseconds32(idleRetransmitMs.unsignedLongValue); - } - if (activeRetransmitMs != nil) { - mrpConfig.mActiveRetransTimeout = System::Clock::Milliseconds32(activeRetransmitMs.unsignedLongValue); - } - if (activeThresholdMs != nil) { - mrpConfig.mActiveThresholdTime = System::Clock::Milliseconds32(activeThresholdMs.unsignedLongValue); - } - - resetAdvertising = ReliableMessageProtocolConfig::SetLocalMRPConfig(MakeOptional(mrpConfig)); - } - - if (resetAdvertising) { - [[MTRDeviceControllerFactory sharedInstance] resetOperationalAdvertising]; - } + [MTRDeviceControllerFactory.sharedInstance setMessageReliabilityProtocolIdleRetransmitMs:idleRetransmitMs + activeRetransmitMs:activeThresholdMs + activeThresholdMs:activeThresholdMs + additionalRetransmitDelayMs:additionalRetransmitDelayMs]; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.mm index f51dae7bbbcaff..fa4a0e456f5626 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.mm @@ -16,27 +16,25 @@ */ #import "MTRDeviceControllerLocalTestStorage.h" +#import "MTRDevice_Internal.h" #import "MTRLogging_Internal.h" -static NSString * const kLocalTestUserDefaultDomain = @"org.csa-iot.matter.darwintest"; -static NSString * const kLocalTestUserDefaultEnabledKey = @"enableTestStorage"; - @implementation MTRDeviceControllerLocalTestStorage { id _passThroughStorage; } + (BOOL)localTestStorageEnabled { - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; - return [defaults boolForKey:kLocalTestUserDefaultEnabledKey]; + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; + return [defaults boolForKey:kTestStorageUserDefaultEnabledKey]; } + (void)setLocalTestStorageEnabled:(BOOL)localTestStorageEnabled { - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; - [defaults setBool:localTestStorageEnabled forKey:kLocalTestUserDefaultEnabledKey]; - MTR_LOG_INFO("MTRDeviceControllerLocalTestStorage setLocalTestStorageEnabled %d", localTestStorageEnabled); - BOOL storedLocalTestStorageEnabled = [defaults boolForKey:kLocalTestUserDefaultEnabledKey]; + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; + [defaults setBool:localTestStorageEnabled forKey:kTestStorageUserDefaultEnabledKey]; + MTR_LOG("MTRDeviceControllerLocalTestStorage setLocalTestStorageEnabled %d", localTestStorageEnabled); + BOOL storedLocalTestStorageEnabled = [defaults boolForKey:kTestStorageUserDefaultEnabledKey]; if (storedLocalTestStorageEnabled != localTestStorageEnabled) { MTR_LOG_ERROR("MTRDeviceControllerLocalTestStorage setLocalTestStorageEnabled %d failed", localTestStorageEnabled); } @@ -47,7 +45,7 @@ - (instancetype)initWithPassThroughStorage:(id> *)valuesForController:(MTRDeviceController *)controller securityLevel:(MTRStorageSecurityLevel)securityLevel sharingType:(MTRStorageSharingType)sharingType { if (sharingType == MTRStorageSharingTypeNotShared) { - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; return [defaults dictionaryRepresentation]; } else { if (_passThroughStorage && [_passThroughStorage respondsToSelector:@selector(valuesForController:securityLevel:sharingType:)]) { return [_passThroughStorage valuesForController:controller securityLevel:securityLevel sharingType:sharingType]; } else { - MTR_LOG_INFO("MTRDeviceControllerLocalTestStorage valuesForController: shared type but no pass-through storage"); + MTR_LOG_ERROR("MTRDeviceControllerLocalTestStorage valuesForController: shared type but no pass-through storage"); return nil; } } @@ -136,13 +134,13 @@ - (BOOL)controller:(MTRDeviceController *)controller - (BOOL)controller:(MTRDeviceController *)controller storeValues:(NSDictionary> *)values securityLevel:(MTRStorageSecurityLevel)securityLevel sharingType:(MTRStorageSharingType)sharingType { if (sharingType == MTRStorageSharingTypeNotShared) { - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; BOOL success = YES; for (NSString * key in values) { NSError * error = nil; NSData * data = [NSKeyedArchiver archivedDataWithRootObject:values[key] requiringSecureCoding:YES error:&error]; if (error) { - MTR_LOG_INFO("MTRDeviceControllerLocalTestStorage storeValues: failed to convert value object to data %@", error); + MTR_LOG_ERROR("MTRDeviceControllerLocalTestStorage storeValues: failed to convert value object to data %@", error); success = NO; continue; } @@ -153,7 +151,7 @@ - (BOOL)controller:(MTRDeviceController *)controller storeValues:(NSDictionary #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -85,6 +86,13 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) */ @property (nonatomic, assign) NSUInteger concurrentSubscriptionEstablishmentsAllowedOnThread MTR_NEWLY_AVAILABLE; +/** + * Sets the storage behavior configuration - see MTRDeviceStorageBehaviorConfiguration.h for details + * + * If this value is nil, a default storage behavior configuration will be used. + */ +@property (nonatomic, copy, nullable) MTRDeviceStorageBehaviorConfiguration * storageBehaviorConfiguration; + @end MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm index a97bae4ece6c6c..f393d48d0a99c1 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm @@ -614,7 +614,7 @@ - (instancetype)initForNewController:(MTRDeviceController *)controller // Our NOC has changed in a way that would affect ACL checks. Clear // out our session resumption storage, because resuming those CASE // sessions will end up doing ACL checks against our old NOC. - MTR_LOG_DEFAULT("Node ID or CATs changed. Clearing CASE resumption storage."); + MTR_LOG("Node ID or CATs changed. Clearing CASE resumption storage."); [controller.controllerDataStore clearAllResumptionInfo]; } } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h index 8aefa481ba7616..8fb61fba9bab80 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h @@ -32,6 +32,7 @@ #import "MTRBaseDevice.h" #import "MTRDeviceController.h" #import "MTRDeviceControllerDataStore.h" +#import "MTRDeviceStorageBehaviorConfiguration.h" #import #import @@ -113,7 +114,8 @@ NS_ASSUME_NONNULL_BEGIN otaProviderDelegate:(id _Nullable)otaProviderDelegate otaProviderDelegateQueue:(dispatch_queue_t _Nullable)otaProviderDelegateQueue uniqueIdentifier:(NSUUID *)uniqueIdentifier - concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize; + concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize + storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; /** * Check whether this controller is running on the given fabric, as represented diff --git a/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.h b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.h new file mode 100644 index 00000000000000..30ea957cd3987d --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Class that configures how MTRDevice objects persist its attributes to storage, so as to not + * overwhelm the underlying storage system. + */ +MTR_NEWLY_AVAILABLE +@interface MTRDeviceStorageBehaviorConfiguration : NSObject + +/** + * Create configuration with a default set of values. See description below for details. + */ ++ (instancetype)configurationWithDefaultStorageBehavior; + +/** + * Create configuration that disables storage behavior optimizations. + */ ++ (instancetype)configurationWithStorageBehaviorOptimizationDisabled; + +/** + * Create configuration with specified values. See description below for details, and the list of + * properties below for valid ranges of these values. + */ ++ (instancetype)configurationWithReportToPersistenceDelayTime:(NSTimeInterval)reportToPersistenceDelayTime + reportToPersistenceDelayTimeMax:(NSTimeInterval)reportToPersistenceDelayTimeMax + recentReportTimesMaxCount:(NSUInteger)recentReportTimesMaxCount + timeBetweenReportsTooShortThreshold:(NSTimeInterval)timeBetweenReportsTooShortThreshold + timeBetweenReportsTooShortMinThreshold:(NSTimeInterval)timeBetweenReportsTooShortMinThreshold + reportToPersistenceDelayMaxMultiplier:(double)reportToPersistenceDelayMaxMultiplier + deviceReportingExcessivelyIntervalThreshold:(NSTimeInterval)deviceReportingExcessivelyIntervalThreshold; + +/** + * Storage behavior with values in the allowed range: + * + * Each time a report comes in, MTRDevice will wait reportToPersistDelayTime before persisting the + * changes to storage. If another report comes in during this internal, MTRDevice will wait another + * reportToPersistDelayTime interval, until reportToPersistDelayTimeMax is reached, at which + * point all the changes so far will be written to storage. + * + * MTRDevice will also track recentReportTimesMaxCount number of report times. If the running + * average time between reports dips below timeBetweenReportsTooShortThreshold, a portion of the + * reportToPersistenceDelayMaxMultiplier will be applied to both the reportToPersistenceDelayTime + * and reportToPersistenceDelayTimeMax. The multiplier will reach the max when the average time + * between reports reach timeBetweenReportsTooShortMinThreshold. + * + * When the running average time between reports dips below timeBetweenReportsTooShortMinThreshold + * for the first time, the time will be noted. If the device remains in this state for longer than + * deviceReportingExcessivelyIntervalThreshold, persistence will stop until the average time between + * reports go back above timeBetweenReportsTooShortMinThreshold. + */ + +/** + * If disableStorageBehaviorOptimization is set to YES, then all the waiting mechanism as described above + * is disabled. + */ +@property (nonatomic, assign) BOOL disableStorageBehaviorOptimization; + +/** + * If any of these properties are set to be out of the documented limits, these default values will + * be used to replace all of them: + * + * reportToPersistenceDelayTimeDefault (15) + * reportToPersistenceDelayTimeMaxDefault (20 * kReportToPersistenceDelayTimeDefault) + * recentReportTimesMaxCountDefault (12) + * timeBetweenReportsTooShortThresholdDefault (15) + * timeBetweenReportsTooShortMinThresholdDefault (5) + * reportToPersistenceDelayMaxMultiplierDefault (10) + * deviceReportingExcessivelyIntervalThresholdDefault (5 * 60) + */ +@property (nonatomic, assign) NSTimeInterval reportToPersistenceDelayTime; /* must be > 0 */ +@property (nonatomic, assign) NSTimeInterval reportToPersistenceDelayTimeMax; /* must be larger than reportToPersistenceDelayTime */ +@property (nonatomic, assign) NSUInteger recentReportTimesMaxCount; /* must be >= 2 */ +@property (nonatomic, assign) NSTimeInterval timeBetweenReportsTooShortThreshold; /* must be > 0 */ +@property (nonatomic, assign) NSTimeInterval timeBetweenReportsTooShortMinThreshold; /* must be > 0 and smaller than timeBetweenReportsTooShortThreshold */ +@property (nonatomic, assign) double reportToPersistenceDelayMaxMultiplier; /* must be > 1 */ +@property (nonatomic, assign) NSTimeInterval deviceReportingExcessivelyIntervalThreshold; /* must be > 0 */ +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm new file mode 100644 index 00000000000000..4522c7e69b4ad6 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm @@ -0,0 +1,105 @@ +/** + * 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 "MTRDeviceStorageBehaviorConfiguration.h" + +#import "MTRLogging_Internal.h" + +#define kReportToPersistenceDelayTimeDefault (15) +#define kReportToPersistenceDelayTimeMaxDefault (20 * kReportToPersistenceDelayTimeDefault) +#define kRecentReportTimesMaxCountDefault (12) +#define kTimeBetweenReportsTooShortThresholdDefault (15) +#define kTimeBetweenReportsTooShortMinThresholdDefault (5) +#define kReportToPersistenceDelayMaxMultiplierDefault (10) +#define kDeviceReportingExcessivelyIntervalThresholdDefault (5 * 60) + +@implementation MTRDeviceStorageBehaviorConfiguration + ++ (instancetype)configurationWithReportToPersistenceDelayTime:(NSTimeInterval)reportToPersistenceDelayTime + reportToPersistenceDelayTimeMax:(NSTimeInterval)reportToPersistenceDelayTimeMax + recentReportTimesMaxCount:(NSUInteger)recentReportTimesMaxCount + timeBetweenReportsTooShortThreshold:(NSTimeInterval)timeBetweenReportsTooShortThreshold + timeBetweenReportsTooShortMinThreshold:(NSTimeInterval)timeBetweenReportsTooShortMinThreshold + reportToPersistenceDelayMaxMultiplier:(double)reportToPersistenceDelayMaxMultiplier + deviceReportingExcessivelyIntervalThreshold:(NSTimeInterval)deviceReportingExcessivelyIntervalThreshold +{ + auto newConfiguration = [[MTRDeviceStorageBehaviorConfiguration alloc] init]; + newConfiguration.reportToPersistenceDelayTime = reportToPersistenceDelayTime; + newConfiguration.reportToPersistenceDelayTimeMax = reportToPersistenceDelayTimeMax; + newConfiguration.recentReportTimesMaxCount = recentReportTimesMaxCount; + newConfiguration.timeBetweenReportsTooShortThreshold = timeBetweenReportsTooShortThreshold; + newConfiguration.timeBetweenReportsTooShortMinThreshold = timeBetweenReportsTooShortMinThreshold; + newConfiguration.reportToPersistenceDelayMaxMultiplier = reportToPersistenceDelayMaxMultiplier; + newConfiguration.deviceReportingExcessivelyIntervalThreshold = deviceReportingExcessivelyIntervalThreshold; + + return newConfiguration; +} + ++ (instancetype)configurationWithDefaultStorageBehavior +{ + auto newConfiguration = [[MTRDeviceStorageBehaviorConfiguration alloc] init]; + [newConfiguration checkValuesAndResetToDefaultIfNecessary]; + return newConfiguration; +} + ++ (instancetype)configurationWithStorageBehaviorOptimizationDisabled +{ + auto newConfiguration = [[MTRDeviceStorageBehaviorConfiguration alloc] init]; + newConfiguration.disableStorageBehaviorOptimization = YES; + return newConfiguration; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"(_recentReportTimesMaxCount), _timeBetweenReportsTooShortThreshold, _timeBetweenReportsTooShortMinThreshold, _reportToPersistenceDelayMaxMultiplier, _deviceReportingExcessivelyIntervalThreshold]; +} + +- (void)checkValuesAndResetToDefaultIfNecessary +{ + if (_disableStorageBehaviorOptimization) { + return; + } + + // Sanity check all the values, and if any is out of range, reset to default values + if ((_reportToPersistenceDelayTime <= 0) || (_reportToPersistenceDelayTimeMax <= 0) || (_reportToPersistenceDelayTimeMax < _reportToPersistenceDelayTime) || (_recentReportTimesMaxCount < 2) || (_timeBetweenReportsTooShortThreshold <= 0) || (_timeBetweenReportsTooShortMinThreshold <= 0) || (_timeBetweenReportsTooShortMinThreshold > _timeBetweenReportsTooShortThreshold) || (_reportToPersistenceDelayMaxMultiplier <= 1) || (_deviceReportingExcessivelyIntervalThreshold <= 0)) { + MTR_LOG_ERROR("%@ storage behavior: MTRDeviceStorageBehaviorConfiguration values out of bounds - resetting to default", self); + + _reportToPersistenceDelayTime = kReportToPersistenceDelayTimeDefault; + _reportToPersistenceDelayTimeMax = kReportToPersistenceDelayTimeMaxDefault; + _recentReportTimesMaxCount = kRecentReportTimesMaxCountDefault; + _timeBetweenReportsTooShortThreshold = kTimeBetweenReportsTooShortThresholdDefault; + _timeBetweenReportsTooShortMinThreshold = kTimeBetweenReportsTooShortMinThresholdDefault; + _reportToPersistenceDelayMaxMultiplier = kReportToPersistenceDelayMaxMultiplierDefault; + _deviceReportingExcessivelyIntervalThreshold = kDeviceReportingExcessivelyIntervalThresholdDefault; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + auto newConfiguration = [[MTRDeviceStorageBehaviorConfiguration alloc] init]; + newConfiguration.disableStorageBehaviorOptimization = _disableStorageBehaviorOptimization; + newConfiguration.reportToPersistenceDelayTime = _reportToPersistenceDelayTime; + newConfiguration.reportToPersistenceDelayTimeMax = _reportToPersistenceDelayTimeMax; + newConfiguration.recentReportTimesMaxCount = _recentReportTimesMaxCount; + newConfiguration.timeBetweenReportsTooShortThreshold = _timeBetweenReportsTooShortThreshold; + newConfiguration.timeBetweenReportsTooShortMinThreshold = _timeBetweenReportsTooShortMinThreshold; + newConfiguration.reportToPersistenceDelayMaxMultiplier = _reportToPersistenceDelayMaxMultiplier; + newConfiguration.deviceReportingExcessivelyIntervalThreshold = _deviceReportingExcessivelyIntervalThreshold; + + return newConfiguration; +} + +@end diff --git a/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration_Internal.h new file mode 100644 index 00000000000000..f3c8cf992f7bbc --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration_Internal.h @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRDeviceStorageBehaviorConfiguration.h" + +@interface MTRDeviceStorageBehaviorConfiguration () +- (void)checkValuesAndResetToDefaultIfNecessary; +@end diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 04313a6d555db2..2ad2f6422dd9e7 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -21,6 +21,7 @@ #import "MTRAsyncWorkQueue.h" #import "MTRDefines_Internal.h" +#import "MTRDeviceStorageBehaviorConfiguration_Internal.h" NS_ASSUME_NONNULL_BEGIN @@ -30,6 +31,26 @@ typedef NSDictionary * MTRDeviceDataValueDictionary; typedef void (^MTRDevicePerformAsyncBlock)(MTRBaseDevice * baseDevice); +typedef NS_ENUM(NSUInteger, MTRInternalDeviceState) { + // Unsubscribed means we do not have a subscription and are not trying to set one up. + MTRInternalDeviceStateUnsubscribed = 0, + // Subscribing means we are actively trying to establish our initial subscription (e.g. doing + // DNS-SD discovery, trying to establish CASE to the peer, getting priming reports, etc). + MTRInternalDeviceStateSubscribing = 1, + // InitialSubscriptionEstablished means we have at some point finished setting up a + // subscription. That subscription may have dropped since then, but if so it's the ReadClient's + // responsibility to re-establish it. + MTRInternalDeviceStateInitialSubscriptionEstablished = 2, + // Resubscribing means we had established a subscription, but then + // detected a subscription drop due to not receiving a report on time. This + // covers all the actions that happen when re-subscribing (discovery, CASE, + // getting priming reports, etc). + MTRInternalDeviceStateResubscribing = 3, + // LaterSubscriptionEstablished meant that we had a subscription drop and + // then re-created a subscription. + MTRInternalDeviceStateLaterSubscriptionEstablished = 4, +}; + /** * Information about a cluster: data version and known attribute values. */ @@ -39,6 +60,7 @@ MTR_TESTABLE @property (nonatomic, readonly) NSDictionary * attributes; // attributeID => data-value dictionary - (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute; +- (void)removeValueForAttribute:(NSNumber *)attribute; - (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes; @end @@ -93,6 +115,8 @@ MTR_TESTABLE - (NSUInteger)unitTestAttributeCount; #endif +- (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; + @end #pragma mark - Utility for clamping numbers @@ -100,4 +124,12 @@ MTR_TESTABLE // Returns min or max, if it is below or above, respectively. NSNumber * MTRClampedNumber(NSNumber * aNumber, NSNumber * min, NSNumber * max); +#pragma mark - Constants + +static NSString * const kDefaultSubscriptionPoolSizeOverrideKey = @"subscriptionPoolSizeOverride"; +static NSString * const kTestStorageUserDefaultEnabledKey = @"enableTestStorage"; + +// Declared inside platform, but noting here for reference +// static NSString * const kSRPTimeoutInMsecsUserDefaultKey = @"SRPTimeoutInMSecsOverride"; + NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsDownloader.mm b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDownloader.mm index 782ff30ba5763f..d412f5a497c3ce 100644 --- a/src/darwin/Framework/CHIP/MTRDiagnosticLogsDownloader.mm +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsDownloader.mm @@ -399,7 +399,7 @@ - (void)downloadLogFromNodeWithID:(NSNumber *)nodeID if (timeout <= 0) { timeoutInSeconds = 0; } else if (timeout > UINT16_MAX) { - MTR_LOG_INFO("Warning: timeout is too large. It will be truncated to UINT16_MAX."); + MTR_LOG("Warning: timeout is too large. It will be truncated to UINT16_MAX."); timeoutInSeconds = UINT16_MAX; } else { timeoutInSeconds = static_cast(timeout); @@ -448,7 +448,7 @@ - (void)handleBDXTransferSessionBeginForFileDesignator:(NSString *)fileDesignato abortHandler:(AbortHandler)abortHandler; { assertChipStackLockedByCurrentThread(); - MTR_LOG_DEFAULT("BDX Transfer Session Begin: %@", fileDesignator); + MTR_LOG("BDX Transfer Session Begin: %@", fileDesignator); auto * download = [_downloads get:fileDesignator fabricIndex:fabricIndex nodeID:nodeID]; VerifyOrReturn(nil != download, completion([MTRError errorForCHIPErrorCode:CHIP_ERROR_NOT_FOUND])); @@ -464,7 +464,7 @@ - (void)handleBDXTransferSessionDataForFileDesignator:(NSString *)fileDesignator completion:(MTRStatusCompletion)completion { assertChipStackLockedByCurrentThread(); - MTR_LOG_DEFAULT("BDX Transfer Session Data: %@: %@", fileDesignator, data); + MTR_LOG("BDX Transfer Session Data: %@: %@", fileDesignator, data); auto * download = [_downloads get:fileDesignator fabricIndex:fabricIndex nodeID:nodeID]; VerifyOrReturn(nil != download, completion([MTRError errorForCHIPErrorCode:CHIP_ERROR_NOT_FOUND])); @@ -482,7 +482,7 @@ - (void)handleBDXTransferSessionEndForFileDesignator:(NSString *)fileDesignator error:(NSError * _Nullable)error { assertChipStackLockedByCurrentThread(); - MTR_LOG_DEFAULT("BDX Transfer Session End: %@: %@", fileDesignator, error); + MTR_LOG("BDX Transfer Session End: %@: %@", fileDesignator, error); auto * download = [_downloads get:fileDesignator fabricIndex:fabricIndex nodeID:nodeID]; VerifyOrReturn(nil != download); diff --git a/src/darwin/Framework/CHIP/MTRLogging_Internal.h b/src/darwin/Framework/CHIP/MTRLogging_Internal.h index 9b2d2fce418822..99892acf9631df 100644 --- a/src/darwin/Framework/CHIP/MTRLogging_Internal.h +++ b/src/darwin/Framework/CHIP/MTRLogging_Internal.h @@ -20,7 +20,6 @@ #include +#define MTR_LOG(msg, ...) ChipLogProgress(NotSpecified, msg, ##__VA_ARGS__) #define MTR_LOG_ERROR(msg, ...) ChipLogError(NotSpecified, msg, ##__VA_ARGS__) -#define MTR_LOG_DEFAULT(msg, ...) ChipLogProgress(NotSpecified, msg, ##__VA_ARGS__) -#define MTR_LOG_INFO(msg, ...) ChipLogDetail(NotSpecified, msg, ##__VA_ARGS__) #define MTR_LOG_DEBUG(msg, ...) ChipLogDetail(NotSpecified, msg, ##__VA_ARGS__) // same as INFO diff --git a/src/darwin/Framework/CHIP/MTRMetricsCollector.mm b/src/darwin/Framework/CHIP/MTRMetricsCollector.mm index 0927da858f1298..92a9ab4b6d373c 100644 --- a/src/darwin/Framework/CHIP/MTRMetricsCollector.mm +++ b/src/darwin/Framework/CHIP/MTRMetricsCollector.mm @@ -113,7 +113,7 @@ - (void)unregisterTracingBackend; void StartupMetricsCollection() { if ([MTRMetricsCollector sharedInstance]) { - MTR_LOG_INFO("Initialized metrics collection backend for Darwin"); + MTR_LOG("Initialized metrics collection backend for Darwin"); [[MTRMetricsCollector sharedInstance] registerTracingBackend]; } @@ -167,7 +167,7 @@ - (void)registerTracingBackend // Register only once if (!_tracingBackendRegistered) { chip::Tracing::Register(_tracingBackend); - MTR_LOG_INFO("Registered tracing backend with the registry"); + MTR_LOG("Registered tracing backend with the registry"); _tracingBackendRegistered = TRUE; } } @@ -179,7 +179,7 @@ - (void)unregisterTracingBackend // Unregister only if registered before if (_tracingBackendRegistered) { chip::Tracing::Unregister(_tracingBackend); - MTR_LOG_INFO("Unregistered tracing backend with the registry"); + MTR_LOG("Unregistered tracing backend with the registry"); _tracingBackendRegistered = FALSE; } } diff --git a/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm b/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm index a547321d88c2e0..a9d1fcdc18ba67 100644 --- a/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm +++ b/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm @@ -102,7 +102,7 @@ - (BOOL)_populateCppOperationalDataset - (BOOL)_checkDataLength:(NSData *)data expectedLength:(size_t)expectedLength { if (data.length != expectedLength) { - MTR_LOG_ERROR("Length Check Failed. Length:%tu is incorrect, must be %tu", data.length, expectedLength); + MTR_LOG_ERROR("Length Check Failed. Length:%lu is incorrect, must be %tu", static_cast(data.length), expectedLength); return NO; } return YES; diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index ebbe1b3765917c..3c0ec41443303c 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -47,6 +47,7 @@ #import #import #import +#import #import #import #import diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.mm b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.mm index d4bf1c7b9cd595..619ca98b2f4b47 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.mm +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.mm @@ -136,14 +136,14 @@ - (BOOL)setValueInternal:(NSDictionary *)value logIfNotAssociate _value = [value copy]; - MTR_LOG_DEFAULT("Attribute value updated: %@", [self _descriptionWhileLocked]); // Logs new value as part of our description. + MTR_LOG("Attribute value updated: %@", [self _descriptionWhileLocked]); // Logs new value as part of our description. MTRDeviceController * deviceController = _deviceController; if (deviceController == nil) { // We're not bound to a controller, so safe to directly update // _serializedValue. if (logIfNotAssociated) { - MTR_LOG_DEFAULT("Not publishing value for attribute " ChipLogFormatMEI "; not bound to a controller", + MTR_LOG("Not publishing value for attribute " ChipLogFormatMEI "; not bound to a controller", ChipLogValueMEI(static_cast(_attributeID.unsignedLongLongValue))); } _serializedValue = serializedValue; @@ -181,7 +181,7 @@ - (BOOL)associateWithController:(nullable MTRDeviceController *)controller _deviceController = controller; - MTR_LOG_DEFAULT("Associated %@ with controller", [self _descriptionWhileLocked]); + MTR_LOG("Associated %@ with controller", [self _descriptionWhileLocked]); return YES; } diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm index 02b5605e8c3388..e00bd10b5dc6c7 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm @@ -346,7 +346,7 @@ - (BOOL)associateWithController:(nullable MTRDeviceController *)controller _deviceController = controller; - MTR_LOG_DEFAULT("Associated %@, attribute count %llu, with controller", [self _descriptionWhileLocked], + MTR_LOG("Associated %@, attribute count %llu, with controller", [self _descriptionWhileLocked], static_cast(attributeCount)); return YES; diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm index 44da6a6cb6016a..d9e54bce58d395 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm @@ -311,7 +311,7 @@ - (BOOL)finishAssociationWithController:(nullable MTRDeviceController *)controll _deviceController = controller; - MTR_LOG_DEFAULT("Associated %@, cluster count %llu, with controller", + MTR_LOG("Associated %@, cluster count %llu, with controller", self, static_cast(clusterCount)); return YES; diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt index 9d6e786ce03149..0b8529b9c566c5 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt @@ -116,7 +116,7 @@ MTR{{cluster}}Cluster{{command}}Params {{! This is used as the implementation for both the new-name and old-name bits, so check for both here. }} {{#if (or (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true)) (and (isSupported (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)) - (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name))))}} + (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name))))}} {{#*inline "attribute"}}Attribute{{asUpperCamelCase name preserveAcronyms=true}}{{/inline}} - (void)read{{>attribute}}With {{~#if_is_fabric_scoped_struct type~}} @@ -223,7 +223,7 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value {{/if}} {{/unless}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping name)) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping name)) (isSupported (compatClusterNameRemapping name)))}} @implementation MTRBaseCluster{{compatClusterNameRemapping name}} (Deprecated) @@ -231,7 +231,7 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value {{#if (is_str_equal source 'client')}} {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandImpl"}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" cluster command=command) (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler { @@ -268,7 +268,7 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value {{/zcl_commands}} {{#zcl_attributes_server removeKeys='isOptional'}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)) (isSupported (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)))}} {{#*inline "attribute"}}Attribute{{compatAttributeNameRemapping parent.name name}}{{/inline}} - (void)read{{>attribute}}With diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt index 7488fda7019126..35d09c0f916431 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt @@ -29,20 +29,20 @@ NS_ASSUME_NONNULL_BEGIN * * {{description}} */ -- (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="First major API revamp"}}; +- (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithCompletion:({{>command_completion_type command=.}})completion {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#if (and (isStrEqual command "KeySetReadAllIndices") (isStrEqual cluster "GroupKeyManagement"))}} -{{availability cluster command=command minimalRelease="Fall 2023"}}; +{{availability cluster command=command minimalRelease="3C23F160-13CE-4397-BC65-122B61E4D691"}}; {{else}} {{#if (isInConfigList (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) "LegacyCommandsWithOnlyOptionalArguments")}} -{{availability cluster command=command minimalRelease="Early 2024"}}; +{{availability cluster command=command minimalRelease="ADDB2DC1-4701-4696-87EB-87CD1123BE1A"}}; {{else}} -{{availability cluster command=command minimalRelease="First major API revamp"}}; +{{availability cluster command=command minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{/if}} {{/if}} {{/unless}} @@ -62,16 +62,16 @@ NS_ASSUME_NONNULL_BEGIN {{~else~}} Completion: {{~/if_is_fabric_scoped_struct~}} -(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; +(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{#if (or isWritableAttribute (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} -- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completion:(MTRStatusCompletion)completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; -- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; +- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completion:(MTRStatusCompletion)completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; +- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{/if}} {{#if isReportableAttribute}} - (void) subscribe{{>attribute}}WithParams:(MTRSubscribeParams *)params -subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))reportHandler {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; -+ (void) read{{>attribute}}WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; +subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))reportHandler {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; ++ (void) read{{>attribute}}WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{/if}} {{/if}} {{/zcl_attributes_server}} @@ -89,7 +89,7 @@ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptio */ - (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID - queue:(dispatch_queue_t)queue {{availability (asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; + queue:(dispatch_queue_t)queue {{availability (asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; @end {{/if}} @@ -207,22 +207,22 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm {{/zcl_clusters}} {{#zcl_clusters}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping name)) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping name)) (isSupported (compatClusterNameRemapping name)))}} @interface MTRBaseCluster{{compatClusterNameRemapping name}} (Deprecated) - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint - queue:(dispatch_queue_t)queue {{availability (compatClusterNameRemapping name) deprecatedRelease="First major API revamp" deprecationMessage="Please use initWithDevice:endpointID:queue:"}}; + queue:(dispatch_queue_t)queue {{availability (compatClusterNameRemapping name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage="Please use initWithDevice:endpointID:queue:"}}; {{#zcl_commands}} {{#if (is_str_equal source 'client')}} {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandDecl"}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" cluster command=command) (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler - {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:completion:")}}; + {{availability cluster command=command deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:completion:")}}; {{#unless commandHasRequiredField}} {{! No need for these backwards-compat APIs for commands that never shipped them. }} {{#unless (isInConfigList @@ -232,7 +232,7 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} - (void){{asLowerCamelCase command}}WithCompletionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler - {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithCompletion:")}}; + {{availability cluster command=command deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithCompletion:")}}; {{/unless}} {{/unless}} {{/unless}} @@ -244,7 +244,7 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm {{/zcl_commands}} {{#zcl_attributes_server removeKeys='isOptional'}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)) (isSupported (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)))}} {{#*inline "attribute"}}Attribute{{compatAttributeNameRemapping parent.name name}}{{/inline}} - (void)read{{>attribute}}With @@ -253,17 +253,17 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm {{~else~}} CompletionHandler: {{~/if_is_fabric_scoped_struct~}} -(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" fabricScopedDeprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams:completion:") nonFabricScopedDeprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithCompletion:") type=type}}; +(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" fabricScopedDeprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams:completion:") nonFabricScopedDeprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithCompletion:") type=type}}; {{#if (or isWritableAttribute (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} -- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value completionHandler:(MTRStatusCompletion)completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue:completion:")}}; -- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value params:(MTRWriteParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue:params:completion:")}}; +- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value completionHandler:(MTRStatusCompletion)completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue:completion:")}}; +- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value params:(MTRWriteParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue:params:completion:")}}; {{/if}} {{#if isReportableAttribute}} - (void) subscribe{{>attribute}}WithMinInterval:(NSNumber * _Nonnull)minInterval maxInterval:(NSNumber * _Nonnull)maxInterval params:(MTRSubscribeParams * _Nullable)params -subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler reportHandler:(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))reportHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use subscribeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams:subscriptionEstablished:")}}; -+ (void) read{{>attribute}}WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completionHandler:(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithAttributeCache:endpoint:queue:completion:")}}; +subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler reportHandler:(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))reportHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use subscribeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams:subscriptionEstablished:")}}; ++ (void) read{{>attribute}}WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completionHandler:(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithAttributeCache:endpoint:queue:completion:")}}; {{/if}} {{/if}} {{/zcl_attributes_server}} diff --git a/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt b/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt index ba2e57a45bc491..98d6d6b35431b1 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt @@ -7,15 +7,15 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { {{#zcl_clusters}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping name) isForIds=true) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping name) isForIds=true) (isSupported (compatClusterNameRemapping name) isForIds=true))}} -MTRCluster{{compatClusterNameRemapping label}}ID {{availability (compatClusterNameRemapping name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use MTRClusterIDType" (asUpperCamelCase label preserveAcronyms=true) "ID") isForIds=true}} = {{asMEI manufacturerCode code}}, +MTRCluster{{compatClusterNameRemapping label}}ID {{availability (compatClusterNameRemapping name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use MTRClusterIDType" (asUpperCamelCase label preserveAcronyms=true) "ID") isForIds=true}} = {{asMEI manufacturerCode code}}, {{/if}} {{/zcl_clusters}} {{#zcl_clusters}} {{#if (isSupported (asUpperCamelCase label preserveAcronyms=true) isForIds=true)}} {{~#*inline "cluster"}}{{asUpperCamelCase label preserveAcronyms=true}}{{/inline~}} -MTRClusterIDType{{>cluster}}ID {{availability (asUpperCamelCase label preserveAcronyms=true) minimalRelease="First major API revamp" isForIds=true deprecationMessage=(concat "The " (asUpperCamelCase label preserveAcronyms=true) " cluster will be removed")}} = {{asMEI manufacturerCode code}}, +MTRClusterIDType{{>cluster}}ID {{availability (asUpperCamelCase label preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE" isForIds=true deprecationMessage=(concat "The " (asUpperCamelCase label preserveAcronyms=true) " cluster will be removed")}} = {{asMEI manufacturerCode code}}, {{/if}} {{/zcl_clusters}} }; @@ -26,7 +26,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Deprecated global attribute names {{#zcl_attributes_server}} {{#unless clusterRef}} -{{#if (wasIntroducedBeforeRelease "First major API revamp" "" globalAttribute=(asUpperCamelCase label) isForIds=true)}} +{{#if (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" "" globalAttribute=(asUpperCamelCase label) isForIds=true)}} MTRClusterGlobalAttribute{{asUpperCamelCase label}}ID {{availability "" api="Deprecated global attribute names" deprecationMessage=(concat "Please use MTRAttributeIDTypeGlobalAttribute" (asUpperCamelCase label) "ID") isForIds=true}} = {{asMEI manufacturerCode code}}, @@ -39,7 +39,7 @@ MTRClusterGlobalAttribute{{asUpperCamelCase label}}ID {{~#*inline "attribute"}}{{asUpperCamelCase label preserveAcronyms=true}}{{/inline~}} {{#unless clusterRef}} {{#if (isSupported "" globalAttribute=(asUpperCamelCase label preserveAcronyms=true) isForIds=true)}} -MTRAttributeIDTypeGlobalAttribute{{>attribute}}ID {{availability "" globalAttribute=(asUpperCamelCase label preserveAcronyms=true) minimalRelease="First major API revamp" isForIds=true}} = {{asMEI manufacturerCode code}}, +MTRAttributeIDTypeGlobalAttribute{{>attribute}}ID {{availability "" globalAttribute=(asUpperCamelCase label preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE" isForIds=true}} = {{asMEI manufacturerCode code}}, {{/if}} {{/unless}} {{/zcl_attributes_server}} @@ -48,7 +48,7 @@ MTRAttributeIDTypeGlobalAttribute{{>attribute}}ID {{availability "" globalAttrib {{#*inline "attributeIDs"}} {{#zcl_attributes_server}} {{#first}} -{{#if (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping ../clusterName) isForIds=true)}} +{{#if (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping ../clusterName) isForIds=true)}} {{#if (isSupported (compatClusterNameRemapping ../clusterName) isForIds=true)}} // Cluster {{compatClusterNameRemapping ../clusterName}} deprecated attribute names {{/if}} @@ -60,14 +60,14 @@ MTRAttributeIDTypeGlobalAttribute{{>attribute}}ID {{availability "" globalAttrib {{#if (isStrEqual (asUpperCamelCase ../clusterName) "Descriptor")}} {{#if (isStrEqual (asUpperCamelCase label) "DeviceTypeList")}} MTRClusterDescriptorAttributeDeviceTypeListID -{{availability "Descriptor" attribute="DeviceTypeList" deprecatedRelease="First major API revamp" deprecationMessage="Please use MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID" isForIds=true}} +{{availability "Descriptor" attribute="DeviceTypeList" deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage="Please use MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID" isForIds=true}} = {{asMEI manufacturerCode code}}, {{/if}} {{/if}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) isForIds=true) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) isForIds=true) (isSupported (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) isForIds=true))}} MTRCluster{{compatClusterNameRemapping ../clusterName}}Attribute{{compatAttributeNameRemapping ../clusterName label}}ID -{{availability (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use MTRAttributeIDTypeCluster" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Attribute" (asUpperCamelCase label preserveAcronyms=true) "ID") isForIds=true}} = +{{availability (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use MTRAttributeIDTypeCluster" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Attribute" (asUpperCamelCase label preserveAcronyms=true) "ID") isForIds=true}} = {{#if clusterRef}} {{asMEI manufacturerCode code}}, {{else}} @@ -89,20 +89,20 @@ MTRClusterGlobalAttribute{{asUpperCamelCase label}}ID, {{#if (and (isSupported (asUpperCamelCase ../clusterName preserveAcronyms=true) attribute=(asUpperCamelCase label preserveAcronyms=true) isForIds=true) (or clusterRef (isSupported "" globalAttribute=(asUpperCamelCase label preserveAcronyms=true) isForIds=true)))}} -MTRAttributeIDTypeCluster{{>cluster}}Attribute{{>attribute}}ID {{availability (asUpperCamelCase ../clusterName preserveAcronyms=true) attribute=(asUpperCamelCase label preserveAcronyms=true) minimalRelease="First major API revamp" isForIds=true deprecationMessage=(concat "The " (asUpperCamelCase label preserveAcronyms=true) " attribute will be removed")}} = +MTRAttributeIDTypeCluster{{>cluster}}Attribute{{>attribute}}ID {{availability (asUpperCamelCase ../clusterName preserveAcronyms=true) attribute=(asUpperCamelCase label preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE" isForIds=true deprecationMessage=(concat "The " (asUpperCamelCase label preserveAcronyms=true) " attribute will be removed")}} = {{#if clusterRef}} {{asMEI manufacturerCode code}}, {{else}} MTRAttributeIDTypeGlobalAttribute{{asUpperCamelCase label}}ID, {{/if}} {{/if}} -{{! Anything which has an old name, and the new name was introduced in the "First after major API revamp" release or later - (or just after the "First major API revamp" release, but we don't have a good way to test for that), +{{! Anything which has an old name, and the new name was introduced in the "27C5E231-9EB5-4932-B4C1-10D88419D9CB" release or later + (or just after the "267F4B03-3256-4056-A62D-5237640FDCFE" release, but we don't have a good way to test for that), we need to generate the new-form id for the old name too, as long as it was not removed. }} {{#if (and (hasOldName (asUpperCamelCase ../clusterName preserveAcronyms=true) attribute=(asUpperCamelCase label preserveAcronyms=true) isForIds=true) - (not (wasIntroducedBeforeRelease "First after major API revamp" (asUpperCamelCase ../clusterName preserveAcronyms=true) attribute=(asUpperCamelCase label preserveAcronyms=true) isForIds=true)) + (not (wasIntroducedBeforeRelease "27C5E231-9EB5-4932-B4C1-10D88419D9CB" (asUpperCamelCase ../clusterName preserveAcronyms=true) attribute=(asUpperCamelCase label preserveAcronyms=true) isForIds=true)) (isSupported (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) isForIds=true))}} -MTRAttributeIDTypeCluster{{compatClusterNameRemapping ../clusterName}}Attribute{{compatAttributeNameRemapping ../clusterName label}}ID {{availability (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) isForIds=true minimalRelease="First major API revamp" deprecationMessage=(concat "Please use MTRAttributeIDType" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Attribute" (asUpperCamelCase label preserveAcronyms=true) "ID")}} = MTRAttributeIDTypeCluster{{>cluster}}Attribute{{>attribute}}ID, +MTRAttributeIDTypeCluster{{compatClusterNameRemapping ../clusterName}}Attribute{{compatAttributeNameRemapping ../clusterName label}}ID {{availability (compatClusterNameRemapping ../clusterName) attribute=(compatAttributeNameRemapping ../clusterName label) isForIds=true minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use MTRAttributeIDType" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Attribute" (asUpperCamelCase label preserveAcronyms=true) "ID")}} = MTRAttributeIDTypeCluster{{>cluster}}Attribute{{>attribute}}ID, {{/if}} {{#last}} @@ -121,7 +121,7 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { {{#*inline "commandIDs"}} {{#zcl_commands}} {{#first}} -{{#if (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping ../clusterName) isForIds=true)}} +{{#if (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping ../clusterName) isForIds=true)}} {{#if (isSupported (compatClusterNameRemapping ../clusterName) isForIds=true)}} // Cluster {{compatClusterNameRemapping ../clusterName}} deprecated command id names {{/if}} @@ -129,10 +129,10 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { {{/first}} {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandIdDecl"}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command isForIds=true) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" cluster command=command isForIds=true) (isSupported cluster command=command isForIds=true))}} MTRCluster{{cluster}}Command{{command}}ID -{{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use MTRCommandIDTypeCluster" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Command" (asUpperCamelCase name preserveAcronyms=true) "ID") isForIds=true}} +{{availability cluster command=command deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use MTRCommandIDTypeCluster" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Command" (asUpperCamelCase name preserveAcronyms=true) "ID") isForIds=true}} = {{asMEI manufacturerCode code}}, {{/if}} {{/inline}} @@ -152,16 +152,16 @@ MTRCluster{{cluster}}Command{{command}}ID {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandIdDecl"}} {{#if (isSupported cluster command=command isForIds=true)}} -MTRCommandIDTypeCluster{{cluster}}Command{{command}}ID {{availability cluster command=command minimalRelease="First major API revamp" isForIds=true deprecationMessage=(concat "The " command " command will be removed")}} = {{asMEI manufacturerCode code}}, +MTRCommandIDTypeCluster{{cluster}}Command{{command}}ID {{availability cluster command=command minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE" isForIds=true deprecationMessage=(concat "The " command " command will be removed")}} = {{asMEI manufacturerCode code}}, {{/if}} {{/inline}} {{> commandIdDecl cluster=(asUpperCamelCase ../clusterName preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true)}} -{{! Anything which has an old name, and the new name was introduced in the "First after major API revamp" release or later - (or just after the "First major API revamp" release, but we don't have a good way to test for that), +{{! Anything which has an old name, and the new name was introduced in the "27C5E231-9EB5-4932-B4C1-10D88419D9CB" release or later + (or just after the "267F4B03-3256-4056-A62D-5237640FDCFE" release, but we don't have a good way to test for that), we need to generate the new-form id for the old name too, as long as it was not removed. }} {{#if (and (hasOldName (asUpperCamelCase ../clusterName preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true) isForIds=true) - (not (wasIntroducedBeforeRelease "First after major API revamp" (asUpperCamelCase ../clusterName preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true) isForIds=true)) + (not (wasIntroducedBeforeRelease "27C5E231-9EB5-4932-B4C1-10D88419D9CB" (asUpperCamelCase ../clusterName preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true) isForIds=true)) (isSupported (compatClusterNameRemapping ../clusterName) command=(compatCommandNameRemapping ../clusterName name) isForIds=true))}} {{> commandIdDecl cluster=(compatClusterNameRemapping ../clusterName) command=(compatCommandNameRemapping ../clusterName name)}} @@ -183,16 +183,16 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { {{#*inline "eventIDs"}} {{#zcl_events}} {{#first}} -{{#if (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping ../clusterName) isForIds=true)}} +{{#if (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping ../clusterName) isForIds=true)}} {{#if (isSupported (compatClusterNameRemapping ../clusterName))}} // Cluster {{compatClusterNameRemapping ../clusterName}} deprecated event names {{/if}} {{/if}} {{/first}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping ../clusterName) event=(asUpperCamelCase name) isForIds=true) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping ../clusterName) event=(asUpperCamelCase name) isForIds=true) (isSupported (compatClusterNameRemapping ../clusterName) event=(asUpperCamelCase name) isForIds=true))}} MTRCluster{{compatClusterNameRemapping ../clusterName}}Event{{asUpperCamelCase name}}ID -{{availability (compatClusterNameRemapping ../clusterName) event=(asUpperCamelCase name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use MTREventIDTypeCluster" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Event" (asUpperCamelCase name preserveAcronyms=true) "ID") isForIds=true}} +{{availability (compatClusterNameRemapping ../clusterName) event=(asUpperCamelCase name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use MTREventIDTypeCluster" (asUpperCamelCase ../clusterName preserveAcronyms=true) "Event" (asUpperCamelCase name preserveAcronyms=true) "ID") isForIds=true}} = {{asMEI manufacturerCode code}}, {{/if}} {{#last}} @@ -208,7 +208,7 @@ MTRCluster{{compatClusterNameRemapping ../clusterName}}Event{{asUpperCamelCase n {{/if}} {{/first}} {{#if (isSupported (asUpperCamelCase ../clusterName preserveAcronyms=true) event=(asUpperCamelCase name preserveAcronyms=true) isForIds=true)}} -MTREventIDTypeCluster{{>cluster}}Event{{>event}}ID {{availability (asUpperCamelCase ../clusterName preserveAcronyms=true) event=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp" isForIds=true}} = {{asMEI manufacturerCode code}}, +MTREventIDTypeCluster{{>cluster}}Event{{>event}}ID {{availability (asUpperCamelCase ../clusterName preserveAcronyms=true) event=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE" isForIds=true}} = {{asMEI manufacturerCode code}}, {{/if}} {{#last}} diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt index c42b95e71ef9b7..c73e8aeb70d023 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt @@ -103,7 +103,7 @@ MTR{{cluster}}Cluster{{command}}Params (isSupported "" globalAttribute=(asUpperCamelCase label preserveAcronyms=true))) (or (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true)) (and (isSupported (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)) - (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)))))}} + (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)))))}} {{#*inline "cluster"}}{{asUpperCamelCase parent.name preserveAcronyms=true}}{{/inline}} {{#*inline "attribute"}}Attribute{{asUpperCamelCase name preserveAcronyms=true}}{{/inline}} - (NSDictionary * _Nullable)read{{>attribute}}WithParams:(MTRReadParams * _Nullable)params { @@ -143,7 +143,7 @@ MTR{{cluster}}Cluster{{command}}Params {{/if}} {{/unless}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping name)) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping name)) (isSupported (compatClusterNameRemapping name)))}} @implementation MTRCluster{{compatClusterNameRemapping name}} (Deprecated) @@ -156,7 +156,7 @@ MTR{{cluster}}Cluster{{command}}Params {{#if (is_str_equal source 'client')}} {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandImpl"}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" cluster command=command) (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler { diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt index 4ea998e04b6f86..ebcd299d0871f4 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt @@ -24,20 +24,20 @@ NS_ASSUME_NONNULL_BEGIN {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandDecl"}} {{#if (isSupported cluster command=command)}} -- (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="First major API revamp"}}; +- (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#if (and (isStrEqual command "KeySetReadAllIndices") (isStrEqual cluster "GroupKeyManagement"))}} -{{availability cluster command=command minimalRelease="Fall 2023"}}; +{{availability cluster command=command minimalRelease="3C23F160-13CE-4397-BC65-122B61E4D691"}}; {{else}} {{#if (isInConfigList (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) "LegacyCommandsWithOnlyOptionalArguments")}} -{{availability cluster command=command minimalRelease="Early 2024"}}; +{{availability cluster command=command minimalRelease="ADDB2DC1-4701-4696-87EB-87CD1123BE1A"}}; {{else}} -{{availability cluster command=command minimalRelease="First major API revamp"}}; +{{availability cluster command=command minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; {{/if}} {{/if}} {{/unless}} @@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype _Nullable)initWithDevice:(MTRDevice *)device endpointID:(NSNumber *)endpointID - queue:(dispatch_queue_t)queue {{availability (asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; + queue:(dispatch_queue_t)queue {{availability (asUpperCamelCase name preserveAcronyms=true) minimalRelease="267F4B03-3256-4056-A62D-5237640FDCFE"}}; @end @@ -104,21 +104,21 @@ NS_ASSUME_NONNULL_BEGIN {{/zcl_clusters}} {{#zcl_clusters}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping name)) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping name)) (isSupported (compatClusterNameRemapping name)))}} @interface MTRCluster{{compatClusterNameRemapping name}} (Deprecated) - (nullable instancetype)initWithDevice:(MTRDevice *)device endpoint:(uint16_t)endpoint - queue:(dispatch_queue_t)queue {{availability (compatClusterNameRemapping name) deprecatedRelease="First major API revamp" deprecationMessage="Please use initWithDevice:endpoindID:queue:"}}; + queue:(dispatch_queue_t)queue {{availability (compatClusterNameRemapping name) deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage="Please use initWithDevice:endpoindID:queue:"}}; {{#zcl_commands}} {{#if (is_str_equal source 'client')}} {{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }} {{#*inline "commandDecl"}} -{{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command) +{{#if (and (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" cluster command=command) (isSupported cluster command=command))}} -- (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:expectedValues:expectedValueInterval:completion:")}}; +- (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:expectedValues:expectedValueInterval:completion:")}}; {{#unless commandHasRequiredField}} {{! No need for these backwards-compat APIs for commands that never shipped them. }} {{#unless (isInConfigList @@ -127,7 +127,7 @@ NS_ASSUME_NONNULL_BEGIN {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} -- (void){{asLowerCamelCase command}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithExpectedValues:expectedValueInterval:completion:")}}; +- (void){{asLowerCamelCase command}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithExpectedValues:expectedValueInterval:completion:")}}; {{/unless}} {{/unless}} {{/unless}} @@ -140,7 +140,7 @@ NS_ASSUME_NONNULL_BEGIN {{~#zcl_attributes_server}} {{~#*inline "attributeDecls"}} {{#unless (isStrEqual attribute (asUpperCamelCase name preserveAcronyms=true))}} -- (NSDictionary *)readAttribute{{attribute}}WithParams:(MTRReadParams * _Nullable)params {{availability cluster attribute=attribute deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams on MTRCluster" (asUpperCamelCase parent.name preserveAcronyms=true))}}; +- (NSDictionary *)readAttribute{{attribute}}WithParams:(MTRReadParams * _Nullable)params {{availability cluster attribute=attribute deprecatedRelease="267F4B03-3256-4056-A62D-5237640FDCFE" deprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams on MTRCluster" (asUpperCamelCase parent.name preserveAcronyms=true))}}; {{#if (or isWritableAttribute (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)writeAttribute{{attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs {{availability cluster attribute=attribute deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue on MTRCluster" (asUpperCamelCase parent.name preserveAcronyms=true))}}; diff --git a/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc-src.zapt b/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc-src.zapt index 783fe2aff9555f..4179d5a905ce07 100644 --- a/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc-src.zapt @@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN {{>init_struct_member label=label type=type cluster=parent.parent.name}} {{/zcl_command_arguments}} {{#if (or (isStrEqual source "client") - (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}} + (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}} _timedInvokeTimeoutMs = nil; {{/if}} {{#if (isStrEqual source "client")}} @@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN other.{{asStructPropertyName label}} = self.{{asStructPropertyName label}}; {{/zcl_command_arguments}} {{#if (or (isStrEqual source "client") - (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}} + (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}} other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; {{/if}} {{#if (isStrEqual source "client")}} @@ -210,7 +210,7 @@ NS_ASSUME_NONNULL_BEGIN {{#if (isStrEqual source "client")}} @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; -{{else if (wasIntroducedBeforeRelease "First major API revamp" cluster command=command)}} +{{else if (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" cluster command=command)}} @dynamic timedInvokeTimeoutMs; {{/if}} @end diff --git a/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc.zapt b/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc.zapt index 686b502405a64c..6e8cfd6ff9b36d 100644 --- a/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRCommandPayloadsObjc.zapt @@ -55,7 +55,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; {{! This is using the pre-renaming names for the isAvailableBefore test, because the pre-rename things inherit from the post-rename ones and need to have this selector.}} -{{else if (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name))}} +{{else if (wasIntroducedBeforeRelease "267F4B03-3256-4056-A62D-5237640FDCFE" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name))}} /** * Controls whether the command is a timed command (using Timed Invoke). * @@ -86,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN * schema for this command. */ - (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue - error:(NSError * __autoreleasing *)error {{availability cluster command=command deprecationMessage="This command has been removed" minimalRelease="Fall 2023"}}; + error:(NSError * __autoreleasing *)error {{availability cluster command=command deprecationMessage="This command has been removed" minimalRelease="3C23F160-13CE-4397-BC65-122B61E4D691"}}; {{/if}} @end {{/if}} diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 5c5439003862b9..8a1e95b8911ebe 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -72,7 +72,7 @@ # "provisional" to make sure all the things that should have # been omitted have been. -- release: "Initial release" +- release: "0E17B7EB-314F-4264-BDA8-AD6A93120B15" versions: iOS: "16.1" macOS: "13.0" @@ -4774,7 +4774,7 @@ - PulseWidthModulation - TimeSynchronization -- release: "First dot-release" +- release: "FD8D09B4-6CF7-4EBA-BD4F-7EDE872E3098" versions: iOS: "16.2" macOS: "13.1" @@ -4830,7 +4830,7 @@ Descriptor: DeviceTypeStruct: DeviceType -- release: "First major API revamp" +- release: "267F4B03-3256-4056-A62D-5237640FDCFE" # First major API revamp versions: iOS: "16.4" macOS: "13.3" @@ -6787,7 +6787,7 @@ HeatSetpointPresent: HeatSetpointFieldPresent CoolSetpointPresent: CoolSetpointFieldPresent -- release: "First after major API revamp" +- release: "27C5E231-9EB5-4932-B4C1-10D88419D9CB" # First after major API revamp versions: iOS: "16.5" macOS: "13.4" @@ -7095,7 +7095,7 @@ PumpFeature: LocalOperation: Local -- release: "Fall 2023" +- release: "3C23F160-13CE-4397-BC65-122B61E4D691" versions: iOS: "17.0" macOS: "14.0" @@ -7560,7 +7560,7 @@ - TimeFailure - MissingTrustedTimeSource -- release: "Fall 2023 #2" +- release: "F7CA8603-6336-4E63-A216-30EE3F77CE8B" versions: iOS: "17.1" macOS: "14.1" @@ -7625,7 +7625,7 @@ - ProxyDiscovery - ProxyValid -- release: "Fall 2023 #3" +- release: "A188F985-88AC-4F0B-8968-C887132CEF9E" versions: iOS: "17.2" macOS: "14.2" @@ -7771,7 +7771,7 @@ Feature: DeadFrontBehavior: DeadFront -- release: "Early 2024" +- release: "ADDB2DC1-4701-4696-87EB-87CD1123BE1A" versions: iOS: "17.4" macOS: "14.4" @@ -8509,7 +8509,7 @@ ContentLaunchStatusEnum: - URLNotAvailable -- release: "Middle of 2024" +- release: "FB974A56-BCF5-46CB-91EF-B5D096E84375" versions: iOS: "17.6" macOS: "14.6" @@ -9687,3 +9687,8 @@ - release: "Future" versions: "future" + provisional: + clusters: + # Targeting Fall 2024 + - ThreadNetworkDirectory + - WiFiNetworkManagement diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index cb98d807f3495d..d581289afd59f2 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -5288,6 +5288,72 @@ static BOOL AttributeIsSpecifiedInRadonConcentrationMeasurementCluster(Attribute } } } +static BOOL AttributeIsSpecifiedInWiFiNetworkManagementCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WiFiNetworkManagement; + switch (aAttributeId) { + case Attributes::Ssid::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} +static BOOL AttributeIsSpecifiedInThreadNetworkDirectoryCluster(AttributeId aAttributeId) +{ + using namespace Clusters::ThreadNetworkDirectory; + switch (aAttributeId) { + case Attributes::PreferredExtendedPanID::Id: { + return YES; + } + case Attributes::ThreadNetworks::Id: { + return YES; + } + case Attributes::ThreadNetworkTableSize::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInWakeOnLANCluster(AttributeId aAttributeId) { using namespace Clusters::WakeOnLan; @@ -6804,6 +6870,12 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::RadonConcentrationMeasurement::Id: { return AttributeIsSpecifiedInRadonConcentrationMeasurementCluster(aAttributeId); } + case Clusters::WiFiNetworkManagement::Id: { + return AttributeIsSpecifiedInWiFiNetworkManagementCluster(aAttributeId); + } + case Clusters::ThreadNetworkDirectory::Id: { + return AttributeIsSpecifiedInThreadNetworkDirectoryCluster(aAttributeId); + } case Clusters::WakeOnLan::Id: { return AttributeIsSpecifiedInWakeOnLANCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index bae1643f3beb39..9497069cb7e507 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -15219,6 +15219,105 @@ static id _Nullable DecodeAttributeValueForRadonConcentrationMeasurementCluster( *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForWiFiNetworkManagementCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WiFiNetworkManagement; + switch (aAttributeId) { + case Attributes::Ssid::Id: { + using TypeInfo = Attributes::Ssid::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSData * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = AsData(cppValue.Value()); + } + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} +static id _Nullable DecodeAttributeValueForThreadNetworkDirectoryCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::ThreadNetworkDirectory; + switch (aAttributeId) { + case Attributes::PreferredExtendedPanID::Id: { + using TypeInfo = Attributes::PreferredExtendedPanID::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedLongLong:cppValue.Value()]; + } + return value; + } + case Attributes::ThreadNetworks::Id: { + using TypeInfo = Attributes::ThreadNetworks::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTRThreadNetworkDirectoryClusterThreadNetworkStruct * newElement_0; + newElement_0 = [MTRThreadNetworkDirectoryClusterThreadNetworkStruct new]; + newElement_0.extendedPanID = [NSNumber numberWithUnsignedLongLong:entry_0.extendedPanID]; + newElement_0.networkName = AsString(entry_0.networkName); + if (newElement_0.networkName == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + newElement_0.channel = [NSNumber numberWithUnsignedShort:entry_0.channel]; + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::ThreadNetworkTableSize::Id: { + using TypeInfo = Attributes::ThreadNetworkTableSize::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForWakeOnLANCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::WakeOnLan; @@ -19593,6 +19692,12 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::RadonConcentrationMeasurement::Id: { return DecodeAttributeValueForRadonConcentrationMeasurementCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::WiFiNetworkManagement::Id: { + return DecodeAttributeValueForWiFiNetworkManagementCluster(aPath.mAttributeId, aReader, aError); + } + case Clusters::ThreadNetworkDirectory::Id: { + return DecodeAttributeValueForThreadNetworkDirectoryCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::WakeOnLan::Id: { return DecodeAttributeValueForWakeOnLANCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 3c7624201d0484..c5e73b22368081 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -12989,6 +12989,182 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @end +/** + * Cluster Wi-Fi Network Management + * + * Functionality to retrieve operational information about a managed Wi-Fi network. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterWiFiNetworkManagement : MTRGenericBaseCluster + +/** + * Command NetworkPassphraseRequest + * + * Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. + */ +- (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams * _Nullable)params completion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)networkPassphraseRequestWithCompletion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSSIDWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSSIDWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSSIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterWiFiNetworkManagement (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + +/** + * Cluster Thread Network Directory + * + * Manages the names and credentials of Thread networks visible to the user. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterThreadNetworkDirectory : MTRGenericBaseCluster + +/** + * Command AddNetwork + * + * Adds an entry to the ThreadNetworks list. + */ +- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command RemoveNetwork + * + * Removes an entry from the ThreadNetworks list. + */ +- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command GetOperationalDataset + * + * Retrieves a Thread Operational Dataset from the ThreadNetworks list. + */ +- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributePreferredExtendedPanIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributePreferredExtendedPanIDWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributePreferredExtendedPanIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeThreadNetworksWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeThreadNetworksWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeThreadNetworksWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeThreadNetworkTableSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeThreadNetworkTableSizeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeThreadNetworkTableSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterThreadNetworkDirectory (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Wake on LAN * diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index b375488f292fc8..1df39709657551 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -92894,6 +92894,734 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterWiFiNetworkManagement + +- (void)networkPassphraseRequestWithCompletion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self networkPassphraseRequestWithParams:nil completion:completion]; +} +- (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams * _Nullable)params completion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeSSIDWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::Ssid::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSSIDWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::Ssid::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSSIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::Ssid::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + +@implementation MTRBaseClusterThreadNetworkDirectory + +- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadNetworkDirectoryClusterAddNetworkParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + if (timedInvokeTimeoutMs == nil) { + timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); + } + + using RequestType = ThreadNetworkDirectory::Commands::AddNetwork::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + if (timedInvokeTimeoutMs == nil) { + timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); + } + + using RequestType = ThreadNetworkDirectory::Commands::RemoveNetwork::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + if (timedInvokeTimeoutMs == nil) { + timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); + } + + using RequestType = ThreadNetworkDirectory::Commands::GetOperationalDataset::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributePreferredExtendedPanIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = value.unsignedLongLongValue; + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributePreferredExtendedPanIDWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributePreferredExtendedPanIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeThreadNetworksWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworks::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeThreadNetworksWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworks::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeThreadNetworksWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworks::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeThreadNetworkTableSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeThreadNetworkTableSizeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeThreadNetworkTableSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ThreadNetworkDirectory::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterWakeOnLAN - (void)readAttributeMACAddressWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 5c3f6a080fdd7b..d609ce5c84179c 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -184,6 +184,8 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypePM10ConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042D, MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042E, MTRClusterIDTypeRadonConcentrationMeasurementID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000042F, + MTRClusterIDTypeWiFiNetworkManagementID MTR_PROVISIONALLY_AVAILABLE = 0x00000451, + MTRClusterIDTypeThreadNetworkDirectoryID MTR_PROVISIONALLY_AVAILABLE = 0x00000453, MTRClusterIDTypeWakeOnLANID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000503, MTRClusterIDTypeChannelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000504, MTRClusterIDTypeTargetNavigatorID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000505, @@ -4361,6 +4363,26 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WiFiNetworkManagement attributes + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeSSIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + + // Cluster ThreadNetworkDirectory attributes + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworksID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WakeOnLan deprecated attribute names MTRClusterWakeOnLanAttributeMACAddressID MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterWakeOnLANAttributeMACAddressID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6575,6 +6597,16 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterColorControlCommandMoveColorTemperatureID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000004B, MTRCommandIDTypeClusterColorControlCommandStepColorTemperatureID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000004C, + // Cluster WiFiNetworkManagement commands + MTRCommandIDTypeClusterWiFiNetworkManagementCommandNetworkPassphraseRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterWiFiNetworkManagementCommandNetworkPassphraseResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + + // Cluster ThreadNetworkDirectory commands + MTRCommandIDTypeClusterThreadNetworkDirectoryCommandAddNetworkID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterThreadNetworkDirectoryCommandRemoveNetworkID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterThreadNetworkDirectoryCommandGetOperationalDatasetID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRCommandIDTypeClusterThreadNetworkDirectoryCommandOperationalDatasetResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + // Cluster Channel deprecated command id names MTRClusterChannelCommandChangeChannelID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterChannelCommandChangeChannelID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -7323,6 +7355,9 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { MTREventIDTypeClusterPumpConfigurationAndControlEventAirDetectionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000F, MTREventIDTypeClusterPumpConfigurationAndControlEventTurbineOperationID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000010, + // Cluster ThreadNetworkDirectory events + MTREventIDTypeClusterThreadNetworkDirectoryEventNetworkChangedID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + // Cluster TargetNavigator deprecated event names // Cluster TargetNavigator events diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 474c5cacf47679..2306fdd1c7d92d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -318,6 +318,12 @@ case MTRClusterIDTypeRadonConcentrationMeasurementID: result = @"RadonConcentrationMeasurement"; break; + case MTRClusterIDTypeWiFiNetworkManagementID: + result = @"WiFiNetworkManagement"; + break; + case MTRClusterIDTypeThreadNetworkDirectoryID: + result = @"ThreadNetworkDirectory"; + break; case MTRClusterIDTypeWakeOnLANID: result = @"WakeOnLAN"; break; @@ -7212,6 +7218,90 @@ break; } + case MTRClusterIDTypeWiFiNetworkManagementID: + + switch (attributeID) { + + // Cluster WiFiNetworkManagement attributes + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeSSIDID: + result = @"SSID"; + break; + + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + + case MTRClusterIDTypeThreadNetworkDirectoryID: + + switch (attributeID) { + + // Cluster ThreadNetworkDirectory attributes + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID: + result = @"PreferredExtendedPanID"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworksID: + result = @"ThreadNetworks"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID: + result = @"ThreadNetworkTableSize"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeWakeOnLANID: switch (attributeID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 6e4e0f80b44d00..29249e35e5a360 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -5993,6 +5993,96 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @end +/** + * Cluster Wi-Fi Network Management + * Functionality to retrieve operational information about a managed Wi-Fi network. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterWiFiNetworkManagement : MTRGenericCluster + +- (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)networkPassphraseRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSSIDWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterWiFiNetworkManagement (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + +/** + * Cluster Thread Network Directory + * Manages the names and credentials of Thread networks visible to the user. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterThreadNetworkDirectory : MTRGenericCluster + +- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributePreferredExtendedPanIDWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeThreadNetworksWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeThreadNetworkTableSizeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterThreadNetworkDirectory (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Wake on LAN * This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index db279250cac8bf..c950d5e4f0f1b8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -16768,6 +16768,226 @@ @implementation MTRClusterRadonConcentrationMeasurement @end +@implementation MTRClusterWiFiNetworkManagement + +- (void)networkPassphraseRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self networkPassphraseRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} +- (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeSSIDWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeSSIDID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeClusterRevisionID) params:params]; +} + +@end + +@implementation MTRClusterThreadNetworkDirectory + +- (void)addNetworkWithParams:(MTRThreadNetworkDirectoryClusterAddNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadNetworkDirectoryClusterAddNetworkParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + if (timedInvokeTimeoutMs == nil) { + timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); + } + + using RequestType = ThreadNetworkDirectory::Commands::AddNetwork::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)removeNetworkWithParams:(MTRThreadNetworkDirectoryClusterRemoveNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + if (timedInvokeTimeoutMs == nil) { + timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); + } + + using RequestType = ThreadNetworkDirectory::Commands::RemoveNetwork::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + if (timedInvokeTimeoutMs == nil) { + timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); + } + + using RequestType = ThreadNetworkDirectory::Commands::GetOperationalDataset::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributePreferredExtendedPanIDWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID) params:params]; +} + +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributePreferredExtendedPanIDWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributePreferredExtendedPanIDID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeThreadNetworksWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworksID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeThreadNetworkTableSizeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterWakeOnLAN - (NSDictionary * _Nullable)readAttributeMACAddressWithParams:(MTRReadParams * _Nullable)params diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 1d1552200b5b1c..0017193f50a673 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -8512,6 +8512,162 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams : NSObject +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams : NSObject + +@property (nonatomic, copy) NSData * _Nonnull passphrase MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadNetworkDirectoryClusterAddNetworkParams : NSObject + +@property (nonatomic, copy) NSData * _Nonnull operationalDataset MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadNetworkDirectoryClusterRemoveNetworkParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams : NSObject + +@property (nonatomic, copy) NSData * _Nonnull operationalDataset MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRChannelClusterChangeChannelParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 3105c9a9d21f80..689b7382ab3fb5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -23968,6 +23968,474 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _passphrase = [NSData data]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams alloc] init]; + + other.passphrase = self.passphrase; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: passphrase:%@; >", NSStringFromClass([self class]), [_passphrase base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType &)decodableStruct +{ + { + self.passphrase = AsData(decodableStruct.passphrase); + } + return CHIP_NO_ERROR; +} + +@end + +@implementation MTRThreadNetworkDirectoryClusterAddNetworkParams +- (instancetype)init +{ + if (self = [super init]) { + + _operationalDataset = [NSData data]; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadNetworkDirectoryClusterAddNetworkParams alloc] init]; + + other.operationalDataset = self.operationalDataset; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: operationalDataset:%@; >", NSStringFromClass([self class]), [_operationalDataset base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +@end + +@implementation MTRThreadNetworkDirectoryClusterAddNetworkParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.operationalDataset = AsByteSpan(self.operationalDataset); + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadNetworkDirectoryClusterRemoveNetworkParams +- (instancetype)init +{ + if (self = [super init]) { + + _extendedPanID = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams alloc] init]; + + other.extendedPanID = self.extendedPanID; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; >", NSStringFromClass([self class]), _extendedPanID]; + return descriptionString; +} + +@end + +@implementation MTRThreadNetworkDirectoryClusterRemoveNetworkParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.extendedPanID = self.extendedPanID.unsignedLongLongValue; + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams +- (instancetype)init +{ + if (self = [super init]) { + + _extendedPanID = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams alloc] init]; + + other.extendedPanID = self.extendedPanID; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; >", NSStringFromClass([self class]), _extendedPanID]; + return descriptionString; +} + +@end + +@implementation MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.extendedPanID = self.extendedPanID.unsignedLongLongValue; + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _operationalDataset = [NSData data]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams alloc] init]; + + other.operationalDataset = self.operationalDataset; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: operationalDataset:%@; >", NSStringFromClass([self class]), [_operationalDataset base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType &)decodableStruct +{ + { + self.operationalDataset = AsData(decodableStruct.operationalDataset); + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRChannelClusterChangeChannelParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 2579d3bc49a9bd..5794e71a896729 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1570,6 +1570,42 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType &)decodableStruct; + +@end + +@interface MTRThreadNetworkDirectoryClusterAddNetworkParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadNetworkDirectoryClusterRemoveNetworkParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType &)decodableStruct; + +@end + @interface MTRChannelClusterChangeChannelParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 685ca8f4f035a9..ee4d2c1386bff0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -956,6 +956,33 @@ static BOOL CommandNeedsTimedInvokeInRadonConcentrationMeasurementCluster(Attrib } } } +static BOOL CommandNeedsTimedInvokeInWiFiNetworkManagementCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WiFiNetworkManagement; + switch (aAttributeId) { + default: { + return NO; + } + } +} +static BOOL CommandNeedsTimedInvokeInThreadNetworkDirectoryCluster(AttributeId aAttributeId) +{ + using namespace Clusters::ThreadNetworkDirectory; + switch (aAttributeId) { + case Commands::AddNetwork::Id: { + return YES; + } + case Commands::RemoveNetwork::Id: { + return YES; + } + case Commands::GetOperationalDataset::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInWakeOnLANCluster(AttributeId aAttributeId) { using namespace Clusters::WakeOnLan; @@ -1419,6 +1446,12 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::RadonConcentrationMeasurement::Id: { return CommandNeedsTimedInvokeInRadonConcentrationMeasurementCluster(commandID); } + case Clusters::WiFiNetworkManagement::Id: { + return CommandNeedsTimedInvokeInWiFiNetworkManagementCluster(commandID); + } + case Clusters::ThreadNetworkDirectory::Id: { + return CommandNeedsTimedInvokeInThreadNetworkDirectoryCluster(commandID); + } case Clusters::WakeOnLan::Id: { return CommandNeedsTimedInvokeInWakeOnLANCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index 46427cba7fab3b..06042f32f9f1d8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -71,6 +71,7 @@ { 0x0000007A, DeviceTypeClass::Simple, "Matter Extractor Hood" }, { 0x0000007B, DeviceTypeClass::Simple, "Matter Oven" }, { 0x0000007C, DeviceTypeClass::Simple, "Matter Laundry Dryer" }, + { 0x00000090, DeviceTypeClass::Simple, "Matter Network Infrastructure Manager" }, { 0x00000100, DeviceTypeClass::Simple, "Matter On/Off Light" }, { 0x00000101, DeviceTypeClass::Simple, "Matter Dimmable Light" }, { 0x00000103, DeviceTypeClass::Simple, "Matter On/Off Light Switch" }, @@ -96,7 +97,6 @@ { 0x00000510, DeviceTypeClass::Utility, "Matter Electrical Sensor" }, { 0x00000840, DeviceTypeClass::Simple, "Matter Control Bridge" }, { 0x00000850, DeviceTypeClass::Simple, "Matter On/Off Sensor" }, - { 0xFFF10010, DeviceTypeClass::Simple, "Matter Network Infrastructure Manager" }, }; static_assert(ExtractVendorFromMEI(0xFFF10001) != 0, "Must have class defined for \"Matter Orphan Clusters\" if it's a standard device type"); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 3e36773ffebd99..69c23e1451e9b7 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -4035,6 +4035,47 @@ static id _Nullable DecodeEventPayloadForRadonConcentrationMeasurementCluster(Ev *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForWiFiNetworkManagementCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WiFiNetworkManagement; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} +static id _Nullable DecodeEventPayloadForThreadNetworkDirectoryCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::ThreadNetworkDirectory; + switch (aEventId) { + case Events::NetworkChanged::Id: { + Events::NetworkChanged::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + + __auto_type * value = [MTRThreadNetworkDirectoryClusterNetworkChangedEvent new]; + + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.extendedPanID]; + value.extendedPanID = memberValue; + } while (0); + + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForWakeOnLANCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::WakeOnLan; @@ -4836,6 +4877,12 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::RadonConcentrationMeasurement::Id: { return DecodeEventPayloadForRadonConcentrationMeasurementCluster(aPath.mEventId, aReader, aError); } + case Clusters::WiFiNetworkManagement::Id: { + return DecodeEventPayloadForWiFiNetworkManagementCluster(aPath.mEventId, aReader, aError); + } + case Clusters::ThreadNetworkDirectory::Id: { + return DecodeEventPayloadForThreadNetworkDirectoryCluster(aPath.mEventId, aReader, aError); + } case Clusters::WakeOnLan::Id: { return DecodeEventPayloadForWakeOnLANCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 92bd095b954393..e4d9eb08566a50 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1637,6 +1637,18 @@ MTR_DEPRECATED("Please use MTRThermostatClusterWeeklyScheduleTransitionStruct", @property (nonatomic, copy) NSNumber * _Nullable coolSetpoint MTR_DEPRECATED("Please use MTRThermostatClusterWeeklyScheduleTransitionStruct", ios(16.1, 17.4), macos(13.0, 14.4), watchos(9.1, 10.4), tvos(16.1, 17.4)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadNetworkDirectoryClusterThreadNetworkStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nonnull networkName MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull channel MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRThreadNetworkDirectoryClusterNetworkChangedEvent : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull extendedPanID MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRChannelClusterProgramCastStruct : NSObject @property (nonatomic, copy) NSString * _Nonnull name MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index c9c38c72710756..30c3531c6d7668 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -6884,6 +6884,66 @@ @implementation MTRThermostatClusterThermostatScheduleTransition : MTRThermostat @dynamic coolSetpoint; @end +@implementation MTRThreadNetworkDirectoryClusterThreadNetworkStruct +- (instancetype)init +{ + if (self = [super init]) { + + _extendedPanID = @(0); + + _networkName = @""; + + _channel = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRThreadNetworkDirectoryClusterThreadNetworkStruct alloc] init]; + + other.extendedPanID = self.extendedPanID; + other.networkName = self.networkName; + other.channel = self.channel; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; networkName:%@; channel:%@; >", NSStringFromClass([self class]), _extendedPanID, _networkName, _channel]; + return descriptionString; +} + +@end + +@implementation MTRThreadNetworkDirectoryClusterNetworkChangedEvent +- (instancetype)init +{ + if (self = [super init]) { + + _extendedPanID = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRThreadNetworkDirectoryClusterNetworkChangedEvent alloc] init]; + + other.extendedPanID = self.extendedPanID; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: extendedPanID:%@; >", NSStringFromClass([self class]), _extendedPanID]; + return descriptionString; +} + +@end + @implementation MTRChannelClusterProgramCastStruct - (instancetype)init { diff --git a/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m b/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m index 4253625af80ff7..047ce4f8588816 100644 --- a/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m @@ -34,13 +34,8 @@ static const uint16_t kTestProductId2 = 0x8001u; static const uint16_t kTestDiscriminator1 = 3840u; static const uint16_t kTestDiscriminator2 = 3839u; -static const uint16_t kTestDiscriminator3 = 101u; -static const uint16_t kTestDiscriminator4 = 102u; -static const uint16_t kTestDiscriminator5 = 103u; -static const uint16_t kTestDiscriminator6 = 104u; -static const uint16_t kTestDiscriminator7 = 105u; static const uint16_t kDiscoverDeviceTimeoutInSeconds = 10; -static const uint16_t kExpectedDiscoveredDevicesCount = 7; +static const uint16_t kExpectedDiscoveredDevicesCount = 2; // Singleton controller we use. static MTRDeviceController * sController = nil; @@ -102,7 +97,7 @@ - (void)controller:(MTRDeviceController *)controller didFindCommissionableDevice XCTAssertEqual(instanceName.length, 16); // The instance name is random, so just ensure the len is right. XCTAssertEqualObjects(vendorId, @(kTestVendorId)); XCTAssertTrue([productId isEqual:@(kTestProductId1)] || [productId isEqual:@(kTestProductId2)]); - XCTAssertTrue([discriminator isEqual:@(kTestDiscriminator1)] || [discriminator isEqual:@(kTestDiscriminator2)] || [discriminator isEqual:@(kTestDiscriminator3)] || [discriminator isEqual:@(kTestDiscriminator4)] || [discriminator isEqual:@(kTestDiscriminator5)] || [discriminator isEqual:@(kTestDiscriminator6)] || [discriminator isEqual:@(kTestDiscriminator7)]); + XCTAssertTrue([discriminator isEqual:@(kTestDiscriminator1)] || [discriminator isEqual:@(kTestDiscriminator2)]); XCTAssertEqual(commissioningMode, YES); NSLog(@"Found Device (%@) with discriminator: %@ (vendor: %@, product: %@)", instanceName, discriminator, vendorId, productId); diff --git a/src/darwin/Framework/CHIPTests/MTRControllerTests.m b/src/darwin/Framework/CHIPTests/MTRControllerTests.m index 975625ea55df4b..436a0df230e3d9 100644 --- a/src/darwin/Framework/CHIPTests/MTRControllerTests.m +++ b/src/darwin/Framework/CHIPTests/MTRControllerTests.m @@ -1552,4 +1552,15 @@ - (void)testControllerCATs XCTAssertFalse([factory isRunning]); } +- (void)testSetMRPParameters +{ + // Can be called before starting the factory + XCTAssertFalse(MTRDeviceControllerFactory.sharedInstance.running); + MTRSetMessageReliabilityParameters(@2000, @2000, @2000, @2000); + + // Now reset back to the default state, so timings in other tests are not + // affected. + MTRSetMessageReliabilityParameters(nil, nil, nil, nil); +} + @end diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 1c2d5ddfe39a9a..f0d6aee1a8556b 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -26,6 +26,7 @@ #import "MTRCommandPayloadExtensions_Internal.h" #import "MTRDeviceControllerLocalTestStorage.h" +#import "MTRDeviceStorageBehaviorConfiguration.h" #import "MTRDeviceTestDelegate.h" #import "MTRDevice_Internal.h" #import "MTRErrorTestUtils.h" @@ -35,6 +36,7 @@ #import "MTRTestStorage.h" #import // For INFINITY +#import // system dependencies #import @@ -3023,8 +3025,21 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage // Get the subscription primed __auto_type * device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + + NSTimeInterval baseTestDelayTime = 1; + MTRDeviceStorageBehaviorConfiguration * config = [MTRDeviceStorageBehaviorConfiguration + configurationWithReportToPersistenceDelayTime:baseTestDelayTime + reportToPersistenceDelayTimeMax:baseTestDelayTime * 2 + recentReportTimesMaxCount:5 + timeBetweenReportsTooShortThreshold:baseTestDelayTime * 0.4 + timeBetweenReportsTooShortMinThreshold:baseTestDelayTime * 0.2 + reportToPersistenceDelayMaxMultiplier:baseTestDelayTime * 5 + deviceReportingExcessivelyIntervalThreshold:baseTestDelayTime * 10]; + [device setStorageBehaviorConfiguration:config]; + XCTestExpectation * gotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received"]; XCTestExpectation * gotDeviceCachePrimed = [self expectationWithDescription:@"Device cache primed for the first time"]; + XCTestExpectation * gotClusterDataPersisted1 = [self expectationWithDescription:@"Cluster data persisted 1"]; __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; __weak __auto_type weakDelegate = delegate; delegate.onReportEnd = ^{ @@ -3035,9 +3050,12 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage delegate.onDeviceCachePrimed = ^{ [gotDeviceCachePrimed fulfill]; }; + delegate.onClusterDataPersisted = ^{ + [gotClusterDataPersisted1 fulfill]; + }; [device setDelegate:delegate queue:queue]; - [self waitForExpectations:@[ gotReportsExpectation, gotDeviceCachePrimed ] timeout:60]; + [self waitForExpectations:@[ gotReportsExpectation, gotDeviceCachePrimed, gotClusterDataPersisted1 ] timeout:60]; NSUInteger attributesReportedWithFirstSubscription = [device unitTestAttributesReportedSinceLastCheck]; @@ -3049,6 +3067,7 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; XCTestExpectation * resubGotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received for resubscription"]; + XCTestExpectation * gotClusterDataPersisted2 = [self expectationWithDescription:@"Cluster data persisted 2"]; delegate.onReportEnd = ^{ [resubGotReportsExpectation fulfill]; __strong __auto_type strongDelegate = weakDelegate; @@ -3058,9 +3077,12 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage delegate.onDeviceCachePrimed = ^{ onDeviceCachePrimedCalled = YES; }; + delegate.onClusterDataPersisted = ^{ + [gotClusterDataPersisted2 fulfill]; + }; [device setDelegate:delegate queue:queue]; - [self waitForExpectations:@[ resubGotReportsExpectation ] timeout:60]; + [self waitForExpectations:@[ resubGotReportsExpectation, gotClusterDataPersisted2 ] timeout:60]; // Make sure that the new callback is only ever called once, the first time subscription was primed XCTAssertFalse(onDeviceCachePrimedCalled); @@ -3618,6 +3640,271 @@ - (void)test034_TestMTRDeviceHistoricalEvents XCTAssertTrue(eventReportsReceived > 0); } +- (void)test035_TestMTRDeviceSubscriptionNotEstablishedOverXPC +{ + NSString * const MTRDeviceControllerId = @"MTRController"; + __auto_type remoteController = [MTRDeviceController + sharedControllerWithID:MTRDeviceControllerId + xpcConnectBlock:^NSXPCConnection * _Nonnull { + return nil; + }]; + + __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:remoteController]; + dispatch_queue_t queue = dispatch_get_main_queue(); + + XCTestExpectation * subscriptionExpectation = [self expectationWithDescription:@"Subscription has been set up"]; + subscriptionExpectation.inverted = YES; + + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + + XCTAssertEqual([device _getInternalState], MTRInternalDeviceStateUnsubscribed); + + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + [subscriptionExpectation fulfill]; + }; + + [device setDelegate:delegate queue:queue]; + [self waitForExpectations:@[ subscriptionExpectation ] timeout:5]; + + XCTAssertEqual([device _getInternalState], MTRInternalDeviceStateUnsubscribed); +} + +- (NSArray *> *)_testAttributeReportWithValue:(unsigned int)testValue +{ + return @[ @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeLevelControlID) attributeID:@(MTRAttributeIDTypeClusterLevelControlAttributeCurrentLevelID)], + MTRDataKey : @ { + MTRDataVersionKey : @(testValue), + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(testValue), + } + } ]; +} + +- (void)test036_TestStorageBehaviorConfiguration +{ + // Use separate queue for timing sensitive test + dispatch_queue_t queue = dispatch_queue_create("storage-behavior-queue", DISPATCH_QUEUE_SERIAL); + + NSDictionary * storedClusterDataAfterClear = [sController.controllerDataStore getStoredClusterDataForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); + + __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; + + __auto_type * delegate = [[MTRDeviceTestDelegateWithSubscriptionSetupOverride alloc] init]; + __block os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; + __block NSDate * reportEndTime = nil; + __block NSDate * dataPersistedTime = nil; + + XCTestExpectation * dataPersistedInitial = [self expectationWithDescription:@"data persisted initial"]; + delegate.onReportEnd = ^() { + os_unfair_lock_lock(&lock); + if (!reportEndTime) { + reportEndTime = [NSDate now]; + } + os_unfair_lock_unlock(&lock); + }; + + delegate.onClusterDataPersisted = ^{ + os_unfair_lock_lock(&lock); + if (!dataPersistedTime) { + dataPersistedTime = [NSDate now]; + } + os_unfair_lock_unlock(&lock); + [dataPersistedInitial fulfill]; + }; + + // Do not subscribe - only inject sequence of reports to control the timing + delegate.skipSetupSubscription = YES; + + NSTimeInterval baseTestDelayTime = 3; + + // Set up a config of relatively short timers so this test doesn't take too long + MTRDeviceStorageBehaviorConfiguration * config = [MTRDeviceStorageBehaviorConfiguration + configurationWithReportToPersistenceDelayTime:baseTestDelayTime + reportToPersistenceDelayTimeMax:baseTestDelayTime * 2 + recentReportTimesMaxCount:5 + timeBetweenReportsTooShortThreshold:baseTestDelayTime * 0.4 + timeBetweenReportsTooShortMinThreshold:baseTestDelayTime * 0.2 + reportToPersistenceDelayMaxMultiplier:baseTestDelayTime * 5 + deviceReportingExcessivelyIntervalThreshold:baseTestDelayTime * 7]; + [device setStorageBehaviorConfiguration:config]; + + [device setDelegate:delegate queue:queue]; + + // Use a counter that will be incremented for each report as the value. + unsigned int currentTestValue = 1; + + // Initial setup: Inject report and see that the attribute persisted. No delay is + // expected for the first (priming) report. + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + [self waitForExpectations:@[ dataPersistedInitial ] timeout:60]; + + XCTestExpectation * dataPersisted1 = [self expectationWithDescription:@"data persisted 1"]; + delegate.onClusterDataPersisted = ^{ + os_unfair_lock_lock(&lock); + if (!dataPersistedTime) { + dataPersistedTime = [NSDate now]; + } + os_unfair_lock_unlock(&lock); + [dataPersisted1 fulfill]; + }; + + // Test 1: Inject report and see that the attribute persisted, with a delay + reportEndTime = nil; + dataPersistedTime = nil; + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + [self waitForExpectations:@[ dataPersisted1 ] timeout:60]; + + os_unfair_lock_lock(&lock); + NSTimeInterval reportToPersistenceDelay = [dataPersistedTime timeIntervalSinceDate:reportEndTime]; + os_unfair_lock_unlock(&lock); + // Check delay exists + XCTAssertGreaterThan(reportToPersistenceDelay, baseTestDelayTime / 2); + // Check delay is expectd - use base delay plus small fudge in case of CPU slowness with dispatch_after + XCTAssertLessThan(reportToPersistenceDelay, baseTestDelayTime * 1.3); + + XCTestExpectation * dataPersisted2 = [self expectationWithDescription:@"data persisted 2"]; + + delegate.onClusterDataPersisted = ^{ + os_unfair_lock_lock(&lock); + if (!dataPersistedTime) { + dataPersistedTime = [NSDate now]; + } + os_unfair_lock_unlock(&lock); + [dataPersisted2 fulfill]; + }; + + // Test 2: Inject multiple reports with delay and see that the attribute persisted eventually + reportEndTime = nil; + dataPersistedTime = nil; + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + double frequentReportMultiplier = 0.5; + usleep((useconds_t) (baseTestDelayTime * frequentReportMultiplier * USEC_PER_SEC)); + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + usleep((useconds_t) (baseTestDelayTime * frequentReportMultiplier * USEC_PER_SEC)); + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + usleep((useconds_t) (baseTestDelayTime * frequentReportMultiplier * USEC_PER_SEC)); + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + usleep((useconds_t) (baseTestDelayTime * frequentReportMultiplier * USEC_PER_SEC)); + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + // At this point, the threshold for reportToPersistenceDelayTimeMax should have hit, and persistence + // should have happened with timer running down to persist again with the 5th report above. Need to + // wait for expectation and immediately clear the onClusterDataPersisted callback + + [self waitForExpectations:@[ dataPersisted2 ] timeout:60]; + + os_unfair_lock_lock(&lock); + reportToPersistenceDelay = [dataPersistedTime timeIntervalSinceDate:reportEndTime]; + os_unfair_lock_unlock(&lock); + // Check delay exists and approximately reportToPersistenceDelayTimeMax, which is base delay times 2 + XCTAssertGreaterThan(reportToPersistenceDelay, baseTestDelayTime * 2 * 0.9); + XCTAssertLessThan(reportToPersistenceDelay, baseTestDelayTime * 2 * 1.3); // larger upper limit in case machine is slow + + delegate.onClusterDataPersisted = nil; + + // sleep the base delay interval to allow the onClusterDataPersisted callback to happen. + usleep((useconds_t) (baseTestDelayTime * 1.1 * USEC_PER_SEC)); + + // Test 3: test reporting frequently, and see that the delay time increased + reportEndTime = nil; + dataPersistedTime = nil; + XCTestExpectation * dataPersisted3 = [self expectationWithDescription:@"data persisted 3"]; + delegate.onClusterDataPersisted = ^{ + os_unfair_lock_lock(&lock); + if (!dataPersistedTime) { + dataPersistedTime = [NSDate now]; + } + os_unfair_lock_unlock(&lock); + [dataPersisted3 fulfill]; + }; + + // Set report times with short delay and check that the multiplier is engaged + [device unitTestSetMostRecentReportTimes:[NSMutableArray arrayWithArray:@[ + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.3 * 4)], + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.3 * 3)], + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.3 * 2)], + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.3)], + ]]]; + + // Inject final report that makes MTRDevice recalculate delay with multiplier + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + [self waitForExpectations:@[ dataPersisted3 ] timeout:60]; + + // 0.3 is between 0.4 and 0.2, which should get us at least 50% of the multiplier. + // The multiplier is 5, which is +400% of the base delay, and so 50% of the multiplier + // is +200% of the base delay, meaning 3x the base delay. + + os_unfair_lock_lock(&lock); + reportToPersistenceDelay = [dataPersistedTime timeIntervalSinceDate:reportEndTime]; + os_unfair_lock_unlock(&lock); + // Check delay exists and at least base delay times 3 + XCTAssertGreaterThan(reportToPersistenceDelay, baseTestDelayTime * 3 * 0.9); + // upper limit at most max delay times full multiplier + extra in case machine is slow + XCTAssertLessThan(reportToPersistenceDelay, baseTestDelayTime * 2 * 5 * 1.3); + + // Test 4: test reporting excessively, and see that persistence does not happen until + // reporting frequency goes back above the threshold + reportEndTime = nil; + dataPersistedTime = nil; + XCTestExpectation * dataPersisted4 = [self expectationWithDescription:@"data persisted 4"]; + delegate.onClusterDataPersisted = ^{ + os_unfair_lock_lock(&lock); + if (!dataPersistedTime) { + dataPersistedTime = [NSDate now]; + } + os_unfair_lock_unlock(&lock); + [dataPersisted4 fulfill]; + }; + + // Set report times with short delay and check that the multiplier is engaged + [device unitTestSetMostRecentReportTimes:[NSMutableArray arrayWithArray:@[ + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.1 * 4)], + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.1 * 3)], + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.1 * 2)], + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 0.1)], + ]]]; + + // Inject report that makes MTRDevice detect the device is reporting excessively + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + // Now keep reporting excessively for base delay time max times max multiplier, plus a bit more + NSDate * excessiveStartTime = [NSDate now]; + for (;;) { + usleep((useconds_t) (baseTestDelayTime * 0.1 * USEC_PER_SEC)); + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + NSTimeInterval elapsed = -[excessiveStartTime timeIntervalSinceNow]; + if (elapsed > (baseTestDelayTime * 2 * 5 * 1.2)) { + break; + } + } + + // Check that persistence has not happened because it's now turned off + XCTAssertNil(dataPersistedTime); + + // Now force report times to large number, to simulate time passage + [device unitTestSetMostRecentReportTimes:[NSMutableArray arrayWithArray:@[ + [NSDate dateWithTimeIntervalSinceNow:-(baseTestDelayTime * 10)], + ]]]; + + // And inject a report to trigger MTRDevice to recalculate that this device is no longer + // reporting excessively + [device unitTestInjectAttributeReport:[self _testAttributeReportWithValue:currentTestValue++] fromSubscription:YES]; + + [self waitForExpectations:@[ dataPersisted4 ] timeout:60]; + + delegate.onReportEnd = nil; + delegate.onClusterDataPersisted = nil; +} + @end @interface MTRDeviceEncoderTests : XCTestCase diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index a415f4c5f0b07d..fc233ffaebf93d 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -19,6 +19,7 @@ #import #import "MTRDeviceControllerLocalTestStorage.h" +#import "MTRDeviceStorageBehaviorConfiguration.h" #import "MTRDeviceTestDelegate.h" #import "MTRDevice_Internal.h" #import "MTRErrorTestUtils.h" @@ -28,6 +29,7 @@ #import "MTRTestKeys.h" #import "MTRTestPerControllerStorage.h" #import "MTRTestResetCommissioneeHelper.h" +#import "MTRTestServerAppRunner.h" static const uint16_t kPairingTimeoutInSeconds = 10; static const uint16_t kTimeoutInSeconds = 3; @@ -259,10 +261,12 @@ - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)roo fabricID:(NSNumber *)fabricID nodeID:(NSNumber *)nodeID storage:(MTRTestPerControllerStorage *)storage - caseAuthenticatedTags:(nullable NSSet *)caseAuthenticatedTags + caseAuthenticatedTags:(NSSet * _Nullable)caseAuthenticatedTags error:(NSError * __autoreleasing *)error certificateIssuer: (MTRPerControllerStorageTestsCertificateIssuer * __autoreleasing *)certificateIssuer + concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize + storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration * _Nullable)storageBehaviorConfiguration { XCTAssertTrue(error != NULL); @@ -307,9 +311,52 @@ - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)roo [params setOperationalCertificateIssuer:ourCertificateIssuer queue:dispatch_get_main_queue()]; + if (concurrentSubscriptionPoolSize > 0) { + params.concurrentSubscriptionEstablishmentsAllowedOnThread = concurrentSubscriptionPoolSize; + } + + if (storageBehaviorConfiguration) { + params.storageBehaviorConfiguration = storageBehaviorConfiguration; + } + return [[MTRDeviceController alloc] initWithParameters:params error:error]; } +- (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)rootKeys + operationalKeys:(MTRTestKeys *)operationalKeys + fabricID:(NSNumber *)fabricID + nodeID:(NSNumber *)nodeID + storage:(MTRTestPerControllerStorage *)storage + caseAuthenticatedTags:(nullable NSSet *)caseAuthenticatedTags + error:(NSError * __autoreleasing *)error + certificateIssuer: + (MTRPerControllerStorageTestsCertificateIssuer * __autoreleasing *)certificateIssuer +{ + return [self startControllerWithRootKeys:rootKeys operationalKeys:operationalKeys fabricID:fabricID nodeID:nodeID storage:storage caseAuthenticatedTags:caseAuthenticatedTags error:error certificateIssuer:certificateIssuer concurrentSubscriptionPoolSize:0 storageBehaviorConfiguration:nil]; +} + +- (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)rootKeys + operationalKeys:(MTRTestKeys *)operationalKeys + fabricID:(NSNumber *)fabricID + nodeID:(NSNumber *)nodeID + storage:(MTRTestPerControllerStorage *)storage + error:(NSError * __autoreleasing *)error + certificateIssuer: + (MTRPerControllerStorageTestsCertificateIssuer * __autoreleasing *)certificateIssuer + concurrentSubscriptionPoolSize:(NSUInteger)concurrentSubscriptionPoolSize +{ + return [self startControllerWithRootKeys:rootKeys + operationalKeys:operationalKeys + fabricID:fabricID + nodeID:nodeID + storage:storage + caseAuthenticatedTags:nil + error:error + certificateIssuer:certificateIssuer + concurrentSubscriptionPoolSize:concurrentSubscriptionPoolSize + storageBehaviorConfiguration:nil]; +} + - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)rootKeys operationalKeys:(MTRTestKeys *)operationalKeys fabricID:(NSNumber *)fabricID @@ -318,6 +365,7 @@ - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)roo error:(NSError * __autoreleasing *)error certificateIssuer: (MTRPerControllerStorageTestsCertificateIssuer * __autoreleasing *)certificateIssuer + storageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration * _Nullable)storageBehaviorConfiguration { return [self startControllerWithRootKeys:rootKeys operationalKeys:operationalKeys @@ -326,7 +374,30 @@ - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)roo storage:storage caseAuthenticatedTags:nil error:error - certificateIssuer:certificateIssuer]; + certificateIssuer:certificateIssuer + concurrentSubscriptionPoolSize:0 + storageBehaviorConfiguration:storageBehaviorConfiguration]; +} + +- (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)rootKeys + operationalKeys:(MTRTestKeys *)operationalKeys + fabricID:(NSNumber *)fabricID + nodeID:(NSNumber *)nodeID + storage:(MTRTestPerControllerStorage *)storage + error:(NSError * __autoreleasing *)error + certificateIssuer: + (MTRPerControllerStorageTestsCertificateIssuer * __autoreleasing *)certificateIssuer +{ + return [self startControllerWithRootKeys:rootKeys + operationalKeys:operationalKeys + fabricID:fabricID + nodeID:nodeID + storage:storage + caseAuthenticatedTags:nil + error:error + certificateIssuer:certificateIssuer + concurrentSubscriptionPoolSize:0 + storageBehaviorConfiguration:nil]; } - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)rootKeys @@ -344,7 +415,9 @@ - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)roo storage:storage caseAuthenticatedTags:caseAuthenticatedTags error:error - certificateIssuer:nil]; + certificateIssuer:nil + concurrentSubscriptionPoolSize:0 + storageBehaviorConfiguration:nil]; } - (nullable MTRDeviceController *)startControllerWithRootKeys:(MTRTestKeys *)rootKeys @@ -1315,7 +1388,7 @@ - (void)test008_TestDataStoreDirect XCTAssertFalse([controller isRunning]); } -- (void)doDataStoreMTRDeviceTestWithStorageDelegate:(id)storageDelegate +- (void)doDataStoreMTRDeviceTestWithStorageDelegate:(id)storageDelegate disableStorageBehaviorOptimization:(BOOL)disableStorageBehaviorOptimization { __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); @@ -1334,13 +1407,18 @@ - (void)doDataStoreMTRDeviceTestWithStorageDelegate:(id * dataStoreClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:deviceID]; @@ -1413,32 +1498,44 @@ - (void)doDataStoreMTRDeviceTestWithStorageDelegate:(id *)deviceOnboardingPayloads { __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); @@ -2059,12 +2178,7 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize NSError * error; - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; - NSNumber * subscriptionPoolSizeOverrideOriginalValue = [defaults objectForKey:kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey]; - // Test DeviceController with a Subscription pool - [defaults setInteger:subscriptionPoolSize forKey:kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey]; - MTRPerControllerStorageTestsCertificateIssuer * certificateIssuer; MTRDeviceController * controller = [self startControllerWithRootKeys:rootKeys operationalKeys:operationalKeys @@ -2072,22 +2186,15 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize nodeID:nodeID storage:storageDelegate error:&error - certificateIssuer:&certificateIssuer]; + certificateIssuer:&certificateIssuer + concurrentSubscriptionPoolSize:subscriptionPoolSize]; XCTAssertNil(error); XCTAssertNotNil(controller); XCTAssertTrue([controller isRunning]); XCTAssertEqualObjects(controller.controllerNodeID, nodeID); - // QRCodes generated for discriminators 101~105 and passcodes 1001~1005 NSArray * orderedDeviceIDs = @[ @(101), @(102), @(103), @(104), @(105) ]; - NSDictionary * deviceOnboardingPayloads = @{ - @(101) : @"MT:00000EBQ15IZC900000", - @(102) : @"MT:00000MNY16-AD900000", - @(103) : @"MT:00000UZ427GOD900000", - @(104) : @"MT:00000CQM00Z.D900000", - @(105) : @"MT:00000K0V01FDE900000", - }; // Commission 5 devices for (NSNumber * deviceID in orderedDeviceIDs) { @@ -2164,18 +2271,514 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize [controller shutdown]; XCTAssertFalse([controller isRunning]); +} - if (subscriptionPoolSizeOverrideOriginalValue) { - [defaults setInteger:subscriptionPoolSizeOverrideOriginalValue.integerValue forKey:kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey]; - } else { - [defaults removeObjectForKey:kLocalTestUserDefaultSubscriptionPoolSizeOverrideKey]; +- (void)testSubscriptionPool +{ + // QRCodes generated for discriminators 1111~1115 and passcodes 1001~1005 + NSDictionary * deviceOnboardingPayloads = @{ + @(101) : @"MT:00000UZ427U0D900000", + @(102) : @"MT:00000CQM00BED900000", + @(103) : @"MT:00000K0V01TRD900000", + @(104) : @"MT:00000SC11293E900000", + @(105) : @"MT:00000-O913RGE900000", + }; + + // Start our helper apps. + __auto_type * sortedKeys = [[deviceOnboardingPayloads allKeys] sortedArrayUsingSelector:@selector(compare:)]; + for (NSNumber * deviceID in sortedKeys) { + __auto_type * appRunner = [[MTRTestServerAppRunner alloc] initWithAppName:@"all-clusters" + arguments:@[] + payload:deviceOnboardingPayloads[deviceID] + testcase:self]; + XCTAssertNotNil(appRunner); } + + [self doTestSubscriptionPoolWithSize:1 deviceOnboardingPayloads:deviceOnboardingPayloads]; + [self doTestSubscriptionPoolWithSize:2 deviceOnboardingPayloads:deviceOnboardingPayloads]; } -- (void)testSubscriptionPool +- (MTRDevice *)getMTRDevice:(NSNumber *)deviceID +{ + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; + XCTAssertNotNil(factory); + + __auto_type * rootKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(rootKeys); + + __auto_type * operationalKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(operationalKeys); + + NSNumber * nodeID = @(123); + NSNumber * fabricID = @(456); + + NSError * error; + __auto_type * storageDelegate = [[MTRTestPerControllerStorageWithBulkReadWrite alloc] initWithControllerID:[NSUUID UUID]]; + 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); + + certificateIssuer.nextNodeID = deviceID; + [self commissionWithController:controller newNodeID:deviceID]; + + MTRDevice * device = [MTRDevice deviceWithNodeID:deviceID controller:controller]; + return device; +} + +- (NSMutableArray *)getEndpointArrayFromPartsList:(MTRDeviceDataValueDictionary)partsList forDevice:(MTRDevice *)device { - [self doTestSubscriptionPoolWithSize:1]; - [self doTestSubscriptionPoolWithSize:2]; + // Initialize the endpoint array with endpoint 0. + NSMutableArray * endpoints = [NSMutableArray arrayWithObject:@0]; + + [endpoints addObjectsFromArray:[device arrayOfNumbersFromAttributeValue:partsList]]; + return endpoints; +} + +- (void)testDataStorageUpdatesWhenRemovingEndpoints +{ + NSNumber * deviceID = @(17); + __auto_type * device = [self getMTRDevice:deviceID]; + __auto_type queue = dispatch_get_main_queue(); + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + __auto_type * controller = device.deviceController; + + XCTestExpectation * subscriptionExpectation = [self expectationWithDescription:@"Subscription has been set up"]; + + __block NSNumber * dataVersionForPartsList; + __block NSNumber * rootEndpoint = @0; + + // This test will do the following - + // 1. Get the data version and attribute value of the parts list for endpoint 0 to inject a fake report. The attribute report will delete endpoint 2. + // That should cause the endpoint and its corresponding clusters to be removed from data storage. + // 2. The data store is populated with cluster index and cluster data for endpoints 0, 1 and 2 initially. + // 3. After the fake attribute report is injected with deleted endpoint 2, make sure the data store is still populated with cluster index and cluster data + // for endpoints 0 and 1 but not 2. + __block MTRDeviceDataValueDictionary testDataForPartsList; + __block id testClusterDataValueForPartsList; + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + XCTAssertGreaterThan(attributeReport.count, 0); + + for (NSDictionary * attributeDict in attributeReport) { + MTRAttributePath * attributePath = attributeDict[MTRAttributePathKey]; + XCTAssertNotNil(attributePath); + + if ([attributePath.endpoint isEqualToNumber:rootEndpoint] && attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributePartsListID) { + testDataForPartsList = attributeDict[MTRDataKey]; + XCTAssertNotNil(testDataForPartsList); + dataVersionForPartsList = testDataForPartsList[MTRDataVersionKey]; + id dataValue = testDataForPartsList[MTRValueKey]; + XCTAssertNotNil(dataValue); + testClusterDataValueForPartsList = [dataValue mutableCopy]; + } + } + }; + + __block NSMutableDictionary *> * initialClusterIndex = [[NSMutableDictionary alloc] init]; + __block NSMutableArray * testEndpoints; + + delegate.onReportEnd = ^{ + XCTAssertNotNil(dataVersionForPartsList); + XCTAssertNotNil(testClusterDataValueForPartsList); + testEndpoints = [self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]; + + // Make sure that the cluster data in the data storage is populated with cluster index and cluster data for endpoints 0, 1 and 2. + // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so + // just checking data storage should suffice here. + dispatch_sync(self->_storageQueue, ^{ + XCTAssertTrue([[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID] isEqualToArray:testEndpoints]); + + // Populate the initialClusterIndex to use as a reference for all cluster paths later. + for (NSNumber * endpoint in testEndpoints) { + [initialClusterIndex setObject:[controller.controllerDataStore _fetchClusterIndexForNodeID:deviceID endpointID:endpoint] forKey:endpoint]; + } + + for (NSNumber * endpoint in testEndpoints) { + for (NSNumber * cluster in [initialClusterIndex objectForKey:endpoint]) { + XCTAssertNotNil([controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:endpoint clusterID:cluster]); + } + } + }); + [subscriptionExpectation fulfill]; + }; + + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ subscriptionExpectation ] timeout:60]; + + // Inject a fake attribute report deleting endpoint 2 from the parts list at the root endpoint. + dataVersionForPartsList = [NSNumber numberWithUnsignedLongLong:(dataVersionForPartsList.unsignedLongLongValue + 1)]; + + // Delete endpoint 2 from the attribute value in parts list. + NSNumber * toBeDeletedEndpoint = @2; + id endpointData = + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : toBeDeletedEndpoint, + } + }; + + [testClusterDataValueForPartsList removeObject:endpointData]; + + NSArray *> * attributeReport = @[ @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:rootEndpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)], + MTRDataKey : @ { + MTRDataVersionKey : dataVersionForPartsList, + MTRTypeKey : MTRArrayValueType, + MTRValueKey : testClusterDataValueForPartsList, + } + } ]; + + XCTestExpectation * attributeDataReceivedExpectation = [self expectationWithDescription:@"Injected Attribute data received"]; + XCTestExpectation * reportEndExpectation = [self expectationWithDescription:@"Injected Attribute data report ended"]; + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + XCTAssertGreaterThan(attributeReport.count, 0); + + for (NSDictionary * attributeDict in attributeReport) { + MTRAttributePath * attributePath = attributeDict[MTRAttributePathKey]; + XCTAssertNotNil(attributePath); + + // Get the new updated parts list value to get the new test endpoints. + if ([attributePath.endpoint isEqualToNumber:rootEndpoint] && attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributePartsListID) { + testDataForPartsList = attributeDict[MTRDataKey]; + XCTAssertNotNil(testDataForPartsList); + id dataValue = testDataForPartsList[MTRValueKey]; + XCTAssertNotNil(dataValue); + testClusterDataValueForPartsList = [dataValue mutableCopy]; + } + } + [attributeDataReceivedExpectation fulfill]; + }; + + delegate.onReportEnd = ^{ + XCTAssertNotNil(testClusterDataValueForPartsList); + testEndpoints = [self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]; + + // Make sure that the cluster data in the data storage for endpoints 0 and 1 are present but not for endpoint 2. + // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so + // just checking data storage should suffice here. + dispatch_sync(self->_storageQueue, ^{ + XCTAssertTrue([[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID] isEqualToArray:testEndpoints]); + for (NSNumber * endpoint in testEndpoints) { + XCTAssertNotNil(initialClusterIndex); + for (NSNumber * cluster in [initialClusterIndex objectForKey:endpoint]) { + if ([endpoint isEqualToNumber:toBeDeletedEndpoint]) { + XCTAssertNil([controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:endpoint clusterID:cluster]); + } else { + XCTAssertNotNil([controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:endpoint clusterID:cluster]); + } + } + } + }); + [reportEndExpectation fulfill]; + }; + + [device unitTestInjectAttributeReport:attributeReport fromSubscription:YES]; + + [self waitForExpectations:@[ attributeDataReceivedExpectation, reportEndExpectation ] timeout:60]; + + [controller.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [controller.controllerDataStore getStoredClusterDataForNodeID:deviceID]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); + + [controller removeDevice:device]; + // Reset our commissionee. + __auto_type * baseDevice = [MTRBaseDevice deviceWithNodeID:deviceID controller:controller]; + ResetCommissionee(baseDevice, queue, self, kTimeoutInSeconds); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); +} + +- (void)testDataStorageUpdatesWhenRemovingClusters +{ + NSNumber * deviceID = @(17); + __auto_type * device = [self getMTRDevice:deviceID]; + __auto_type queue = dispatch_get_main_queue(); + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + __auto_type * controller = device.deviceController; + + XCTestExpectation * subscriptionExpectation = [self expectationWithDescription:@"Subscription has been set up"]; + + __block NSNumber * dataVersionForServerList; + __block NSNumber * testEndpoint = @1; + + // This test will do the following - + // 1. Get the data version and attribute value of the server list for endpoint 1 to inject a fake report. The attribute report will delete cluster ID - MTRClusterIDTypeIdentifyID. + // That should cause the cluster to be removed from cluster index for endpoint 1 and the cluster data for the removed cluster should be cleared from data storage. + // 2. The data store is populated with MTRClusterIDTypeIdentifyID in the cluster index and cluster data for endpoint 1 initially. + // 3. After the fake attribute report is injected with deleted cluster ID - MTRClusterIDTypeIdentifyID, make sure the data store is still populated with cluster index and + // cluster data for all other clusters at endpoint 1 but not the deleted cluster. + __block id testClusterDataValue; + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + XCTAssertGreaterThan(attributeReport.count, 0); + + for (NSDictionary * attributeDict in attributeReport) { + MTRAttributePath * attributePath = attributeDict[MTRAttributePathKey]; + XCTAssertNotNil(attributePath); + + if ([attributePath.endpoint isEqualToNumber:testEndpoint] && attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterDescriptorAttributeServerListID) { + MTRDeviceDataValueDictionary data = attributeDict[MTRDataKey]; + XCTAssertNotNil(data); + dataVersionForServerList = data[MTRDataVersionKey]; + id dataValue = data[MTRValueKey]; + XCTAssertNotNil(dataValue); + testClusterDataValue = [dataValue mutableCopy]; + } + } + }; + + __block NSMutableArray * initialClusterIndex = [[NSMutableArray alloc] init]; + __block NSNumber * toBeDeletedCluster = @(MTRClusterIDTypeIdentifyID); + + delegate.onReportEnd = ^{ + XCTAssertNotNil(dataVersionForServerList); + XCTAssertNotNil(testClusterDataValue); + + // Make sure that the cluster data in the data storage has cluster ID - MTRClusterIDTypeIdentifyID in the cluster index for endpoint 1 + // and cluster data for MTRClusterIDTypeIdentifyID exists. + // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so + // just checking data storage should suffice here. + dispatch_sync(self->_storageQueue, ^{ + initialClusterIndex = [[controller.controllerDataStore _fetchClusterIndexForNodeID:deviceID endpointID:testEndpoint] mutableCopy]; + XCTAssertTrue([initialClusterIndex containsObject:toBeDeletedCluster]); + for (NSNumber * cluster in initialClusterIndex) { + XCTAssertNotNil([controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:testEndpoint clusterID:cluster]); + } + }); + [subscriptionExpectation fulfill]; + }; + + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ subscriptionExpectation ] timeout:60]; + + // Inject a fake attribute report after removing cluster ID - MTRClusterIDTypeIdentifyID from endpoint 1 to the server list. + dataVersionForServerList = [NSNumber numberWithUnsignedLongLong:(dataVersionForServerList.unsignedLongLongValue + 1)]; + id identifyClusterData = + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : toBeDeletedCluster, + } + }; + [testClusterDataValue removeObject:identifyClusterData]; + + NSArray *> * attributeReport = @[ @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:testEndpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID)], + MTRDataKey : @ { + MTRDataVersionKey : dataVersionForServerList, + MTRTypeKey : MTRArrayValueType, + MTRValueKey : testClusterDataValue, + } + } ]; + + XCTestExpectation * attributeDataReceivedExpectation = [self expectationWithDescription:@"Injected Attribute data received"]; + XCTestExpectation * reportEndExpectation = [self expectationWithDescription:@"Injected Attribute data report ended"]; + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + XCTAssertGreaterThan(attributeReport.count, 0); + [attributeDataReceivedExpectation fulfill]; + }; + + delegate.onReportEnd = ^{ + // Make sure that the cluster data does not have cluster ID - MTRClusterIDTypeIdentifyID in the cluster index for endpoint 1 + // and cluster data for MTRClusterIDTypeIdentifyID is nil. + // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so + // just checking data storage should suffice here. + dispatch_sync(self->_storageQueue, ^{ + XCTAssertFalse([[controller.controllerDataStore _fetchClusterIndexForNodeID:deviceID endpointID:testEndpoint] containsObject:toBeDeletedCluster]); + for (NSNumber * cluster in initialClusterIndex) { + if ([cluster isEqualToNumber:toBeDeletedCluster]) { + XCTAssertNil([controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:testEndpoint clusterID:cluster]); + } else { + XCTAssertNotNil([controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:testEndpoint clusterID:cluster]); + } + } + }); + [reportEndExpectation fulfill]; + }; + + [device unitTestInjectAttributeReport:attributeReport fromSubscription:YES]; + + [self waitForExpectations:@[ attributeDataReceivedExpectation, reportEndExpectation ] timeout:60]; + + [controller.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [controller.controllerDataStore getStoredClusterDataForNodeID:deviceID]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); + + [controller removeDevice:device]; + // Reset our commissionee. + __auto_type * baseDevice = [MTRBaseDevice deviceWithNodeID:deviceID controller:controller]; + ResetCommissionee(baseDevice, queue, self, kTimeoutInSeconds); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); +} + +- (void)testDataStorageUpdatesWhenRemovingAttributes +{ + NSNumber * deviceID = @(17); + __auto_type * device = [self getMTRDevice:deviceID]; + __auto_type queue = dispatch_get_main_queue(); + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + __auto_type * controller = device.deviceController; + + XCTestExpectation * subscriptionExpectation = [self expectationWithDescription:@"Subscription has been set up"]; + + __block NSNumber * dataVersionForIdentify; + __block NSNumber * testEndpoint = @(1); + __block NSNumber * toBeDeletedAttribute = @(1); + __block id testClusterDataValue; + + // This test will do the following - + // 1. Get the data version and attribute value of the attribute list for endpoint 1 to inject a fake report with attribute 1 removed from MTRClusterIDTypeIdentifyID. + // 2. The data store is populated with cluster data for MTRClusterIDTypeIdentifyID cluster and has all attributes including attribute 1. + // 3. After the fake attribute report is injected, make sure the data store is populated with cluster data for all attributes in MTRClusterIDTypeIdentifyID + // cluster except for attribute 1 which has been deleted. + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + XCTAssertGreaterThan(attributeReport.count, 0); + + for (NSDictionary * attributeDict in attributeReport) { + MTRAttributePath * attributePath = attributeDict[MTRAttributePathKey]; + XCTAssertNotNil(attributePath); + + if ([attributePath.endpoint isEqualToNumber:testEndpoint] && attributePath.cluster.unsignedLongValue == MTRClusterIDTypeIdentifyID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeGlobalAttributeAttributeListID) { + MTRDeviceDataValueDictionary data = attributeDict[MTRDataKey]; + XCTAssertNotNil(data); + dataVersionForIdentify = data[MTRDataVersionKey]; + id dataValue = data[MTRValueKey]; + XCTAssertNotNil(dataValue); + testClusterDataValue = [dataValue mutableCopy]; + } + } + }; + + __block NSMutableArray * initialTestAttributes = [[NSMutableArray alloc] init]; + + delegate.onReportEnd = ^{ + XCTAssertNotNil(dataVersionForIdentify); + XCTAssertNotNil(testClusterDataValue); + + dispatch_sync(self->_storageQueue, ^{ + for (NSNumber * cluster in [controller.controllerDataStore _fetchClusterIndexForNodeID:deviceID endpointID:testEndpoint]) { + + // Make sure that the cluster data in the data storage is populated with cluster data for MTRClusterIDTypeIdentifyID cluster + // and has all attributes including attribute 1. + // We will page in the cluster data from storage to check the above. + MTRClusterPath * path = [MTRClusterPath clusterPathWithEndpointID:testEndpoint clusterID:cluster]; + + if ([cluster isEqualToNumber:@(MTRClusterIDTypeIdentifyID)]) { + MTRDeviceClusterData * data = [device _getClusterDataForPath:path]; + XCTAssertNotNil(data); + XCTAssertNotNil(data.attributes); + + MTRDeviceDataValueDictionary dict = [data.attributes objectForKey:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)]; + XCTAssertNotNil(dict); + + NSMutableArray * persistedAttributes = [device arrayOfNumbersFromAttributeValue:dict]; + initialTestAttributes = [device arrayOfNumbersFromAttributeValue:@ { MTRTypeKey : MTRArrayValueType, MTRValueKey : testClusterDataValue }]; + XCTAssertNotNil(persistedAttributes); + for (NSNumber * attribute in initialTestAttributes) { + XCTAssertTrue([persistedAttributes containsObject:attribute]); + } + } + } + }); + + [subscriptionExpectation fulfill]; + }; + + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ subscriptionExpectation ] timeout:60]; + + dataVersionForIdentify = [NSNumber numberWithUnsignedLongLong:(dataVersionForIdentify.unsignedLongLongValue + 1)]; + id attributeData = + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : toBeDeletedAttribute, + } + }; + + [testClusterDataValue removeObject:attributeData]; + + NSArray *> * attributeReport = @[ @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:testEndpoint clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], + MTRDataKey : @ { + MTRDataVersionKey : dataVersionForIdentify, + MTRTypeKey : MTRArrayValueType, + MTRValueKey : testClusterDataValue, + } + } ]; + + XCTestExpectation * attributeDataReceivedExpectation = [self expectationWithDescription:@"Injected Attribute data received"]; + XCTestExpectation * reportEndExpectation = [self expectationWithDescription:@"Injected Attribute data report ended"]; + delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + XCTAssertGreaterThan(attributeReport.count, 0); + + [attributeDataReceivedExpectation fulfill]; + }; + + delegate.onReportEnd = ^{ + // Make sure that the cluster data in the data storage is populated with cluster data for MTRClusterIDTypeIdentifyID cluster + // and has all attributes except attribute 1 which was deleted. + // We will page in the cluster data from storage to check the above. + dispatch_sync(self->_storageQueue, ^{ + for (NSNumber * cluster in [controller.controllerDataStore _fetchClusterIndexForNodeID:deviceID endpointID:testEndpoint]) { + MTRDeviceClusterData * clusterData = [controller.controllerDataStore _fetchClusterDataForNodeID:deviceID endpointID:testEndpoint clusterID:cluster]; + XCTAssertNotNil(clusterData); + MTRClusterPath * path = [MTRClusterPath clusterPathWithEndpointID:testEndpoint clusterID:cluster]; + + if ([cluster isEqualToNumber:@(MTRClusterIDTypeIdentifyID)]) { + MTRDeviceClusterData * data = [device _getClusterDataForPath:path]; + XCTAssertNotNil(data); + XCTAssertNotNil(data.attributes); + + MTRDeviceDataValueDictionary attributeListValue = [data.attributes objectForKey:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)]; + XCTAssertNotNil(attributeListValue); + + NSMutableArray * persistedAttributes = [device arrayOfNumbersFromAttributeValue:attributeListValue]; + XCTAssertNotNil(persistedAttributes); + for (NSNumber * attribute in initialTestAttributes) { + if ([attribute isEqualToNumber:toBeDeletedAttribute]) { + XCTAssertFalse([persistedAttributes containsObject:attribute]); + } else { + XCTAssertTrue([persistedAttributes containsObject:attribute]); + } + } + } + } + }); + + [reportEndExpectation fulfill]; + }; + + [device unitTestInjectAttributeReport:attributeReport fromSubscription:YES]; + + [self waitForExpectations:@[ attributeDataReceivedExpectation, reportEndExpectation ] timeout:60]; + + [controller.controllerDataStore clearAllStoredClusterData]; + NSDictionary * storedClusterDataAfterClear = [controller.controllerDataStore getStoredClusterDataForNodeID:deviceID]; + XCTAssertEqual(storedClusterDataAfterClear.count, 0); + + [controller removeDevice:device]; + // 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 2492a184e2c69c..0ca5026a7c5e73 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h @@ -34,6 +34,11 @@ typedef void (^MTRDeviceTestDelegateDataHandler)(NSArray *)_fetchEndpointIndexForNodeID:(NSNumber *)nodeID; +- (nullable NSArray *)_fetchClusterIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID; +- (nullable MTRDeviceClusterData *)_fetchClusterDataForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; @end // Declare internal methods for testing @@ -44,6 +47,9 @@ NS_ASSUME_NONNULL_BEGIN @interface MTRDevice (Test) - (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; +- (MTRDeviceClusterData *)_getClusterDataForPath:(MTRClusterPath *)path; +- (BOOL)_clusterHasBeenPersisted:(MTRClusterPath *)path; +- (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary; @end #pragma mark - Declarations for items compiled only for DEBUG configuration @@ -63,6 +69,15 @@ NS_ASSUME_NONNULL_BEGIN - (void)unitTestInjectAttributeReport:(NSArray *> *)attributeReport fromSubscription:(BOOL)isFromSubscription; - (NSUInteger)unitTestAttributesReportedSinceLastCheck; - (void)unitTestClearClusterData; +- (MTRInternalDeviceState)_getInternalState; +- (void)unitTestSetReportToPersistenceDelayTime:(NSTimeInterval)reportToPersistenceDelayTime + reportToPersistenceDelayTimeMax:(NSTimeInterval)reportToPersistenceDelayTimeMax + recentReportTimesMaxCount:(NSUInteger)recentReportTimesMaxCount + timeBetweenReportsTooShortThreshold:(NSTimeInterval)timeBetweenReportsTooShortThreshold + timeBetweenReportsTooShortMinThreshold:(NSTimeInterval)timeBetweenReportsTooShortMinThreshold + reportToPersistenceDelayMaxMultiplier:(double)reportToPersistenceDelayMaxMultiplier + deviceReportingExcessivelyIntervalThreshold:(NSTimeInterval)deviceReportingExcessivelyIntervalThreshold; +- (void)unitTestSetMostRecentReportTimes:(NSMutableArray *)mostRecentReportTimes; @end #endif diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m index 83912e9eb2dc0b..18424ed332a6af 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m @@ -90,7 +90,7 @@ - (instancetype)initWithAppName:(NSString *)name arguments:(NSArray [testcase launchTask:_appTask]; - NSLog(@"Started %@ with arguments %@ stdout=%@ and stderr=%@", name, allArguments, outFile, errorFile); + NSLog(@"Started chip-%@-app with arguments %@ stdout=%@ and stderr=%@", name, allArguments, outFile, errorFile); return self; #endif // HAVE_NSTASK diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 212c859610172b..df5949868d0012 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -254,6 +254,8 @@ 75139A702B7FE68C00E3A919 /* MTRDeviceControllerLocalTestStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */; }; 7534F12928BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7534F12728BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h */; }; + 754784652BFE65CB0089C372 /* MTRDeviceStorageBehaviorConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = 754784642BFE65CB0089C372 /* MTRDeviceStorageBehaviorConfiguration.mm */; }; + 754784672BFE93B00089C372 /* MTRDeviceStorageBehaviorConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 754784632BFE65B70089C372 /* MTRDeviceStorageBehaviorConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 754F3DF427FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 754F3DF327FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h */; }; 7560FD1C27FBBD3F005E85B3 /* MTREventTLVValueDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7560FD1B27FBBD3F005E85B3 /* MTREventTLVValueDecoder.mm */; }; 7596A83E28751220004DAE0E /* MTRBaseClusters_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7596A83D28751220004DAE0E /* MTRBaseClusters_Internal.h */; }; @@ -676,6 +678,9 @@ 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceControllerLocalTestStorage.mm; sourceTree = ""; }; 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceAttestationDelegate.mm; sourceTree = ""; }; 7534F12728BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDeviceAttestationDelegate_Internal.h; sourceTree = ""; }; + 754784632BFE65B70089C372 /* MTRDeviceStorageBehaviorConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceStorageBehaviorConfiguration.h; sourceTree = ""; }; + 754784642BFE65CB0089C372 /* MTRDeviceStorageBehaviorConfiguration.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceStorageBehaviorConfiguration.mm; sourceTree = ""; }; + 754784662BFE6B890089C372 /* MTRDeviceStorageBehaviorConfiguration_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceStorageBehaviorConfiguration_Internal.h; sourceTree = ""; }; 754F3DF327FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTREventTLVValueDecoder_Internal.h; sourceTree = ""; }; 7560FD1B27FBBD3F005E85B3 /* MTREventTLVValueDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTREventTLVValueDecoder.mm; sourceTree = ""; }; 7596A83D28751220004DAE0E /* MTRBaseClusters_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRBaseClusters_Internal.h; sourceTree = ""; }; @@ -1330,6 +1335,9 @@ 5A6FEC9527B5983000F25F42 /* MTRDeviceControllerXPCConnection.mm */, 5A6FEC8B27B5609C00F25F42 /* MTRDeviceOverXPC.h */, 5A6FEC9727B5C6AF00F25F42 /* MTRDeviceOverXPC.mm */, + 754784632BFE65B70089C372 /* MTRDeviceStorageBehaviorConfiguration.h */, + 754784662BFE6B890089C372 /* MTRDeviceStorageBehaviorConfiguration_Internal.h */, + 754784642BFE65CB0089C372 /* MTRDeviceStorageBehaviorConfiguration.mm */, 51F522692AE70761000C4050 /* MTRDeviceTypeMetadata.h */, 5129BCFC26A9EE3300122DDF /* MTRError.h */, B2E0D7AB245B0B5C003C5B48 /* MTRError_Internal.h */, @@ -1593,6 +1601,7 @@ 7596A85728788557004DAE0E /* MTRClusters.h in Headers */, 99D466E12798936D0089A18F /* MTRCommissioningParameters.h in Headers */, 75B3269C2BCDB9D600E17C4E /* MTRDeviceConnectivityMonitor.h in Headers */, + 754784672BFE93B00089C372 /* MTRDeviceStorageBehaviorConfiguration.h in Headers */, 5136661528067D550025EDAE /* MTRDeviceControllerFactory_Internal.h in Headers */, 515C1C70284F9FFB00A48F0C /* MTRFramework.h in Headers */, 7534F12928BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h in Headers */, @@ -1979,6 +1988,7 @@ B289D4222639C0D300D4E314 /* MTROnboardingPayloadParser.mm in Sources */, 3CF134AD289D8E570017A19E /* MTRDeviceAttestationInfo.mm in Sources */, 2C1B027A2641DB4E00780EF1 /* MTROperationalCredentialsDelegate.mm in Sources */, + 754784652BFE65CB0089C372 /* MTRDeviceStorageBehaviorConfiguration.mm in Sources */, 7560FD1C27FBBD3F005E85B3 /* MTREventTLVValueDecoder.mm in Sources */, 5178E67E2AE098210069DF72 /* MTRCommandTimedCheck.mm in Sources */, 7596A84928762783004DAE0E /* MTRAsyncCallbackWorkQueue.mm in Sources */, diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.ipp b/src/include/platform/internal/GenericPlatformManagerImpl.ipp index 64878f5928cd9b..589dd4ccbe4584 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.ipp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.ipp @@ -139,7 +139,7 @@ exit: template void GenericPlatformManagerImpl::_Shutdown() { - ChipLogError(DeviceLayer, "Inet Layer shutdown"); + ChipLogProgress(DeviceLayer, "Inet Layer shutdown"); UDPEndPointManager()->Shutdown(); #if INET_CONFIG_ENABLE_TCP_ENDPOINT @@ -147,11 +147,11 @@ void GenericPlatformManagerImpl::_Shutdown() #endif #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE - ChipLogError(DeviceLayer, "BLE shutdown"); + ChipLogProgress(DeviceLayer, "BLE Layer shutdown"); BLEMgr().Shutdown(); #endif - ChipLogError(DeviceLayer, "System Layer shutdown"); + ChipLogProgress(DeviceLayer, "System Layer shutdown"); SystemLayer().Shutdown(); } diff --git a/src/lib/core/BUILD.gn b/src/lib/core/BUILD.gn index 43a6763a709697..ea09ddd01bbaad 100644 --- a/src/lib/core/BUILD.gn +++ b/src/lib/core/BUILD.gn @@ -15,6 +15,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("//build_overrides/nlio.gni") +import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/buildconfig_header.gni") import("${chip_root}/build/chip/tests.gni") @@ -106,6 +107,18 @@ source_set("error") { ] } +source_set("string-builder-adapters") { + sources = [ + "StringBuilderAdapters.cpp", + "StringBuilderAdapters.h", + ] + + public_deps = [ + ":error", + "$dir_pw_string", + ] +} + source_set("encoding") { sources = [ "CHIPEncoding.h" ] public_deps = [ "${nlio_root}:nlio" ] diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index fe030670fea57d..aebf7804aefb10 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -132,7 +132,7 @@ class ChipError * The result is valid only if CanEncapsulate() is true. */ constexpr ChipError(Range range, ValueType value) : ChipError(range, value, /*file=*/nullptr, /*line=*/0) {} -#if __cplusplus >= 202002L +#if CHIP_CONFIG_ERROR_SOURCE && __cplusplus >= 202002L constexpr ChipError(Range range, ValueType value, const char * file, unsigned int line, std::source_location location = std::source_location::current()) : mError(MakeInteger(range, (value & MakeMask(0, kValueLength)))) CHIP_INITIALIZE_ERROR_SOURCE(file, line, location) @@ -141,7 +141,7 @@ class ChipError constexpr ChipError(Range range, ValueType value, const char * file, unsigned int line) : mError(MakeInteger(range, (value & MakeMask(0, kValueLength)))) CHIP_INITIALIZE_ERROR_SOURCE(file, line, /*loc=*/nullptr) {} -#endif // __cplusplus >= 202002L +#endif // CHIP_CONFIG_ERROR_SOURCE && __cplusplus >= 202002L /** * Construct a CHIP_ERROR for SdkPart @a part with @a code. @@ -150,7 +150,7 @@ class ChipError * The macro version CHIP_SDK_ERROR checks that the numeric value is constant and well-formed. */ constexpr ChipError(SdkPart part, uint8_t code) : ChipError(part, code, /*file=*/nullptr, /*line=*/0) {} -#if __cplusplus >= 202002L +#if CHIP_CONFIG_ERROR_SOURCE && __cplusplus >= 202002L constexpr ChipError(SdkPart part, uint8_t code, const char * file, unsigned int line, std::source_location location = std::source_location::current()) : mError(MakeInteger(part, code)) CHIP_INITIALIZE_ERROR_SOURCE(file, line, location) @@ -159,7 +159,7 @@ class ChipError constexpr ChipError(SdkPart part, uint8_t code, const char * file, unsigned int line) : mError(MakeInteger(part, code)) CHIP_INITIALIZE_ERROR_SOURCE(file, line, /*loc=*/nullptr) {} -#endif // __cplusplus >= 202002L +#endif // CHIP_CONFIG_ERROR_SOURCE && __cplusplus >= 202002L /** * Construct a CHIP_ERROR constant for SdkPart @a part with @a code at the current source line. @@ -180,7 +180,7 @@ class ChipError * This is intended to be used only in foreign function interfaces. */ explicit constexpr ChipError(StorageType error) : ChipError(error, /*file=*/nullptr, /*line=*/0) {} -#if __cplusplus >= 202002L +#if CHIP_CONFIG_ERROR_SOURCE && __cplusplus >= 202002L explicit constexpr ChipError(StorageType error, const char * file, unsigned int line, std::source_location location = std::source_location::current()) : mError(error) CHIP_INITIALIZE_ERROR_SOURCE(file, line, location) @@ -189,7 +189,7 @@ class ChipError explicit constexpr ChipError(StorageType error, const char * file, unsigned int line) : mError(error) CHIP_INITIALIZE_ERROR_SOURCE(file, line, /*loc=*/nullptr) {} -#endif // __cplusplus >= 202002L +#endif // CHIP_CONFIG_ERROR_SOURCE && __cplusplus >= 202002L #undef CHIP_INITIALIZE_ERROR_SOURCE diff --git a/src/lib/core/StringBuilderAdapters.cpp b/src/lib/core/StringBuilderAdapters.cpp new file mode 100644 index 00000000000000..d072c1ee905ab7 --- /dev/null +++ b/src/lib/core/StringBuilderAdapters.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +namespace pw { + +template <> +StatusWithSize ToString(const CHIP_ERROR & err, pw::span buffer) +{ + if (CHIP_ERROR::IsSuccess(err)) + { + // source location probably does not matter + return pw::string::Format(buffer, "CHIP_NO_ERROR"); + } + return pw::string::Format(buffer, "CHIP_ERROR:<%" CHIP_ERROR_FORMAT ">", err.Format()); +} + +} // namespace pw diff --git a/src/lib/core/StringBuilderAdapters.h b/src/lib/core/StringBuilderAdapters.h new file mode 100644 index 00000000000000..f173d56b46e6a1 --- /dev/null +++ b/src/lib/core/StringBuilderAdapters.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +/// This header includes pigweed stringbuilder adaptations for various chip types. +/// You can see https://pigweed.dev/pw_string/guide.html as a reference. +/// +/// In particular, pigweed code generally looks like: +/// +/// pw::StringBuffer<42> sb; +/// sb << "Here is a value: "; +/// sb << value; +/// +/// Where specific formatters exist for "value". In particular these are used when +/// reporting unit test assertions such as ASSERT_EQ/EXPECT_EQ so if you write code +/// like: +/// +/// ASSERT_EQ(SomeCall(), CHIP_NO_ERROR); +/// +/// On failure without adapters, the objects are reported as "24-byte object at 0x....." +/// which is not as helpful as a full CHIP_ERROR formatted output. +/// +/// Example output WITHOUT the adapters +/// Expected: .... == CHIP_ERROR(0, "src/setup_payload/tests/TestAdditionalDataPayload.cpp", 234) +/// Actual: <24-byte object at 0x7ffe39510b80> == <24-byte object at 0x7ffe39510ba0> +/// +/// Example output WITH the adapters: +/// Expected: .... == CHIP_ERROR(0, "src/setup_payload/tests/TestAdditionalDataPayload.cpp", 234) +/// Actual: CHIP_ERROR: == CHIP_NO_ERROR + +#include + +#include + +namespace pw { + +template <> +StatusWithSize ToString(const CHIP_ERROR & err, pw::span buffer); + +} // namespace pw diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index f4a524f2c81f31..a1b28b726614f9 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -50,13 +50,33 @@ static void HandleNodeResolve(void * context, DnssdService * result, const Span< } DiscoveredNodeData nodeData; - result->ToDiscoveredNodeData(addresses, nodeData); + + result->ToDiscoveredCommissionNodeData(addresses, nodeData); nodeData.Get().LogDetail(); discoveryContext->OnNodeDiscovered(nodeData); discoveryContext->Release(); } +static void HandleNodeOperationalBrowse(void * context, DnssdService * result, CHIP_ERROR error) +{ + DiscoveryContext * discoveryContext = static_cast(context); + + if (error != CHIP_NO_ERROR) + { + discoveryContext->Release(); + return; + } + + DiscoveredNodeData nodeData; + + result->ToDiscoveredOperationalNodeBrowseData(nodeData); + + nodeData.Get().LogDetail(); + discoveryContext->OnNodeDiscovered(nodeData); + discoveryContext->Release(); +} + static void HandleNodeBrowse(void * context, DnssdService * services, size_t servicesSize, bool finalBrowse, CHIP_ERROR error) { DiscoveryContext * discoveryContext = static_cast(context); @@ -75,8 +95,16 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser auto & ipAddress = services[i].mAddress; - // Check if SRV, TXT and AAAA records were received in DNS responses - if (strlen(services[i].mHostName) == 0 || services[i].mTextEntrySize == 0 || !ipAddress.has_value()) + // mType(service name) exactly matches with operational service name + bool isOperationalBrowse = strcmp(services[i].mType, kOperationalServiceName) == 0; + + // For operational browse result we currently don't need IP address hence skip resolution and handle differently. + if (isOperationalBrowse) + { + HandleNodeOperationalBrowse(context, &services[i], error); + } + // check whether SRV, TXT and AAAA records were received in DNS responses + else if (strlen(services[i].mHostName) == 0 || services[i].mTextEntrySize == 0 || !ipAddress.has_value()) { ChipDnssdResolve(&services[i], services[i].mInterface, HandleNodeResolve, context); } @@ -340,7 +368,15 @@ void DiscoveryImplPlatform::HandleNodeIdResolve(void * context, DnssdService * r impl->mOperationalDelegate->OnOperationalNodeResolved(nodeData); } -void DnssdService::ToDiscoveredNodeData(const Span & addresses, DiscoveredNodeData & nodeData) +void DnssdService::ToDiscoveredOperationalNodeBrowseData(DiscoveredNodeData & nodeData) +{ + nodeData.Set(); + + ExtractIdFromInstanceName(mName, &nodeData.Get().peerId); + nodeData.Get().hasZeroTTL = (mTtlSeconds == 0); +} + +void DnssdService::ToDiscoveredCommissionNodeData(const Span & addresses, DiscoveredNodeData & nodeData) { nodeData.Set(); auto & discoveredData = nodeData.Get(); @@ -746,6 +782,31 @@ CHIP_ERROR DiscoveryImplPlatform::DiscoverCommissioners(DiscoveryFilter filter, return error; } +CHIP_ERROR DiscoveryImplPlatform::DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) +{ + ReturnErrorOnFailure(InitImpl()); + StopDiscovery(context); + + char serviceName[kMaxOperationalServiceNameSize]; + ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kOperational)); + + intptr_t browseIdentifier; + // Increase the reference count of the context to keep it alive until HandleNodeBrowse is called back. + CHIP_ERROR error = ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolTcp, Inet::IPAddressType::kAny, + Inet::InterfaceId::Null(), HandleNodeBrowse, context.Retain(), &browseIdentifier); + + if (error == CHIP_NO_ERROR) + { + context.SetBrowseIdentifier(browseIdentifier); + } + else + { + context.Release(); + } + + return error; +} + CHIP_ERROR DiscoveryImplPlatform::StartDiscovery(DiscoveryType type, DiscoveryFilter filter, DiscoveryContext & context) { switch (type) @@ -755,7 +816,7 @@ CHIP_ERROR DiscoveryImplPlatform::StartDiscovery(DiscoveryType type, DiscoveryFi case DiscoveryType::kCommissionerNode: return DiscoverCommissioners(filter, context); case DiscoveryType::kOperational: - return CHIP_ERROR_NOT_IMPLEMENTED; + return DiscoverOperational(filter, context); default: return CHIP_ERROR_INVALID_ARGUMENT; } diff --git a/src/lib/dnssd/Discovery_ImplPlatform.h b/src/lib/dnssd/Discovery_ImplPlatform.h index 34fedf831b5ecf..d51d5e758c0268 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.h +++ b/src/lib/dnssd/Discovery_ImplPlatform.h @@ -55,6 +55,7 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver void NodeIdResolutionNoLongerNeeded(const PeerId & peerId) override; CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter, DiscoveryContext & context); CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context); + CHIP_ERROR DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context); CHIP_ERROR StartDiscovery(DiscoveryType type, DiscoveryFilter filter, DiscoveryContext & context) override; CHIP_ERROR StopDiscovery(DiscoveryContext & context) override; CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) override; diff --git a/src/lib/dnssd/ServiceNaming.cpp b/src/lib/dnssd/ServiceNaming.cpp index 25bdfbf2cbf341..8ec86a1bfb9b2b 100644 --- a/src/lib/dnssd/ServiceNaming.cpp +++ b/src/lib/dnssd/ServiceNaming.cpp @@ -162,6 +162,10 @@ CHIP_ERROR MakeServiceTypeName(char * buffer, size_t bufferLen, DiscoveryFilter { requiredSize = snprintf(buffer, bufferLen, kCommissionerServiceName); } + else if (type == DiscoveryType::kOperational) + { + requiredSize = snprintf(buffer, bufferLen, kOperationalServiceName); + } else { return CHIP_ERROR_NOT_IMPLEMENTED; diff --git a/src/lib/dnssd/platform/Dnssd.h b/src/lib/dnssd/platform/Dnssd.h index 02fb851a12d861..e1e44053640617 100644 --- a/src/lib/dnssd/platform/Dnssd.h +++ b/src/lib/dnssd/platform/Dnssd.h @@ -81,7 +81,8 @@ struct DnssdService // Time to live in seconds. Per rfc6762 section 10, because we have a hostname, our default TTL is 120 seconds uint32_t mTtlSeconds = 120; - void ToDiscoveredNodeData(const Span & addresses, DiscoveredNodeData & nodeData); + void ToDiscoveredCommissionNodeData(const Span & addresses, DiscoveredNodeData & nodeData); + void ToDiscoveredOperationalNodeBrowseData(DiscoveredNodeData & nodeData); }; /** diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index 65b3f7bc9cc537..50be591ddfeaee 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -261,6 +261,13 @@ CHIP_ERROR BrowseOperationalHandler(int argc, char ** argv) return sResolverProxy.DiscoverOperationalNodes(filter); } +CHIP_ERROR BrowseStopHandler(int argc, char ** argv) +{ + streamer_printf(streamer_get(), "Stopping browse...\r\n"); + + return sResolverProxy.StopDiscovery(); +} + } // namespace void RegisterDnsCommands() @@ -270,6 +277,8 @@ void RegisterDnsCommands() "Browse Matter commissionables. Usage: dns browse commissionable [subtype]" }, { &BrowseCommissionerHandler, "commissioner", "Browse Matter commissioners. Usage: dns browse commissioner [subtype]" }, { &BrowseOperationalHandler, "operational", "Browse Matter operational nodes. Usage: dns browse operational" }, + { &BrowseStopHandler, "stop", "Stop ongoing browse. Usage: dns browse stop" }, + }; static constexpr Command subCommands[] = { diff --git a/src/lib/support/static_support_smart_ptr.h b/src/lib/support/static_support_smart_ptr.h index 76035e48d33841..8d5ab3eaae4071 100644 --- a/src/lib/support/static_support_smart_ptr.h +++ b/src/lib/support/static_support_smart_ptr.h @@ -54,7 +54,7 @@ template class CheckedGlobalInstanceReference { public: - CheckedGlobalInstanceReference() = default; + CheckedGlobalInstanceReference() = default; CheckedGlobalInstanceReference(T * e) { VerifyOrDie(e == GlobalInstanceProvider::InstancePointer()); } CheckedGlobalInstanceReference & operator=(T * value) { @@ -89,7 +89,7 @@ template class SimpleInstanceReference { public: - SimpleInstanceReference() = default; + SimpleInstanceReference() = default; SimpleInstanceReference(T * e) : mValue(e) {} SimpleInstanceReference & operator=(T * value) { diff --git a/src/lib/support/tests/BUILD.gn b/src/lib/support/tests/BUILD.gn index 565eb85097d133..b8cdcfeb2e059f 100644 --- a/src/lib/support/tests/BUILD.gn +++ b/src/lib/support/tests/BUILD.gn @@ -19,6 +19,15 @@ import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/chip_test_suite.gni") +pw_source_set("pw-test-macros") { + output_dir = "${root_out_dir}/lib" + public_deps = [ + "$dir_pw_log:impl", + "$dir_pw_unit_test", + ] + sources = [ "ExtraPwTestMacros.h" ] +} + chip_test_suite("tests") { output_name = "libSupportTests" diff --git a/src/lib/support/tests/ExtraPwTestMacros.h b/src/lib/support/tests/ExtraPwTestMacros.h new file mode 100644 index 00000000000000..ab592800716592 --- /dev/null +++ b/src/lib/support/tests/ExtraPwTestMacros.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +/* + * Run Fixture's class function as a test. + * It is used to execute test cases that need to use private members of a particular class. + * Unlike the pigweed macro `FRIEND_TEST`, this approach allows you to define the entire + * test_fixture class as a friend, rather than having to define each testcase as a friend. + * + * @param test_fixture - the fixture class. + * + * @param test_name - the name of the test function. + * + * Example: + * class Foo // class to be tested + * { + * friend class TestCtx; + * private: + * bool privateFunction(); + * }; + * + * class TestCtx: public ::testing::Test + * { + * public: + * void testFunction(); + * }; + * + * TEST_F_FROM_FIXTURE(TestCtx, testFunction) + * { + * Foo foo; + * EXPECT_TRUE(foo.privateFunction()); + * } + * + */ +#define TEST_F_FROM_FIXTURE(test_fixture, test_name) \ + TEST_F(test_fixture, test_name) \ + { \ + test_name(); \ + } \ + void test_fixture::test_name() diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index 89f0934486b9c1..3232796aabe7e1 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -14,7 +14,6 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") import("${chip_root}/src/app/icd/icd.gni") @@ -38,15 +37,9 @@ static_library("helpers") { "${chip_root}/src/transport", "${chip_root}/src/transport/tests:helpers", ] - - # MessagingContext exposes nl-test compatible setup/teardown functions, specifically - # they return nltest specific SUCCESS/FAILURE constants hence this dependency. - # - # Once all tests are moved to pw_unittest/gtest, this dependency should be removed - public_deps = [ "${nlunit_test_root}:nlunit-test" ] } -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libMessagingLayerTests" test_sources = [ @@ -73,12 +66,10 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", - "${chip_root}/src/lib/support:testing_nlunit", "${chip_root}/src/messaging", "${chip_root}/src/protocols", "${chip_root}/src/transport", "${chip_root}/src/transport/raw/tests:helpers", - "${nlunit_test_root}:nlunit-test", ] if (chip_enable_icd_server) { diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index 61565da1cd4ac0..909bc90f443575 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -58,7 +58,7 @@ CHIP_ERROR MessagingContext::Init(TransportMgrBase * transport, IOContext * ioCo ReturnErrorOnFailure(mExchangeManager.Init(&mSessionManager)); ReturnErrorOnFailure(mMessageCounterManager.Init(&mExchangeManager)); - if (sInitializeNodes) + if (mInitializeNodes) { ReturnErrorOnFailure(CreateAliceFabric()); ReturnErrorOnFailure(CreateBobFabric()); @@ -112,8 +112,6 @@ using namespace System::Clock::Literals; constexpr chip::System::Clock::Timeout MessagingContext::kResponsiveIdleRetransTimeout; constexpr chip::System::Clock::Timeout MessagingContext::kResponsiveActiveRetransTimeout; -bool MessagingContext::sInitializeNodes = true; - void MessagingContext::SetMRPMode(MRPMode mode) { if (mode == MRPMode::kDefault) diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index ab9912924e713c..51525f967d1475 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -32,8 +32,6 @@ #include #include -#include - #include namespace chip { @@ -98,10 +96,12 @@ class MessagingContext : public PlatformMemoryUser mInitialized(false), mAliceAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)), mBobAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)) {} + // TODO Replace VerifyOrDie with Pigweed assert after transition app/tests to Pigweed. + // TODO Currently src/app/icd/server/tests is using MessagingConetext as dependency. ~MessagingContext() { VerifyOrDie(mInitialized == false); } // Whether Alice and Bob are initialized, must be called before Init - static void ConfigInitializeNodes(bool initializeNodes) { sInitializeNodes = initializeNodes; } + void ConfigInitializeNodes(bool initializeNodes) { mInitializeNodes = initializeNodes; } /// Initialize the underlying layers and test suite pointer CHIP_ERROR Init(TransportMgrBase * transport, IOContext * io); @@ -178,7 +178,7 @@ class MessagingContext : public PlatformMemoryUser System::Layer & GetSystemLayer() { return mIOContext->GetSystemLayer(); } private: - static bool sInitializeNodes; + bool mInitializeNodes = true; bool mInitialized; FabricTable mFabricTable; diff --git a/src/messaging/tests/TestAbortExchangesForFabric.cpp b/src/messaging/tests/TestAbortExchangesForFabric.cpp index d5c945c848a9aa..8f8eb825553bf5 100644 --- a/src/messaging/tests/TestAbortExchangesForFabric.cpp +++ b/src/messaging/tests/TestAbortExchangesForFabric.cpp @@ -21,10 +21,9 @@ * one) for a fabric. */ +#include + #include -#include -#include -#include #include #include #include @@ -49,16 +48,23 @@ using namespace chip::System; using namespace chip::System::Clock::Literals; using namespace chip::Protocols; -struct TestContext : Test::LoopbackMessagingContext +struct TestAbortExchangesForFabric : public chip::Test::LoopbackMessagingContext, public ::testing::Test { + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } + void SetUp() override { #if CHIP_CRYPTO_PSA - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDie(psa_crypto_init() == PSA_SUCCESS); + ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS); #endif chip::Test::LoopbackMessagingContext::SetUp(); } + + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } + + void CommonCheckAbortAllButOneExchange(bool dropResponseMessages); }; class MockAppDelegate : public ExchangeDelegate @@ -76,57 +82,57 @@ class MockAppDelegate : public ExchangeDelegate bool mOnMessageReceivedCalled = false; }; -void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx, bool dropResponseMessages) +void TestAbortExchangesForFabric::CommonCheckAbortAllButOneExchange(bool dropResponseMessages) { // We want to have two sessions using the same fabric id that we use for // creating our exchange contexts. That lets us test exchanges on the same // session as the "special exchange" as well as on other sessions. - auto & sessionManager = ctx.GetSecureSessionManager(); + auto & sessionManager = GetSecureSessionManager(); // Use key ids that are not going to collide with anything else that ctx is // doing. // TODO: These should really be CASE sessions... SessionHolder session1; - CHIP_ERROR err = sessionManager.InjectCaseSessionWithTestKey(session1, 100, 101, ctx.GetAliceFabric()->GetNodeId(), - ctx.GetBobFabric()->GetNodeId(), ctx.GetAliceFabricIndex(), - ctx.GetBobAddress(), CryptoContext::SessionRole::kInitiator, {}); + CHIP_ERROR err = sessionManager.InjectCaseSessionWithTestKey(session1, 100, 101, GetAliceFabric()->GetNodeId(), + GetBobFabric()->GetNodeId(), GetAliceFabricIndex(), + GetBobAddress(), CryptoContext::SessionRole::kInitiator, {}); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); SessionHolder session1Reply; - err = sessionManager.InjectCaseSessionWithTestKey(session1Reply, 101, 100, ctx.GetBobFabric()->GetNodeId(), - ctx.GetAliceFabric()->GetNodeId(), ctx.GetBobFabricIndex(), - ctx.GetAliceAddress(), CryptoContext::SessionRole::kResponder, {}); + err = sessionManager.InjectCaseSessionWithTestKey(session1Reply, 101, 100, GetBobFabric()->GetNodeId(), + GetAliceFabric()->GetNodeId(), GetBobFabricIndex(), GetAliceAddress(), + CryptoContext::SessionRole::kResponder, {}); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // TODO: Ideally this would go to a different peer, but we don't have that // set up right now: only Alice and Bob have useful node ids and whatnot. SessionHolder session2; - err = sessionManager.InjectCaseSessionWithTestKey(session2, 200, 201, ctx.GetAliceFabric()->GetNodeId(), - ctx.GetBobFabric()->GetNodeId(), ctx.GetAliceFabricIndex(), - ctx.GetBobAddress(), CryptoContext::SessionRole::kInitiator, {}); + err = sessionManager.InjectCaseSessionWithTestKey(session2, 200, 201, GetAliceFabric()->GetNodeId(), + GetBobFabric()->GetNodeId(), GetAliceFabricIndex(), GetBobAddress(), + CryptoContext::SessionRole::kInitiator, {}); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); SessionHolder session2Reply; - err = sessionManager.InjectCaseSessionWithTestKey(session2Reply, 101, 100, ctx.GetBobFabric()->GetNodeId(), - ctx.GetAliceFabric()->GetNodeId(), ctx.GetBobFabricIndex(), - ctx.GetAliceAddress(), CryptoContext::SessionRole::kResponder, {}); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = sessionManager.InjectCaseSessionWithTestKey(session2Reply, 101, 100, GetBobFabric()->GetNodeId(), + GetAliceFabric()->GetNodeId(), GetBobFabricIndex(), GetAliceAddress(), + CryptoContext::SessionRole::kResponder, {}); + EXPECT_EQ(err, CHIP_NO_ERROR); - auto & exchangeMgr = ctx.GetExchangeManager(); + auto & exchangeMgr = GetExchangeManager(); MockAppDelegate delegate; Echo::EchoServer server; err = server.Init(&exchangeMgr); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); auto trySendMessage = [&](ExchangeContext * exchange, SendMessageFlags flags) { PacketBufferHandle buffer = MessagePacketBuffer::New(0); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); return exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), flags); }; @@ -137,79 +143,81 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx, loopback.mDroppedMessageCount = 0; err = trySendMessage(exchange, flags); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, !delegate.mOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); + DrainAndServiceIO(); + EXPECT_FALSE(delegate.mOnMessageReceivedCalled); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); }; - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); // We want to test three possible exchange states: // 1) Closed but waiting for ack. // 2) Waiting for a response. // 3) Waiting for a send. auto * waitingForAck1 = exchangeMgr.NewContext(session1.Get().Value(), &delegate); - NL_TEST_ASSERT(inSuite, waitingForAck1 != nullptr); + ASSERT_NE(waitingForAck1, nullptr); sendAndDropMessage(waitingForAck1, SendMessageFlags::kNone); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); auto * waitingForAck2 = exchangeMgr.NewContext(session2.Get().Value(), &delegate); - NL_TEST_ASSERT(inSuite, waitingForAck2 != nullptr); + ASSERT_NE(waitingForAck2, nullptr); sendAndDropMessage(waitingForAck2, SendMessageFlags::kNone); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 2); + EXPECT_EQ(rm->TestGetCountRetransTable(), 2); auto * waitingForIncomingMessage1 = exchangeMgr.NewContext(session1.Get().Value(), &delegate); - NL_TEST_ASSERT(inSuite, waitingForIncomingMessage1 != nullptr); + ASSERT_NE(waitingForIncomingMessage1, nullptr); sendAndDropMessage(waitingForIncomingMessage1, SendMessageFlags::kExpectResponse); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 3); + EXPECT_EQ(rm->TestGetCountRetransTable(), 3); auto * waitingForIncomingMessage2 = exchangeMgr.NewContext(session2.Get().Value(), &delegate); - NL_TEST_ASSERT(inSuite, waitingForIncomingMessage2 != nullptr); + ASSERT_NE(waitingForIncomingMessage2, nullptr); sendAndDropMessage(waitingForIncomingMessage2, SendMessageFlags::kExpectResponse); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 4); + EXPECT_EQ(rm->TestGetCountRetransTable(), 4); auto * waitingForSend1 = exchangeMgr.NewContext(session1.Get().Value(), &delegate); - NL_TEST_ASSERT(inSuite, waitingForSend1 != nullptr); + ASSERT_NE(waitingForSend1, nullptr); waitingForSend1->WillSendMessage(); auto * waitingForSend2 = exchangeMgr.NewContext(session2.Get().Value(), &delegate); - NL_TEST_ASSERT(inSuite, waitingForSend2 != nullptr); + ASSERT_NE(waitingForSend2, nullptr); waitingForSend2->WillSendMessage(); // Grab handles to our sessions now, before we evict things. const auto & sessionHandle1 = session1.Get(); const auto & sessionHandle2 = session2.Get(); - session1->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( - Test::MessagingContext::kResponsiveIdleRetransTimeout, Test::MessagingContext::kResponsiveActiveRetransTimeout)); + session1->AsSecureSession()->SetRemoteSessionParameters( + ReliableMessageProtocolConfig(chip::Test::MessagingContext::kResponsiveIdleRetransTimeout, + chip::Test::MessagingContext::kResponsiveActiveRetransTimeout)); - session1Reply->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig( - Test::MessagingContext::kResponsiveIdleRetransTimeout, Test::MessagingContext::kResponsiveActiveRetransTimeout)); + session1Reply->AsSecureSession()->SetRemoteSessionParameters( + ReliableMessageProtocolConfig(chip::Test::MessagingContext::kResponsiveIdleRetransTimeout, + chip::Test::MessagingContext::kResponsiveActiveRetransTimeout)); - NL_TEST_ASSERT(inSuite, session1); - NL_TEST_ASSERT(inSuite, session2); + EXPECT_TRUE(session1); + EXPECT_TRUE(session2); auto * specialExhange = exchangeMgr.NewContext(session1.Get().Value(), &delegate); specialExhange->AbortAllOtherCommunicationOnFabric(); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); - NL_TEST_ASSERT(inSuite, !session1); - NL_TEST_ASSERT(inSuite, !session2); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); + EXPECT_FALSE(session1); + EXPECT_FALSE(session2); - NL_TEST_ASSERT(inSuite, exchangeMgr.NewContext(sessionHandle1.Value(), &delegate) == nullptr); - NL_TEST_ASSERT(inSuite, exchangeMgr.NewContext(sessionHandle2.Value(), &delegate) == nullptr); + EXPECT_EQ(exchangeMgr.NewContext(sessionHandle1.Value(), &delegate), nullptr); + EXPECT_EQ(exchangeMgr.NewContext(sessionHandle2.Value(), &delegate), nullptr); // Make sure we can't send messages on any of the other exchanges. - NL_TEST_ASSERT(inSuite, trySendMessage(waitingForSend1, SendMessageFlags::kExpectResponse) != CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, trySendMessage(waitingForSend2, SendMessageFlags::kExpectResponse) != CHIP_NO_ERROR); + EXPECT_NE(trySendMessage(waitingForSend1, SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); + EXPECT_NE(trySendMessage(waitingForSend2, SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); // Make sure we can send a message on the special exchange. - NL_TEST_ASSERT(inSuite, !delegate.mOnMessageReceivedCalled); + EXPECT_FALSE(delegate.mOnMessageReceivedCalled); err = trySendMessage(specialExhange, SendMessageFlags::kNone); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Should be waiting for an ack now. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); if (dropResponseMessages) { @@ -217,7 +225,7 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx, // This version of the test allows us to validate logic that marks expired sessions as defunct // on encountering an MRP failure. // - loopback.mNumMessagesToDrop = Test::LoopbackTransport::kUnlimitedMessageCount; + loopback.mNumMessagesToDrop = chip::Test::LoopbackTransport::kUnlimitedMessageCount; loopback.mDroppedMessageCount = 0; // @@ -231,18 +239,18 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx, waitTimeout += ICDConfigurationData::GetInstance().GetFastPollingInterval(); #endif - ctx.GetIOContext().DriveIOUntil(waitTimeout, [&]() { return false; }); + GetIOContext().DriveIOUntil(waitTimeout, [&]() { return false; }); } else { - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } // Should not get an app-level response, since we are not expecting one. - NL_TEST_ASSERT(inSuite, !delegate.mOnMessageReceivedCalled); + EXPECT_FALSE(delegate.mOnMessageReceivedCalled); // We should have gotten our ack. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); waitingForSend1->Close(); waitingForSend2->Close(); @@ -251,43 +259,14 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx, loopback.mDroppedMessageCount = 0; } -void CheckAbortAllButOneExchange(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAbortExchangesForFabric, CheckAbortAllButOneExchange) { - TestContext & ctx = *reinterpret_cast(inContext); - CommonCheckAbortAllButOneExchange(inSuite, ctx, false); + CommonCheckAbortAllButOneExchange(false); } -void CheckAbortAllButOneExchangeResponseTimeout(nlTestSuite * inSuite, void * inContext) +TEST_F(TestAbortExchangesForFabric, CheckAbortAllButOneExchangeResponseTimeout) { - TestContext & ctx = *reinterpret_cast(inContext); - CommonCheckAbortAllButOneExchange(inSuite, ctx, true); + CommonCheckAbortAllButOneExchange(true); } -const nlTest sTests[] = { - NL_TEST_DEF("Test aborting all but one exchange", CheckAbortAllButOneExchange), - NL_TEST_DEF("Test aborting all but one exchange + response timeout", CheckAbortAllButOneExchangeResponseTimeout), - NL_TEST_SENTINEL(), -}; - -// clang-format off -nlTestSuite sSuite = { - "Test-AbortExchangesForFabric", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - } // namespace - -/** - * Main - */ -int TestAbortExchangesForFabric() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestAbortExchangesForFabric); diff --git a/src/messaging/tests/TestExchange.cpp b/src/messaging/tests/TestExchange.cpp index fbc1c9e505204d..7c0257d3093d3f 100644 --- a/src/messaging/tests/TestExchange.cpp +++ b/src/messaging/tests/TestExchange.cpp @@ -14,12 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include + +#include #include #include #include -#include -#include #include #include #include @@ -28,12 +30,6 @@ #include #include -#include -#include - -#include -#include - #if CHIP_CRYPTO_PSA #include "psa/crypto.h" #endif @@ -45,18 +41,30 @@ using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Messaging; -struct TestContext : Test::LoopbackMessagingContext +class MockExchangeDelegate; + +struct TestExchange : public Test::LoopbackMessagingContext, public ::testing::Test { // TODO Add TearDown function when changing test framework to Pigweed to make it more clear how it works. // Currently, the TearDown function is from LoopbackMessagingContext void SetUp() override { #if CHIP_CRYPTO_PSA - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDie(psa_crypto_init() == PSA_SUCCESS); + ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS); #endif chip::Test::LoopbackMessagingContext::SetUp(); } + + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } + + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } + + template + void DoRoundTripTest(MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2, uint8_t requestMessageType, + uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker, + AfterResponseChecker && afterResponseChecker); }; enum : uint8_t @@ -113,18 +121,16 @@ class MockExchangeDelegate : public UnsolicitedMessageHandler, public ExchangeDe // handler, sends a message of type requestMessageType via an exchange that has // delegate1 as delegate, responds with responseMessageType. template -void DoRoundTripTest(nlTestSuite * inSuite, void * inContext, MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2, - uint8_t requestMessageType, uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker, - AfterResponseChecker && afterResponseChecker) +void TestExchange::DoRoundTripTest(MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2, uint8_t requestMessageType, + uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker, + AfterResponseChecker && afterResponseChecker) { - TestContext & ctx = *reinterpret_cast(inContext); - - ExchangeContext * ec1 = ctx.NewExchangeToBob(&delegate1); - NL_TEST_ASSERT(inSuite, ec1 != nullptr); + ExchangeContext * ec1 = NewExchangeToBob(&delegate1); + ASSERT_NE(ec1, nullptr); - CHIP_ERROR err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, - requestMessageType, &delegate2); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + CHIP_ERROR err = + GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, requestMessageType, &delegate2); + EXPECT_EQ(err, CHIP_NO_ERROR); // To simplify things, skip MRP for all our messages, and make sure we are // always expecting responses. @@ -133,45 +139,45 @@ void DoRoundTripTest(nlTestSuite * inSuite, void * inContext, MockExchangeDelega err = ec1->SendMessage(Protocols::SecureChannel::Id, requestMessageType, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), sendFlags); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); afterRequestChecker(); ExchangeContext * ec2 = delegate2.mExchange; err = ec2->SendMessage(Protocols::SecureChannel::Id, responseMessageType, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), sendFlags); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); afterResponseChecker(); ec1->Close(); ec2->Close(); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, kMsgType_TEST1); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, kMsgType_TEST1); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void CheckBasicMessageRoundTrip(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchange, CheckBasicMessageRoundTrip) { MockExchangeDelegate delegate1; MockExchangeDelegate delegate2; DoRoundTripTest( - inSuite, inContext, delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2, + delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2, [&] { - NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0); - NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1); + EXPECT_EQ(delegate1.mReceivedMessageCount, 0u); + EXPECT_EQ(delegate2.mReceivedMessageCount, 1u); }, [&] { - NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 1); - NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1); + EXPECT_EQ(delegate1.mReceivedMessageCount, 1u); + EXPECT_EQ(delegate2.mReceivedMessageCount, 1u); }); } -void CheckBasicExchangeMessageDispatch(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchange, CheckBasicExchangeMessageDispatch) { class MockMessageDispatch : public ExchangeMessageDispatch { @@ -191,14 +197,14 @@ void CheckBasicExchangeMessageDispatch(nlTestSuite * inSuite, void * inContext) MockExchangeDelegate delegate2; DoRoundTripTest( - inSuite, inContext, delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST1, + delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST1, [&] { - NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0); - NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1); + EXPECT_EQ(delegate1.mReceivedMessageCount, 0u); + EXPECT_EQ(delegate2.mReceivedMessageCount, 1u); }, [&] { - NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 1); - NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1); + EXPECT_EQ(delegate1.mReceivedMessageCount, 1u); + EXPECT_EQ(delegate2.mReceivedMessageCount, 1u); }); } @@ -209,53 +215,15 @@ void CheckBasicExchangeMessageDispatch(nlTestSuite * inSuite, void * inContext) MockExchangeDelegate delegate2; DoRoundTripTest( - inSuite, inContext, delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2, + delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2, [&] { - NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0); - NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1); + EXPECT_EQ(delegate1.mReceivedMessageCount, 0u); + EXPECT_EQ(delegate2.mReceivedMessageCount, 1u); }, [&] { - NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0); - NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1); + EXPECT_EQ(delegate1.mReceivedMessageCount, 0u); + EXPECT_EQ(delegate2.mReceivedMessageCount, 1u); }); } } - -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("Test ExchangeContext::SendMessage", CheckBasicMessageRoundTrip), - NL_TEST_DEF("Test ExchangeMessageDispatch", CheckBasicExchangeMessageDispatch), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -nlTestSuite sSuite = -{ - "Test-Exchange", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - } // namespace - -/** - * Main - */ -int TestExchange() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestExchange); diff --git a/src/messaging/tests/TestExchangeHolder.cpp b/src/messaging/tests/TestExchangeHolder.cpp index 849c1856d9b013..35f0856cfede24 100644 --- a/src/messaging/tests/TestExchangeHolder.cpp +++ b/src/messaging/tests/TestExchangeHolder.cpp @@ -21,11 +21,10 @@ * one) for a fabric. */ +#include + #include "messaging/ExchangeDelegate.h" #include "system/SystemClock.h" -#include -#include -#include #include #include #include @@ -69,9 +68,16 @@ using namespace chip::Messaging; using namespace chip::System; using namespace chip::Protocols; -using TestContext = Test::LoopbackMessagingContext; +struct TestExchangeHolder : public chip::Test::LoopbackMessagingContext, public ::testing::Test +{ + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } -TestContext * gCtx = nullptr; + void SetUp() override { chip::Test::LoopbackMessagingContext::SetUp(); } + + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } +}; class MockProtocolResponder : public ExchangeDelegate, public Messaging::UnsolicitedMessageHandler { @@ -87,26 +93,27 @@ class MockProtocolResponder : public ExchangeDelegate, public Messaging::Unsolic }; template - MockProtocolResponder(BehaviorModifier modifier1, Args &&... args) : - mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward(args)...) + MockProtocolResponder(TestExchangeHolder & ctx, BehaviorModifier modifier1, Args &&... args) : + mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward(args)...), testExchangeHolder(ctx) { - VerifyOrDie(gCtx != nullptr); - gCtx->GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id, this); + testExchangeHolder.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id, + this); ChipLogDetail(ExchangeManager, "[%p] MockProtocolResponder: %p", this, &mExchangeCtx); } - MockProtocolResponder(BehaviorModifier modifier = BehaviorModifier::kNone) : mExchangeCtx(*this) + MockProtocolResponder(TestExchangeHolder & ctx, BehaviorModifier modifier = BehaviorModifier::kNone) : + mExchangeCtx(*this), testExchangeHolder(ctx) { - VerifyOrDie(gCtx != nullptr); mBehaviorModifier.Set(modifier); - gCtx->GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id, this); + testExchangeHolder.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id, + this); ChipLogDetail(ExchangeManager, "[%p] MockProtocolResponder: %p", this, &mExchangeCtx); } ~MockProtocolResponder() { ChipLogDetail(ExchangeManager, "[%p] ~MockProtocolResponder", this); - gCtx->GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id); + testExchangeHolder.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id); } bool DidInteractionSucceed() { return mInteractionSucceeded; } @@ -126,6 +133,7 @@ class MockProtocolResponder : public ExchangeDelegate, public Messaging::Unsolic ExchangeHolder mExchangeCtx; BitFlags mBehaviorModifier = BehaviorModifier::kNone; bool mInteractionSucceeded = false; + TestExchangeHolder & testExchangeHolder; }; class MockProtocolInitiator : public ExchangeDelegate @@ -144,15 +152,16 @@ class MockProtocolInitiator : public ExchangeDelegate kExpireSessionAfterMsg3Send = 0x18, }; - MockProtocolInitiator(BehaviorModifier modifier = BehaviorModifier::kNone) : mExchangeCtx(*this) + MockProtocolInitiator(TestExchangeHolder & ctx, BehaviorModifier modifier = BehaviorModifier::kNone) : + mExchangeCtx(*this), testExchangeHolder(ctx) { mBehaviorModifier.Set(modifier); ChipLogDetail(ExchangeManager, "[%p] MockProtocolInitiator: %p", this, &mExchangeCtx); } template - MockProtocolInitiator(BehaviorModifier modifier1, Args &&... args) : - mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward(args)...) + MockProtocolInitiator(TestExchangeHolder & ctx, BehaviorModifier modifier1, Args &&... args) : + mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward(args)...), testExchangeHolder(ctx) { ChipLogDetail(ExchangeManager, "[%p] MockProtocolInitiator: %p", this, &mExchangeCtx); } @@ -172,6 +181,7 @@ class MockProtocolInitiator : public ExchangeDelegate ExchangeHolder mExchangeCtx; BitFlags mBehaviorModifier = BehaviorModifier::kNone; bool mInteractionSucceeded = false; + TestExchangeHolder & testExchangeHolder; }; CHIP_ERROR MockProtocolResponder::OnMessageReceived(ExchangeContext * ec, const PayloadHeader & payloadHeader, @@ -248,7 +258,7 @@ CHIP_ERROR MockProtocolInitiator::StartInteraction(SessionHandle & sessionHandle PacketBufferHandle buffer = MessagePacketBuffer::New(0); VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_NO_MEMORY); - auto exchange = gCtx->GetExchangeManager().NewContext(sessionHandle, this); + auto exchange = testExchangeHolder.GetExchangeManager().NewContext(sessionHandle, this); VerifyOrReturnError(exchange != nullptr, CHIP_ERROR_NO_MEMORY); // @@ -344,15 +354,11 @@ CHIP_ERROR MockProtocolInitiator::OnMessageReceived(ExchangeContext * ec, const return err; } -void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeHolder, TestExchangeHolder) { - TestContext & ctx = *reinterpret_cast(inContext); - - gCtx = &ctx; + auto sessionHandle = GetSessionAliceToBob(); - auto sessionHandle = ctx.GetSessionAliceToBob(); - - ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); + SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive); // // #1: Initiator (AllocExchange) @@ -366,14 +372,14 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) ChipLogProgress(ExchangeManager, "-------- #1: Initiator (AllocExchange) ----------"); { - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kDontSendMsg1); - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kDontSendMsg1); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -389,19 +395,19 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) ChipLogProgress(ExchangeManager, "-------- #2: Initiator --X (SendErr) Msg1 --------- "); { - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kErrMsg1); - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kErrMsg1); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); } // // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also // flush any pending messages in the queue. // - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + DrainAndServiceIO(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -417,19 +423,19 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) ChipLogProgress(ExchangeManager, "-------- #3: Initiator --X (SessionReleased before) Msg1 --------- "); { - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg1Send); - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg1Send); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); } // // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also // flush any pending messages in the queue. // - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + DrainAndServiceIO(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -445,20 +451,20 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) ChipLogProgress(ExchangeManager, "-------- #4: Initiator --X (SendErr + SessionReleased after) Msg1 --------- "); { - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kExpireSessionAfterMsg1Send, + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kExpireSessionAfterMsg1Send, MockProtocolInitiator::BehaviorModifier::kErrMsg1); - MockProtocolResponder responder; + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); } // // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also // flush any pending messages in the queue. // - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + DrainAndServiceIO(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -474,19 +480,19 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) ChipLogProgress(ExchangeManager, "-------- #5: Initiator >-- Msg1 --X Responder ---------"); { - MockProtocolInitiator initiator; - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } // // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also // flush any pending messages in the queue. // - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + DrainAndServiceIO(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -502,16 +508,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #6: Initiator >-- Msg1 --> Responder (WillSend) ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kHoldMsg2); + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kHoldMsg2); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -529,16 +535,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #7: Msg2 (SendFailure) X-- Responder ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kErrMsg2); + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kErrMsg2); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -554,16 +560,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #8: Msg2 (SessionReleased Before) X-- Responder ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kExpireSessionBeforeMsg2Send); + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kExpireSessionBeforeMsg2Send); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -579,17 +585,17 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #9: Msg2 (SendErr + SessionReleased after) X-- Responder ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kErrMsg2, + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kErrMsg2, MockProtocolResponder::BehaviorModifier::kExpireSessionAfterMsg2Send); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -605,16 +611,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #10: (WillSend) Initiator <-- Msg2 <-- Responder ---------"); - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kHoldMsg3); - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kHoldMsg3); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -630,16 +636,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #11: Initiator --X (SessionReleased before) Msg3 ------------"); - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg3Send); - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg3Send); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -657,17 +663,17 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #12: Initiator --X (SendErr + SessionReleased after) Msg3 ------------"); - MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kErrMsg3, + MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kErrMsg3, MockProtocolInitiator::BehaviorModifier::kExpireSessionAfterMsg3Send); - MockProtocolResponder responder; + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -685,16 +691,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #13: Initiator >-- Msg3 --> Responder ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -711,13 +717,13 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #14: Initiator >-- Msg3 --> Responder (SessionReleased) ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kExpireSessionAfterMsg3Receive); + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kExpireSessionAfterMsg3Receive); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // // Because of the session expiration right after Msg3 is received, it causes an abort of the underlying EC @@ -730,11 +736,11 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) // entry has been removed. To make this happen, drive the IO forward enough that a single re-transmission happens. This // will result in a duplicate message ACK being delivered by the responder, causing the EC to finally get released. // - ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), - [&]() { return ctx.GetExchangeManager().GetNumActiveExchanges() == 0; }); + GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), + [&]() { return GetExchangeManager().GetNumActiveExchanges() == 0; }); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -750,22 +756,22 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #15: Initiator >-- Msg1 --> Responder (WillSend) X2 ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kHoldMsg2); + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kHoldMsg2); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + DrainAndServiceIO(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } // @@ -784,58 +790,21 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext) { ChipLogProgress(ExchangeManager, "-------- #16: Initiator >-- Msg3 --> Responder X2 ---------"); - MockProtocolInitiator initiator; - MockProtocolResponder responder; + MockProtocolInitiator initiator(*this); + MockProtocolResponder responder(*this); auto err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); err = initiator.StartInteraction(sessionHandle); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); } - NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } } - -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("TestExchangeHolder", TestExchangeHolder), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -nlTestSuite sSuite = -{ - "Test-TestExchangeHolder", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - } // anonymous namespace - -/** - * Main - */ -int TestExchangeHolder() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestExchangeHolder); diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index efca83e6d1a92a..975078ede9bd78 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -20,12 +20,14 @@ * @file * This file implements unit tests for the ExchangeManager implementation. */ +#include +#include + +#include #include #include #include -#include -#include #include #include #include @@ -34,12 +36,6 @@ #include #include -#include -#include - -#include -#include - #if CHIP_CRYPTO_PSA #include "psa/crypto.h" #endif @@ -51,18 +47,21 @@ using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Messaging; -struct TestContext : Test::LoopbackMessagingContext +struct TestExchangeMgr : public chip::Test::LoopbackMessagingContext, public ::testing::Test { - // TODO Add TearDown function during changing test framework to Pigweed to make it more clear how does it work. - // Currently, the TearDown function is from LoopbackMessagingContext + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } + void SetUp() override { #if CHIP_CRYPTO_PSA - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDie(psa_crypto_init() == PSA_SUCCESS); + ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS); #endif chip::Test::LoopbackMessagingContext::SetUp(); } + + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } }; enum : uint8_t @@ -115,207 +114,155 @@ class ExpireSessionFromTimeoutDelegate : public WaitForTimeoutDelegate } }; -void CheckNewContextTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeMgr, CheckNewContextTest) { - TestContext & ctx = *reinterpret_cast(inContext); - MockAppDelegate mockAppDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToBob(&mockAppDelegate); - NL_TEST_EXIT_ON_FAILED_ASSERT(inSuite, ec1 != nullptr); - NL_TEST_ASSERT(inSuite, ec1->IsInitiator() == true); - NL_TEST_ASSERT(inSuite, ec1->GetSessionHandle() == ctx.GetSessionAliceToBob()); - NL_TEST_ASSERT(inSuite, ec1->GetDelegate() == &mockAppDelegate); + ExchangeContext * ec1 = NewExchangeToBob(&mockAppDelegate); + ASSERT_NE(ec1, nullptr); + EXPECT_EQ(ec1->IsInitiator(), true); + EXPECT_EQ(ec1->GetSessionHandle(), GetSessionAliceToBob()); + EXPECT_EQ(ec1->GetDelegate(), &mockAppDelegate); - ExchangeContext * ec2 = ctx.NewExchangeToAlice(&mockAppDelegate); - NL_TEST_EXIT_ON_FAILED_ASSERT(inSuite, ec2 != nullptr); - NL_TEST_ASSERT(inSuite, ec2->GetExchangeId() > ec1->GetExchangeId()); - NL_TEST_ASSERT(inSuite, ec2->GetSessionHandle() == ctx.GetSessionBobToAlice()); + ExchangeContext * ec2 = NewExchangeToAlice(&mockAppDelegate); + ASSERT_NE(ec2, nullptr); + EXPECT_GT(ec2->GetExchangeId(), ec1->GetExchangeId()); + EXPECT_EQ(ec2->GetSessionHandle(), GetSessionBobToAlice()); ec1->Close(); ec2->Close(); } -void CheckSessionExpirationBasics(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeMgr, CheckSessionExpirationBasics) { - TestContext & ctx = *reinterpret_cast(inContext); - MockAppDelegate sendDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate); + ExchangeContext * ec1 = NewExchangeToBob(&sendDelegate); + ASSERT_NE(ec1, nullptr); // Expire the session this exchange is supposedly on. ec1->GetSessionHandle()->AsSecureSession()->MarkForEviction(); MockAppDelegate receiveDelegate; CHIP_ERROR err = - ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1, &receiveDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1, &receiveDelegate); + EXPECT_EQ(err, CHIP_NO_ERROR); err = ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_NE(err, CHIP_NO_ERROR); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, !receiveDelegate.IsOnMessageReceivedCalled); + EXPECT_FALSE(receiveDelegate.IsOnMessageReceivedCalled); ec1->Close(); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1); + EXPECT_EQ(err, CHIP_NO_ERROR); // recreate closed session. - NL_TEST_ASSERT(inSuite, ctx.CreateSessionAliceToBob() == CHIP_NO_ERROR); + EXPECT_EQ(CreateSessionAliceToBob(), CHIP_NO_ERROR); } -void CheckSessionExpirationTimeout(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeMgr, CheckSessionExpirationTimeout) { - TestContext & ctx = *reinterpret_cast(inContext); - WaitForTimeoutDelegate sendDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate); + ExchangeContext * ec1 = NewExchangeToBob(&sendDelegate); ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(Messaging::SendMessageFlags::kExpectResponse).Set(Messaging::SendMessageFlags::kNoAutoRequestAck)); - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, !sendDelegate.IsOnResponseTimeoutCalled); + DrainAndServiceIO(); + EXPECT_FALSE(sendDelegate.IsOnResponseTimeoutCalled); // Expire the session this exchange is supposedly on. This should close the exchange. ec1->GetSessionHandle()->AsSecureSession()->MarkForEviction(); - NL_TEST_ASSERT(inSuite, sendDelegate.IsOnResponseTimeoutCalled); + EXPECT_TRUE(sendDelegate.IsOnResponseTimeoutCalled); // recreate closed session. - NL_TEST_ASSERT(inSuite, ctx.CreateSessionAliceToBob() == CHIP_NO_ERROR); + EXPECT_EQ(CreateSessionAliceToBob(), CHIP_NO_ERROR); } -void CheckSessionExpirationDuringTimeout(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeMgr, CheckSessionExpirationDuringTimeout) { using namespace chip::System::Clock::Literals; - TestContext & ctx = *reinterpret_cast(inContext); - ExpireSessionFromTimeoutDelegate sendDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate); + ExchangeContext * ec1 = NewExchangeToBob(&sendDelegate); auto timeout = System::Clock::Timeout(100); ec1->SetResponseTimeout(timeout); - NL_TEST_ASSERT(inSuite, !sendDelegate.IsOnResponseTimeoutCalled); + EXPECT_FALSE(sendDelegate.IsOnResponseTimeoutCalled); ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(Messaging::SendMessageFlags::kExpectResponse).Set(Messaging::SendMessageFlags::kNoAutoRequestAck)); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Wait for our timeout to elapse. Give it an extra 1000ms of slack, // because if we lose the timeslice for longer than the slack we could end // up breaking out of the loop before the timeout timer has actually fired. - ctx.GetIOContext().DriveIOUntil(timeout + 1000_ms32, [&sendDelegate] { return sendDelegate.IsOnResponseTimeoutCalled; }); + GetIOContext().DriveIOUntil(timeout + 1000_ms32, [&sendDelegate] { return sendDelegate.IsOnResponseTimeoutCalled; }); - NL_TEST_ASSERT(inSuite, sendDelegate.IsOnResponseTimeoutCalled); + EXPECT_TRUE(sendDelegate.IsOnResponseTimeoutCalled); // recreate closed session. - NL_TEST_ASSERT(inSuite, ctx.CreateSessionAliceToBob() == CHIP_NO_ERROR); + EXPECT_EQ(CreateSessionAliceToBob(), CHIP_NO_ERROR); } -void CheckUmhRegistrationTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeMgr, CheckUmhRegistrationTest) { - TestContext & ctx = *reinterpret_cast(inContext); - CHIP_ERROR err; MockAppDelegate mockAppDelegate; - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id, &mockAppDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id, &mockAppDelegate); + EXPECT_EQ(err, CHIP_NO_ERROR); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1, &mockAppDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1, &mockAppDelegate); + EXPECT_EQ(err, CHIP_NO_ERROR); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id); + EXPECT_EQ(err, CHIP_NO_ERROR); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Echo::Id); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Echo::Id); + EXPECT_NE(err, CHIP_NO_ERROR); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1); + EXPECT_EQ(err, CHIP_NO_ERROR); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST2); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST2); + EXPECT_NE(err, CHIP_NO_ERROR); } -void CheckExchangeMessages(nlTestSuite * inSuite, void * inContext) +TEST_F(TestExchangeMgr, CheckExchangeMessages) { - TestContext & ctx = *reinterpret_cast(inContext); - CHIP_ERROR err; // create solicited exchange MockAppDelegate mockSolicitedAppDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate); + ExchangeContext * ec1 = NewExchangeToAlice(&mockSolicitedAppDelegate); // create unsolicited exchange MockAppDelegate mockUnsolicitedAppDelegate; - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1, - &mockUnsolicitedAppDelegate); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1, + &mockUnsolicitedAppDelegate); + EXPECT_EQ(err, CHIP_NO_ERROR); // send a malicious packet ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST2, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, !mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled); + DrainAndServiceIO(); + EXPECT_FALSE(mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled); - ec1 = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate); + ec1 = NewExchangeToAlice(&mockSolicitedAppDelegate); // send a good packet ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled); + DrainAndServiceIO(); + EXPECT_TRUE(mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1); + EXPECT_EQ(err, CHIP_NO_ERROR); } -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("Test ExchangeMgr::NewContext", CheckNewContextTest), - NL_TEST_DEF("Test ExchangeMgr::CheckUmhRegistrationTest", CheckUmhRegistrationTest), - NL_TEST_DEF("Test ExchangeMgr::CheckExchangeMessages", CheckExchangeMessages), - NL_TEST_DEF("Test OnConnectionExpired basics", CheckSessionExpirationBasics), - NL_TEST_DEF("Test OnConnectionExpired timeout handling", CheckSessionExpirationTimeout), - NL_TEST_DEF("Test session eviction in timeout handling", CheckSessionExpirationDuringTimeout), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -nlTestSuite sSuite = -{ - "Test-CHIP-ExchangeManager", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - } // namespace - -/** - * Main - */ -int TestExchangeMgr() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestExchangeMgr); diff --git a/src/messaging/tests/TestMessagingLayer.cpp b/src/messaging/tests/TestMessagingLayer.cpp index 00dca89f2b6639..4e52cb96972ea6 100644 --- a/src/messaging/tests/TestMessagingLayer.cpp +++ b/src/messaging/tests/TestMessagingLayer.cpp @@ -20,13 +20,15 @@ * @file * This file implements unit tests for the ExchangeManager implementation. */ +#include +#include + +#include #include #include #include #include -#include -#include #include #include #include @@ -36,12 +38,6 @@ #include #include -#include -#include - -#include -#include - namespace { using namespace chip; @@ -53,6 +49,17 @@ using namespace chip::System::Clock::Literals; using TestContext = Test::UDPMessagingContext; +struct TestMessagingLayer : public chip::Test::UDPMessagingContext, public ::testing::Test +{ + static void SetUpTestSuite() { chip::Test::UDPMessagingContext::SetUpTestSuite(); } + static void TearDownTestSuite() { chip::Test::UDPMessagingContext::TearDownTestSuite(); } + + // Performs setup for each individual test in the test suite + void SetUp() override { chip::Test::UDPMessagingContext::SetUp(); } + + void TearDown() override { chip::Test::UDPMessagingContext::TearDown(); } +}; + // The message timeout value in milliseconds. constexpr System::Clock::Timeout kMessageTimeout = System::Clock::Milliseconds32(100); @@ -87,25 +94,23 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat * - Confirm the message is sent successfully * - Observe DUT response timeout with no response */ -void CheckExchangeOutgoingMessagesSuccess(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMessagingLayer, CheckExchangeOutgoingMessagesSuccess) { - TestContext & ctx = *reinterpret_cast(inContext); - // create solicited exchange MockAppDelegate mockSolicitedAppDelegate; - ExchangeContext * ec = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate); + ExchangeContext * ec = NewExchangeToAlice(&mockSolicitedAppDelegate); - NL_TEST_ASSERT(inSuite, ec != nullptr); + ASSERT_NE(ec, nullptr); ec->SetResponseTimeout(kMessageTimeout); CHIP_ERROR err = ec->SendMessage(Echo::MsgType::EchoRequest, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); // Wait for the initial message to fail (should take 330-413ms) - ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; }); + GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; }); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mockSolicitedAppDelegate.IsOnResponseTimeoutCalled); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(mockSolicitedAppDelegate.IsOnResponseTimeoutCalled); } /** @@ -118,15 +123,13 @@ void CheckExchangeOutgoingMessagesSuccess(nlTestSuite * inSuite, void * inContex * - Confirm the message is sent with failure * - Confirm the DUT response timeout timer is cancelled */ -void CheckExchangeOutgoingMessagesFail(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMessagingLayer, CheckExchangeOutgoingMessagesFail) { - TestContext & ctx = *reinterpret_cast(inContext); - // create solicited exchange MockAppDelegate mockSolicitedAppDelegate; - ExchangeContext * ec = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate); + ExchangeContext * ec = NewExchangeToAlice(&mockSolicitedAppDelegate); - NL_TEST_ASSERT(inSuite, ec != nullptr); + ASSERT_NE(ec, nullptr); ec->SetResponseTimeout(kMessageTimeout); chip::FaultInjection::GetManager().FailAtFault(chip::FaultInjection::kFault_DropOutgoingUDPMsg, 0, 1); @@ -135,48 +138,11 @@ void CheckExchangeOutgoingMessagesFail(nlTestSuite * inSuite, void * inContext) SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); // Wait for the initial message to fail (should take 330-413ms) - ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; }); + GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; }); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, !mockSolicitedAppDelegate.IsOnResponseTimeoutCalled); + EXPECT_NE(err, CHIP_NO_ERROR); + EXPECT_FALSE(mockSolicitedAppDelegate.IsOnResponseTimeoutCalled); ec->Close(); } -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("Test MessagingLayer::ExchangeOutgoingMessagesSuccess", CheckExchangeOutgoingMessagesSuccess), - NL_TEST_DEF("Test MessagingLayer::ExchangeOutgoingMessagesFail", CheckExchangeOutgoingMessagesFail), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -nlTestSuite sSuite = -{ - "Test-CHIP-MessagingLayer", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - } // namespace - -/** - * Main - */ -int TestMessagingLayer() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestMessagingLayer); diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 68342838a735b1..d965c172a1c010 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -21,13 +21,13 @@ * This file implements unit tests for the ReliableMessageProtocol * implementation. */ +#include + +#include #include #include #include -#include -#include -#include #include #include #include @@ -36,11 +36,6 @@ #include #include -#include -#include - -#include - #include #include #include @@ -65,26 +60,30 @@ using namespace chip::System::Clock::Literals; const char PAYLOAD[] = "Hello!"; -class TestContext : public chip::Test::LoopbackMessagingContext +class TestReliableMessageProtocol : public chip::Test::LoopbackMessagingContext, public ::testing::Test { public: + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } + // Performs setup for each individual test in the test suite void SetUp() override { #if CHIP_CRYPTO_PSA - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDie(psa_crypto_init() == PSA_SUCCESS); + ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS); #endif chip::Test::LoopbackMessagingContext::SetUp(); GetSessionAliceToBob()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())); GetSessionBobToAlice()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())); } + + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } }; class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegate { public: - MockAppDelegate(TestContext & ctx) : mTestContext(ctx) {} + MockAppDelegate(TestReliableMessageProtocol & ctx) : mTestReliableMessageProtocol(ctx) {} CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override { @@ -128,11 +127,8 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat } mExchange = ec; - if (mTestSuite != nullptr) - { - NL_TEST_ASSERT(mTestSuite, buffer->TotalLength() == sizeof(PAYLOAD)); - NL_TEST_ASSERT(mTestSuite, memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()) == 0); - } + EXPECT_EQ(buffer->TotalLength(), sizeof(PAYLOAD)); + EXPECT_EQ(memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()), 0); return CHIP_NO_ERROR; } @@ -155,7 +151,7 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat // Restart the MRP retransmit timer, now that we are not going to be // dropping acks anymore, so we send out pending retransmits, if // any, as needed. - mTestContext.GetExchangeManager().GetReliableMessageMgr()->StartTimer(); + mTestReliableMessageProtocol.GetExchangeManager().GetReliableMessageMgr()->StartTimer(); } } @@ -164,10 +160,9 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat bool mRetainExchange = false; bool mResponseTimedOut = false; ExchangeContext * mExchange = nullptr; - nlTestSuite * mTestSuite = nullptr; private: - TestContext & mTestContext; + TestReliableMessageProtocol & mTestReliableMessageProtocol; bool mDropAckResponse = false; }; @@ -199,11 +194,8 @@ class MockSessionEstablishmentDelegate : public UnsolicitedMessageHandler, publi System::PacketBufferHandle && buffer) override { IsOnMessageReceivedCalled = true; - if (mTestSuite != nullptr) - { - NL_TEST_ASSERT(mTestSuite, buffer->TotalLength() == sizeof(PAYLOAD)); - NL_TEST_ASSERT(mTestSuite, memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()) == 0); - } + EXPECT_EQ(buffer->TotalLength(), sizeof(PAYLOAD)); + EXPECT_EQ(memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()), 0); return CHIP_NO_ERROR; } @@ -213,7 +205,6 @@ class MockSessionEstablishmentDelegate : public UnsolicitedMessageHandler, publi bool IsOnMessageReceivedCalled = false; MockSessionEstablishmentExchangeDispatch mMessageDispatch; - nlTestSuite * mTestSuite = nullptr; }; struct BackoffComplianceTestVector @@ -316,7 +307,7 @@ struct BackoffComplianceTestVector theBackoffComplianceTestVector[] = { { .backoffMax = System::Clock::Timeout(20'286'001), } }; -void CheckGetBackoffImpl(nlTestSuite * inSuite, System::Clock::Timeout additionalMRPBackoffTime) +void CheckGetBackoffImpl(System::Clock::Timeout additionalMRPBackoffTime) { ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(additionalMRPBackoffTime)); @@ -336,8 +327,8 @@ void CheckGetBackoffImpl(nlTestSuite * inSuite, System::Clock::Timeout additiona ChipLogProgress(Test, "Backoff base %" PRIu32 " extra %" PRIu32 " # %d: %" PRIu32, test.backoffBase.count(), extraBackoff.count(), test.sendCount, backoff.count()); - NL_TEST_ASSERT(inSuite, backoff >= test.backoffMin + extraBackoff); - NL_TEST_ASSERT(inSuite, backoff <= test.backoffMax + extraBackoff); + EXPECT_GE(backoff, test.backoffMin + extraBackoff); + EXPECT_LE(backoff, test.backoffMax + extraBackoff); } } @@ -346,52 +337,23 @@ void CheckGetBackoffImpl(nlTestSuite * inSuite, System::Clock::Timeout additiona } // namespace -class TestReliableMessageProtocol +TEST_F(TestReliableMessageProtocol, CheckAddClearRetrans) { -public: - static void CheckAddClearRetrans(nlTestSuite * inSuite, void * inContext); - static void CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext); - static void CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * inContext); - static void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext); - static void CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext); - static void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext); - static void CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext); - static void CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext); - static void CheckDuplicateOldMessageClosedExchange(nlTestSuite * inSuite, void * inContext); - static void CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext); - static void CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext); - static void CheckSendUnsolicitedStandaloneAckMessage(nlTestSuite * inSuite, void * inContext); - static void CheckSendStandaloneAckMessage(nlTestSuite * inSuite, void * inContext); - static void CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext); - static void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inContext); - static void CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext); - static void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext); - static void CheckIsPeerActiveNotInitiator(nlTestSuite * inSuite, void * inContext); - static void CheckGetBackoff(nlTestSuite * inSuite, void * inContext); - static void CheckGetBackoffAdditionalTime(nlTestSuite * inSuite, void * inContext); - static void CheckApplicationResponseDelayed(nlTestSuite * inSuite, void * inContext); - static void CheckApplicationResponseNeverComes(nlTestSuite * inSuite, void * inContext); -}; + MockAppDelegate mockAppDelegate(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockAppDelegate); + ASSERT_NE(exchange, nullptr); -void TestReliableMessageProtocol::CheckAddClearRetrans(nlTestSuite * inSuite, void * inContext) -{ - TestContext & ctx = *reinterpret_cast(inContext); - - MockAppDelegate mockAppDelegate(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate); - NL_TEST_ASSERT(inSuite, exchange != nullptr); - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = exchange->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, rm != nullptr); - NL_TEST_ASSERT(inSuite, rc != nullptr); + ASSERT_NE(rm, nullptr); + ASSERT_NE(rc, nullptr); ReliableMessageMgr::RetransTableEntry * entry; rm->AddToRetransTable(rc, &entry); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); rm->ClearRetransTable(*entry); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); exchange->Close(); } @@ -422,26 +384,25 @@ void TestReliableMessageProtocol::CheckAddClearRetrans(nlTestSuite * inSuite, vo * - PEER to acknowledge message * - Observe DUT signal successful reliable transmission */ -void TestReliableMessageProtocol::CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessage) { - TestContext & ctx = *reinterpret_cast(inContext); BackoffComplianceTestVector * expectedBackoff; System::Clock::Timestamp now, startTime; System::Clock::Timeout timeoutTime, margin; margin = System::Clock::Timeout(15); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockSender(ctx); + MockAppDelegate mockSender(*this); // TODO: temporarily create a SessionHandle from node id, will be fix in PR 3602 - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ System::Clock::Timestamp(300), // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -449,112 +410,111 @@ void TestReliableMessageProtocol::CheckResendApplicationMessage(nlTestSuite * in })); // Let's drop the initial message - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 4; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // Ensure the exchange stays open after we send (unlike the CheckCloseExchangeAndResendApplicationMessage case), by claiming to // expect a response. startTime = System::SystemClock().GetMonotonicTimestamp(); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the initial message was dropped and was added to retransmit table - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 3); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mNumMessagesToDrop, 3u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Wait for the initial message to fail (should take 330-413ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); now = System::SystemClock().GetMonotonicTimestamp(); timeoutTime = now - startTime; ChipLogProgress(Test, "Attempt #1 Timeout : %" PRIu32 "ms", timeoutTime.count()); expectedBackoff = &theBackoffComplianceTestVector[0]; - NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin); + EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin); startTime = System::SystemClock().GetMonotonicTimestamp(); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure the 1st retry was dropped, and is still there in the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 2u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Wait for the 1st retry to fail (should take 330-413ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); now = System::SystemClock().GetMonotonicTimestamp(); timeoutTime = now - startTime; ChipLogProgress(Test, "Attempt #2 Timeout : %" PRIu32 "ms", timeoutTime.count()); expectedBackoff = &theBackoffComplianceTestVector[1]; - NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin); + EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin); startTime = System::SystemClock().GetMonotonicTimestamp(); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure the 2nd retry was dropped, and is still there in the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 3); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 3u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 3u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Wait for the 2nd retry to fail (should take 528-660ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; }); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; }); now = System::SystemClock().GetMonotonicTimestamp(); timeoutTime = now - startTime; ChipLogProgress(Test, "Attempt #3 Timeout : %" PRIu32 "ms", timeoutTime.count()); expectedBackoff = &theBackoffComplianceTestVector[2]; - NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin); + EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin); startTime = System::SystemClock().GetMonotonicTimestamp(); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure the 3rd retry was dropped, and is still there in the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 4); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 4u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mDroppedMessageCount, 4u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Wait for the 3rd retry to fail (should take 845-1056ms) - ctx.GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; }); + GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; }); now = System::SystemClock().GetMonotonicTimestamp(); timeoutTime = now - startTime; ChipLogProgress(Test, "Attempt #4 Timeout : %" PRIu32 "ms", timeoutTime.count()); expectedBackoff = &theBackoffComplianceTestVector[3]; - NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin); + EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin); // Trigger final transmission - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure the last retransmission was NOT dropped, and the retransmit table is empty, as we should have gotten an ack - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 5); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 4); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_GE(loopback.mSentMessageCount, 5u); + EXPECT_EQ(loopback.mDroppedMessageCount, 4u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); exchange->Close(); } -void TestReliableMessageProtocol::CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckCloseExchangeAndResendApplicationMessage) { - TestContext & ctx = *reinterpret_cast(inContext); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockSender(ctx); + MockAppDelegate mockSender(*this); // TODO: temporarily create a SessionHandle from node id, will be fixed in PR 3602 - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -562,58 +522,57 @@ void TestReliableMessageProtocol::CheckCloseExchangeAndResendApplicationMessage( })); // Let's drop the initial message - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 2; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mNumMessagesToDrop, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Wait for the first re-transmit (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); + DrainAndServiceIO(); // Ensure the retransmit message was dropped, and is still there in the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mDroppedMessageCount, 2u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Wait for the second re-transmit (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); + DrainAndServiceIO(); // Ensure the retransmit message was NOT dropped, and the retransmit table is empty, as we should have gotten an ack - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 3); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_GE(loopback.mSentMessageCount, 3u); + EXPECT_EQ(loopback.mDroppedMessageCount, 2u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckFailedMessageRetainOnSend) { - TestContext & ctx = *reinterpret_cast(inContext); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -622,88 +581,82 @@ void TestReliableMessageProtocol::CheckFailedMessageRetainOnSend(nlTestSuite * i mockSender.mMessageDispatch.mRetainMessageOnSend = false; // Let's drop the initial message - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 1; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was dropped - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); // Wait for the first re-transmit (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); + DrainAndServiceIO(); // Ensure the retransmit table is empty, as we did not provide a message to retain - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckUnencryptedMessageReceiveFailure) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; - CHIP_ERROR err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + CHIP_ERROR err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); // Expect the received messages to be encrypted mockReceiver.mMessageDispatch.mRequireEncryption = true; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + ExchangeContext * exchange = NewUnauthenticatedExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; // We are sending a malicious packet, doesn't expect an ack err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kNoAutoRequestAck)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Test that the message was actually sent (and not dropped) - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Test that the message was dropped by the receiver - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessageWithPeerExchange) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -711,61 +664,55 @@ void TestReliableMessageProtocol::CheckResendApplicationMessageWithPeerExchange( })); // Let's drop the initial message - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 1; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); // Wait for the first re-transmit (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); + DrainAndServiceIO(); // Ensure the retransmit message was not dropped, and is no longer in the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); - - mockReceiver.mTestSuite = nullptr; + EXPECT_GE(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckDuplicateMessageClosedExchange) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL @@ -773,7 +720,7 @@ void TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange(nlTestSuit })); // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; @@ -783,56 +730,52 @@ void TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange(nlTestSuit mockReceiver.mRetainExchange = false; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent // The ack was dropped, and message was added to the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Let's not drop the duplicate message mockReceiver.SetDropAckResponse(false); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); // Wait for the first re-transmit and ack (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); + DrainAndServiceIO(); // Ensure the retransmit message was sent and the ack was sent // and retransmit table was cleared - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(loopback.mSentMessageCount, 3u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckDuplicateOldMessageClosedExchange) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL @@ -840,7 +783,7 @@ void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestS })); // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; @@ -850,17 +793,17 @@ void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestS mockReceiver.mRetainExchange = false; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent // The ack was dropped, and message was added to the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Now send CHIP_CONFIG_MESSAGE_COUNTER_WINDOW_SIZE + 2 messages to make // sure our original message is out of the message counter window. These @@ -870,70 +813,65 @@ void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestS for (size_t i = 0; i < extraMessages; ++i) { buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); - ExchangeContext * newExchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, newExchange != nullptr); + ExchangeContext * newExchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(newExchange, nullptr); mockReceiver.mRetainExchange = false; // Ensure the retransmit table has our one message right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Send without MRP. err = newExchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kNoAutoRequestAck); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent, but not added to the retransmit table. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1 + (i + 1)); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 1u + (i + 1u)); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); } // Let's not drop the duplicate message's ack. mockReceiver.SetDropAckResponse(false); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); // Wait for the first re-transmit and ack (should take 64ms) rm->StartTimer(); - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3 + extraMessages; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3 + extraMessages; }); + DrainAndServiceIO(); // Ensure the retransmit message was sent and the ack was sent // and retransmit table was cleared - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3 + extraMessages); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(loopback.mSentMessageCount, 3u + extraMessages); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckResendSessionEstablishmentMessageWithPeerExchange) { // Making this static to reduce stack usage, as some platforms have limits on stack size. - static Test::MessagingContext ctx; - - TestContext & inctx = *static_cast(inContext); - - CHIP_ERROR err = ctx.InitFromExisting(inctx); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + static chip::Test::MessagingContext ctx; + CHIP_ERROR err = ctx.InitFromExisting(*this); + EXPECT_EQ(err, CHIP_NO_ERROR); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + ASSERT_FALSE(buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + EXPECT_EQ(err, CHIP_NO_ERROR); MockSessionEstablishmentDelegate mockSender; ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + ASSERT_NE(exchange, nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -941,63 +879,57 @@ void TestReliableMessageProtocol::CheckResendSessionEstablishmentMessageWithPeer })); // Let's drop the initial message - auto & loopback = inctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 1; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - inctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); // Wait for the first re-transmit (should take 64ms) - inctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); - inctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); + DrainAndServiceIO(); // Ensure the retransmit message was not dropped, and is no longer in the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); - - mockReceiver.mTestSuite = nullptr; + EXPECT_GE(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.ShutdownAndRestoreExisting(inctx); + ctx.ShutdownAndRestoreExisting(*this); } -void TestReliableMessageProtocol::CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckDuplicateMessage) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL @@ -1005,7 +937,7 @@ void TestReliableMessageProtocol::CheckDuplicateMessage(nlTestSuite * inSuite, v })); // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; @@ -1015,154 +947,142 @@ void TestReliableMessageProtocol::CheckDuplicateMessage(nlTestSuite * inSuite, v mockReceiver.mRetainExchange = true; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent // The ack was dropped, and message was added to the retransmit table - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); // Let's not drop the duplicate message mockReceiver.SetDropAckResponse(false); mockReceiver.mRetainExchange = false; // Wait for the first re-transmit and ack (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; }); + DrainAndServiceIO(); // Ensure the retransmit message was sent and the ack was sent // and retransmit table was cleared - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(loopback.mSentMessageCount, 3u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); mockReceiver.CloseExchangeIfNeeded(); } -void TestReliableMessageProtocol::CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckReceiveAfterStandaloneAck) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - mockSender.mTestSuite = inSuite; - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // We send a message, have it get received by the peer, then an ack is // returned, then a reply is returned. We need to keep the receiver // exchange alive until it does the message send (so we can send the // response from the receiver and so the initial sender exchange can get // it). - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; mockReceiver.mRetainExchange = true; err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // And that we have not seen an ack yet. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending()); + EXPECT_TRUE(receiverRc->IsAckPending()); // Send the standalone ack. receiverRc->SendStandaloneAckMessage(); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure the ack was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Ensure that we have not gotten any app-level responses so far. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // And that we have now gotten our ack. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // Now send a message from the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the response and its ack was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 4u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Ensure that we have received that response. - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckPiggybackAfterPiggyback) { - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - mockSender.mTestSuite = inSuite; - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // We send a message, have it get received by the peer, have the peer return // a piggybacked ack. Then we send a second message this time _not_ @@ -1170,7 +1090,7 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS // piggybacked. We need to keep both exchanges alive for that (so we can // send the response from the receiver and so the initial sender exchange // can get it). - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; @@ -1178,45 +1098,45 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS mockSender.mRetainExchange = true; err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // And that we have not seen an ack yet. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending()); + EXPECT_TRUE(receiverRc->IsAckPending()); // Ensure that we have not gotten any app-level responses or acks so far. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.mReceivedPiggybackAck); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.mReceivedPiggybackAck); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Now send a message from the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the response was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Ensure that we have received that response and it had a piggyback ack. - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockSender.mReceivedPiggybackAck); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // Reset various state so we can measure things again. mockReceiver.IsOnMessageReceivedCalled = false; @@ -1225,22 +1145,22 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS // Now send a new message to the other side, but don't ask for an ack. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 3u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // And that we are not expecting an ack. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // Send the final response. At this point we don't need to keep the // exchanges alive anymore. @@ -1248,27 +1168,27 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS mockSender.mRetainExchange = false; buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the response and its ack was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 5); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 5u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Ensure that we have received that response and it had a piggyback ack. - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockSender.mReceivedPiggybackAck); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckSendUnsolicitedStandaloneAckMessage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckSendUnsolicitedStandaloneAckMessage) { /** * Tests sending a standalone ack message that is: @@ -1278,68 +1198,62 @@ void TestReliableMessageProtocol::CheckSendUnsolicitedStandaloneAckMessage(nlTes * This is not a thing that would normally happen, but a malicious entity * could absolutely do this. */ - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData("", 0); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - mockSender.mTestSuite = inSuite; - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // We send a message, have it get received by the peer, expect an ack from // the peer. - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; // Purposefully sending a standalone ack that requests an ack! err = exchange->SendMessage(SecureChannel::MsgType::StandaloneAck, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // Needs a manual close, because SendMessage does not close for standalone acks. exchange->Close(); - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // Ensure the message and its ack were sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that nothing is waiting for acks. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckSendStandaloneAckMessage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckSendStandaloneAckMessage) { - TestContext & ctx = *reinterpret_cast(inContext); - - MockAppDelegate mockAppDelegate(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockAppDelegate(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockAppDelegate); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = exchange->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, rm != nullptr); - NL_TEST_ASSERT(inSuite, rc != nullptr); + ASSERT_NE(rm, nullptr); + ASSERT_NE(rc, nullptr); - NL_TEST_ASSERT(inSuite, rc->SendStandaloneAckMessage() == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(rc->SendStandaloneAckMessage(), CHIP_NO_ERROR); + DrainAndServiceIO(); // Need manual close because standalone acks don't close exchanges. exchange->Close(); } -void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckMessageAfterClosed) { /** * This test performs the following sequence of actions, where all messages @@ -1355,32 +1269,26 @@ void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite, * responder closing the exchange after it sends the response. */ - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - mockSender.mTestSuite = inSuite; - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; @@ -1388,49 +1296,49 @@ void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite, mockReceiver.mRetainExchange = true; mockSender.mRetainExchange = true; - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockReceiver.mReceivedPiggybackAck); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockReceiver.mReceivedPiggybackAck); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockReceiver.mReceivedPiggybackAck); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockReceiver.mReceivedPiggybackAck); // And that we have not seen an ack yet. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending()); + EXPECT_TRUE(receiverRc->IsAckPending()); // Ensure that we have not gotten any app-level responses or acks so far. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.mReceivedPiggybackAck); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.mReceivedPiggybackAck); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Now send a message from the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the response was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Ensure that we have received that response and it had a piggyback ack. - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockSender.mReceivedPiggybackAck); // And that we are now waiting for an ack for the response. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // Reset various state so we can measure things again. mockReceiver.IsOnMessageReceivedCalled = false; @@ -1440,31 +1348,31 @@ void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite, // Now send a second message to the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent (and the ack for it was also sent). - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 4u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was not received (because the exchange is closed on the // receiver). - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); // And that we are not expecting an ack; acks should have been flushed // immediately on the receiver, due to the exchange being closed. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckLostResponseWithPiggyback) { /** * This tests the following scenario: @@ -1475,30 +1383,24 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i * 5) The responder retransmits the application-level response. * 4) The initiator should receive the application-level response. */ - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - mockSender.mTestSuite = inSuite; - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // Make sure that we resend our message before the other side does. exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ @@ -1512,30 +1414,30 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i // we can send the response from the receiver), but don't need anything // special for the sender exchange, because it will be waiting for the // application-level response. - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; mockReceiver.mRetainExchange = true; err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // And that we have not gotten any app-level responses or acks so far. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext(); // Should have pending ack here. - NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending()); + EXPECT_TRUE(receiverRc->IsAckPending()); // Make sure receiver resends after sender does, and there's enough of a gap // that we are very unlikely to actually trigger the resends on the receiver // when we trigger the resends on the sender. @@ -1548,26 +1450,26 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i loopback.mNumMessagesToDrop = 1; buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); // Stop keeping receiver exchange alive. mockReceiver.mRetainExchange = true; err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the response was sent but dropped. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); // Ensure that we have not received that response. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.mReceivedPiggybackAck); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.mReceivedPiggybackAck); // We now have our un-acked message still waiting to retransmit and the // message that the other side sent is waiting for an ack. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 2); + EXPECT_EQ(rm->TestGetCountRetransTable(), 2); // Reset various state so we can measure things again. mockReceiver.IsOnMessageReceivedCalled = false; @@ -1576,8 +1478,8 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i mockSender.mReceivedPiggybackAck = false; // Wait for re-transmit from sender and ack (should take 64ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; }); + DrainAndServiceIO(); // We resent our first message, which did not make it to the app-level // listener on the receiver (because it's a duplicate) but did trigger a @@ -1586,39 +1488,39 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i // Now the annoying part is that depending on how long we _actually_ slept // we might have also triggered the retransmit from the other side, even // though we did not want to. Handle both cases here. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4 || loopback.mSentMessageCount == 6); + EXPECT_TRUE(loopback.mSentMessageCount == 4 || loopback.mSentMessageCount == 6); if (loopback.mSentMessageCount == 4) { // Just triggered the retransmit from the sender. - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); } else { // Also triggered the retransmit from the receiver. - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } // Wait for re-transmit from receiver (should take 256ms) - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 6; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 6; }); + DrainAndServiceIO(); // And now we've definitely resent our response message, which should show // up as an app-level message and trigger a standalone ack. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 6); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mSentMessageCount, 6u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); // Should be all done now. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckIsPeerActiveNotInitiator) { /** * This tests the following scenario: @@ -1630,37 +1532,31 @@ void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * in * 6) Initiator receives the response */ - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; - - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - mockSender.mTestSuite = inSuite; + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 1000_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL 1000_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL })); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 1; loopback.mDroppedMessageCount = 0; @@ -1668,40 +1564,40 @@ void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * in mockReceiver.mRetainExchange = true; mockSender.mRetainExchange = true; - NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage()); + EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage()); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Verify that the first message is dropped - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); // Make sure retransmit was not done before the idle restrans interval hits - ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 1; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 1; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage()); + EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage()); // // Make sure nothing happened - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); // // Retrasnmit message - ctx.GetIOContext().DriveIOUntil(2000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(2000_ms32, [&] { return loopback.mSentMessageCount >= 2; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage()); + EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage()); // // Make sure nothing happened - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // // Verify that the receiver considers the sender is active - NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage()); - NL_TEST_ASSERT(inSuite, mockReceiver.mExchange->HasReceivedAtLeastOneMessage()); + EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage()); + EXPECT_TRUE(mockReceiver.mExchange->HasReceivedAtLeastOneMessage()); mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 1000_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -1713,30 +1609,30 @@ void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * in // Now send a message from the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); // Make receiver message fail once loopback.mNumMessagesToDrop = 1; err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Make sure nothing happened - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3); - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mDroppedMessageCount, 2u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mSentMessageCount, 3u); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // // Retrasnmit message - ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 4; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 4; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 5); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mSentMessageCount, 5u); } -void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckLostStandaloneAck) { /** * This tests the following scenario: @@ -1748,37 +1644,31 @@ void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite, * This should succeed, with all application-level messages being delivered * and no crashes. */ - TestContext & ctx = *reinterpret_cast(inContext); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); CHIP_ERROR err = CHIP_NO_ERROR; - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - mockSender.mTestSuite = inSuite; - - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // We send a message, the other side sends a standalone ack first (which is // lost), then an application response, then we respond to that response. // We need to keep both exchanges alive for that (so we can send the // response from the receiver and so the initial sender exchange can send a // response to that). - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = 0; loopback.mDroppedMessageCount = 0; @@ -1789,48 +1679,48 @@ void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite, mockReceiver.SetDropAckResponse(true); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // And that we have not gotten any app-level responses or acks so far. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext(); // Ack should have been dropped. - NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending()); + EXPECT_FALSE(receiverRc->IsAckPending()); // Don't drop any more acks. mockReceiver.SetDropAckResponse(false); // Now send a message from the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the response was sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 2u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // Ensure that we have received that response and had a piggyback ack. - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck); + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockSender.mReceivedPiggybackAck); // We now have just the received message waiting for an ack. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // And receiver still has no ack pending. - NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending()); + EXPECT_FALSE(receiverRc->IsAckPending()); // Reset various state so we can measure things again. mockReceiver.IsOnMessageReceivedCalled = false; @@ -1843,67 +1733,64 @@ void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite, // Now send a new message to the other side. buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message and the standalone ack to it were sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0); + EXPECT_EQ(loopback.mSentMessageCount, 4u); + EXPECT_EQ(loopback.mDroppedMessageCount, 0u); // And that it was received. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, mockReceiver.mReceivedPiggybackAck); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_TRUE(mockReceiver.mReceivedPiggybackAck); // At this point all our exchanges and reliable message contexts should be // dead, so we can't test anything about their state. // And that there are no un-acked messages left. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); } -void TestReliableMessageProtocol::CheckGetBackoff(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckGetBackoff) { - CheckGetBackoffImpl(inSuite, System::Clock::kZero); + CheckGetBackoffImpl(System::Clock::kZero); } -void TestReliableMessageProtocol::CheckGetBackoffAdditionalTime(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckGetBackoffAdditionalTime) { - CheckGetBackoffImpl(inSuite, System::Clock::Seconds32(1)); + CheckGetBackoffImpl(System::Clock::Seconds32(1)); } -void TestReliableMessageProtocol::CheckApplicationResponseDelayed(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckApplicationResponseDelayed) { - TestContext & ctx = *reinterpret_cast(inContext); - CHIP_ERROR err = CHIP_NO_ERROR; // Make sure we are using CASE sessions, because there is no defunct-marking for PASE. - ctx.ExpireSessionBobToAlice(); - ctx.ExpireSessionAliceToBob(); - err = ctx.CreateCASESessionBobToAlice(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - err = ctx.CreateCASESessionAliceToBob(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + err = CreateCASESessionBobToAlice(); + EXPECT_EQ(err, CHIP_NO_ERROR); + err = CreateCASESessionAliceToBob(); + EXPECT_EQ(err, CHIP_NO_ERROR); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - mockReceiver.mTestSuite = inSuite; mockReceiver.mRetainExchange = true; - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -1913,51 +1800,51 @@ void TestReliableMessageProtocol::CheckApplicationResponseDelayed(nlTestSuite * constexpr uint32_t kMaxMRPTransmits = 5; // Counting the initial message. // Let's drop all but the last MRP transmit. - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = kMaxMRPTransmits - 1; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); exchange->SetResponseTimeout(3000_ms32); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == kMaxMRPTransmits - 2); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mNumMessagesToDrop, kMaxMRPTransmits - 2u); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // Wait for all but the last retransmit to happen. - ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; }); + DrainAndServiceIO(); // Ensure that nothing has been sent yet. - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // Now allow through the next message (our last retransmit), but make sure // there is no standalone ack for it. mockReceiver.SetDropAckResponse(true); - ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; }); + DrainAndServiceIO(); // Verify that message was sent and received but nothing else has been sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); // We have no ack yet. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got the message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We did not get a response. + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // We have no ack yet. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got the message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We did not get a response. // Ensure there will be no more weirdness with acks and that our MRP timer is restarted properly. mockReceiver.SetDropAckResponse(false); @@ -1973,99 +1860,93 @@ void TestReliableMessageProtocol::CheckApplicationResponseDelayed(nlTestSuite * })); buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); + EXPECT_FALSE(buffer.IsNull()); err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // At this point, we should have two MRP contexts pending. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 2); // We have no ack yet. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We did not get a response. + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 2); // We have no ack yet. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We did not get a response. // Now wait for all but the last retransmit to happen from the other side. - ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits - 1; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits - 1; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); // We might have timed our MRP resends out, or not, but the other side is waiting for an ack. - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1 || rm->TestGetCountRetransTable() == 2); - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We did not get a response. + EXPECT_TRUE(rm->TestGetCountRetransTable() == 1 || rm->TestGetCountRetransTable() == 2); + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We did not get a response. // Now wait for us to time out our MRP context for sure. - ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return rm->TestGetCountRetransTable() == 1; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(5000_ms32, [&] { return rm->TestGetCountRetransTable() == 1; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); // We timed out our MRP context. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We did not get a response. - NL_TEST_ASSERT(inSuite, !mockSender.mResponseTimedOut); // We did not time out yet. + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // We timed out our MRP context. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We did not get a response. + EXPECT_FALSE(mockSender.mResponseTimedOut); // We did not time out yet. // Now wait for the last retransmit (and our ack) to to happen. - ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; }); - ctx.DrainAndServiceIO(); - - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits + 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); // Everything has been acked. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. - NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled); // We got the response. - NL_TEST_ASSERT(inSuite, !mockSender.mResponseTimedOut); // We did not time out yet. + GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; }); + DrainAndServiceIO(); - mockReceiver.mTestSuite = nullptr; + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits + 1); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // Everything has been acked. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. + EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled); // We got the response. + EXPECT_FALSE(mockSender.mResponseTimedOut); // We did not time out yet. // Ensure that we did not mark any sessions defunct. - NL_TEST_ASSERT(inSuite, !ctx.GetSessionBobToAlice()->AsSecureSession()->IsDefunct()); - NL_TEST_ASSERT(inSuite, !ctx.GetSessionAliceToBob()->AsSecureSession()->IsDefunct()); + EXPECT_FALSE(GetSessionBobToAlice()->AsSecureSession()->IsDefunct()); + EXPECT_FALSE(GetSessionAliceToBob()->AsSecureSession()->IsDefunct()); // Reset our sessions, so other tests get the usual PASE session - ctx.ExpireSessionBobToAlice(); - ctx.ExpireSessionAliceToBob(); - err = ctx.CreateSessionBobToAlice(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - err = ctx.CreateSessionAliceToBob(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + err = CreateSessionBobToAlice(); + EXPECT_EQ(err, CHIP_NO_ERROR); + err = CreateSessionAliceToBob(); + EXPECT_EQ(err, CHIP_NO_ERROR); + + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); } -void TestReliableMessageProtocol::CheckApplicationResponseNeverComes(nlTestSuite * inSuite, void * inContext) +TEST_F(TestReliableMessageProtocol, CheckApplicationResponseNeverComes) { - TestContext & ctx = *reinterpret_cast(inContext); - CHIP_ERROR err = CHIP_NO_ERROR; // Make sure we are using CASE sessions, because there is no defunct-marking for PASE. - ctx.ExpireSessionBobToAlice(); - ctx.ExpireSessionAliceToBob(); - err = ctx.CreateCASESessionBobToAlice(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - err = ctx.CreateCASESessionAliceToBob(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + err = CreateCASESessionBobToAlice(); + EXPECT_EQ(err, CHIP_NO_ERROR); + err = CreateCASESessionAliceToBob(); + EXPECT_EQ(err, CHIP_NO_ERROR); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); - NL_TEST_ASSERT(inSuite, !buffer.IsNull()); - - MockAppDelegate mockReceiver(ctx); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_FALSE(buffer.IsNull()); - mockReceiver.mTestSuite = inSuite; + MockAppDelegate mockReceiver(*this); + err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); - MockAppDelegate mockSender(ctx); - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + MockAppDelegate mockSender(*this); + ExchangeContext * exchange = NewExchangeToAlice(&mockSender); + ASSERT_NE(exchange, nullptr); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm != nullptr); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + ASSERT_NE(rm, nullptr); exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL @@ -2075,94 +1956,92 @@ void TestReliableMessageProtocol::CheckApplicationResponseNeverComes(nlTestSuite constexpr uint32_t kMaxMRPTransmits = 5; // Counting the initial message. // Let's drop all but the last MRP transmit. - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; loopback.mNumMessagesToDrop = kMaxMRPTransmits - 1; loopback.mDroppedMessageCount = 0; // Ensure the retransmit table is empty right now - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); exchange->SetResponseTimeout(2500_ms32); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(err, CHIP_NO_ERROR); + DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == kMaxMRPTransmits - 2); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mNumMessagesToDrop, kMaxMRPTransmits - 2u); + EXPECT_EQ(loopback.mSentMessageCount, 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // Wait for all but the last retransmit to happen. - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; }); + DrainAndServiceIO(); // Ensure that nothing has been sent yet. - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); - NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled); - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1u); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1u); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); + EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled); + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // Now allow through the next message (our last retransmit), but make sure // there is no standalone ack for it. mockReceiver.SetDropAckResponse(true); - ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; }); + DrainAndServiceIO(); // Verify that message was sent and received but nothing else has been sent. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); // We have no ack yet. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got the message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We did not get a response. + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 1); // We have no ack yet. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got the message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We did not get a response. // Ensure there will be no more weirdness with acks and that our MRP timer is restarted properly. mockReceiver.SetDropAckResponse(false); // Now wait for us to time out our MRP context. - ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(1000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); // We timed out our MRP context. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We did not get a response. - NL_TEST_ASSERT(inSuite, !mockSender.mResponseTimedOut); // We did not time out yet. + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // We timed out our MRP context. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We did not get a response. + EXPECT_FALSE(mockSender.mResponseTimedOut); // We did not time out yet. // Now wait for our exchange to time out. - ctx.GetIOContext().DriveIOUntil(3000_ms32, [&] { return mockSender.mResponseTimedOut; }); - ctx.DrainAndServiceIO(); + GetIOContext().DriveIOUntil(3000_ms32, [&] { return mockSender.mResponseTimedOut; }); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); // We timed this out long ago. - NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. - NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled); // We never got a response. - NL_TEST_ASSERT(inSuite, mockSender.mResponseTimedOut); // We tiemd out - - mockReceiver.mTestSuite = nullptr; + EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits); + EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); // We timed this out long ago. + EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message. + EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled); // We never got a response. + EXPECT_TRUE(mockSender.mResponseTimedOut); // We tiemd out // We should have marked out session defunct. - NL_TEST_ASSERT(inSuite, ctx.GetSessionBobToAlice()->AsSecureSession()->IsDefunct()); + EXPECT_TRUE(GetSessionBobToAlice()->AsSecureSession()->IsDefunct()); // Other side had no reason to mark its session defunct. - NL_TEST_ASSERT(inSuite, !ctx.GetSessionAliceToBob()->AsSecureSession()->IsDefunct()); + EXPECT_FALSE(GetSessionAliceToBob()->AsSecureSession()->IsDefunct()); // Reset our sessions, so other tests get the usual PASE session - ctx.ExpireSessionBobToAlice(); - ctx.ExpireSessionAliceToBob(); - err = ctx.CreateSessionBobToAlice(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - err = ctx.CreateSessionAliceToBob(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - - err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ExpireSessionBobToAlice(); + ExpireSessionAliceToBob(); + err = CreateSessionBobToAlice(); + EXPECT_EQ(err, CHIP_NO_ERROR); + err = CreateSessionAliceToBob(); + EXPECT_EQ(err, CHIP_NO_ERROR); + + err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); + EXPECT_EQ(err, CHIP_NO_ERROR); } /** @@ -2179,66 +2058,3 @@ void TestReliableMessageProtocol::CheckApplicationResponseNeverComes(nlTestSuite * (this is the part that needs testing!) * 8. A sends message 5 to B. */ - -const nlTest sTests[] = { - NL_TEST_DEF("Test ReliableMessageMgr::CheckAddClearRetrans", TestReliableMessageProtocol::CheckAddClearRetrans), - NL_TEST_DEF("Test ReliableMessageMgr::CheckResendApplicationMessage", - TestReliableMessageProtocol::CheckResendApplicationMessage), - NL_TEST_DEF("Test ReliableMessageMgr::CheckCloseExchangeAndResendApplicationMessage", - TestReliableMessageProtocol::CheckCloseExchangeAndResendApplicationMessage), - NL_TEST_DEF("Test ReliableMessageMgr::CheckFailedMessageRetainOnSend", - TestReliableMessageProtocol::CheckFailedMessageRetainOnSend), - NL_TEST_DEF("Test ReliableMessageMgr::CheckResendApplicationMessageWithPeerExchange", - TestReliableMessageProtocol::CheckResendApplicationMessageWithPeerExchange), - NL_TEST_DEF("Test ReliableMessageMgr::CheckResendSessionEstablishmentMessageWithPeerExchange", - TestReliableMessageProtocol::CheckResendSessionEstablishmentMessageWithPeerExchange), - NL_TEST_DEF("Test ReliableMessageMgr::CheckDuplicateMessage", TestReliableMessageProtocol::CheckDuplicateMessage), - NL_TEST_DEF("Test ReliableMessageMgr::CheckDuplicateMessageClosedExchange", - TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange), - NL_TEST_DEF("Test ReliableMessageMgr::CheckDuplicateOldMessageClosedExchange", - TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange), - NL_TEST_DEF("Test that a reply after a standalone ack comes through correctly", - TestReliableMessageProtocol::CheckReceiveAfterStandaloneAck), - NL_TEST_DEF("Test that a reply to a non-MRP message piggybacks an ack if there were MRP things happening on the context before", - TestReliableMessageProtocol::CheckPiggybackAfterPiggyback), - NL_TEST_DEF("Test sending an unsolicited ack-soliciting 'standalone ack' message", - TestReliableMessageProtocol::CheckSendUnsolicitedStandaloneAckMessage), - NL_TEST_DEF("Test ReliableMessageMgr::CheckSendStandaloneAckMessage", - TestReliableMessageProtocol::CheckSendStandaloneAckMessage), - NL_TEST_DEF("Test command, response, default response, with receiver closing exchange after sending response", - TestReliableMessageProtocol::CheckMessageAfterClosed), - NL_TEST_DEF("Test that unencrypted message is dropped if exchange requires encryption", - TestReliableMessageProtocol::CheckUnencryptedMessageReceiveFailure), - NL_TEST_DEF("Test that dropping an application-level message with a piggyback ack works ok once both sides retransmit", - TestReliableMessageProtocol::CheckLostResponseWithPiggyback), - NL_TEST_DEF("Test that an application-level response-to-response after a lost standalone ack to the initial message works", - TestReliableMessageProtocol::CheckLostStandaloneAck), - NL_TEST_DEF("Test Is Peer Active Retry logic", TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator), - NL_TEST_DEF("Test MRP backoff algorithm", TestReliableMessageProtocol::CheckGetBackoff), - NL_TEST_DEF("Test MRP backoff algorithm with additional time", TestReliableMessageProtocol::CheckGetBackoffAdditionalTime), - // TODO: Re-enable this test, after changing test to use Mock clock / DriveIO rather than DriveIOUntil. - // Issue: https://github.com/project-chip/connectedhomeip/issues/32440 - // NL_TEST_DEF("Test an application response that comes after MRP retransmits run out", - // TestReliableMessageProtocol::CheckApplicationResponseDelayed), - NL_TEST_DEF("Test an application response that never comes, so MRP retransmits run out and then exchange times out", - TestReliableMessageProtocol::CheckApplicationResponseNeverComes), - NL_TEST_SENTINEL(), -}; - -// clang-format off -nlTestSuite sSuite = { - "Test-CHIP-ReliableMessageProtocol", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - -int TestReliableMessageProtocolSuite() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestReliableMessageProtocolSuite) diff --git a/src/platform/Darwin/DnssdContexts.cpp b/src/platform/Darwin/DnssdContexts.cpp index 7dc5956845414f..fc68a5d779616b 100644 --- a/src/platform/Darwin/DnssdContexts.cpp +++ b/src/platform/Darwin/DnssdContexts.cpp @@ -607,7 +607,16 @@ bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceInde { auto delegate = static_cast(context); DiscoveredNodeData nodeData; - service.ToDiscoveredNodeData(addresses, nodeData); + + // Check whether mType (service name) exactly matches with operational service name + if (strcmp(service.mType, kOperationalServiceName) == 0) + { + service.ToDiscoveredOperationalNodeBrowseData(nodeData); + } + else + { + service.ToDiscoveredCommissionNodeData(addresses, nodeData); + } delegate->OnNodeDiscovered(nodeData); } else diff --git a/src/platform/Darwin/UserDefaults.mm b/src/platform/Darwin/UserDefaults.mm index d24b0a4ee20f37..e28c1fa90fc0de 100644 --- a/src/platform/Darwin/UserDefaults.mm +++ b/src/platform/Darwin/UserDefaults.mm @@ -21,7 +21,6 @@ #import -static NSString * const kUserDefaultDomain = @"org.csa-iot.matter.darwin"; static NSString * const kSRPTimeoutInMsecsUserDefaultKey = @"SRPTimeoutInMSecsOverride"; namespace chip { @@ -29,7 +28,7 @@ std::optional GetUserDefaultDnssdSRPTimeoutInMSecs() { - NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kUserDefaultDomain]; + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; NSInteger srpTimeoutValue = [defaults integerForKey:kSRPTimeoutInMsecsUserDefaultKey]; if (CanCastTo(srpTimeoutValue)) { uint16_t timeoutinMsecs = static_cast(srpTimeoutValue); diff --git a/src/platform/ESP32/CHIPDevicePlatformConfig.h b/src/platform/ESP32/CHIPDevicePlatformConfig.h index e6d7870c35fda6..e347df109d1e3a 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -54,8 +54,17 @@ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD 0 #endif // CONFIG_ENABLE_MATTER_OVER_THREAD +#ifdef CONFIG_OPENTHREAD_SRP_CLIENT #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT CONFIG_OPENTHREAD_SRP_CLIENT +#else +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 0 +#endif // CONFIG_OPENTHREAD_SRP_CLIENT + +#ifdef CONFIG_OPENTHREAD_DNS_CLIENT #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT CONFIG_OPENTHREAD_DNS_CLIENT +#else +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 0 +#endif // CONFIG_OPENTHREAD_DNS_CLIENT #ifdef CONFIG_ENABLE_ETHERNET_TELEMETRY #define CHIP_DEVICE_CONFIG_ENABLE_ETHERNET 1 diff --git a/src/platform/ESP32/ConfigurationManagerImpl.cpp b/src/platform/ESP32/ConfigurationManagerImpl.cpp index 55c8758bb85fe7..e03ec70ce8192b 100644 --- a/src/platform/ESP32/ConfigurationManagerImpl.cpp +++ b/src/platform/ESP32/ConfigurationManagerImpl.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #if CHIP_DEVICE_CONFIG_ENABLE_ETHERNET @@ -404,6 +405,22 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) { CHIP_ERROR err; + // Unregistering the wifi and IP event handlers from the esp_default_event_loop() + err = ESP32Utils::MapError(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to unregister IP event handler"); + } + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + err = + ESP32Utils::MapError(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to unregister wifi event handler"); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI + ChipLogProgress(DeviceLayer, "Performing factory reset"); // Erase all values in the chip-config NVS namespace. diff --git a/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp b/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp index a3e369a85917aa..bbeaf6cdbc7169 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp +++ b/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp @@ -780,7 +780,7 @@ void ConnectivityManagerImpl::ChangeWiFiStationState(WiFiStationState newState) ChipLogProgress(DeviceLayer, "WiFi station state change: %s -> %s", WiFiStationStateToStr(mWiFiStationState), WiFiStationStateToStr(newState)); mWiFiStationState = newState; - SystemLayer().ScheduleLambda([]() { NetworkCommissioning::ESPWiFiDriver::GetInstance().OnNetworkStatusChange(); }); + NetworkCommissioning::ESPWiFiDriver::GetInstance().OnNetworkStatusChange(); } } diff --git a/src/platform/ESP32/DnssdImpl.cpp b/src/platform/ESP32/DnssdImpl.cpp index 1ca07213a866c6..df83ec818ead57 100644 --- a/src/platform/ESP32/DnssdImpl.cpp +++ b/src/platform/ESP32/DnssdImpl.cpp @@ -30,6 +30,7 @@ #endif using namespace ::chip::DeviceLayer; +using chip::DeviceLayer::Internal::ESP32Utils; namespace chip { namespace Dnssd { @@ -39,7 +40,7 @@ CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturn #if CHIP_DEVICE_CONFIG_ENABLE_WIFI || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET ReturnErrorOnFailure(EspDnssdInit(initCallback, errorCallback, context)); #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT ReturnErrorOnFailure(OpenThreadDnssdInit(initCallback, errorCallback, context)); #endif return CHIP_NO_ERROR; @@ -52,7 +53,7 @@ CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCal #if CHIP_DEVICE_CONFIG_ENABLE_WIFI || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET ReturnErrorOnFailure(EspDnssdPublishService(service, callback, context)); #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT if (ConnectivityMgr().IsThreadProvisioned()) { ReturnErrorOnFailure(OpenThreadDnssdPublishService(service, callback, context)); @@ -66,7 +67,7 @@ CHIP_ERROR ChipDnssdRemoveServices() #if CHIP_DEVICE_CONFIG_ENABLE_WIFI || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET ReturnErrorOnFailure(EspDnssdRemoveServices()); #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT if (ConnectivityMgr().IsThreadProvisioned()) { ReturnErrorOnFailure(OpenThreadDnssdRemoveServices()); @@ -77,7 +78,7 @@ CHIP_ERROR ChipDnssdRemoveServices() CHIP_ERROR ChipDnssdFinalizeServiceUpdate() { -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT if (ConnectivityMgr().IsThreadProvisioned()) { ReturnErrorOnFailure(OpenThreadDnssdFinalizeServiceUpdate()); @@ -91,13 +92,12 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chi intptr_t * browseIdentifier) { #if CHIP_DEVICE_CONFIG_ENABLE_WIFI || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET - if (ConnectivityMgr().IsWiFiStationProvisioned() || - Internal::ESP32Utils::HasIPv6LinkLocalAddress(Internal::ESP32Utils::kDefaultEthernetNetifKey)) + if (ConnectivityMgr().IsWiFiStationProvisioned() || ESP32Utils::HasIPv6LinkLocalAddress(ESP32Utils::kDefaultEthernetNetifKey)) { ReturnErrorOnFailure(EspDnssdBrowse(type, protocol, addressType, interface, callback, context, browseIdentifier)); } #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT && CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT if (ConnectivityMgr().IsThreadProvisioned()) { ReturnErrorOnFailure(OpenThreadDnssdBrowse(type, protocol, addressType, interface, callback, context, browseIdentifier)); @@ -115,13 +115,12 @@ CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId inte void * context) { #if CHIP_DEVICE_CONFIG_ENABLE_WIFI || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET - if (ConnectivityMgr().IsWiFiStationProvisioned() || - Internal::ESP32Utils::HasIPv6LinkLocalAddress(Internal::ESP32Utils::kDefaultEthernetNetifKey)) + if (ConnectivityMgr().IsWiFiStationProvisioned() || ESP32Utils::HasIPv6LinkLocalAddress(ESP32Utils::kDefaultEthernetNetifKey)) { ReturnErrorOnFailure(EspDnssdResolve(service, interface, callback, context)); } #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT && CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT if (ConnectivityMgr().IsThreadProvisioned()) { ReturnErrorOnFailure(OpenThreadDnssdResolve(service, interface, callback, context)); diff --git a/src/platform/ESP32/ESP32DnssdImpl.cpp b/src/platform/ESP32/ESP32DnssdImpl.cpp index 2c896a0d5904db..e898a9cadf767d 100644 --- a/src/platform/ESP32/ESP32DnssdImpl.cpp +++ b/src/platform/ESP32/ESP32DnssdImpl.cpp @@ -355,7 +355,7 @@ static CHIP_ERROR OnBrowseDone(BrowseContext * ctx) Inet::IPAddress IPAddr; error = GetIPAddress(IPAddr, currentResult->addr); SuccessOrExit(error); - ctx->mService[servicesIndex].mAddress.SetValue(IPAddr); + ctx->mService[servicesIndex].mAddress.emplace(IPAddr); } currentResult = currentResult->next; servicesIndex++; diff --git a/src/platform/ESP32/ThreadStackManagerImpl.cpp b/src/platform/ESP32/ThreadStackManagerImpl.cpp index 0449607999668b..c05a911a8b4adb 100644 --- a/src/platform/ESP32/ThreadStackManagerImpl.cpp +++ b/src/platform/ESP32/ThreadStackManagerImpl.cpp @@ -52,8 +52,12 @@ ThreadStackManagerImpl ThreadStackManagerImpl::sInstance; CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() { + CHIP_ERROR err = CHIP_NO_ERROR; openthread_init_stack(); - return GenericThreadStackManagerImpl_OpenThread::DoInit(esp_openthread_get_instance()); + _LockThreadStack(); + err = GenericThreadStackManagerImpl_OpenThread::DoInit(esp_openthread_get_instance()); + _UnlockThreadStack(); + return err; } CHIP_ERROR ThreadStackManagerImpl::_StartThreadTask() diff --git a/src/platform/Infineon/CYW30739/BUILD.gn b/src/platform/Infineon/CYW30739/BUILD.gn index 7613847e0f134c..433b8dcdc49d9d 100644 --- a/src/platform/Infineon/CYW30739/BUILD.gn +++ b/src/platform/Infineon/CYW30739/BUILD.gn @@ -34,8 +34,6 @@ static_library("CYW30739") { "ConfigurationManagerImpl.h", "ConnectivityManagerImpl.cpp", "ConnectivityManagerImpl.h", - "FactoryDataProvider.cpp", - "FactoryDataProvider.h", "InetPlatformConfig.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", @@ -57,6 +55,8 @@ static_library("CYW30739") { "EventFlags.h", "FactoryDataProvider.h", "OTAImageProcessorImpl.h", + "OptigaFactoryDataProvider.h", + "UnprovisionedOptigaFactoryDataProvider.h", "cycfg_gatt_db.h", ] diff --git a/src/platform/Infineon/CYW30739/CYW30739Config.h b/src/platform/Infineon/CYW30739/CYW30739Config.h index f5e56f0fee42cc..24b074689d0ecf 100644 --- a/src/platform/Infineon/CYW30739/CYW30739Config.h +++ b/src/platform/Infineon/CYW30739/CYW30739Config.h @@ -72,25 +72,33 @@ class CYW30739Config static constexpr Key kConfigKey_PAICert = CYW30739ConfigKey(kChipFactory_KeyBase, 0x22); static constexpr Key kConfigKey_CertDeclaration = CYW30739ConfigKey(kChipFactory_KeyBase, 0x23); // CHIP Config Keys - static constexpr Key kConfigKey_ServiceConfig = CYW30739ConfigKey(kChipConfig_KeyBase, 0x00); - static constexpr Key kConfigKey_PairedAccountId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x01); - static constexpr Key kConfigKey_ServiceId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x02); - static constexpr Key kConfigKey_LastUsedEpochKeyId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x03); - static constexpr Key kConfigKey_FailSafeArmed = CYW30739ConfigKey(kChipConfig_KeyBase, 0x04); - static constexpr Key kConfigKey_GroupKey = CYW30739ConfigKey(kChipConfig_KeyBase, 0x05); - static constexpr Key kConfigKey_RegulatoryLocation = CYW30739ConfigKey(kChipConfig_KeyBase, 0x07); - static constexpr Key kConfigKey_CountryCode = CYW30739ConfigKey(kChipConfig_KeyBase, 0x08); - static constexpr Key kConfigKey_RebootCount = CYW30739ConfigKey(kChipConfig_KeyBase, 0x09); - static constexpr Key kConfigKey_UniqueId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0a); - static constexpr Key kConfigKey_LockUser = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0b); - static constexpr Key kConfigKey_Credential = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0c); - static constexpr Key kConfigKey_LockUserName = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0d); - static constexpr Key kConfigKey_CredentialData = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0e); - static constexpr Key kConfigKey_UserCredentials = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0f); - static constexpr Key kConfigKey_WeekDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x10); - static constexpr Key kConfigKey_YearDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x11); - static constexpr Key kConfigKey_HolidaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x12); - static constexpr Key kConfigKey_BootReason = CYW30739ConfigKey(kChipConfig_KeyBase, 0x13); + static constexpr Key kConfigKey_ServiceConfig = CYW30739ConfigKey(kChipConfig_KeyBase, 0x00); + static constexpr Key kConfigKey_PairedAccountId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x01); + static constexpr Key kConfigKey_ServiceId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x02); + static constexpr Key kConfigKey_LastUsedEpochKeyId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x03); + static constexpr Key kConfigKey_FailSafeArmed = CYW30739ConfigKey(kChipConfig_KeyBase, 0x04); + static constexpr Key kConfigKey_GroupKey = CYW30739ConfigKey(kChipConfig_KeyBase, 0x05); + static constexpr Key kConfigKey_RegulatoryLocation = CYW30739ConfigKey(kChipConfig_KeyBase, 0x07); + static constexpr Key kConfigKey_CountryCode = CYW30739ConfigKey(kChipConfig_KeyBase, 0x08); + static constexpr Key kConfigKey_RebootCount = CYW30739ConfigKey(kChipConfig_KeyBase, 0x09); + static constexpr Key kConfigKey_UniqueId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0a); + static constexpr Key kConfigKey_LockUser = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0b); + static constexpr Key kConfigKey_Credential = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0c); + static constexpr Key kConfigKey_LockUserName = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0d); + static constexpr Key kConfigKey_CredentialData = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0e); + static constexpr Key kConfigKey_UserCredentials = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0f); + static constexpr Key kConfigKey_WeekDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x10); + static constexpr Key kConfigKey_YearDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x11); + static constexpr Key kConfigKey_HolidaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x12); + static constexpr Key kConfigKey_BootReason = CYW30739ConfigKey(kChipConfig_KeyBase, 0x13); + static constexpr Key kConfigKey_ProvisioningDAC = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe0); + static constexpr Key kConfigKey_ProvisioningPAICert = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe1); + static constexpr Key kConfigKey_ProvisioningSecret = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe2); + static constexpr Key kConfigKey_ProvisioningSecretMetaData = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe3); + static constexpr Key kConfigKey_ProvisioningDACMetaData = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe4); + static constexpr Key kConfigKey_ProvisioningDACKeyMetaData = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe5); + static constexpr Key kConfigKey_ProvisioningManifest = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe6); + static constexpr Key kConfigKey_ProvisioningFragment = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe7); // Set key id limits for each group. static constexpr Key kMinConfigKey_ChipFactory = CYW30739ConfigKey(kChipFactory_KeyBase, 0x00); diff --git a/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp index 0ece03d3c19c83..412259bda75013 100644 --- a/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp +++ b/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp @@ -25,6 +25,11 @@ namespace DeviceLayer { using namespace chip::DeviceLayer::Internal; +CHIP_ERROR FactoryDataProvider::Init() +{ + return CHIP_NO_ERROR; +} + /* * Members functions that implement the CommissionableDataProvider */ diff --git a/src/platform/Infineon/CYW30739/FactoryDataProvider.h b/src/platform/Infineon/CYW30739/FactoryDataProvider.h index def69734e1dc22..07228520f8ceb6 100644 --- a/src/platform/Infineon/CYW30739/FactoryDataProvider.h +++ b/src/platform/Infineon/CYW30739/FactoryDataProvider.h @@ -30,6 +30,8 @@ class FactoryDataProvider : public CommissionableDataProvider, public DeviceInstanceInfoProvider { public: + CHIP_ERROR Init(); + // ===== Members functions that implement the CommissionableDataProvider CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator); CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator); diff --git a/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp new file mode 100644 index 00000000000000..5febc46f7170c3 --- /dev/null +++ b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp @@ -0,0 +1,93 @@ +/* + * + * 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 "OptigaFactoryDataProvider.h" + +#include +#include + +namespace chip { +namespace DeviceLayer { + +using namespace chip::DeviceLayer::Internal; + +/* + * Members functions that implement the DeviceAttestationCredentialsProvider + */ +CHIP_ERROR OptigaFactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) +{ + uint16_t length = out_dac_buffer.size(); + VerifyOrReturnError(wiced_optiga_read_data(OPTIGA_DAC_OBJECT_ID, OPTIGA_OBJECT_DATA, out_dac_buffer.data(), &length) == + WICED_SUCCESS, + CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + out_dac_buffer.reduce_size(length); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OptigaFactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) +{ + uint16_t length = out_pai_buffer.size(); + VerifyOrReturnError(wiced_optiga_read_data(OPTIGA_PAI_CERT_OBJECT_ID, OPTIGA_OBJECT_DATA, out_pai_buffer.data(), &length) == + WICED_SUCCESS, + CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + out_pai_buffer.reduce_size(length); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OptigaFactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, + MutableByteSpan & out_signature_buffer) +{ + VerifyOrReturnError(!out_signature_buffer.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!message_to_sign.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_signature_buffer.size() >= Crypto::kMax_ECDSA_Signature_Length, CHIP_ERROR_BUFFER_TOO_SMALL); + + uint8_t digest[Crypto::kSHA256_Hash_Length]; + ReturnErrorOnFailure(Crypto::Hash_SHA256(message_to_sign.data(), message_to_sign.size(), digest)); + ByteSpan digest_span(digest); + + constexpr uint8_t kAsn1HeaderLength = 2u; + constexpr uint8_t kSeqTag = 0x30u; + + uint8_t asn1_sigature_buffer[Crypto::kMax_ECDSA_Signature_Length_Der]; + MutableByteSpan asn1_signature_span(asn1_sigature_buffer); + + MutableByteSpan optiga_signature_span(asn1_signature_span.SubSpan(kAsn1HeaderLength)); + ReturnErrorOnFailure(SignWithOptigaDeviceAttestationKey(digest_span, optiga_signature_span)); + + asn1_signature_span[0] = kSeqTag; + asn1_signature_span[1] = optiga_signature_span.size(); + asn1_signature_span.reduce_size(kAsn1HeaderLength + optiga_signature_span.size()); + ReturnErrorOnFailure(Crypto::EcdsaAsn1SignatureToRaw(Crypto::kP256_FE_Length, asn1_signature_span, out_signature_buffer)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OptigaFactoryDataProvider::SignWithOptigaDeviceAttestationKey(const ByteSpan & digest, MutableByteSpan & signature) +{ + uint16_t signature_length = signature.size(); + VerifyOrReturnError(wiced_optiga_ecdsa_sign(digest.data(), digest.size(), OPTIGA_DAC_KEY_OBJECT_ID, signature.data(), + &signature_length) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + signature.reduce_size(signature_length); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h new file mode 100644 index 00000000000000..a11074632c9ba5 --- /dev/null +++ b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h @@ -0,0 +1,38 @@ +/* + * + * 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 "FactoryDataProvider.h" + +namespace chip { +namespace DeviceLayer { + +class OptigaFactoryDataProvider : public FactoryDataProvider +{ +public: + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override; + +protected: + CHIP_ERROR SignWithOptigaDeviceAttestationKey(const ByteSpan & digest, MutableByteSpan & signature); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp new file mode 100644 index 00000000000000..9d56181d6bd79b --- /dev/null +++ b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UnprovisionedOptigaFactoryDataProvider.h" + +#include +#include + +using namespace chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::Init() +{ + ReturnErrorOnFailure(OptigaFactoryDataProvider::Init()); + + if (CYW30739Config::ConfigValueExists(CYW30739Config::kConfigKey_ProvisioningDAC)) + { + if (!ChipError::IsSuccess(CheckProvisionedDataValidity())) + { + ReturnErrorOnFailure(ProvisionDataOnce()); + } + + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningDAC); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningPAICert); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningSecret); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningSecretMetaData); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningDACMetaData); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningDACKeyMetaData); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningManifest); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningFragment); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::ProvisionDataOnce() +{ + constexpr struct + { + CYW30739Config::Key key; + uint16_t object_id; + uint8_t object_type; + } configs[] = { + { CYW30739Config::kConfigKey_ProvisioningDAC, OPTIGA_DAC_OBJECT_ID, OPTIGA_OBJECT_DATA }, + { CYW30739Config::kConfigKey_ProvisioningPAICert, OPTIGA_PAI_CERT_OBJECT_ID, OPTIGA_OBJECT_DATA }, + { CYW30739Config::kConfigKey_ProvisioningSecret, OPTIGA_SECRET_OBJECT_ID, OPTIGA_OBJECT_DATA }, + { CYW30739Config::kConfigKey_ProvisioningSecretMetaData, OPTIGA_SECRET_OBJECT_ID, OPTIGA_OBJECT_METADATA }, + { CYW30739Config::kConfigKey_ProvisioningDACMetaData, OPTIGA_DAC_OBJECT_ID, OPTIGA_OBJECT_METADATA }, + { CYW30739Config::kConfigKey_ProvisioningDACKeyMetaData, OPTIGA_DAC_KEY_OBJECT_ID, OPTIGA_OBJECT_METADATA }, + }; + + ChipLogProgress(DeviceLayer, "Provisioning Optiga data"); + + for (size_t i = 0; i < ArraySize(configs); i++) + { + ProvisionDataFromConfig(configs[i].key, configs[i].object_id, configs[i].object_type); + } + + ProvisionProtectedData(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::ProvisionDataFromConfig(CYW30739Config::Key key, uint16_t object_id, + uint8_t object_type) +{ + size_t read_size; + uint8_t buf[Credentials::kMaxDERCertLength]; + MutableByteSpan buf_span(buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(key, buf_span.data(), buf_span.size(), read_size)); + buf_span.reduce_size(read_size); + + VerifyOrReturnError(wiced_optiga_write_data(object_id, object_type, buf_span.data(), buf_span.size()) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::CheckProvisionedDataValidity() +{ + uint8_t digest_buf[Crypto::kSHA256_Hash_Length]; + MutableByteSpan digest_span(digest_buf); + ReturnErrorOnFailure(Crypto::DRBG_get_bytes(digest_span.data(), digest_span.size())); + + uint8_t signature_buffer[Crypto::kMax_ECDSA_Signature_Length_Der]; + MutableByteSpan signature_span(signature_buffer); + ReturnErrorOnFailure(SignWithOptigaDeviceAttestationKey(digest_span, signature_span)); + + ReturnErrorOnFailure(VerifyOptigaSignature(digest_span, signature_span, OPTIGA_DAC_OBJECT_ID)); + + Crypto::P256PublicKey dac_public_key; + ReturnErrorOnFailure(GetDeviceAttestationCertPublicKey(dac_public_key)); + ReturnErrorOnFailure(VerifyOptigaSignature(digest_span, signature_span, dac_public_key)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::ProvisionProtectedData() +{ + constexpr size_t kMaxManifestLength = 256; + uint8_t buf[kMaxManifestLength]; + size_t read_size; + + /* Update the manifest */ + MutableByteSpan manifest_span(buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_ProvisioningManifest, manifest_span.data(), + manifest_span.size(), read_size)); + manifest_span.reduce_size(read_size); + + VerifyOrReturnError(wiced_optiga_protected_update_start(1, manifest_span.data(), manifest_span.size()) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + + /* Update the fragment */ + MutableByteSpan fragment_span(buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_ProvisioningFragment, fragment_span.data(), + fragment_span.size(), read_size)); + fragment_span.reduce_size(read_size); + + VerifyOrReturnError(wiced_optiga_protected_update_final(fragment_span.data(), fragment_span.size()) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, + uint16_t public_key) +{ + VerifyOrReturnError(wiced_optiga_ecdsa_verify(digest.data(), digest.size(), signature.data(), signature.size(), + OPTIGA_CRYPT_OID_DATA, &public_key) == WICED_SUCCESS, + CHIP_ERROR_INVALID_SIGNATURE); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, + Crypto::P256PublicKey & public_key) +{ + VerifyOrReturnError(public_key.Length() == Crypto::kP256_PublicKey_Length, CHIP_ERROR_INVALID_PUBLIC_KEY); + + constexpr uint8_t kOptigaDerBitstringTag = 0x03; + constexpr uint8_t kOptigaDerAdditionalLength = 0x01; + constexpr uint8_t kOptigaDerNumUnusedBits = 0x00; + constexpr size_t kOptigaPublicKeyHeaderLength = 3; + static uint8_t host_public_key[kOptigaPublicKeyHeaderLength + Crypto::kP256_PublicKey_Length] = { + [0] = kOptigaDerBitstringTag, + [1] = kOptigaDerAdditionalLength + Crypto::kP256_PublicKey_Length, + [2] = kOptigaDerNumUnusedBits, + }; + memcpy(host_public_key + kOptigaPublicKeyHeaderLength, public_key, public_key.Length()); + const public_key_from_host_t public_key_from_host = { + .public_key = host_public_key, + .length = sizeof(host_public_key), + .key_type = OPTIGA_ECC_CURVE_NIST_P_256, + }; + VerifyOrReturnError(wiced_optiga_ecdsa_verify(digest.data(), digest.size(), signature.data(), signature.size(), + OPTIGA_CRYPT_HOST_DATA, &public_key_from_host) == WICED_SUCCESS, + CHIP_ERROR_INVALID_SIGNATURE); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::GetDeviceAttestationCertPublicKey(Crypto::P256PublicKey & public_key) +{ + size_t read_size; + uint8_t dac_buf[Credentials::kMaxDERCertLength]; + MutableByteSpan dac_span(dac_buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_ProvisioningDAC, dac_span.data(), + dac_span.size(), read_size)); + dac_span.reduce_size(read_size); + + ReturnErrorOnFailure(ExtractPubkeyFromX509Cert(dac_span, public_key)); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h new file mode 100644 index 00000000000000..8c746ee0210aac --- /dev/null +++ b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h @@ -0,0 +1,43 @@ +/* + * + * 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 "OptigaFactoryDataProvider.h" + +#include + +namespace chip { +namespace DeviceLayer { + +class UnprovisionedOptigaFactoryDataProvider : public OptigaFactoryDataProvider +{ +public: + CHIP_ERROR Init(); + +private: + CHIP_ERROR ProvisionDataOnce(); + CHIP_ERROR ProvisionDataFromConfig(Internal::CYW30739Config::Key key, uint16_t object_id, uint8_t object_type); + CHIP_ERROR CheckProvisionedDataValidity(); + CHIP_ERROR ProvisionProtectedData(); + CHIP_ERROR VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, uint16_t public_key); + CHIP_ERROR VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, Crypto::P256PublicKey & public_key); + CHIP_ERROR GetDeviceAttestationCertPublicKey(Crypto::P256PublicKey & public_key); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/args.gni b/src/platform/Infineon/CYW30739/args.gni index 11bfab9379ff68..84a72321b420bd 100644 --- a/src/platform/Infineon/CYW30739/args.gni +++ b/src/platform/Infineon/CYW30739/args.gni @@ -65,3 +65,5 @@ openthread_config_ip6_slaac_enable = true openthread_config_joiner_enable = true openthread_config_log_output = "platform_defined" openthread_config_srp_client_enable = true + +optiga_trust_m_dir = "${chip_root}/third_party/infineon/trustm/optiga-trust-m" diff --git a/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h b/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h index 1446a2d3d7b3a9..c6e275d4521f69 100644 --- a/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h +++ b/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h @@ -188,6 +188,39 @@ */ #define MBEDTLS_PKCS5_C +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, + * MBEDTLS_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ + +#define MBEDTLS_X509_CRT_PARSE_C /** * \def MBEDTLS_X509_CREATE_C * diff --git a/src/platform/Infineon/CYW30739/cyw30739_platform.gni b/src/platform/Infineon/CYW30739/cyw30739_platform.gni index 367727207e506b..9854a590b99841 100644 --- a/src/platform/Infineon/CYW30739/cyw30739_platform.gni +++ b/src/platform/Infineon/CYW30739/cyw30739_platform.gni @@ -20,7 +20,7 @@ import("${chip_root}/src/platform/Infineon/CYW30739/args.gni") cyw30739_platform_dir = "${chip_root}/src/platform/Infineon/CYW30739" template("cyw30739_platform") { - forward_variables_from(invoker, [ "chip_family" ]) + forward_variables_from(invoker, [ "board" ]) static_library(target_name) { sources = [ @@ -29,6 +29,7 @@ template("cyw30739_platform") { "${cyw30739_platform_dir}/ConfigurationManagerImpl.cpp", "${cyw30739_platform_dir}/DiagnosticDataProviderImpl.cpp", "${cyw30739_platform_dir}/EventFlags.cpp", + "${cyw30739_platform_dir}/FactoryDataProvider.cpp", "${cyw30739_platform_dir}/Logging.cpp", "${cyw30739_platform_dir}/OTAImageProcessorImpl.cpp", "${cyw30739_platform_dir}/PlatformManagerImpl.cpp", @@ -40,8 +41,14 @@ template("cyw30739_platform") { sources += [ "${cyw30739_platform_dir}/ThreadStackManagerImpl.cpp" ] } - configs += - [ "${matter_wpan_sdk_build_root}:wpan_sdk-${chip_family}-config" ] + if (invoker.board_use_optiga) { + sources += [ + "${cyw30739_platform_dir}/OptigaFactoryDataProvider.cpp", + "${cyw30739_platform_dir}/UnprovisionedOptigaFactoryDataProvider.cpp", + ] + } + + configs += [ "${matter_wpan_sdk_build_root}:${board}-config" ] deps = [ "${chip_root}/src/platform:platform", diff --git a/src/platform/Linux/DiagnosticDataProviderImpl.cpp b/src/platform/Linux/DiagnosticDataProviderImpl.cpp index 5ee5558064afeb..bebe5827163fa9 100644 --- a/src/platform/Linux/DiagnosticDataProviderImpl.cpp +++ b/src/platform/Linux/DiagnosticDataProviderImpl.cpp @@ -74,8 +74,10 @@ enum class WiFiStatsCountType kWiFiOverrunCount }; +#if defined(__GLIBC__) // Static variable to store the maximum heap size static size_t maxHeapHighWatermark = 0; +#endif CHIP_ERROR GetEthernetStatsCount(EthernetStatsCountType type, uint64_t & count) { @@ -223,9 +225,7 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) { -#ifndef __GLIBC__ - return CHIP_ERROR_NOT_IMPLEMENTED; -#else +#if defined(__GLIBC__) struct mallinfo mallocInfo = mallinfo(); // Get the current amount of heap memory, in bytes, that are not being utilized @@ -233,14 +233,14 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeap currentHeapFree = mallocInfo.fordblks; return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; #endif } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) { -#ifndef __GLIBC__ - return CHIP_ERROR_NOT_IMPLEMENTED; -#else +#if defined(__GLIBC__) struct mallinfo mallocInfo = mallinfo(); // Get the current amount of heap memory, in bytes, that are being used by @@ -253,14 +253,14 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeap maxHeapHighWatermark = currentHeapUsed; } return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; #endif } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) { -#ifndef __GLIBC__ - return CHIP_ERROR_NOT_IMPLEMENTED; -#else +#if defined(__GLIBC__) struct mallinfo mallocInfo = mallinfo(); // The usecase of this function is embedded devices,on which we would need to intercept @@ -279,6 +279,8 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & cu currentHeapHighWatermark = maxHeapHighWatermark; return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; #endif } @@ -287,10 +289,12 @@ CHIP_ERROR DiagnosticDataProviderImpl::ResetWatermarks() // If implemented, the server SHALL set the value of the CurrentHeapHighWatermark attribute to the // value of the CurrentHeapUsed. +#if defined(__GLIBC__) // Get the current amount of heap memory, in bytes, that are being used by // the current running program and reset the max heap high watermark to current heap amount. struct mallinfo mallocInfo = mallinfo(); maxHeapHighWatermark = mallocInfo.uordblks; +#endif return CHIP_NO_ERROR; } diff --git a/src/platform/Linux/DnssdImpl.cpp b/src/platform/Linux/DnssdImpl.cpp index 800064f52157de..40b7c89812d251 100644 --- a/src/platform/Linux/DnssdImpl.cpp +++ b/src/platform/Linux/DnssdImpl.cpp @@ -611,9 +611,9 @@ CHIP_ERROR MdnsAvahi::Browse(const char * type, DnssdServiceProtocol protocol, c { avahiInterface = AVAHI_IF_UNSPEC; } - browseContext->mInterface = avahiInterface; - browseContext->mProtocol = GetFullType(type, protocol); - browseContext->mBrowseRetries = 0; + browseContext->mInterface = avahiInterface; + browseContext->mProtocol = GetFullType(type, protocol); + browseContext->mReceivedAllCached = false; browseContext->mStopped.store(false); browser = avahi_service_browser_new(mClient, avahiInterface, AVAHI_PROTO_UNSPEC, browseContext->mProtocol.c_str(), nullptr, @@ -686,23 +686,22 @@ void CopyTypeWithoutProtocol(char (&dest)[N], const char * typeAndProtocol) } } -void MdnsAvahi::BrowseRetryCallback(chip::System::Layer * aLayer, void * appState) +void MdnsAvahi::InvokeDelegateOrCleanUp(BrowseContext * context, AvahiServiceBrowser * browser) { - BrowseContext * context = static_cast(appState); - // Don't schedule anything new if we've stopped. - if (context->mStopped.load()) + // If we were already asked to stop, no need to send a callback - no one is listening. + if (!context->mStopped.load()) { - chip::Platform::Delete(context); - return; + // since this is continuous browse, finalBrowse will always be false. + context->mCallback(context->mContext, context->mServices.data(), context->mServices.size(), false, CHIP_NO_ERROR); + + // Clearing records/services already passed to application through delegate. Keeping it may cause + // duplicates in next query / retry attempt as currently found will also come again from cache. + context->mServices.clear(); } - AvahiServiceBrowser * newBrowser = - avahi_service_browser_new(context->mInstance->mClient, context->mInterface, AVAHI_PROTO_UNSPEC, context->mProtocol.c_str(), - nullptr, static_cast(0), HandleBrowse, context); - if (newBrowser == nullptr) + else { - // If we failed to create the browser, this browse context is effectively done. We need to call the final callback and - // delete the context. - context->mCallback(context->mContext, context->mServices.data(), context->mServices.size(), true, CHIP_NO_ERROR); + // browse is stopped, so free browse handle and context + avahi_service_browser_free(browser); chip::Platform::Delete(context); } } @@ -722,6 +721,13 @@ void MdnsAvahi::HandleBrowse(AvahiServiceBrowser * browser, AvahiIfIndex interfa break; case AVAHI_BROWSER_NEW: ChipLogProgress(DeviceLayer, "Avahi browse: cache new"); + if (context->mStopped.load()) + { + // browse is stopped, so free browse handle and context + avahi_service_browser_free(browser); + chip::Platform::Delete(context); + break; + } if (strcmp("local", domain) == 0) { DnssdService service = {}; @@ -738,41 +744,53 @@ void MdnsAvahi::HandleBrowse(AvahiServiceBrowser * browser, AvahiIfIndex interfa } service.mType[kDnssdTypeMaxSize] = 0; context->mServices.push_back(service); + if (context->mReceivedAllCached) + { + InvokeDelegateOrCleanUp(context, browser); + } } break; case AVAHI_BROWSER_ALL_FOR_NOW: { ChipLogProgress(DeviceLayer, "Avahi browse: all for now"); - bool needRetries = context->mBrowseRetries++ < kMaxBrowseRetries && !context->mStopped.load(); - // If we were already asked to stop, no need to send a callback - no one is listening. - if (!context->mStopped.load()) - { - context->mCallback(context->mContext, context->mServices.data(), context->mServices.size(), !needRetries, - CHIP_NO_ERROR); - } - avahi_service_browser_free(browser); - if (needRetries) - { - context->mNextRetryDelay *= 2; - // Hand the ownership of the context over to the timer. It will either schedule a new browse on the context, - // triggering this function, or it will delete and not reschedule (if stopped). - DeviceLayer::SystemLayer().StartTimer(context->mNextRetryDelay / 2, BrowseRetryCallback, context); - } - else - { - // We didn't schedule a timer, so we're responsible for deleting the context - chip::Platform::Delete(context); - } + context->mReceivedAllCached = true; + + InvokeDelegateOrCleanUp(context, browser); break; } case AVAHI_BROWSER_REMOVE: ChipLogProgress(DeviceLayer, "Avahi browse: remove"); if (strcmp("local", domain) == 0) { - context->mServices.erase( - std::remove_if(context->mServices.begin(), context->mServices.end(), [name, type](const DnssdService & service) { - return strcmp(name, service.mName) == 0 && type == GetFullType(service.mType, service.mProtocol); - })); + // don't attempt to erase if vector has been cleared + if (context->mServices.size()) + { + context->mServices.erase(std::remove_if( + context->mServices.begin(), context->mServices.end(), [name, type](const DnssdService & service) { + return strcmp(name, service.mName) == 0 && type == GetFullType(service.mType, service.mProtocol); + })); + } + + if (context->mReceivedAllCached) + { + DnssdService service = {}; + + Platform::CopyString(service.mName, name); + CopyTypeWithoutProtocol(service.mType, type); + service.mProtocol = GetProtocolInType(type); + service.mAddressType = context->mAddressType; + service.mTransportType = ToAddressType(protocol); + service.mInterface = Inet::InterfaceId::Null(); + if (interface != AVAHI_IF_UNSPEC) + { + service.mInterface = static_cast(interface); + } + service.mTtlSeconds = 0; + + context->mServices.push_back(service); + InvokeDelegateOrCleanUp(context, browser); + } } + break; case AVAHI_BROWSER_CACHE_EXHAUSTED: ChipLogProgress(DeviceLayer, "Avahi browse: cache exhausted"); diff --git a/src/platform/Linux/DnssdImpl.h b/src/platform/Linux/DnssdImpl.h index c66a8c23f700b6..f1de8dbf0b1491 100644 --- a/src/platform/Linux/DnssdImpl.h +++ b/src/platform/Linux/DnssdImpl.h @@ -131,11 +131,11 @@ class MdnsAvahi void * mContext; Inet::IPAddressType mAddressType; std::vector mServices; - size_t mBrowseRetries; + bool mReceivedAllCached; AvahiIfIndex mInterface; std::string mProtocol; - chip::System::Clock::Timeout mNextRetryDelay = chip::System::Clock::Seconds16(1); std::atomic_bool mStopped{ false }; + AvahiServiceBrowser * mBrowser; }; struct ResolveContext @@ -181,7 +181,7 @@ class MdnsAvahi static void HandleBrowse(AvahiServiceBrowser * broswer, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char * name, const char * type, const char * domain, AvahiLookupResultFlags flags, void * userdata); - static void BrowseRetryCallback(chip::System::Layer * aLayer, void * appState); + static void InvokeDelegateOrCleanUp(BrowseContext * context, AvahiServiceBrowser * browser); static void HandleResolve(AvahiServiceResolver * resolver, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char * name, const char * type, const char * domain, const char * host_name, const AvahiAddress * address, uint16_t port, AvahiStringList * txt, diff --git a/src/platform/Linux/bluez/BluezConnection.cpp b/src/platform/Linux/bluez/BluezConnection.cpp index 722cb2478d1665..6ed15b5bb7cb45 100644 --- a/src/platform/Linux/bluez/BluezConnection.cpp +++ b/src/platform/Linux/bluez/BluezConnection.cpp @@ -94,7 +94,7 @@ CHIP_ERROR BluezConnection::Init(const BluezEndpoint & aEndpoint) if (service != nullptr) { if ((BluezIsServiceOnDevice(service, mDevice.get())) == TRUE && - (strcmp(bluez_gatt_service1_get_uuid(service), CHIP_BLE_UUID_SERVICE_STRING) == 0)) + (strcmp(bluez_gatt_service1_get_uuid(service), Ble::CHIP_BLE_SERVICE_LONG_UUID_STR) == 0)) { mService.reset(service); break; @@ -111,18 +111,18 @@ CHIP_ERROR BluezConnection::Init(const BluezEndpoint & aEndpoint) if (char1 != nullptr) { if ((BluezIsCharOnService(char1, mService.get()) == TRUE) && - (strcmp(bluez_gatt_characteristic1_get_uuid(char1), CHIP_PLAT_BLE_UUID_C1_STRING) == 0)) + (strcmp(bluez_gatt_characteristic1_get_uuid(char1), Ble::CHIP_BLE_CHAR_1_UUID_STR) == 0)) { mC1.reset(char1); } else if ((BluezIsCharOnService(char1, mService.get()) == TRUE) && - (strcmp(bluez_gatt_characteristic1_get_uuid(char1), CHIP_PLAT_BLE_UUID_C2_STRING) == 0)) + (strcmp(bluez_gatt_characteristic1_get_uuid(char1), Ble::CHIP_BLE_CHAR_2_UUID_STR) == 0)) { mC2.reset(char1); } #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING else if ((BluezIsCharOnService(char1, mService.get()) == TRUE) && - (strcmp(bluez_gatt_characteristic1_get_uuid(char1), CHIP_PLAT_BLE_UUID_C3_STRING) == 0)) + (strcmp(bluez_gatt_characteristic1_get_uuid(char1), Ble::CHIP_BLE_CHAR_3_UUID_STR) == 0)) { mC3.reset(char1); } @@ -335,7 +335,7 @@ void BluezConnection::SubscribeCharacteristicDone(GObject * aObject, GAsyncResul auto * pC2 = reinterpret_cast(aObject); GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(pC2, aResult, &error.GetReceiver()); + gboolean success = bluez_gatt_characteristic1_call_start_notify_finish(pC2, aResult, &error.GetReceiver()); VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: SubscribeCharacteristic : %s", error->message)); @@ -367,7 +367,7 @@ void BluezConnection::UnsubscribeCharacteristicDone(GObject * aObject, GAsyncRes auto * pC2 = reinterpret_cast(aObject); GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(pC2, aResult, &error.GetReceiver()); + gboolean success = bluez_gatt_characteristic1_call_stop_notify_finish(pC2, aResult, &error.GetReceiver()); VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: UnsubscribeCharacteristic : %s", error->message)); diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 151c09e09f662d..55b127e1b17014 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -438,10 +438,10 @@ void BluezEndpoint::SetupGattService() static const char * const c3_flags[] = { "read", nullptr }; #endif - mService.reset(CreateGattService(CHIP_BLE_UUID_SERVICE_SHORT_STRING)); + mService.reset(CreateGattService(Ble::CHIP_BLE_SERVICE_SHORT_UUID_STR)); // C1 characteristic - mC1.reset(CreateGattCharacteristic(mService.get(), "c1", CHIP_PLAT_BLE_UUID_C1_STRING, c1_flags)); + mC1.reset(CreateGattCharacteristic(mService.get(), "c1", Ble::CHIP_BLE_CHAR_1_UUID_STR, c1_flags)); g_signal_connect(mC1.get(), "handle-read-value", G_CALLBACK(+[](BluezGattCharacteristic1 * aChar, GDBusMethodInvocation * aInv, GVariant * aOpt, BluezEndpoint * self) { return self->BluezCharacteristicReadValue(aChar, aInv, aOpt); }), @@ -455,7 +455,7 @@ void BluezEndpoint::SetupGattService() g_signal_connect(mC1.get(), "handle-confirm", G_CALLBACK(BluezCharacteristicConfirmError), nullptr); // C2 characteristic - mC2.reset(CreateGattCharacteristic(mService.get(), "c2", CHIP_PLAT_BLE_UUID_C2_STRING, c2_flags)); + mC2.reset(CreateGattCharacteristic(mService.get(), "c2", Ble::CHIP_BLE_CHAR_2_UUID_STR, c2_flags)); g_signal_connect(mC2.get(), "handle-read-value", G_CALLBACK(+[](BluezGattCharacteristic1 * aChar, GDBusMethodInvocation * aInv, GVariant * aOpt, BluezEndpoint * self) { return self->BluezCharacteristicReadValue(aChar, aInv, aOpt); }), @@ -478,7 +478,7 @@ void BluezEndpoint::SetupGattService() #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING ChipLogDetail(DeviceLayer, "CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING is TRUE"); // Additional data characteristics - mC3.reset(CreateGattCharacteristic(mService.get(), "c3", CHIP_PLAT_BLE_UUID_C3_STRING, c3_flags)); + mC3.reset(CreateGattCharacteristic(mService.get(), "c3", Ble::CHIP_BLE_CHAR_3_UUID_STR, c3_flags)); g_signal_connect(mC3.get(), "handle-read-value", G_CALLBACK(+[](BluezGattCharacteristic1 * aChar, GDBusMethodInvocation * aInv, GVariant * aOpt, BluezEndpoint * self) { return self->BluezCharacteristicReadValue(aChar, aInv, aOpt); }), diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.cpp b/src/platform/Linux/bluez/ChipDeviceScanner.cpp index dcb113b7f479c9..3323f1e7da57af 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.cpp +++ b/src/platform/Linux/bluez/ChipDeviceScanner.cpp @@ -42,7 +42,7 @@ bool BluezGetChipDeviceInfo(BluezDevice1 & aDevice, chip::Ble::ChipBLEDeviceIden GVariant * serviceData = bluez_device1_get_service_data(&aDevice); VerifyOrReturnError(serviceData != nullptr, false); - GAutoPtr dataValue(g_variant_lookup_value(serviceData, CHIP_BLE_UUID_SERVICE_STRING, nullptr)); + GAutoPtr dataValue(g_variant_lookup_value(serviceData, Ble::CHIP_BLE_SERVICE_LONG_UUID_STR, nullptr)); VerifyOrReturnError(dataValue != nullptr, false); size_t dataLen = 0; diff --git a/src/platform/Linux/bluez/Types.h b/src/platform/Linux/bluez/Types.h index 95fd669efc1226..4bd2c89d9a7966 100644 --- a/src/platform/Linux/bluez/Types.h +++ b/src/platform/Linux/bluez/Types.h @@ -110,18 +110,6 @@ namespace Internal { #define ADVERTISING_INTERFACE BLUEZ_INTERFACE ".LEAdvertisement1" #define DEVICE_INTERFACE BLUEZ_INTERFACE ".Device1" -#define CHIP_PLAT_BLE_UUID_C1_STRING "18ee2ef5-263d-4559-959f-4f9c429f9d11" -#define CHIP_PLAT_BLE_UUID_C2_STRING "18ee2ef5-263d-4559-959f-4f9c429f9d12" -#define CHIP_PLAT_BLE_UUID_C3_STRING "64630238-8772-45F2-B87D-748A83218F04" - -#define CHIP_BLE_BASE_SERVICE_UUID_STRING "-0000-1000-8000-00805f9b34fb" -#define CHIP_BLE_SERVICE_PREFIX_LENGTH 8 -#define CHIP_BLE_BASE_SERVICE_PREFIX "0000" -#define CHIP_BLE_UUID_SERVICE_SHORT_STRING "fff6" - -#define CHIP_BLE_UUID_SERVICE_STRING \ - CHIP_BLE_BASE_SERVICE_PREFIX CHIP_BLE_UUID_SERVICE_SHORT_STRING CHIP_BLE_BASE_SERVICE_UUID_STRING - #define BLUEZ_ADV_TYPE_FLAGS 0x01 #define BLUEZ_ADV_TYPE_SERVICE_DATA 0x16 diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h index 6b9e1f7432612c..317bff7c05403e 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h @@ -230,7 +230,6 @@ class GenericThreadStackManagerImpl_OpenThread DnsBrowseCallback mDnsBrowseCallback; DnsResolveCallback mDnsResolveCallback; - GeneralFaults mNetworkFaults; struct DnsServiceTxtEntries { @@ -264,6 +263,8 @@ class GenericThreadStackManagerImpl_OpenThread #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + GeneralFaults mNetworkFaults; + inline ImplClass * Impl() { return static_cast(this); } }; diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index 12f9af57a44342..cf1894cf93fc74 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -247,7 +247,9 @@ void GenericThreadStackManagerImpl_OpenThread::_OnPlatformEvent(const } #if CHIP_DETAIL_LOGGING + Impl()->LockThreadStack(); LogOpenThreadStateChange(mOTInst, event->ThreadStateChange.OpenThread.Flags); + Impl()->UnlockThreadStack(); #endif // CHIP_DETAIL_LOGGING } } diff --git a/src/platform/OpenThread/OpenThreadDnssdImpl.cpp b/src/platform/OpenThread/OpenThreadDnssdImpl.cpp index cb205df95eb72b..f5b0a85f2d0d83 100644 --- a/src/platform/OpenThread/OpenThreadDnssdImpl.cpp +++ b/src/platform/OpenThread/OpenThreadDnssdImpl.cpp @@ -24,6 +24,7 @@ namespace Dnssd { CHIP_ERROR OpenThreadDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) { +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT ReturnErrorOnFailure(ThreadStackMgr().SetSrpDnsCallbacks(initCallback, errorCallback, context)); uint8_t macBuffer[ConfigurationManager::kPrimaryMACAddressLength]; @@ -33,6 +34,9 @@ CHIP_ERROR OpenThreadDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsync MakeHostName(hostname, sizeof(hostname), mac); return ThreadStackMgr().ClearSrpHost(hostname); +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT } const char * GetProtocolString(DnssdServiceProtocol protocol) diff --git a/src/platform/OpenThread/OpenThreadUtils.cpp b/src/platform/OpenThread/OpenThreadUtils.cpp index ef97c7a4e35947..093997c66fb789 100644 --- a/src/platform/OpenThread/OpenThreadUtils.cpp +++ b/src/platform/OpenThread/OpenThreadUtils.cpp @@ -87,11 +87,6 @@ void RegisterOpenThreadErrorFormatter(void) RegisterErrorFormatter(&sOpenThreadErrorFormatter); } -/** - * Log information related to a state change in the OpenThread stack. - * - * NB: This function *must* be called with the Thread stack lock held. - */ void LogOpenThreadStateChange(otInstance * otInst, uint32_t flags) { #if CHIP_DETAIL_LOGGING diff --git a/src/platform/OpenThread/OpenThreadUtils.h b/src/platform/OpenThread/OpenThreadUtils.h index ad2687cf53aea5..f9609e8d8728af 100644 --- a/src/platform/OpenThread/OpenThreadUtils.h +++ b/src/platform/OpenThread/OpenThreadUtils.h @@ -60,6 +60,12 @@ namespace Internal { extern CHIP_ERROR MapOpenThreadError(otError otErr); extern void RegisterOpenThreadErrorFormatter(void); + +/** + * Log information related to a state change in the OpenThread stack. + * + * NB: This function *must* be called with the Thread stack lock held. + */ extern void LogOpenThreadStateChange(otInstance * otInst, uint32_t flags); extern void LogOpenThreadPacket(const char * titleStr, otMessage * pkt); extern bool IsOpenThreadMeshLocalAddress(otInstance * otInst, const Inet::IPAddress & addr); diff --git a/src/platform/Tizen/BLEManagerImpl.cpp b/src/platform/Tizen/BLEManagerImpl.cpp index a78efd9c944cce..209c5fb2337356 100644 --- a/src/platform/Tizen/BLEManagerImpl.cpp +++ b/src/platform/Tizen/BLEManagerImpl.cpp @@ -74,14 +74,6 @@ namespace Internal { namespace { -/* CHIPoBLE UUID strings */ -constexpr char chip_ble_service_uuid[] = "0000FFF6-0000-1000-8000-00805F9B34FB"; -constexpr char chip_ble_char_c1_tx_uuid[] = "18EE2EF5-263D-4559-959F-4F9C429F9D11"; -constexpr char chip_ble_char_c2_rx_uuid[] = "18EE2EF5-263D-4559-959F-4F9C429F9D12"; - -constexpr char chip_ble_desc_uuid_short[] = "2902"; -constexpr char chip_ble_service_uuid_short[] = "FFF6"; - constexpr System::Clock::Timeout kNewConnectionScanTimeout = System::Clock::Seconds16(20); constexpr System::Clock::Timeout kConnectTimeout = System::Clock::Seconds16(20); constexpr System::Clock::Timeout kFastAdvertiseTimeout = @@ -582,12 +574,12 @@ CHIP_ERROR BLEManagerImpl::RegisterGATTServer() VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_server_create() failed: %s", get_error_message(ret))); // Create Service (BTP Service) - ret = bt_gatt_service_create(chip_ble_service_uuid, BT_GATT_SERVICE_TYPE_PRIMARY, &service); + ret = bt_gatt_service_create(Ble::CHIP_BLE_SERVICE_LONG_UUID_STR, BT_GATT_SERVICE_TYPE_PRIMARY, &service); VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_service_create() failed: %s", get_error_message(ret))); // Create 1st Characteristic (Client TX Buffer) ret = bt_gatt_characteristic_create( - chip_ble_char_c1_tx_uuid, BT_GATT_PERMISSION_WRITE, + Ble::CHIP_BLE_CHAR_1_UUID_STR, BT_GATT_PERMISSION_WRITE, BT_GATT_PROPERTY_WRITE, // Write Request is not coming if we use WITHOUT_RESPONSE property. Let's use WRITE property and // consider to use WITHOUT_RESPONSE property in the future according to the CHIP Spec 4.16.3.2. BTP // GATT Service @@ -611,7 +603,7 @@ CHIP_ERROR BLEManagerImpl::RegisterGATTServer() ChipLogError(DeviceLayer, "bt_gatt_service_add_characteristic() failed: %s", get_error_message(ret))); // Create 2nd Characteristic (Client RX Buffer) - ret = bt_gatt_characteristic_create(chip_ble_char_c2_rx_uuid, BT_GATT_PERMISSION_READ, + ret = bt_gatt_characteristic_create(Ble::CHIP_BLE_CHAR_2_UUID_STR, BT_GATT_PERMISSION_READ, BT_GATT_PROPERTY_READ | BT_GATT_PROPERTY_INDICATE, "CHIPoBLE_C2", strlen("CHIPoBLE_C2"), &char2); VerifyOrExit(ret == BT_ERROR_NONE, @@ -637,8 +629,8 @@ CHIP_ERROR BLEManagerImpl::RegisterGATTServer() get_error_message(ret))); // Create CCC Descriptor - ret = bt_gatt_descriptor_create(chip_ble_desc_uuid_short, BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE, desc_value, - sizeof(desc_value), &desc); + ret = bt_gatt_descriptor_create(Ble::CHIP_BLE_DESC_SHORT_UUID_STR, BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE, + desc_value, sizeof(desc_value), &desc); VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_descriptor_create() failed: %s", get_error_message(ret))); ret = bt_gatt_characteristic_add_descriptor(char2, desc); VerifyOrExit(ret == BT_ERROR_NONE, @@ -711,7 +703,8 @@ CHIP_ERROR BLEManagerImpl::StartBLEAdvertising() VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "GetBLEDeviceIdentificationInfo() failed: %" CHIP_ERROR_FORMAT, err.Format())); - ret = bt_adapter_le_add_advertising_service_data(mAdvertiser, BT_ADAPTER_LE_PACKET_ADVERTISING, chip_ble_service_uuid_short, + ret = bt_adapter_le_add_advertising_service_data(mAdvertiser, BT_ADAPTER_LE_PACKET_ADVERTISING, + Ble::CHIP_BLE_SERVICE_SHORT_UUID_STR, reinterpret_cast(&deviceIdInfo), sizeof(deviceIdInfo)); VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_adapter_le_add_advertising_service_data() failed: %s", get_error_message(ret))); @@ -779,12 +772,12 @@ static bool __GattClientForeachCharCb(int total, int index, bt_gatt_h charHandle VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from CHAR handle: %s", get_error_message(ret))); - if (strcasecmp(uuid.get(), chip_ble_char_c1_tx_uuid) == 0) + if (strcasecmp(uuid.get(), Ble::CHIP_BLE_CHAR_1_UUID_STR) == 0) { ChipLogProgress(DeviceLayer, "CHIP Char C1 TX Found [%s]", StringOrNullMarker(uuid.get())); conn->gattCharC1Handle = charHandle; } - else if (strcasecmp(uuid.get(), chip_ble_char_c2_rx_uuid) == 0) + else if (strcasecmp(uuid.get(), Ble::CHIP_BLE_CHAR_2_UUID_STR) == 0) { ChipLogProgress(DeviceLayer, "CHIP Char C2 RX Found [%s]", StringOrNullMarker(uuid.get())); conn->gattCharC2Handle = charHandle; @@ -806,7 +799,7 @@ static bool __GattClientForeachServiceCb(int total, int index, bt_gatt_h svcHand VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from SVC handle: %s", get_error_message(ret))); - if (strcasecmp(uuid.get(), chip_ble_service_uuid) == 0) + if (strcasecmp(uuid.get(), chip::Ble::CHIP_BLE_SERVICE_LONG_UUID_STR) == 0) { ChipLogProgress(DeviceLayer, "CHIP Service UUID Found [%s]", StringOrNullMarker(uuid.get())); @@ -1142,36 +1135,21 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv } break; case DeviceEventType::kPlatformTizenBLEWriteComplete: { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_write_uuid; - - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c1_tx_uuid, char_write_uuid); - - HandleWriteConfirmation(apEvent->Platform.BLEWriteComplete.mConnection, &service_uuid, &char_write_uuid); + HandleWriteConfirmation(apEvent->Platform.BLEWriteComplete.mConnection, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_1_UUID); break; } case DeviceEventType::kPlatformTizenBLESubscribeOpComplete: { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_notif_uuid; - - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notif_uuid); - if (apEvent->Platform.BLESubscribeOpComplete.mIsSubscribed) - HandleSubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &service_uuid, &char_notif_uuid); + HandleSubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &Ble::CHIP_BLE_SVC_ID, + &chip::Ble::CHIP_BLE_CHAR_2_UUID); else - HandleUnsubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &service_uuid, &char_notif_uuid); + HandleUnsubscribeComplete(apEvent->Platform.BLESubscribeOpComplete.mConnection, &Ble::CHIP_BLE_SVC_ID, + &chip::Ble::CHIP_BLE_CHAR_2_UUID); break; } case DeviceEventType::kPlatformTizenBLEIndicationReceived: { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_notif_uuid; - - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notif_uuid); - - HandleIndicationReceived(apEvent->Platform.BLEIndicationReceived.mConnection, &service_uuid, &char_notif_uuid, + HandleIndicationReceived(apEvent->Platform.BLEIndicationReceived.mConnection, &Ble::CHIP_BLE_SVC_ID, + &chip::Ble::CHIP_BLE_CHAR_2_UUID, System::PacketBufferHandle::Adopt(apEvent->Platform.BLEIndicationReceived.mData)); break; } @@ -1182,43 +1160,29 @@ void BLEManagerImpl::HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * apEv void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_notification_uuid; - Ble::ChipBleUUID char_write_uuid; - switch (event->Type) { case DeviceEventType::kCHIPoBLESubscribe: ChipLogProgress(DeviceLayer, "CHIPoBLESubscribe"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notification_uuid); - - HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &service_uuid, &char_notification_uuid); + HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); NotifyBLEConnectionEstablished(event->CHIPoBLESubscribe.ConId, CHIP_NO_ERROR); break; case DeviceEventType::kCHIPoBLEUnsubscribe: ChipLogProgress(DeviceLayer, "CHIPoBLEUnsubscribe"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notification_uuid); - - HandleUnsubscribeReceived(event->CHIPoBLESubscribe.ConId, &service_uuid, &char_notification_uuid); + HandleUnsubscribeReceived(event->CHIPoBLESubscribe.ConId, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); break; case DeviceEventType::kCHIPoBLEWriteReceived: ChipLogProgress(DeviceLayer, "CHIPoBLEWriteReceived"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c1_tx_uuid, char_write_uuid); - HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &service_uuid, &char_write_uuid, + HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_1_UUID, System::PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); break; case DeviceEventType::kCHIPoBLEIndicateConfirm: ChipLogProgress(DeviceLayer, "CHIPoBLEIndicateConfirm"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notification_uuid); - HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &service_uuid, &char_notification_uuid); + HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &Ble::CHIP_BLE_SVC_ID, &Ble::CHIP_BLE_CHAR_2_UUID); break; case DeviceEventType::kCHIPoBLEConnectionError: ChipLogProgress(DeviceLayer, "CHIPoBLEConnectionError"); @@ -1241,19 +1205,14 @@ uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId) { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_notif_uuid; int ret; ChipLogProgress(DeviceLayer, "SubscribeCharacteristic"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notif_uuid); - VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Invalid Connection")); - VerifyOrExit(Ble::UUIDsMatch(svcId, &service_uuid), + VerifyOrExit(Ble::UUIDsMatch(svcId, &Ble::CHIP_BLE_SVC_ID), ChipLogError(DeviceLayer, "SubscribeCharacteristic() called with invalid service ID")); - VerifyOrExit(Ble::UUIDsMatch(charId, &char_notif_uuid), + VerifyOrExit(Ble::UUIDsMatch(charId, &Ble::CHIP_BLE_CHAR_2_UUID), ChipLogError(DeviceLayer, "SubscribeCharacteristic() called with invalid characteristic ID")); VerifyOrExit(conId->gattCharC2Handle != nullptr, ChipLogError(DeviceLayer, "Char C2 is null")); @@ -1274,19 +1233,14 @@ bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId) { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_notif_uuid; int ret; ChipLogProgress(DeviceLayer, "UnSubscribeCharacteristic"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c2_rx_uuid, char_notif_uuid); - VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Invalid Connection")); - VerifyOrExit(Ble::UUIDsMatch(svcId, &service_uuid), + VerifyOrExit(Ble::UUIDsMatch(svcId, &Ble::CHIP_BLE_SVC_ID), ChipLogError(DeviceLayer, "UnSubscribeCharacteristic() called with invalid service ID")); - VerifyOrExit(Ble::UUIDsMatch(charId, &char_notif_uuid), + VerifyOrExit(Ble::UUIDsMatch(charId, &Ble::CHIP_BLE_CHAR_2_UUID), ChipLogError(DeviceLayer, "UnSubscribeCharacteristic() called with invalid characteristic ID")); VerifyOrExit(conId->gattCharC2Handle != nullptr, ChipLogError(DeviceLayer, "Char C2 is null")); @@ -1360,19 +1314,14 @@ bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::Chip bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, System::PacketBufferHandle pBuf) { - Ble::ChipBleUUID service_uuid; - Ble::ChipBleUUID char_write_uuid; int ret; ChipLogProgress(DeviceLayer, "SendWriteRequest"); - StringToUUID(chip_ble_service_uuid, service_uuid); - StringToUUID(chip_ble_char_c1_tx_uuid, char_write_uuid); - VerifyOrExit(conId != nullptr, ChipLogError(DeviceLayer, "Invalid Connection")); - VerifyOrExit(Ble::UUIDsMatch(svcId, &service_uuid), + VerifyOrExit(Ble::UUIDsMatch(svcId, &Ble::CHIP_BLE_SVC_ID), ChipLogError(DeviceLayer, "SendWriteRequest() called with invalid service ID")); - VerifyOrExit(Ble::UUIDsMatch(charId, &char_write_uuid), + VerifyOrExit(Ble::UUIDsMatch(charId, &Ble::CHIP_BLE_CHAR_1_UUID), ChipLogError(DeviceLayer, "SendWriteRequest() called with invalid characteristic ID")); VerifyOrExit(conId->gattCharC1Handle != nullptr, ChipLogError(DeviceLayer, "Char C1 is null")); @@ -1455,7 +1404,7 @@ void BLEManagerImpl::InitiateScan(BleScanState scanType) } /* Send StartChipScan Request to Scanner Class */ - strcpy(data.service_uuid, chip_ble_service_uuid_short); + strcpy(data.service_uuid, Ble::CHIP_BLE_SERVICE_SHORT_UUID_STR); err = mDeviceScanner->StartChipScan(kNewConnectionScanTimeout, ScanFilterType::kServiceData, data); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "Failed to start BLE scan")); diff --git a/src/platform/Tizen/ChipDeviceScanner.cpp b/src/platform/Tizen/ChipDeviceScanner.cpp index aea5aabd7d0799..5f334535d904fc 100644 --- a/src/platform/Tizen/ChipDeviceScanner.cpp +++ b/src/platform/Tizen/ChipDeviceScanner.cpp @@ -25,11 +25,13 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -40,10 +42,6 @@ namespace chip { namespace DeviceLayer { namespace Internal { -// CHIPoBLE UUID strings -const char chip_service_uuid[] = "0000FFF6-0000-1000-8000-00805F9B34FB"; -const char chip_service_uuid_short[] = "FFF6"; - ChipDeviceScanner::ChipDeviceScanner(ChipDeviceScannerDelegate * delegate) : mDelegate(delegate) {} ChipDeviceScanner::~ChipDeviceScanner() @@ -58,31 +56,16 @@ std::unique_ptr ChipDeviceScanner::Create(ChipDeviceScannerDe return std::make_unique(delegate); } -static void __CleanupServiceData(bt_adapter_le_service_data_s * dataList, size_t count) -{ - VerifyOrReturn(dataList != nullptr); - VerifyOrReturn(count != 0); - - for (size_t i = 0; i < count; i++) - { - g_free(dataList[i].service_uuid); - g_free(dataList[i].service_data); - } - g_free(dataList); -} - -static void __PrintLEScanData(bt_adapter_le_service_data_s * dataList, size_t idx) +static void __PrintLEScanData(const bt_adapter_le_service_data_s & data) { - VerifyOrReturn(dataList != nullptr); - // Print Service UUID in the Service Data ChipLogDetail(DeviceLayer, "======Service UUID========"); - ChipLogDetail(DeviceLayer, "Service UUID::[%s]", dataList[idx].service_uuid); + ChipLogDetail(DeviceLayer, "Service UUID::[%s]", data.service_uuid); // Print Service Data ChipLogDetail(DeviceLayer, "======Service Data========"); - ChipLogDetail(DeviceLayer, "Service Data Length::[%d]", dataList[idx].service_data_len); - ChipLogByteSpan(DeviceLayer, ByteSpan(reinterpret_cast(dataList[idx].service_data), dataList[idx].service_data_len)); + ChipLogDetail(DeviceLayer, "Service Data Length::[%d]", data.service_data_len); + ChipLogByteSpan(DeviceLayer, ByteSpan(reinterpret_cast(data.service_data), data.service_data_len)); } static bool __IsChipThingDevice(bt_adapter_le_device_scan_result_info_s * info, @@ -94,25 +77,22 @@ static bool __IsChipThingDevice(bt_adapter_le_device_scan_result_info_s * info, bt_adapter_le_service_data_s * dataList = nullptr; bool isChipDevice = false; - ChipLogProgress(DeviceLayer, "Is [%s] ChipThingDevice ?: Check now", info->remote_address); - if (bt_adapter_le_get_scan_result_service_data_list(info, BT_ADAPTER_LE_PACKET_ADVERTISING, &dataList, &count) == BT_ERROR_NONE) { for (int i = 0; i < count; i++) { - if (g_strcmp0(dataList[i].service_uuid, chip_service_uuid) == 0 || - g_strcmp0(dataList[i].service_uuid, chip_service_uuid_short) == 0) + if (strcasecmp(dataList[i].service_uuid, chip::Ble::CHIP_BLE_SERVICE_LONG_UUID_STR) == 0 || + strcasecmp(dataList[i].service_uuid, chip::Ble::CHIP_BLE_SERVICE_SHORT_UUID_STR) == 0) { - ChipLogProgress(DeviceLayer, "CHIP Thing Device Found! [Service Data UUID] = %s", dataList[i].service_uuid); - // Print full Service Data - __PrintLEScanData(dataList, i); + __PrintLEScanData(dataList[i]); memcpy(&aDeviceInfo, dataList[i].service_data, dataList[i].service_data_len); isChipDevice = true; break; } } } - __CleanupServiceData(dataList, count); + + bt_adapter_le_free_service_data_list(dataList, count); return isChipDevice; } @@ -123,17 +103,12 @@ void ChipDeviceScanner::LeScanResultCb(int result, bt_adapter_le_device_scan_res auto self = reinterpret_cast(userData); chip::Ble::ChipBLEDeviceIdentificationInfo deviceInfo; - ChipLogProgress(DeviceLayer, "LE Device Reported!! remote addr [%s]", info->remote_address); + ChipLogProgress(DeviceLayer, "LE device reported: %s", info->remote_address); + VerifyOrReturn(__IsChipThingDevice(info, deviceInfo), + ChipLogDetail(Ble, "Device %s does not look like a CHIP device", info->remote_address)); - if (__IsChipThingDevice(info, deviceInfo)) - { - // Looks like a CHIP Thing Device: Service UUID matched - ChipLogProgress(DeviceLayer, "Looks Like Got a CHIP Thing Device: Process further"); - // Report probable CHIP Thing Device to BLEMgrImp class - self->mDelegate->OnChipDeviceScanned(info, deviceInfo); - } - else - ChipLogProgress(DeviceLayer, "Does not Look like a CHIP Device, Skip....."); + // Report probable CHIP device to BLEMgrImp class + self->mDelegate->OnChipDeviceScanned(info, deviceInfo); } gboolean ChipDeviceScanner::TimerExpiredCb(gpointer userData) diff --git a/src/platform/Zephyr/wifi/WiFiManager.cpp b/src/platform/Zephyr/wifi/WiFiManager.cpp index 69d2943235cdbd..11187a7cef1655 100644 --- a/src/platform/Zephyr/wifi/WiFiManager.cpp +++ b/src/platform/Zephyr/wifi/WiFiManager.cpp @@ -159,33 +159,33 @@ void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mg CHIP_ERROR WiFiManager::Init() { // TODO: consider moving these to ConnectivityManagerImpl to be prepared for handling multiple interfaces on a single device. - Inet::UDPEndPointImplSockets::SetMulticastGroupHandler( - [](Inet::InterfaceId interfaceId, const Inet::IPAddress & address, UDPEndPointImplSockets::MulticastOperation operation) { - const in6_addr addr = InetUtils::ToZephyrAddr(address); - net_if * iface = InetUtils::GetInterface(interfaceId); - VerifyOrReturnError(iface != nullptr, INET_ERROR_UNKNOWN_INTERFACE); + Inet::UDPEndPointImplSockets::SetMulticastGroupHandler([](Inet::InterfaceId interfaceId, const Inet::IPAddress & address, + Inet::UDPEndPointImplSockets::MulticastOperation operation) { + const in6_addr addr = InetUtils::ToZephyrAddr(address); + net_if * iface = InetUtils::GetInterface(interfaceId); + VerifyOrReturnError(iface != nullptr, INET_ERROR_UNKNOWN_INTERFACE); - if (operation == UDPEndPointImplSockets::MulticastOperation::kJoin) - { - net_if_mcast_addr * maddr = net_if_ipv6_maddr_add(iface, &addr); + if (operation == Inet::UDPEndPointImplSockets::MulticastOperation::kJoin) + { + net_if_mcast_addr * maddr = net_if_ipv6_maddr_add(iface, &addr); - if (maddr && !net_if_ipv6_maddr_is_joined(maddr) && !net_ipv6_is_addr_mcast_link_all_nodes(&addr)) - { - net_if_ipv6_maddr_join(iface, maddr); - } - } - else if (operation == UDPEndPointImplSockets::MulticastOperation::kLeave) - { - VerifyOrReturnError(net_ipv6_is_addr_mcast_link_all_nodes(&addr) || net_if_ipv6_maddr_rm(iface, &addr), - CHIP_ERROR_INVALID_ADDRESS); - } - else + if (maddr && !net_if_ipv6_maddr_is_joined(maddr) && !net_ipv6_is_addr_mcast_link_all_nodes(&addr)) { - return CHIP_ERROR_INCORRECT_STATE; + net_if_ipv6_maddr_join(iface, maddr); } + } + else if (operation == Inet::UDPEndPointImplSockets::MulticastOperation::kLeave) + { + VerifyOrReturnError(net_ipv6_is_addr_mcast_link_all_nodes(&addr) || net_if_ipv6_maddr_rm(iface, &addr), + CHIP_ERROR_INVALID_ADDRESS); + } + else + { + return CHIP_ERROR_INCORRECT_STATE; + } - return CHIP_NO_ERROR; - }); + return CHIP_NO_ERROR; + }); net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents); net_mgmt_add_event_callback(&mWiFiMgmtClbk); diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java b/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java index 28fc6988a9dbbd..e4ac8a673b5db2 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceBrowser.java @@ -172,7 +172,11 @@ public void onStopDiscoveryFailed(String serviceType, int errorCode) { @Override public void onDiscoveryStopped(String serviceType) { Log.w(TAG, "Successfully stopped discovery service '" + serviceType); - this.handleServiceBrowse(chipMdnsCallback); + new Handler(Looper.getMainLooper()) + .post( + () -> { + this.handleServiceBrowse(chipMdnsCallback); + }); } public void handleServiceBrowse(ChipMdnsCallback chipMdnsCallback) { diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index 1f1a9efa4307f0..11b53537bf7d71 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -39,6 +39,7 @@ public class NsdManagerServiceResolver implements ServiceResolver { private static final long RESOLVE_SERVICE_TIMEOUT = 30000; private final NsdManager nsdManager; private MulticastLock multicastLock; + private MulticastLock publishMulticastLock; private List registrationListeners = new ArrayList<>(); private final CopyOnWriteArrayList mMFServiceName = new CopyOnWriteArrayList<>(); @Nullable private final NsdManagerResolverAvailState nsdManagerResolverAvailState; @@ -60,6 +61,12 @@ public NsdManagerServiceResolver( ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)) .createMulticastLock("chipMulticastLock"); this.multicastLock.setReferenceCounted(true); + + this.publishMulticastLock = + ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)) + .createMulticastLock("chipPublishMulticastLock"); + this.publishMulticastLock.setReferenceCounted(true); + this.nsdManagerResolverAvailState = nsdManagerResolverAvailState; this.timeout = timeout; } @@ -204,7 +211,7 @@ public void onServiceUnregistered(NsdServiceInfo serviceInfo) { } }; if (registrationListeners.size() == 0) { - multicastLock.acquire(); + publishMulticastLock.acquire(); } registrationListeners.add(registrationListener); mMFServiceName.add(serviceName); @@ -216,8 +223,8 @@ public void onServiceUnregistered(NsdServiceInfo serviceInfo) { @Override public void removeServices() { Log.d(TAG, "removeServices: "); - if (registrationListeners.size() > 0) { - multicastLock.release(); + if (registrationListeners.size() > 0 && publishMulticastLock.isHeld()) { + publishMulticastLock.release(); } for (NsdManager.RegistrationListener l : registrationListeners) { Log.i(TAG, "Remove " + l); diff --git a/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java b/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java index 70ffdbc0102a62..c1a187680c5c73 100644 --- a/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java +++ b/src/platform/android/java/chip/platform/NsdServiceFinderAndResolver.java @@ -21,6 +21,8 @@ import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.net.wifi.WifiManager.MulticastLock; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import androidx.annotation.Nullable; import java.util.concurrent.Executors; @@ -118,20 +120,24 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { Log.w( TAG, "Failed to resolve service '" + serviceInfo.getServiceName() + "': " + errorCode); - chipMdnsCallback.handleServiceResolve( - serviceInfo.getServiceName(), - // Use the target service info since the resolved service info sometimes appends a - // "." at the front likely because it is trying to strip the service name out of it - // and something is missed. - // The target service info service type should be effectively the same as the - // resolved service info. - NsdServiceFinderAndResolver.this.targetServiceInfo.getServiceType(), - null, - null, - 0, - null, - callbackHandle, - contextHandle); + new Handler(Looper.getMainLooper()) + .post( + () -> { + chipMdnsCallback.handleServiceResolve( + serviceInfo.getServiceName(), + // Use the target service info since the resolved service info sometimes + // appends a "." at the front likely because it is trying to strip the + // service name out of it and something is missed. + // The target service info service type should be effectively the same as + // the resolved service info. + NsdServiceFinderAndResolver.this.targetServiceInfo.getServiceType(), + null, + null, + 0, + null, + callbackHandle, + contextHandle); + }); if (multicastLock.isHeld()) { multicastLock.release(); @@ -153,21 +159,28 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { + serviceInfo.getHost() + ", type : " + serviceInfo.getServiceType()); - // TODO: Find out if DNS-SD results for Android should contain interface ID - chipMdnsCallback.handleServiceResolve( - serviceInfo.getServiceName(), - // Use the target service info since the resolved service info sometimes appends a - // "." at the front likely because it is trying to strip the service name out of it - // and something is missed. - // The target service info service type should be effectively the same as the - // resolved service info. - NsdServiceFinderAndResolver.this.targetServiceInfo.getServiceType(), - serviceInfo.getHost().getHostName(), - serviceInfo.getHost().getHostAddress(), - serviceInfo.getPort(), - serviceInfo.getAttributes(), - callbackHandle, - contextHandle); + final String hostName = serviceInfo.getHost().getHostName(); + final String address = serviceInfo.getHost().getHostAddress(); + final int port = serviceInfo.getPort(); + new Handler(Looper.getMainLooper()) + .post( + () -> { + // TODO: Find out if DNS-SD results for Android should contain interface ID + chipMdnsCallback.handleServiceResolve( + serviceInfo.getServiceName(), + // Use the target service info since the resolved service info sometimes + // appends a "." at the front likely because it is trying to strip the + // service name out of it and something is missed. + // The target service info service type should be effectively the same as + // the resolved service info. + NsdServiceFinderAndResolver.this.targetServiceInfo.getServiceType(), + hostName, + address, + port, + serviceInfo.getAttributes(), + callbackHandle, + contextHandle); + }); if (multicastLock.isHeld()) { multicastLock.release(); diff --git a/src/platform/qpg/BLEManagerImpl.cpp b/src/platform/qpg/BLEManagerImpl.cpp index 271c9b02e10d9f..45d291e651146d 100644 --- a/src/platform/qpg/BLEManagerImpl.cpp +++ b/src/platform/qpg/BLEManagerImpl.cpp @@ -98,10 +98,10 @@ CHIP_ERROR BLEManagerImpl::_Init() err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); SuccessOrExit(err); - appCbacks.stackCback = ExternalCbHandler; - appCbacks.chrReadCback = HandleTXCharRead; - appCbacks.chrWriteCback = HandleRXCharWrite; - appCbacks.cccCback = _handleTXCharCCCDWrite; + appCbacks.stackCallback = ExternalCbHandler; + appCbacks.chrReadCallback = HandleTXCharRead; + appCbacks.chrWriteCallback = HandleRXCharWrite; + appCbacks.cccCallback = _handleTXCharCCCDWrite; #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING qvCHIP_BleSetUUIDs(chipUUID_CHIPoBLE_Service, chipUUID_CHIPoBLEChar_TX.bytes, chipUUID_CHIPoBLEChar_RX.bytes, @@ -210,7 +210,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) case DeviceEventType::kCHIPoBLESubscribe: { ChipDeviceEvent connEstEvent; - ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe"); + ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe"); HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; PlatformMgr().PostEventOrDie(&connEstEvent); @@ -220,7 +220,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) case DeviceEventType::kCHIPoBLEUnsubscribe: { ChipDeviceEvent connClosedEvent; - ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe"); + ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe"); HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); connClosedEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; PlatformMgr().PostEventOrDie(&connClosedEvent); @@ -228,14 +228,14 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) break; case DeviceEventType::kCHIPoBLEWriteReceived: { - ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived"); + ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived"); HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX, PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); } break; case DeviceEventType::kCHIPoBLEConnectionError: { - ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError"); + ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError"); HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); } break; @@ -250,7 +250,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) break; case DeviceEventType::kCHIPoBLEIndicateConfirm: { - ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm"); + ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm"); HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); } break; @@ -610,7 +610,7 @@ void BLEManagerImpl::HandleRXCharWrite(uint16_t connId, uint16_t handle, uint8_t { CHIP_ERROR err = CHIP_NO_ERROR; - ChipLogProgress(DeviceLayer, "Write request received for CHIPoBLE Client RX characteristic (con %u, len %u)", connId, len); + ChipLogDetail(DeviceLayer, "Write request received for CHIPoBLE Client RX characteristic (con %u, len %u)", connId, len); // Copy the data to a packet buffer. PacketBufferHandle buf = System::PacketBufferHandle::NewWithData(pValue, len, 0, 0); @@ -727,11 +727,6 @@ void BLEManagerImpl::HandleDmMsg(qvCHIP_Ble_DmEvt_t * pDmEvt) ChipLogError(DeviceLayer, "QVCHIP_DM_ADV_STOP_IND error: %d", (int) pDmEvt->advSetStop.status); return; } - - if (mFlags.Has(Flags::kRestartAdvertising)) - { - BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); - } break; } case QVCHIP_DM_CONN_OPEN_IND: { @@ -843,13 +838,13 @@ void BLEManagerImpl::ExternalCbHandler(qvCHIP_Ble_MsgHdr_t * pMsg) /* Process advertising/scanning and connection-related messages */ if (pMsg->event >= QVCHIP_DM_CBACK_START && pMsg->event <= QVCHIP_DM_CBACK_END) { - ChipLogProgress(DeviceLayer, "DM event %d: status %d", pMsg->event, pMsg->status); + ChipLogDetail(DeviceLayer, "DM event %d: status %d", pMsg->event, pMsg->status); sInstance.HandleDmMsg((qvCHIP_Ble_DmEvt_t *) pMsg); } /* Process attribute-related messages */ else if (pMsg->event >= QVCHIP_ATT_CBACK_START && pMsg->event <= QVCHIP_ATT_CBACK_END) { - ChipLogProgress(DeviceLayer, "ATT event %d: status %d", pMsg->event, pMsg->status); + ChipLogDetail(DeviceLayer, "ATT event %d: status %d", pMsg->event, pMsg->status); sInstance.HandleAttMsg((qvCHIP_Ble_AttEvt_t *) pMsg); } else @@ -929,6 +924,7 @@ void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisement"); sInstance.mFlags.Set(Flags::kRestartAdvertising); sInstance.StopAdvertising(); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); } } diff --git a/src/platform/qpg/ConfigurationManagerImpl.cpp b/src/platform/qpg/ConfigurationManagerImpl.cpp index a7a59bf1438483..6dc81dcf4b7678 100644 --- a/src/platform/qpg/ConfigurationManagerImpl.cpp +++ b/src/platform/qpg/ConfigurationManagerImpl.cpp @@ -71,6 +71,12 @@ CHIP_ERROR ConfigurationManagerImpl::Init() SuccessOrExit(err); } + if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_TotalOperationalHours)) + { + err = StoreTotalOperationalHours(0); + SuccessOrExit(err); + } + qvRebootReason = qvCHIP_GetResetReason(); switch (qvRebootReason) @@ -121,12 +127,6 @@ CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount) CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) { - if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_TotalOperationalHours)) - { - totalOperationalHours = 0; - return CHIP_NO_ERROR; - } - return QPGConfig::ReadConfigValue(QPGConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); } diff --git a/src/platform/qpg/args.gni b/src/platform/qpg/args.gni index 94669645f4cf2d..75e99c6d9a6863 100644 --- a/src/platform/qpg/args.gni +++ b/src/platform/qpg/args.gni @@ -42,13 +42,6 @@ lwip_debug = false chip_build_tests = false openthread_external_mbedtls = mbedtls_target -openthread_project_core_config_file = - "openthread-core-${qpg_target_ic}-config.h" -openthread_core_config_platform_check_file = - "openthread-core-${qpg_target_ic}-config-check.h" -openthread_core_config_deps = [ - "${chip_root}/third_party/openthread/platforms/qpg:libopenthread-qpg-config", -] openthread_external_platform = "${chip_root}/third_party/openthread/platforms/qpg:libopenthread-qpg" diff --git a/src/platform/stm32/BLEManagerImpl.cpp b/src/platform/stm32/BLEManagerImpl.cpp index fc24ebc64ac006..7a040a5fb93ba3 100644 --- a/src/platform/stm32/BLEManagerImpl.cpp +++ b/src/platform/stm32/BLEManagerImpl.cpp @@ -24,7 +24,8 @@ /* this file behaves like a config.h, comes first */ #include -#include +#include +#include #include #include @@ -445,7 +446,15 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) mFlags.Clear(Flags::kRestartAdvertising); - APP_BLE_Adv_Request(APP_BLE_FAST_ADV); + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + APP_BLE_Adv_Request(APP_BLE_FAST_ADV); + } + else + { + APP_BLE_Adv_Request(APP_BLE_LP_ADV); + } + // Flag updated asynchronously by BLE host callback mFlags.Set(Flags::kAdvertising); @@ -700,16 +709,8 @@ void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) { if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) { - /* Stop advertising and defer restart for when stop confirmation is received from the stack */ - ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertisement"); - sInstance.StopAdvertising(); - sInstance.mFlags.Set(Flags::kRestartAdvertising); - } - else if (BLEMgrImpl().mFlags.Has(Flags::kAdvertising)) - { - // Advertisement time expired. Stop advertising - ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertisement"); - BLEMgr().SetAdvertisingEnabled(false); + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisement"); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); } } diff --git a/src/platform/stm32/BUILD.gn b/src/platform/stm32/BUILD.gn index 43f656d0eca988..9b2ed9008c858a 100644 --- a/src/platform/stm32/BUILD.gn +++ b/src/platform/stm32/BUILD.gn @@ -10,7 +10,7 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. +# limitations under the License. import("//build_overrides/chip.gni") import("//build_overrides/pigweed.gni") @@ -32,6 +32,7 @@ if (chip_enable_openthread) { } static_library("stm32") { + friend = [ ":lighting_app" ] deps = [ "${chip_root}/src/setup_payload" ] if (stm32_board == "STM32WB5MM-DK") { @@ -48,6 +49,8 @@ static_library("stm32") { "CHIPPlatformConfig.h", "ConfigurationManagerImpl.cpp", "ConfigurationManagerImpl.h", + "DeviceInfoProviderImpl.cpp", + "DeviceInfoProviderImpl.h", "DiagnosticDataProviderImpl.cpp", "DiagnosticDataProviderImpl.h", "FactoryDataProvider.cpp", @@ -55,6 +58,8 @@ static_library("stm32") { "InetPlatformConfig.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", + "OTAImageProcessorImpl.cpp", + "OTAImageProcessorImpl.h", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", "STM32Config.cpp", @@ -67,7 +72,10 @@ static_library("stm32") { deps += [ "${chip_root}/src/platform/logging:headers" ] } - public = [ "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h" ] + public = [ + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", + "${chip_root}/src/credentials/examples/ExampleDACs.h", + ] public_deps = [ "${chip_root}/src/crypto", "${chip_root}/src/platform:platform_base", diff --git a/src/platform/stm32/CHIPDevicePlatformConfig.h b/src/platform/stm32/CHIPDevicePlatformConfig.h index aee9ec36a2b73a..6fe4c14eb26a3c 100644 --- a/src/platform/stm32/CHIPDevicePlatformConfig.h +++ b/src/platform/stm32/CHIPDevicePlatformConfig.h @@ -36,7 +36,6 @@ #define CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE uint16_t #define CHIP_CONFIG_PERSISTED_STORAGE_ENC_MSG_CNTR_ID 1 #define CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH 2 - #define CHIP_CONFIG_LIFETIIME_PERSISTED_COUNTER_KEY 0x01 #if CHIP_ENABLE_OPENTHREAD @@ -56,7 +55,10 @@ // ========== Platform-specific Configuration Overrides ========= -#define CHIP_DEVICE_CONFIG_CHIP_TASK_NAME "STM32WB TASK" +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "STMicroelectronics" +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "STM32WB Demo App" + +#define CHIP_DEVICE_CONFIG_CHIP_TASK_NAME "STM32 TASK" #define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (8 * 1024) /** diff --git a/src/platform/stm32/CHIPMem-Platform.cpp b/src/platform/stm32/CHIPMem-Platform.cpp index 2e37bafe7cf1b8..b9bf90f429f444 100644 --- a/src/platform/stm32/CHIPMem-Platform.cpp +++ b/src/platform/stm32/CHIPMem-Platform.cpp @@ -162,6 +162,20 @@ static void VerifyInitialized(const char * func) } } +static size_t MemoryBlockSize(void * ptr) +{ + + uint8_t * p = static_cast(ptr); + // Subtract the size of the header from the pointer + p -= sizeof(size_t); + // Read the size of the memory block from the header + size_t size = *reinterpret_cast(p); + // Add the size of the header to the size of the memory block + size += sizeof(size_t); + + return size; +} + CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) { if (memoryInitialized++ > 0) @@ -211,10 +225,31 @@ void * MemoryCalloc(size_t num, size_t size) void * MemoryRealloc(void * p, size_t size) { - VERIFY_INITIALIZED(); + void * new_ptr; + if (size == 0) + { + MemoryFree(p); + return NULL; + } - p = realloc(p, size); - return p; + new_ptr = MemoryAlloc(size); + if (new_ptr == NULL) + { + return NULL; + } + + if (p != NULL) + { + size_t copy_size = MemoryBlockSize(p); + if (copy_size > size) + { + copy_size = size; + } + memcpy(new_ptr, p, copy_size); + MemoryFree(p); + } + + return new_ptr; } void MemoryFree(void * p) diff --git a/src/platform/stm32/ConfigurationManagerImpl.cpp b/src/platform/stm32/ConfigurationManagerImpl.cpp index da8638460a78f3..cbfa37cf3c3272 100644 --- a/src/platform/stm32/ConfigurationManagerImpl.cpp +++ b/src/platform/stm32/ConfigurationManagerImpl.cpp @@ -164,5 +164,10 @@ ConfigurationManager & ConfigurationMgrImpl() return ConfigurationManagerImpl::GetDefaultInstance(); } +CHIP_ERROR ConfigurationManagerImpl::GetCountryCode(char * buf, size_t bufSize, size_t & codeLen) +{ + return STM32Config::ReadConfigValueStr(STM32Config::kConfigKey_CountryCode, buf, bufSize, codeLen); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/stm32/ConfigurationManagerImpl.h b/src/platform/stm32/ConfigurationManagerImpl.h index 78b885581ce151..46b5b6a1247de2 100644 --- a/src/platform/stm32/ConfigurationManagerImpl.h +++ b/src/platform/stm32/ConfigurationManagerImpl.h @@ -34,7 +34,7 @@ namespace DeviceLayer { */ // class ConfigurationManagerImpl final : public Internal::GenericConfigurationManagerImpl, -// public Internal::STM32Config +// public Internal::STM32Config class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl { public: @@ -66,6 +66,7 @@ class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImp CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen) override; CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) override; void RunConfigUnitTest(void) override; + CHIP_ERROR GetCountryCode(char * buf, size_t bufSize, size_t & codeLen) override; // ===== Private members reserved for use by this class only. diff --git a/src/platform/stm32/DeviceInfoProviderImpl.cpp b/src/platform/stm32/DeviceInfoProviderImpl.cpp new file mode 100644 index 00000000000000..5524b770c0585a --- /dev/null +++ b/src/platform/stm32/DeviceInfoProviderImpl.cpp @@ -0,0 +1,374 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { + +namespace { +constexpr TLV::Tag kLabelNameTag = TLV::ContextTag(0); +constexpr TLV::Tag kLabelValueTag = TLV::ContextTag(1); +} // anonymous namespace + +DeviceInfoProviderImpl & DeviceInfoProviderImpl::GetDefaultInstance() +{ + static DeviceInfoProviderImpl sInstance; + return sInstance; +} + +DeviceInfoProvider::FixedLabelIterator * DeviceInfoProviderImpl::IterateFixedLabel(EndpointId endpoint) +{ + return chip::Platform::New(endpoint); +} + +DeviceInfoProviderImpl::FixedLabelIteratorImpl::FixedLabelIteratorImpl(EndpointId endpoint) : mEndpoint(endpoint) +{ + mIndex = 0; +} + +size_t DeviceInfoProviderImpl::FixedLabelIteratorImpl::Count() +{ + // A hardcoded labelList on all endpoints. + return 4; +} + +bool DeviceInfoProviderImpl::FixedLabelIteratorImpl::Next(FixedLabelType & output) +{ + bool retval = true; + + // A hardcoded list for testing only + CHIP_ERROR err = CHIP_NO_ERROR; + + const char * labelPtr = nullptr; + const char * valuePtr = nullptr; + + VerifyOrReturnError(mIndex < 4, false); + + ChipLogProgress(DeviceLayer, "Get the fixed label with index:%u at endpoint:%d", static_cast(mIndex), mEndpoint); + + switch (mIndex) + { + case 0: + labelPtr = "room"; + valuePtr = "bedroom 2"; + break; + case 1: + labelPtr = "orientation"; + valuePtr = "North"; + break; + case 2: + labelPtr = "floor"; + valuePtr = "2"; + break; + case 3: + labelPtr = "direction"; + valuePtr = "up"; + break; + default: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + } + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(std::strlen(labelPtr) <= kMaxLabelNameLength, false); + VerifyOrReturnError(std::strlen(valuePtr) <= kMaxLabelValueLength, false); + + Platform::CopyString(mFixedLabelNameBuf, kMaxLabelNameLength + 1, labelPtr); + Platform::CopyString(mFixedLabelValueBuf, kMaxLabelValueLength + 1, valuePtr); + + output.label = CharSpan::fromCharString(mFixedLabelNameBuf); + output.value = CharSpan::fromCharString(mFixedLabelValueBuf); + + mIndex++; + + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelLength(EndpointId endpoint, size_t val) +{ + return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val, + static_cast(sizeof(val))); +} + +CHIP_ERROR DeviceInfoProviderImpl::GetUserLabelLength(EndpointId endpoint, size_t & val) +{ + uint16_t len = static_cast(sizeof(val)); + + return mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val, len); +} + +CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) +{ + VerifyOrReturnError(CanCastTo(index), CHIP_ERROR_INVALID_ARGUMENT); + + uint8_t buf[UserLabelTLVMaxSize()]; + TLV::TLVWriter writer; + writer.Init(buf); + + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType)); + ReturnErrorOnFailure(writer.PutString(kLabelNameTag, userLabel.label)); + ReturnErrorOnFailure(writer.PutString(kLabelValueTag, userLabel.value)); + ReturnErrorOnFailure(writer.EndContainer(outerType)); + + return mStorage->SyncSetKeyValue( + DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, static_cast(index)).KeyName(), buf, + static_cast(writer.GetLengthWritten())); +} + +CHIP_ERROR DeviceInfoProviderImpl::DeleteUserLabelAt(EndpointId endpoint, size_t index) +{ + return mStorage->SyncDeleteKeyValue( + DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, static_cast(index)).KeyName()); +} + +DeviceInfoProvider::UserLabelIterator * DeviceInfoProviderImpl::IterateUserLabel(EndpointId endpoint) +{ + return chip::Platform::New(*this, endpoint); +} + +DeviceInfoProviderImpl::UserLabelIteratorImpl::UserLabelIteratorImpl(DeviceInfoProviderImpl & provider, EndpointId endpoint) : + mProvider(provider), mEndpoint(endpoint) +{ + size_t total = 0; + + ReturnOnFailure(mProvider.GetUserLabelLength(mEndpoint, total)); + mTotal = total; + mIndex = 0; +} + +bool DeviceInfoProviderImpl::UserLabelIteratorImpl::Next(UserLabelType & output) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(mIndex < mTotal, false); + VerifyOrReturnError(CanCastTo(mIndex), false); + + uint8_t buf[UserLabelTLVMaxSize()]; + uint16_t len = static_cast(sizeof(buf)); + + err = mProvider.mStorage->SyncGetKeyValue( + DefaultStorageKeyAllocator::UserLabelIndexKey(mEndpoint, static_cast(mIndex)).KeyName(), buf, len); + VerifyOrReturnError(err == CHIP_NO_ERROR, false); + + TLV::ContiguousBufferTLVReader reader; + reader.Init(buf); + err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()); + VerifyOrReturnError(err == CHIP_NO_ERROR, false); + + TLV::TLVType containerType; + VerifyOrReturnError(reader.EnterContainer(containerType) == CHIP_NO_ERROR, false); + + chip::CharSpan label; + chip::CharSpan value; + + VerifyOrReturnError(reader.Next(kLabelNameTag) == CHIP_NO_ERROR, false); + VerifyOrReturnError(reader.Get(label) == CHIP_NO_ERROR, false); + + VerifyOrReturnError(reader.Next(kLabelValueTag) == CHIP_NO_ERROR, false); + VerifyOrReturnError(reader.Get(value) == CHIP_NO_ERROR, false); + + VerifyOrReturnError(reader.VerifyEndOfContainer() == CHIP_NO_ERROR, false); + VerifyOrReturnError(reader.ExitContainer(containerType) == CHIP_NO_ERROR, false); + + Platform::CopyString(mUserLabelNameBuf, label); + Platform::CopyString(mUserLabelValueBuf, value); + + output.label = CharSpan::fromCharString(mUserLabelNameBuf); + output.value = CharSpan::fromCharString(mUserLabelValueBuf); + + mIndex++; + + return true; +} + +DeviceInfoProvider::SupportedLocalesIterator * DeviceInfoProviderImpl::IterateSupportedLocales() +{ + return chip::Platform::New(); +} + +size_t DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Count() +{ + // Hardcoded list of locales + // {("en-US"), ("de-DE"), ("fr-FR"), ("en-GB"), ("es-ES"), ("zh-CN"), ("it-IT"), ("ja-JP")} + + return 8; +} + +bool DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Next(CharSpan & output) +{ + bool retval = true; + + // Hardcoded list of locales + CHIP_ERROR err = CHIP_NO_ERROR; + + const char * activeLocalePtr = nullptr; + + VerifyOrReturnError(mIndex < 8, false); + + switch (mIndex) + { + case 0: + activeLocalePtr = "en-US"; + break; + case 1: + activeLocalePtr = "de-DE"; + break; + case 2: + activeLocalePtr = "fr-FR"; + break; + case 3: + activeLocalePtr = "en-GB"; + break; + case 4: + activeLocalePtr = "es-ES"; + break; + case 5: + activeLocalePtr = "zh-CN"; + break; + case 6: + activeLocalePtr = "it-IT"; + break; + case 7: + activeLocalePtr = "ja-JP"; + break; + default: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + } + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(std::strlen(activeLocalePtr) <= kMaxActiveLocaleLength, false); + + Platform::CopyString(mActiveLocaleBuf, kMaxActiveLocaleLength + 1, activeLocalePtr); + + output = CharSpan::fromCharString(mActiveLocaleBuf); + + mIndex++; + + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +DeviceInfoProvider::SupportedCalendarTypesIterator * DeviceInfoProviderImpl::IterateSupportedCalendarTypes() +{ + return chip::Platform::New(); +} + +size_t DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Count() +{ + // Hardcoded list of strings + // {("kBuddhist"), ("kChinese"), ("kCoptic"), ("kEthiopian"), ("kGregorian"), ("kHebrew"), ("kIndian"), ("kJapanese"), + // ("kKorean"), ("kPersian"), ("kTaiwanese"), ("kIslamic")} + + return 12; +} + +bool DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Next(CalendarType & output) +{ + bool retval = true; + + // Hardcoded list of Strings that are valid values for the Calendar Types. + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(mIndex < 12, false); + + switch (mIndex) + { + case 0: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kBuddhist; + break; + case 1: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kChinese; + break; + case 2: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kCoptic; + break; + case 3: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kEthiopian; + break; + case 4: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kGregorian; + break; + case 5: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kHebrew; + break; + case 6: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kIndian; + break; + case 7: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kJapanese; + break; + case 8: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kKorean; + break; + case 9: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kPersian; + break; + case 10: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kTaiwanese; + break; + case 11: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kIslamic; + break; + default: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + } + + if (err == CHIP_NO_ERROR) + { + mIndex++; + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/DeviceInfoProviderImpl.h b/src/platform/stm32/DeviceInfoProviderImpl.h new file mode 100644 index 00000000000000..30e153e2815537 --- /dev/null +++ b/src/platform/stm32/DeviceInfoProviderImpl.h @@ -0,0 +1,107 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include + +namespace chip { +namespace DeviceLayer { + +class DeviceInfoProviderImpl : public DeviceInfoProvider +{ +public: + DeviceInfoProviderImpl() = default; + ~DeviceInfoProviderImpl() override {} + + // Iterators + FixedLabelIterator * IterateFixedLabel(EndpointId endpoint) override; + UserLabelIterator * IterateUserLabel(EndpointId endpoint) override; + SupportedLocalesIterator * IterateSupportedLocales() override; + SupportedCalendarTypesIterator * IterateSupportedCalendarTypes() override; + + static DeviceInfoProviderImpl & GetDefaultInstance(); + +protected: + class FixedLabelIteratorImpl : public FixedLabelIterator + { + public: + FixedLabelIteratorImpl(EndpointId endpoint); + size_t Count() override; + bool Next(FixedLabelType & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + EndpointId mEndpoint = 0; + size_t mIndex = 0; + char mFixedLabelNameBuf[kMaxLabelNameLength + 1]; + char mFixedLabelValueBuf[kMaxLabelValueLength + 1]; + }; + + class UserLabelIteratorImpl : public UserLabelIterator + { + public: + UserLabelIteratorImpl(DeviceInfoProviderImpl & provider, EndpointId endpoint); + size_t Count() override { return mTotal; } + bool Next(UserLabelType & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + DeviceInfoProviderImpl & mProvider; + EndpointId mEndpoint = 0; + size_t mIndex = 0; + size_t mTotal = 0; + char mUserLabelNameBuf[kMaxLabelNameLength + 1]; + char mUserLabelValueBuf[kMaxLabelValueLength + 1]; + }; + + class SupportedLocalesIteratorImpl : public SupportedLocalesIterator + { + public: + SupportedLocalesIteratorImpl() = default; + size_t Count() override; + bool Next(CharSpan & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + size_t mIndex = 0; + char mActiveLocaleBuf[kMaxActiveLocaleLength + 1]; + }; + + class SupportedCalendarTypesIteratorImpl : public SupportedCalendarTypesIterator + { + public: + SupportedCalendarTypesIteratorImpl() = default; + size_t Count() override; + bool Next(CalendarType & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + size_t mIndex = 0; + }; + + CHIP_ERROR SetUserLabelLength(EndpointId endpoint, size_t val) override; + CHIP_ERROR GetUserLabelLength(EndpointId endpoint, size_t & val) override; + CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) override; + CHIP_ERROR DeleteUserLabelAt(EndpointId endpoint, size_t index) override; + +private: + static constexpr size_t UserLabelTLVMaxSize() { return TLV::EstimateStructOverhead(kMaxLabelNameLength, kMaxLabelValueLength); } +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/DiagnosticDataProviderImpl.h b/src/platform/stm32/DiagnosticDataProviderImpl.h index 85ac3fc206f8ae..eb843ea9a3d140 100644 --- a/src/platform/stm32/DiagnosticDataProviderImpl.h +++ b/src/platform/stm32/DiagnosticDataProviderImpl.h @@ -30,7 +30,7 @@ namespace chip { namespace DeviceLayer { /** - * Concrete implementation of the PlatformManager singleton object for stm32 platforms. + * Concrete implementation of the PlatformManager singleton object for STM32 platforms. */ class DiagnosticDataProviderImpl : public DiagnosticDataProvider diff --git a/src/platform/stm32/FactoryDataProvider.cpp b/src/platform/stm32/FactoryDataProvider.cpp index fc8e072836fd41..8b3d0af05a6ec7 100644 --- a/src/platform/stm32/FactoryDataProvider.cpp +++ b/src/platform/stm32/FactoryDataProvider.cpp @@ -17,12 +17,21 @@ #include "FactoryDataProvider.h" +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) +#include +#endif + #include #include #include #include #include +#ifdef USE_STM32WBXX_DAC_CRYPTO +#include +#include +#endif + namespace chip { namespace {} // namespace @@ -33,6 +42,24 @@ CHIP_ERROR FactoryDataProvider::Init() return CHIP_NO_ERROR; } +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 1) +CHIP_ERROR FactoryDataProvider::MapSTM32WBError(FACTORYDATA_StatusTypeDef err) +{ + switch (err) + { + case DATAFACTORY_OK: + return CHIP_NO_ERROR; + case DATAFACTORY_BUFFER_TOO_SMALL: + return CHIP_ERROR_BUFFER_TOO_SMALL; + case DATAFACTORY_PARAM_ERROR: + return CHIP_ERROR_INVALID_ARGUMENT; + default: + break; + } + return CHIP_ERROR_INTERNAL; +} +#endif + FactoryDataProvider & FactoryDataProvider::GetDefaultInstance() { static FactoryDataProvider sInstance; @@ -61,96 +88,159 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto: CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; - const uint8_t kDevelopmentDAC_PublicKey_FFF1_8004[65] = { - 0x04, 0x50, 0x41, 0x38, 0xef, 0x31, 0xc9, 0xdd, 0x16, 0x0e, 0xb4, 0x6c, 0x6c, 0x17, 0x11, 0x4f, 0x9d, - 0x72, 0x88, 0x40, 0x80, 0x1f, 0x73, 0xbb, 0x9b, 0x5a, 0x2c, 0x51, 0x91, 0xc9, 0xb2, 0x06, 0x63, 0x01, - 0x9d, 0x94, 0x76, 0xd1, 0x93, 0x1b, 0x93, 0xff, 0x47, 0xf4, 0x32, 0x56, 0x37, 0x90, 0x35, 0xd2, 0x29, - 0x62, 0x0b, 0x7e, 0x21, 0x0e, 0x59, 0x2f, 0x26, 0x43, 0x7d, 0x2d, 0x57, 0x62, 0x05, - }; - const uint8_t kDevelopmentDAC_PrivateKey_FFF1_8004[32] = { - 0x82, 0x0a, 0x24, 0x2a, 0x03, 0x0e, 0xbc, 0xe1, 0x1f, 0x38, 0x73, 0x5a, 0xcf, 0x1a, 0x6f, 0x37, - 0xc3, 0xad, 0xa6, 0xe4, 0x32, 0xd2, 0x47, 0x0a, 0x8a, 0x41, 0x37, 0x43, 0xf8, 0x95, 0x63, 0xf3, - }; - ByteSpan kDacPrivateKey = ByteSpan(kDevelopmentDAC_PrivateKey_FFF1_8004); - ByteSpan kDacPublicKey = ByteSpan(kDevelopmentDAC_PublicKey_FFF1_8004); +#ifdef USE_STM32WBXX_DAC_CRYPTO + otError otCksDAC_error; + uint8_t signature_bytes[Crypto::kP256_ECDSA_Signature_Length_Raw]; +#endif VerifyOrReturnError(!outSignBuffer.empty(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(!messageToSign.empty(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); +#ifdef USE_STM32WBXX_DAC_CRYPTO + + otCksDAC_error = + otCksDacSignature(messageToSign.data(), messageToSign.size(), DevelopmentCerts::kDacPublicKey.data(), &signature_bytes[0]); + memcpy(signature.Bytes(), &signature_bytes[0], Crypto::kP256_ECDSA_Signature_Length_Raw); + signature.SetLength(Crypto::kP256_ECDSA_Signature_Length_Raw); + + if (otCksDAC_error != OT_ERROR_NONE) + { + ChipLogProgress(Crypto, "DAC signature unexpected failure"); + return CHIP_ERROR_INTERNAL; + } + +#else // In a non-exemplary implementation, the public key is not needed here. It is used here merely because // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. - ReturnErrorOnFailure(LoadKeypairFromRaw(kDacPrivateKey, kDacPublicKey, keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) + ReturnErrorOnFailure(LoadKeypairFromRaw(DevelopmentCerts::kDacPrivateKey, DevelopmentCerts::kDacPublicKey, keypair)); - return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + uint8_t Privatekeybuffer[PRIVATE_KEY_LEN]; + uint8_t Publickeybuffer[PUBLIC_KEY_LEN]; + uint32_t tlvDataLength; // Dummy value keys values are fix + FACTORYDATA_StatusTypeDef err; + + err = FACTORYDATA_GetValue(TAG_ID_DEVICE_ATTESTATION_PRIVATE_KEY, Privatekeybuffer, PRIVATE_KEY_LEN, &tlvDataLength); + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + err = FACTORYDATA_GetValue(TAG_ID_DEVICE_ATTESTATION_PUBLIC_KEY, Publickeybuffer, PUBLIC_KEY_LEN, &tlvDataLength); + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + ReturnErrorOnFailure(LoadKeypairFromRaw(ByteSpan(Privatekeybuffer), ByteSpan(Publickeybuffer), keypair)); +#endif + + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); #endif + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); } CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) setupDiscriminator = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SETUP_DISCRIMINATOR, (uint8_t *) &setupDiscriminator, sizeof(setupDiscriminator), + &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) constexpr uint32_t kDefaultTestVerifierIterationCount = 1000; iterationCount = kDefaultTestVerifierIterationCount; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_ITERATION_COUNT, (uint8_t *) &iterationCount, sizeof(iterationCount), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) setupPasscode = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_SETUP_PASSCODE, (uint8_t *) &setupPasscode, sizeof(setupPasscode), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) vendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_VENDOR_ID, (uint8_t *) &vendorId, sizeof(vendorId), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) productId = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_PRODUCT_ID, (uint8_t *) &productId, sizeof(productId), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) hardwareVersion = CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_HARDWARE_VERSION, (uint8_t *) &hardwareVersion, sizeof(hardwareVersion), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } @@ -176,32 +266,68 @@ CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) + ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + + memcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME, sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME)); +#else + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_VENDOR_NAME, (uint8_t *) buf, bufSize, &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + +#endif + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) + ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME, sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME)); +#else + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_PRODUCT_NAME, (uint8_t *) buf, bufSize, &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); +#endif + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) memcpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER, bufSize); return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SERIAL_NUMBER, (uint8_t *) buf, bufSize, &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING, + sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING)); + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierSpan, size_t & verifierLen) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) static const uint8_t kDefaultTestVerifier[97] = { 0xb9, 0x61, 0x70, 0xaa, 0xe8, 0x03, 0x34, 0x68, 0x84, 0x72, 0x4f, 0xe9, 0xa3, 0xb2, 0x87, 0xc3, 0x03, 0x30, 0xc2, 0xa6, 0x60, 0x37, 0x5d, 0x17, 0xbb, 0x20, 0x5a, 0x8c, 0xf1, 0xae, 0xcb, 0x35, 0x04, 0x57, 0xf8, 0xab, 0x79, 0xee, 0x25, 0x3a, @@ -217,16 +343,24 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierSpa } memcpy(verifierSpan.data(), &kDefaultTestVerifier[0], verifierLen); verifierSpan.reduce_size(verifierLen); - return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_VERIFIER, verifierSpan.data(), verifierSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + verifierSpan.reduce_size(tlvDataLength); + verifierLen = tlvDataLength; #endif + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBufferSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) //-> format_version = 1 //-> vendor_id = 0xFFF1 //-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, @@ -276,7 +410,15 @@ CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & ou return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBufferSpan); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_CERTIFICATION_DECLARATION, outBufferSpan.data(), outBufferSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + outBufferSpan.reduce_size(tlvDataLength); + return CHIP_NO_ERROR; #endif } @@ -287,7 +429,7 @@ CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & firmwar CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & attestationCertSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) static const uint8_t kDevelopmentDAC_Cert_FFF1_8004[493] = { 0x30, 0x82, 0x01, 0xe9, 0x30, 0x82, 0x01, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x1e, 0x06, 0x7f, 0x3b, 0xfe, 0xcd, 0xd8, 0x13, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3d, 0x31, 0x25, 0x30, @@ -318,13 +460,23 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & attes return CopySpanToMutableSpan(ByteSpan(kDevelopmentDAC_Cert_FFF1_8004), attestationCertSpan); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_DEVICE_ATTESTATION_CERTIFICATE, attestationCertSpan.data(), attestationCertSpan.size(), + &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + attestationCertSpan.reduce_size(tlvDataLength); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & intermediateCertSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) static const uint8_t kDevelopmentPAI_Cert_FFF1[463] = { 0x30, 0x82, 0x01, 0xcb, 0x30, 0x82, 0x01, 0x71, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x56, 0xad, 0x82, 0x22, 0xad, 0x94, 0x5b, 0x64, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x18, 0x30, @@ -354,13 +506,23 @@ CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByt return CopySpanToMutableSpan(ByteSpan(kDevelopmentPAI_Cert_FFF1), intermediateCertSpan); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_PRODUCT_ATTESTATION_INTERMEDIATE_CERTIFICATE, intermediateCertSpan.data(), + intermediateCertSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + intermediateCertSpan.reduce_size(tlvDataLength); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) static const uint8_t kDefaultTestVerifierSalt[16] = { 0x53, 0x50, 0x41, 0x4b, 0x45, 0x32, 0x50, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x53, 0x61, 0x6c, 0x74, }; @@ -374,7 +536,16 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltSpan) saltSpan.reduce_size(saltLen); return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_SALT, saltSpan.data(), saltSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + saltSpan.reduce_size(tlvDataLength); + + return CHIP_NO_ERROR; #endif } diff --git a/src/platform/stm32/FactoryDataProvider.h b/src/platform/stm32/FactoryDataProvider.h index 2882b989e8902d..e9522734dca9d2 100644 --- a/src/platform/stm32/FactoryDataProvider.h +++ b/src/platform/stm32/FactoryDataProvider.h @@ -17,6 +17,10 @@ #pragma once +#include "app_conf.h" +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 1) +#include "stm32_factorydata.h" +#endif #include #include #include @@ -63,6 +67,11 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia // ===== Members functions that are platform-specific CHIP_ERROR GetEnableKey(MutableByteSpan & enableKey); + +protected: +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 1) + static CHIP_ERROR MapSTM32WBError(FACTORYDATA_StatusTypeDef err); +#endif }; } // namespace DeviceLayer diff --git a/src/platform/stm32/KeyValueStoreManagerImpl.cpp b/src/platform/stm32/KeyValueStoreManagerImpl.cpp index b68ea2c1c9adc9..723b97318eba49 100644 --- a/src/platform/stm32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/stm32/KeyValueStoreManagerImpl.cpp @@ -23,7 +23,6 @@ #include #include -#define MATTER_KEY_NAME_MAX_LENGTH (15 * 2) // ADD Max key name string size is 30 "keyType...;KeyName..." namespace chip { namespace DeviceLayer { namespace PersistedStorage { diff --git a/src/platform/stm32/KeyValueStoreManagerImpl.h b/src/platform/stm32/KeyValueStoreManagerImpl.h index 335ffb2b907df9..614bae7da594d2 100644 --- a/src/platform/stm32/KeyValueStoreManagerImpl.h +++ b/src/platform/stm32/KeyValueStoreManagerImpl.h @@ -16,8 +16,8 @@ * limitations under the License. */ -#ifndef MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ -#define MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ +#ifndef MIDDLEWARES_MATTER_PLATFORM_STM32_KEYVALUESTOREMANAGERIMPL_H_ +#define MIDDLEWARES_MATTER_PLATFORM_STM32_KEYVALUESTOREMANAGERIMPL_H_ #pragma once @@ -79,4 +79,4 @@ inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) } // namespace DeviceLayer } // namespace chip -#endif /* MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ */ +#endif /* MIDDLEWARES_MATTER_PLATFORM_STM32_KEYVALUESTOREMANAGERIMPL_H_ */ diff --git a/src/platform/stm32/OTAImageProcessorImpl.cpp b/src/platform/stm32/OTAImageProcessorImpl.cpp new file mode 100644 index 00000000000000..76363befebb005 --- /dev/null +++ b/src/platform/stm32/OTAImageProcessorImpl.cpp @@ -0,0 +1,439 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "app_common.h" +#if (OTA_SUPPORT == 1) +#include +#include + +#include "OTAImageProcessorImpl.h" +#include "ota.h" +#include "sfu_fwimg_regions.h" +#include "stm_ext_flash.h" +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +#include "mapping_fwimg.h" +#include "mapping_sbsfu.h" +#elif defined(__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __CC_ARM || __ARMCC_VERSION */ +#include "sfu_standalone_loader.h" + +#define STM_HEADER_SIZE 8 +static uint32_t mCPU1Size; +static uint32_t mCPU2Size; +static uint32_t mDownloadedBytesCPU2; +static uint8_t mSwitchDwlSlot; + +namespace chip { + +bool OTAImageProcessorImpl::IsFirstImageRun() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return false; + } + + return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying; +} + +CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() +{ + ChipLogProgress(DeviceLayer, "OTA Confirm current image"); + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + uint32_t currentVersion; + uint32_t targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); + + if (currentVersion != targetVersion) + { + ChipLogError(SoftwareUpdate, "Current software version = %" PRIu32 ", expected software version = %" PRIu32, currentVersion, + targetVersion); + return CHIP_ERROR_INCORRECT_STATE; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() +{ + + // Get OTA status - under what circumstances does prepared break? + // what happens if a prepare is pending and another one is invoked + // Should we store the state here and wait until we receive notification + + mHeaderParser.Init(); + + DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) +{ + ChipLogProgress(DeviceLayer, "OTA Process Header"); + if (mHeaderParser.IsInitialized()) + { + OTAImageHeader header; + CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); + + // Needs more data to decode the header + ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + ReturnErrorOnFailure(error); + + mParams.totalFileBytes = header.mPayloadSize; + mHeaderParser.Clear(); + + // Load Ota_ImageHeader_t header structure and call application callback to validate image header + Ota_ImageHeader_t OtaImgHeader; + this->mSwVer = header.mSoftwareVersion; // Store software version in imageProcessor as well + OtaImgHeader.vendorId = header.mVendorId; + OtaImgHeader.productId = header.mProductId; + OtaImgHeader.softwareVersion = header.mSoftwareVersion; + OtaImgHeader.minApplicableVersion = header.mMinApplicableVersion.ValueOr(0); + OtaImgHeader.maxApplicableVersion = header.mMaxApplicableVersion.ValueOr(0); + + if (true != OtaHeaderValidation(OtaImgHeader)) + { + return CHIP_ERROR_INCORRECT_STATE; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Finalize() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Apply() +{ + ChipLogProgress(SoftwareUpdate, "Applying - resetting device"); + + if (mCPU2Size == 0) + { + STANDALONE_LOADER_STATE = STANDALONE_LOADER_INSTALL_REQ; // install only CPU1 + } + else if (mCPU1Size == 0) + { + STANDALONE_LOADER_STATE = STANDALONE_LOADER_BYPASS_REQ; // install only CPU2 + } + else + { + STANDALONE_LOADER_STATE = STANDALONE_LOADER_BYPASS_REQ_AND_INSTALL_REQ; // install CPU1 and CPU2 + } + NVIC_SystemReset(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Abort() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) +{ + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + CHIP_ERROR err = ProcessHeader(block); + ChipLogProgress(DeviceLayer, "OTA Process Block"); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Matter image header parser error %s", chip::ErrorStr(err)); + this->mDownloader->EndDownload(CHIP_ERROR_INVALID_FILE_IDENTIFIER); + return err; + } + + // Store block data for HandleProcessBlock to access + err = SetBlock(block); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + ChipLogProgress(DeviceLayer, "OTA Prepare DL"); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + // running this in a thread so won't block main event loop + ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload"); + + mSwitchDwlSlot = false; // start with dwl_slot1 for CPU1 + + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_1_START, SLOT_SIZE(SLOT_DWL_1)); + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_4_START, SLOT_SIZE(SLOT_DWL_4)); + + // Initialize tracking variables + imageProcessor->mParams.downloadedBytes = 0; + mDownloadedBytesCPU2 = 0; + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); +} + +void OTAImageProcessorImpl::HandleFinalize(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + ChipLogProgress(SoftwareUpdate, "HandleFinalize"); + + imageProcessor->ReleaseBlock(); + // Start from scratch + imageProcessor->mParams.downloadedBytes = 0; +} + +void OTAImageProcessorImpl::HandleAbort(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + ChipLogProgress(SoftwareUpdate, "HandleAbort"); + + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_1_START, SLOT_SIZE(SLOT_DWL_1)); + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_4_START, SLOT_SIZE(SLOT_DWL_4)); + imageProcessor->ReleaseBlock(); + // Start from scratch + imageProcessor->mParams.downloadedBytes = 0; + mDownloadedBytesCPU2 = 0; + mSwitchDwlSlot = false; // start with dwl_slot1 for CPU1 +} + +void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) +{ + STM_OTA_StatusTypeDef status; + auto * imageProcessor = reinterpret_cast(context); + + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + if (mSwitchDwlSlot == false) + { // CPU1 write in DWL_SLOT 1 + if (imageProcessor->mParams.downloadedBytes == 0) + { // get STM_Header + uint8_t STMHeader[STM_HEADER_SIZE]; + + memcpy(STMHeader, reinterpret_cast(imageProcessor->mBlock.data()), sizeof(STMHeader)); + + // retrieve the cpu1/2 size with STM header + mCPU1Size = STMHeader[0] + ((STMHeader[1]) << 8) + ((STMHeader[2]) << 16) + ((STMHeader[3]) << 24); + mCPU2Size = STMHeader[4] + ((STMHeader[5]) << 8) + ((STMHeader[6]) << 16) + ((STMHeader[7]) << 24); + + // check the header + if ((mCPU1Size > SLOT_SIZE(SLOT_DWL_1)) || (mCPU2Size > SLOT_SIZE(SLOT_DWL_4)) || (mCPU2Size + mCPU1Size == 0)) + { + ChipLogError(SoftwareUpdate, "Flash decode failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_DECODE_FAILED); + return; + } + + if (mCPU1Size == 0) + { // update only CPU2 + // write in DWL_SLOT1 data without STM header + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_4_START, + reinterpret_cast(imageProcessor->mBlock.data()) + STM_HEADER_SIZE, + static_cast(imageProcessor->mBlock.size()) - STM_HEADER_SIZE); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size() - STM_HEADER_SIZE; + mSwitchDwlSlot = true; // switch to DWL_SLOT 4 for all the next data + mDownloadedBytesCPU2 = imageProcessor->mBlock.size() - STM_HEADER_SIZE; // update the bytes write in Dwl_slot4 + } + else + { + + // write in DWL_SLOT1 data without STM header + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_1_START, + reinterpret_cast(imageProcessor->mBlock.data()) + STM_HEADER_SIZE, + static_cast(imageProcessor->mBlock.size()) - STM_HEADER_SIZE); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size() - STM_HEADER_SIZE; + } + } + else if ((imageProcessor->mParams.downloadedBytes + static_cast(imageProcessor->mBlock.size())) >= mCPU1Size) + { + + // split the block in 2 for Dwl_slot1 and Dwl_slot4 + uint32_t CPU2BlockStart = + imageProcessor->mParams.downloadedBytes + static_cast(imageProcessor->mBlock.size()) - mCPU1Size; + uint32_t CPU1BlockEnd = static_cast(imageProcessor->mBlock.size()) - CPU2BlockStart; + + if (CPU2BlockStart + CPU1BlockEnd == static_cast(imageProcessor->mBlock.size())) + { + mDownloadedBytesCPU2 = 0; + + // CPU1 write in DWL_SLOT 1 + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_1_START, + reinterpret_cast(imageProcessor->mBlock.data()), CPU1BlockEnd); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + if (mCPU2Size != 0) + { + // CPU2 write in DWL_SLOT 4 + status = STM_EXT_FLASH_WriteChunk( + mDownloadedBytesCPU2 + SLOT_DWL_4_START, + reinterpret_cast(imageProcessor->mBlock.data()) + CPU1BlockEnd, CPU2BlockStart); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + mSwitchDwlSlot = true; // switch to DWL_SLOT 4 for all the next data + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); // keep track of all bytes dwl + mDownloadedBytesCPU2 = CPU2BlockStart; // update the bytes write in Dwl_slot4 + } + } + else + { + ChipLogError(SoftwareUpdate, "Flash decode failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_DECODE_FAILED); + return; + } + } + else + { // CPU1 write in DWL_SLOT 1 + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_1_START, + reinterpret_cast(imageProcessor->mBlock.data()), + static_cast(imageProcessor->mBlock.size())); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); + } + } + else + { // CPU2 write in DWL_SLOT 4 + status = STM_EXT_FLASH_WriteChunk(mDownloadedBytesCPU2 + SLOT_DWL_4_START, + reinterpret_cast(imageProcessor->mBlock.data()), + static_cast(imageProcessor->mBlock.size())); + + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); // keep track of all bytes dwl + mDownloadedBytesCPU2 += imageProcessor->mBlock.size(); // update the bytes write in Dwl_slot4 + } + + imageProcessor->mDownloader->FetchNextData(); +} + +CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) +{ + if (!IsSpanUsable(block)) + { + ReleaseBlock(); + return CHIP_NO_ERROR; + } + if (mBlock.size() < block.size()) + { + if (!mBlock.empty()) + { + ReleaseBlock(); + } + uint8_t * mBlock_ptr = static_cast(chip::Platform::MemoryAlloc(block.size())); + if (mBlock_ptr == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + mBlock = MutableByteSpan(mBlock_ptr, block.size()); + } + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +} // namespace chip +#endif diff --git a/src/platform/stm32/OTAImageProcessorImpl.h b/src/platform/stm32/OTAImageProcessorImpl.h new file mode 100644 index 00000000000000..493aa23842e816 --- /dev/null +++ b/src/platform/stm32/OTAImageProcessorImpl.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { + +class OTAImageProcessorImpl : public OTAImageProcessorInterface +{ +public: + //////////// OTAImageProcessorInterface Implementation /////////////// + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR ProcessHeader(ByteSpan & block); + CHIP_ERROR Finalize() override; + CHIP_ERROR Apply() override; + CHIP_ERROR Abort() override; + CHIP_ERROR ProcessBlock(ByteSpan & block) override; + bool IsFirstImageRun() override; + CHIP_ERROR ConfirmCurrentImage() override; + + void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; } + +private: + //////////// Actual handlers for the OTAImageProcessorInterface /////////////// + static void HandlePrepareDownload(intptr_t context); + static void HandleFinalize(intptr_t context); + static void HandleAbort(intptr_t context); + static void HandleProcessBlock(intptr_t context); + + /** + * Called to allocate memory for mBlock if necessary and set it to block + */ + CHIP_ERROR SetBlock(ByteSpan & block); + + /** + * Called to release allocated memory for mBlock + */ + CHIP_ERROR ReleaseBlock(); + + std::uint32_t mSwVer; + std::uint32_t mHwVer; + + MutableByteSpan mBlock; + OTADownloader * mDownloader = nullptr; + OTAImageHeaderParser mHeaderParser; +}; + +} // namespace chip diff --git a/src/platform/stm32/PlatformManagerImpl.cpp b/src/platform/stm32/PlatformManagerImpl.cpp index 60148b07f6e4ca..4c8d25dcd5cb60 100644 --- a/src/platform/stm32/PlatformManagerImpl.cpp +++ b/src/platform/stm32/PlatformManagerImpl.cpp @@ -34,6 +34,7 @@ namespace chip { namespace DeviceLayer { PlatformManagerImpl PlatformManagerImpl::sInstance; + extern "C" int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen); CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) diff --git a/src/platform/stm32/PlatformManagerImpl.h b/src/platform/stm32/PlatformManagerImpl.h index 8de9bfa4a24f48..0ed24ce93f9d9e 100644 --- a/src/platform/stm32/PlatformManagerImpl.h +++ b/src/platform/stm32/PlatformManagerImpl.h @@ -31,7 +31,7 @@ namespace chip { namespace DeviceLayer { /** - * Concrete implementation of the PlatformManager singleton object for the stm32 platform. + * Concrete implementation of the PlatformManager singleton object for the STM32 platform. */ class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS { @@ -49,7 +49,6 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener // ===== Platform-specific members that may be accessed directly by the application. CHIP_ERROR InitLwIPCoreLock(void); - // static void HandleESPSystemEvent(void * arg, esp_event_base_t eventBase, int32_t eventId, void * eventData); private: // ===== Methods that implement the PlatformManager abstract interface. @@ -90,7 +89,7 @@ inline PlatformManager & PlatformMgr(void) * Returns the platform-specific implementation of the PlatformManager singleton object. * * Chip applications can use this to gain access to features of the PlatformManager - * that are specific to the stm32 platform. + * that are specific to the STM32 platform. */ inline PlatformManagerImpl & PlatformMgrImpl(void) { diff --git a/src/platform/stm32/STM32Config.cpp b/src/platform/stm32/STM32Config.cpp index cf1a6bdc652e19..6b1134dcf0fdf2 100644 --- a/src/platform/stm32/STM32Config.cpp +++ b/src/platform/stm32/STM32Config.cpp @@ -29,42 +29,61 @@ CHIP_ERROR STM32Config::Init() return CHIP_NO_ERROR; } -template -CHIP_ERROR STM32Config::ReadConfigValue(Key key, T & val) +CHIP_ERROR STM32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { - uint8_t * buffer_key[35] = { 0 }; - size_t * read_by_size = NULL; + + uint8_t buffer_key[35] = { 0 }; sprintf((char *) buffer_key, "Config%i", key); - NM_GetKeyValue((void *) &val, (char *) buffer_key, sizeof(val), read_by_size, SECTOR_NO_SECURE); + return PrintError(NM_GetKeyValue(buf, (char *) buffer_key, bufSize, &outLen, SECTOR_SECURE)); +} - return CHIP_NO_ERROR; +CHIP_ERROR STM32Config::ReadConfigValue(Key key, bool & val) +{ + uint8_t buffer_key[35] = { 0 }; + size_t Out_Length; + + sprintf((char *) buffer_key, "Config%i", key); + return PrintError( + NM_GetKeyValue(reinterpret_cast(&val), (char *) buffer_key, sizeof(bool), &Out_Length, SECTOR_SECURE)); } -CHIP_ERROR STM32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint32_t & val) { + uint8_t buffer_key[35] = { 0 }; + size_t Out_Length; - return ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); + sprintf((char *) buffer_key, "Config%i", key); + return PrintError( + NM_GetKeyValue(reinterpret_cast(&val), (char *) buffer_key, sizeof(uint32_t), &Out_Length, SECTOR_SECURE)); } -CHIP_ERROR STM32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint64_t & val) { + uint8_t buffer_key[35] = { 0 }; + size_t Out_Length; - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + sprintf((char *) buffer_key, "Config%i", key); + return PrintError( + NM_GetKeyValue(reinterpret_cast(&val), (char *) buffer_key, sizeof(uint64_t), &Out_Length, SECTOR_SECURE)); } -template CHIP_ERROR STM32Config::ReadConfigValue(Key key, bool & val); -template CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint32_t & val); -template CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint64_t & val); +CHIP_ERROR STM32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + + return ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); +} CHIP_ERROR STM32Config::WriteConfigValue(Key key, uint32_t val) { - uint8_t * buffer_key[35] = { 0 }; - size_t * read_by_size = NULL; - + uint8_t buffer_key[35] = { 0 }; + uint8_t buffer_convert[4]; + buffer_convert[0] = val; + buffer_convert[1] = val >> 8; + buffer_convert[2] = val >> 16; + buffer_convert[3] = val >> 24; sprintf((char *) buffer_key, "Config%i", key); - NM_SetKeyValue((char *) &val, (char *) buffer_key, sizeof(val), SECTOR_NO_SECURE); - return CHIP_NO_ERROR; + return PrintError(NM_SetKeyValue((char *) buffer_convert, (char *) buffer_key, sizeof(uint32_t), SECTOR_SECURE)); } CHIP_ERROR STM32Config::WriteConfigValueStr(Key key, const char * str) @@ -79,12 +98,10 @@ CHIP_ERROR STM32Config::WriteConfigValueStr(Key key, const char * str, size_t st CHIP_ERROR STM32Config::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { - uint8_t * buffer_key[35] = { 0 }; - size_t * read_by_size = NULL; + uint8_t buffer_key[35] = { 0 }; sprintf((char *) buffer_key, "Config%i", key); - NM_SetKeyValue((char *) data, (char *) buffer_key, dataLen, SECTOR_NO_SECURE); - return CHIP_NO_ERROR; + return PrintError(NM_SetKeyValue((char *) data, (char *) buffer_key, dataLen, SECTOR_SECURE)); } bool STM32Config::ConfigValueExists(Key key) @@ -100,6 +117,55 @@ CHIP_ERROR STM32Config::FactoryResetConfig(void) void STM32Config::RunConfigUnitTest(void) {} +CHIP_ERROR STM32Config::PrintError(NVM_StatusTypeDef err) +{ + switch (err) + { + case NVM_OK: + ChipLogDetail(DataManagement, "NVM_OK"); + return CHIP_NO_ERROR; + + case NVM_KEY_NOT_FOUND: + ChipLogDetail(DataManagement, "CHIP_ERROR_PERSISTED_STORAGE_NOT_FOUND"); + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + + case NVM_WRITE_FAILED: + ChipLogDetail(DataManagement, "NVM_WRITE_FAILED"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_READ_FAILED: + ChipLogDetail(DataManagement, "NVM_READ_FAILED"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_DELETE_FAILED: + ChipLogDetail(DataManagement, "NVM_DELETE_FAILED"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_SIZE_FULL: + ChipLogDetail(DataManagement, "NVM_SIZE_FULL"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_BLOCK_SIZE_OVERFLOW: + ChipLogDetail(DataManagement, "NVM_BLOCK_SIZE_OVERFLOW"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_ERROR_BLOCK_ALIGN: + ChipLogDetail(DataManagement, "NVM_ERROR_BLOCK_ALIGN"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_BUFFER_TOO_SMALL: + ChipLogDetail(DataManagement, "NVM_BUFFER_TOO_SMALL"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_PARAM_ERROR: + ChipLogDetail(DataManagement, "NVM_BUFFER_TOO_SMALL"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + default: + ChipLogDetail(DataManagement, "NVM_UNKNOWN_ERROR "); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } +} } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/stm32/STM32Config.h b/src/platform/stm32/STM32Config.h index 98ddb844616342..f1df1dc7638861 100644 --- a/src/platform/stm32/STM32Config.h +++ b/src/platform/stm32/STM32Config.h @@ -23,6 +23,7 @@ #pragma once +#include "flash_wb.h" #include namespace chip { @@ -71,11 +72,11 @@ class STM32Config static constexpr Key kConfigKey_Max = kConfigKey_UniqueId; static CHIP_ERROR Init(); + // Config value accessors. - template - // Config value accessors. - static CHIP_ERROR ReadConfigValue(Key key, T & val); - // Configuration methods used by the GenericConfigurationManagerImpl<> template. + static CHIP_ERROR ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); @@ -86,6 +87,7 @@ class STM32Config static bool ConfigValueExists(Key key); static CHIP_ERROR FactoryResetConfig(void); static void RunConfigUnitTest(void); + static CHIP_ERROR PrintError(NVM_StatusTypeDef err); }; } // namespace Internal diff --git a/src/platform/stm32/args.gni b/src/platform/stm32/args.gni index 56fd4e52bab0d6..4357e8ea8fa20f 100644 --- a/src/platform/stm32/args.gni +++ b/src/platform/stm32/args.gni @@ -10,7 +10,7 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. +# limitations under the License. import("//build_overrides/chip.gni") import("//build_overrides/stm32_sdk.gni") diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index ccc2bc2188d176..b0642a966890fd 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -2362,21 +2362,36 @@ CHIP_ERROR CASESession::OnMessageReceived(ExchangeContext * ec, const PayloadHea return err; } -System::Clock::Timeout CASESession::ComputeSigma1ResponseTimeout(const ReliableMessageProtocolConfig & remoteMrpConfig) +namespace { +System::Clock::Timeout ComputeRoundTripTimeout(ExchangeContext::Timeout serverProcessingTime, + const ReliableMessageProtocolConfig & remoteMrpConfig) { + // TODO: This is duplicating logic from Session::ComputeRoundTripTimeout. Unfortunately, it's called by + // consumers who do not have a session. + const auto & maybeLocalMRPConfig = GetLocalMRPConfig(); + const auto & defaultMRRPConfig = GetDefaultMRPConfig(); + const auto & localMRPConfig = maybeLocalMRPConfig.ValueOr(defaultMRRPConfig); return GetRetransmissionTimeout(remoteMrpConfig.mActiveRetransTimeout, remoteMrpConfig.mIdleRetransTimeout, - // Assume peer is idle, since that's what we - // will assume for our initial message. + // Assume peer is idle, as a worst-case assumption (probably true for + // Sigma1, since that will be our initial message on the session, but less + // so for Sigma2). System::Clock::kZero, remoteMrpConfig.mActiveThresholdTime) + - kExpectedSigma1ProcessingTime; + serverProcessingTime + + GetRetransmissionTimeout(localMRPConfig.mActiveRetransTimeout, localMRPConfig.mIdleRetransTimeout, + // Peer will assume we are active, since it's + // responding to our message. + System::SystemClock().GetMonotonicTimestamp(), localMRPConfig.mActiveThresholdTime); +} +} // anonymous namespace + +System::Clock::Timeout CASESession::ComputeSigma1ResponseTimeout(const ReliableMessageProtocolConfig & remoteMrpConfig) +{ + return ComputeRoundTripTimeout(kExpectedSigma1ProcessingTime, remoteMrpConfig); } System::Clock::Timeout CASESession::ComputeSigma2ResponseTimeout(const ReliableMessageProtocolConfig & remoteMrpConfig) { - return GetRetransmissionTimeout(remoteMrpConfig.mActiveRetransTimeout, remoteMrpConfig.mIdleRetransTimeout, - // Assume peer is idle, as a worst-case assumption. - System::Clock::kZero, remoteMrpConfig.mActiveThresholdTime) + - kExpectedHighProcessingTime; + return ComputeRoundTripTimeout(kExpectedHighProcessingTime, remoteMrpConfig); } bool CASESession::InvokeBackgroundWorkWatchdog() diff --git a/src/protocols/secure_channel/tests/BUILD.gn b/src/protocols/secure_channel/tests/BUILD.gn index 371937c4297b7b..0760998e818422 100644 --- a/src/protocols/secure_channel/tests/BUILD.gn +++ b/src/protocols/secure_channel/tests/BUILD.gn @@ -1,6 +1,5 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") import("${chip_root}/src/app/icd/icd.gni") @@ -8,32 +7,9 @@ chip_test_suite("tests") { output_name = "libSecureChannelTests" test_sources = [ + "TestCASESession.cpp", "TestCheckInCounter.cpp", "TestCheckinMsg.cpp", - ] - - sources = [ "CheckIn_Message_test_vectors.h" ] - - cflags = [ "-Wconversion" ] - public_deps = [ - "${chip_root}/src/app/icd/server:icd-server-config", - "${chip_root}/src/credentials/tests:cert_test_vectors", - "${chip_root}/src/lib/core", - "${chip_root}/src/lib/support", - "${chip_root}/src/lib/support:test_utils", - "${chip_root}/src/lib/support:testing", - "${chip_root}/src/protocols/secure_channel", - "${chip_root}/src/protocols/secure_channel:check-in-counter", - "${dir_pw_unit_test}", - ] -} - -chip_test_suite_using_nltest("tests_nltest") { - # Renamed ouput during the transition away from nltest - output_name = "libSecureChannelTestsNL" - - test_sources = [ - "TestCASESession.cpp", "TestDefaultSessionResumptionStorage.cpp", "TestPASESession.cpp", "TestPairingSession.cpp", @@ -44,22 +20,26 @@ chip_test_suite_using_nltest("tests_nltest") { # "TestMessageCounterManager.cpp", ] + sources = [ "CheckIn_Message_test_vectors.h" ] + + cflags = [ "-Wconversion" ] public_deps = [ + "${chip_root}/src/app/icd/server:icd-server-config", + "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/crypto/tests:tests.lib", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/lib/support:testing", - "${chip_root}/src/lib/support:testing_nlunit", + "${chip_root}/src/lib/support/tests:pw-test-macros", "${chip_root}/src/messaging/tests:helpers", "${chip_root}/src/protocols", "${chip_root}/src/protocols/secure_channel", + "${chip_root}/src/protocols/secure_channel:check-in-counter", "${chip_root}/src/transport/raw/tests:helpers", - "${nlunit_test_root}:nlunit-test", + "${dir_pw_unit_test}", ] - cflags = [ "-Wconversion" ] - if (chip_enable_icd_server) { public_deps += [ "${chip_root}/src/app/icd/server:configuration-data" ] } diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 5fc6a37f72f4ab..24aaffce0dbcb4 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,10 +35,8 @@ #include #include #include -#include -#include +#include #include -#include #include #include #include @@ -55,24 +54,38 @@ using namespace chip::Protocols; using namespace chip::Crypto; namespace chip { -namespace { +class TestCASESecurePairingDelegate; -class TestContext : public Test::LoopbackMessagingContext +class TestCASESession : public Test::LoopbackMessagingContext, public ::testing::Test { public: // Performs shared setup for all tests in the test suite static void SetUpTestSuite(); // Performs shared teardown for all tests in the test suite static void TearDownTestSuite(); + + virtual void SetUp() override + { + ConfigInitializeNodes(false); + chip::Test::LoopbackMessagingContext::SetUp(); + } + + virtual void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } + + void ServiceEvents(); + void SecurePairingHandshakeTestCommon(SessionManager & sessionManager, CASESession & pairingCommissioner, + TestCASESecurePairingDelegate & delegateCommissioner); + + void SimulateUpdateNOCInvalidatePendingEstablishment(); }; -void ServiceEvents(TestContext & ctx) +void TestCASESession::ServiceEvents() { // Takes a few rounds of this because handling IO messages may schedule work, // and scheduled work may queue messages for sending... for (int i = 0; i < 3; ++i) { - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); chip::DeviceLayer::PlatformMgr().ScheduleWork( [](intptr_t) -> void { chip::DeviceLayer::PlatformMgr().StopEventLoopTask(); }, (intptr_t) nullptr); @@ -83,12 +96,11 @@ void ServiceEvents(TestContext & ctx) class TemporarySessionManager { public: - TemporarySessionManager(nlTestSuite * suite, TestContext & ctx) : mCtx(ctx) + TemporarySessionManager(TestCASESession & ctx) : mCtx(ctx) { - NL_TEST_ASSERT(suite, - CHIP_NO_ERROR == - mSessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &ctx.GetMessageCounterManager(), - &mStorage, &ctx.GetFabricTable(), ctx.GetSessionKeystore())); + EXPECT_EQ(CHIP_NO_ERROR, + mSessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &ctx.GetMessageCounterManager(), &mStorage, + &ctx.GetFabricTable(), ctx.GetSessionKeystore())); // The setup here is really weird: we are using one session manager for // the actual messages we send (the PASE handshake, so the // unauthenticated sessions) and a different one for allocating the PASE @@ -108,7 +120,7 @@ class TemporarySessionManager operator SessionManager &() { return mSessionManager; } private: - TestContext & mCtx; + TestCASESession & mCtx; TestPersistentStorageDelegate mStorage; SessionManager mSessionManager; }; @@ -327,23 +339,22 @@ CHIP_ERROR InitCredentialSets() return CHIP_NO_ERROR; } -void TestContext::SetUpTestSuite() +void TestCASESession::SetUpTestSuite() { - ConfigInitializeNodes(false); - CHIP_ERROR err = CHIP_NO_ERROR; LoopbackMessagingContext::SetUpTestSuite(); - // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete - VerifyOrDieWithMsg((err = chip::DeviceLayer::PlatformMgr().InitChipStack()) == CHIP_NO_ERROR, AppServer, - "Init CHIP stack failed: %" CHIP_ERROR_FORMAT, err.Format()); - VerifyOrDieWithMsg((err = InitFabricTable(gCommissionerFabrics, &gCommissionerStorageDelegate, /* opKeyStore = */ nullptr, - &gCommissionerOpCertStore)) == CHIP_NO_ERROR, - AppServer, "InitFabricTable failed: %" CHIP_ERROR_FORMAT, err.Format()); - VerifyOrDieWithMsg((err = InitCredentialSets()) == CHIP_NO_ERROR, AppServer, "InitCredentialSets failed: %" CHIP_ERROR_FORMAT, - err.Format()); + + ASSERT_EQ(chip::DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR); + + ASSERT_EQ( + InitFabricTable(gCommissionerFabrics, &gCommissionerStorageDelegate, /* opKeyStore = */ nullptr, &gCommissionerOpCertStore), + CHIP_NO_ERROR); + + ASSERT_EQ(InitCredentialSets(), CHIP_NO_ERROR); + chip::DeviceLayer::SetSystemLayerForTesting(&GetSystemLayer()); } -void TestContext::TearDownTestSuite() +void TestCASESession::TearDownTestSuite() { chip::DeviceLayer::SetSystemLayerForTesting(nullptr); gDeviceOperationalKeystore.Shutdown(); @@ -356,52 +367,27 @@ void TestContext::TearDownTestSuite() LoopbackMessagingContext::TearDownTestSuite(); } -} // anonymous namespace - -// Specifically for SimulateUpdateNOCInvalidatePendingEstablishment, we need it to be static so that the class below can -// be a friend to CASESession so that test can get access to CASESession::State and test method that are not public. To -// keep the rest of this file consistent we brought all other tests into this class. -class TestCASESession +TEST_F(TestCASESession, SecurePairingWaitTest) { -public: - static void SecurePairingWaitTest(nlTestSuite * inSuite, void * inContext); - static void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext); - static void SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext); - static void SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inContext); - static void ClientReceivesBusyTest(nlTestSuite * inSuite, void * inContext); - static void Sigma1ParsingTest(nlTestSuite * inSuite, void * inContext); - static void DestinationIdTest(nlTestSuite * inSuite, void * inContext); - static void SessionResumptionStorage(nlTestSuite * inSuite, void * inContext); -#if CONFIG_BUILD_FOR_HOST_UNIT_TEST - static void SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuite * inSuite, void * inContext); -#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST - static void Sigma1BadDestinationIdTest(nlTestSuite * inSuite, void * inContext); -}; - -void TestCASESession::SecurePairingWaitTest(nlTestSuite * inSuite, void * inContext) -{ - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); - + TemporarySessionManager sessionManager(*this); // Test all combinations of invalid parameters TestCASESecurePairingDelegate delegate; - FabricTable fabrics; + // Making this static to reduce stack usage, as some platforms have limits on stack size. + static FabricTable fabrics; CASESession caseSession; - NL_TEST_ASSERT(inSuite, caseSession.GetSecureSessionType() == SecureSession::Type::kCASE); + EXPECT_EQ(caseSession.GetSecureSessionType(), SecureSession::Type::kCASE); caseSession.SetGroupDataProvider(&gDeviceGroupDataProvider); - NL_TEST_ASSERT(inSuite, - caseSession.PrepareForSessionEstablishment(sessionManager, nullptr, nullptr, nullptr, nullptr, ScopedNodeId(), - Optional::Missing()) == - CHIP_ERROR_INVALID_ARGUMENT); - NL_TEST_ASSERT(inSuite, - caseSession.PrepareForSessionEstablishment(sessionManager, nullptr, nullptr, nullptr, &delegate, ScopedNodeId(), - Optional::Missing()) == - CHIP_ERROR_INVALID_ARGUMENT); - NL_TEST_ASSERT(inSuite, - caseSession.PrepareForSessionEstablishment(sessionManager, &fabrics, nullptr, nullptr, &delegate, ScopedNodeId(), - Optional::Missing()) == CHIP_NO_ERROR); + EXPECT_EQ(caseSession.PrepareForSessionEstablishment(sessionManager, nullptr, nullptr, nullptr, nullptr, ScopedNodeId(), + Optional::Missing()), + CHIP_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(caseSession.PrepareForSessionEstablishment(sessionManager, nullptr, nullptr, nullptr, &delegate, ScopedNodeId(), + Optional::Missing()), + CHIP_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(caseSession.PrepareForSessionEstablishment(sessionManager, &fabrics, nullptr, nullptr, &delegate, ScopedNodeId(), + Optional::Missing()), + CHIP_NO_ERROR); // Calling Clear() here since ASAN will have an issue if FabricTable destructor is called before CASESession's // destructor. We could reorder FabricTable and CaseSession, but this makes it a little more clear what we are @@ -409,42 +395,37 @@ void TestCASESession::SecurePairingWaitTest(nlTestSuite * inSuite, void * inCont caseSession.Clear(); } -void TestCASESession::SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, SecurePairingStartTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); - + TemporarySessionManager sessionManager(*this); // Test all combinations of invalid parameters TestCASESecurePairingDelegate delegate; CASESession pairing; pairing.SetGroupDataProvider(&gCommissionerGroupDataProvider); - ExchangeContext * context = ctx.NewUnauthenticatedExchangeToBob(&pairing); + ExchangeContext * context = NewUnauthenticatedExchangeToBob(&pairing); - NL_TEST_ASSERT(inSuite, - pairing.EstablishSession(sessionManager, nullptr, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, nullptr, - nullptr, nullptr, nullptr, - Optional::Missing()) != CHIP_NO_ERROR); - ServiceEvents(ctx); + EXPECT_NE(pairing.EstablishSession(sessionManager, nullptr, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, nullptr, + nullptr, nullptr, nullptr, Optional::Missing()), + CHIP_NO_ERROR); + ServiceEvents(); - NL_TEST_ASSERT(inSuite, - pairing.EstablishSession(sessionManager, &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, nullptr, nullptr, nullptr, nullptr, - Optional::Missing()) != CHIP_NO_ERROR); - ServiceEvents(ctx); + EXPECT_NE(pairing.EstablishSession(sessionManager, &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, + nullptr, nullptr, nullptr, nullptr, Optional::Missing()), + CHIP_NO_ERROR); + ServiceEvents(); - NL_TEST_ASSERT(inSuite, - pairing.EstablishSession(sessionManager, &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, context, nullptr, nullptr, - &delegate, Optional::Missing()) == CHIP_NO_ERROR); - ServiceEvents(ctx); + EXPECT_EQ(pairing.EstablishSession(sessionManager, &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, + context, nullptr, nullptr, &delegate, Optional::Missing()), + CHIP_NO_ERROR); + ServiceEvents(); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); // There should have been two message sent: Sigma1 and an ack. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); + EXPECT_EQ(loopback.mSentMessageCount, 2u); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); loopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; @@ -453,22 +434,19 @@ void TestCASESession::SecurePairingStartTest(nlTestSuite * inSuite, void * inCon loopback.mSentMessageCount = 0; loopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; - ExchangeContext * context1 = ctx.NewUnauthenticatedExchangeToBob(&pairing1); + ExchangeContext * context1 = NewUnauthenticatedExchangeToBob(&pairing1); - NL_TEST_ASSERT(inSuite, - pairing1.EstablishSession( - sessionManager, &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, context1, - nullptr, nullptr, &delegate, Optional::Missing()) == CHIP_ERROR_BAD_REQUEST); - ServiceEvents(ctx); + EXPECT_EQ(pairing1.EstablishSession(sessionManager, &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, + context1, nullptr, nullptr, &delegate, Optional::Missing()), + CHIP_ERROR_BAD_REQUEST); + ServiceEvents(); loopback.mMessageSendError = CHIP_NO_ERROR; } -void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, SessionManager & sessionManager, - CASESession & pairingCommissioner, TestCASESecurePairingDelegate & delegateCommissioner) +void TestCASESession::SecurePairingHandshakeTestCommon(SessionManager & sessionManager, CASESession & pairingCommissioner, + TestCASESecurePairingDelegate & delegateCommissioner) { - TestContext & ctx = *reinterpret_cast(inContext); - // Test all combinations of invalid parameters TestCASESecurePairingDelegate delegateAccessory; CASESession pairingAccessory; @@ -477,39 +455,36 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, S ReliableMessageProtocolConfig nonSleepyCommissionerRmpConfig( System::Clock::Milliseconds32(5000), System::Clock::Milliseconds32(300), System::Clock::Milliseconds16(4000)); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, - ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::CASE_Sigma1, - &pairingAccessory) == CHIP_NO_ERROR); + EXPECT_EQ(GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::CASE_Sigma1, + &pairingAccessory), + CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(&pairingCommissioner); pairingAccessory.SetGroupDataProvider(&gDeviceGroupDataProvider); - NL_TEST_ASSERT(inSuite, - pairingAccessory.PrepareForSessionEstablishment(sessionManager, &gDeviceFabrics, nullptr, nullptr, - &delegateAccessory, ScopedNodeId(), - MakeOptional(verySleepyAccessoryRmpConfig)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - pairingCommissioner.EstablishSession(sessionManager, &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner, - nullptr, nullptr, &delegateCommissioner, - MakeOptional(nonSleepyCommissionerRmpConfig)) == CHIP_NO_ERROR); - ServiceEvents(ctx); - - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == sTestCaseMessageCount); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, pairingAccessory.GetRemoteMRPConfig().mIdleRetransTimeout == System::Clock::Milliseconds32(5000)); - NL_TEST_ASSERT(inSuite, pairingAccessory.GetRemoteMRPConfig().mActiveRetransTimeout == System::Clock::Milliseconds32(300)); - NL_TEST_ASSERT(inSuite, pairingAccessory.GetRemoteMRPConfig().mActiveThresholdTime == System::Clock::Milliseconds16(4000)); - NL_TEST_ASSERT(inSuite, pairingCommissioner.GetRemoteMRPConfig().mIdleRetransTimeout == System::Clock::Milliseconds32(360000)); - NL_TEST_ASSERT(inSuite, - pairingCommissioner.GetRemoteMRPConfig().mActiveRetransTimeout == System::Clock::Milliseconds32(100000)); - NL_TEST_ASSERT(inSuite, pairingCommissioner.GetRemoteMRPConfig().mActiveThresholdTime == System::Clock::Milliseconds16(300)); + EXPECT_EQ(pairingAccessory.PrepareForSessionEstablishment(sessionManager, &gDeviceFabrics, nullptr, nullptr, &delegateAccessory, + ScopedNodeId(), MakeOptional(verySleepyAccessoryRmpConfig)), + CHIP_NO_ERROR); + EXPECT_EQ(pairingCommissioner.EstablishSession( + sessionManager, &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner, + nullptr, nullptr, &delegateCommissioner, MakeOptional(nonSleepyCommissionerRmpConfig)), + CHIP_NO_ERROR); + ServiceEvents(); + + EXPECT_EQ(loopback.mSentMessageCount, sTestCaseMessageCount); + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 1u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 1u); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 0u); + EXPECT_EQ(pairingAccessory.GetRemoteMRPConfig().mIdleRetransTimeout, System::Clock::Milliseconds32(5000)); + EXPECT_EQ(pairingAccessory.GetRemoteMRPConfig().mActiveRetransTimeout, System::Clock::Milliseconds32(300)); + EXPECT_EQ(pairingAccessory.GetRemoteMRPConfig().mActiveThresholdTime, System::Clock::Milliseconds16(4000)); + EXPECT_EQ(pairingCommissioner.GetRemoteMRPConfig().mIdleRetransTimeout, System::Clock::Milliseconds32(360000)); + EXPECT_EQ(pairingCommissioner.GetRemoteMRPConfig().mActiveRetransTimeout, System::Clock::Milliseconds32(100000)); + EXPECT_EQ(pairingCommissioner.GetRemoteMRPConfig().mActiveThresholdTime, System::Clock::Milliseconds16(300)); #if CONFIG_BUILD_FOR_HOST_UNIT_TEST // Confirming that FabricTable sending a notification that fabric was updated doesn't affect // already established connections. @@ -517,26 +492,24 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, S // This is compiled for host tests which is enough test coverage gCommissionerFabrics.SendUpdateFabricNotificationForTest(gCommissionerFabricIndex); gDeviceFabrics.SendUpdateFabricNotificationForTest(gDeviceFabricIndex); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == sTestCaseMessageCount); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 0); + EXPECT_EQ(loopback.mSentMessageCount, sTestCaseMessageCount); + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 1u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 1u); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 0u); #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST } -void TestCASESession::SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, SecurePairingHandshakeTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); - + TemporarySessionManager sessionManager(*this); TestCASESecurePairingDelegate delegateCommissioner; CASESession pairingCommissioner; pairingCommissioner.SetGroupDataProvider(&gCommissionerGroupDataProvider); - SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, delegateCommissioner); + SecurePairingHandshakeTestCommon(sessionManager, pairingCommissioner, delegateCommissioner); } -void TestCASESession::SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, SecurePairingHandshakeServerTest) { // TODO: Add cases for mismatching IPK config between initiator/responder @@ -545,47 +518,43 @@ void TestCASESession::SecurePairingHandshakeServerTest(nlTestSuite * inSuite, vo auto * pairingCommissioner = chip::Platform::New(); pairingCommissioner->SetGroupDataProvider(&gCommissionerGroupDataProvider); - TestContext & ctx = *reinterpret_cast(inContext); - - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; // Use the same session manager on both CASE client and server sides to validate that both // components may work simultaneously on a single device. - NL_TEST_ASSERT(inSuite, - gPairingServer.ListenForSessionEstablishment(&ctx.GetExchangeManager(), &ctx.GetSecureSessionManager(), - &gDeviceFabrics, nullptr, nullptr, - &gDeviceGroupDataProvider) == CHIP_NO_ERROR); + EXPECT_EQ(gPairingServer.ListenForSessionEstablishment(&GetExchangeManager(), &GetSecureSessionManager(), &gDeviceFabrics, + nullptr, nullptr, &gDeviceGroupDataProvider), + CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(pairingCommissioner); + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(pairingCommissioner); - NL_TEST_ASSERT(inSuite, - pairingCommissioner->EstablishSession(ctx.GetSecureSessionManager(), &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner, - nullptr, nullptr, &delegateCommissioner, - Optional::Missing()) == CHIP_NO_ERROR); - ServiceEvents(ctx); + EXPECT_EQ(pairingCommissioner->EstablishSession( + GetSecureSessionManager(), &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, + contextCommissioner, nullptr, nullptr, &delegateCommissioner, Optional::Missing()), + CHIP_NO_ERROR); + ServiceEvents(); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == sTestCaseMessageCount); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); + EXPECT_EQ(loopback.mSentMessageCount, sTestCaseMessageCount); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 1u); // Validate that secure session is created SessionHolder & holder = delegateCommissioner.GetSessionHolder(); - NL_TEST_ASSERT(inSuite, bool(holder)); + EXPECT_TRUE(bool(holder)); - NL_TEST_ASSERT(inSuite, (holder->GetPeer() == chip::ScopedNodeId{ Node01_01, gCommissionerFabricIndex })); + EXPECT_EQ(holder->GetPeer(), (chip::ScopedNodeId{ Node01_01, gCommissionerFabricIndex })); auto * pairingCommissioner1 = chip::Platform::New(); pairingCommissioner1->SetGroupDataProvider(&gCommissionerGroupDataProvider); - ExchangeContext * contextCommissioner1 = ctx.NewUnauthenticatedExchangeToBob(pairingCommissioner1); + ExchangeContext * contextCommissioner1 = NewUnauthenticatedExchangeToBob(pairingCommissioner1); - NL_TEST_ASSERT(inSuite, - pairingCommissioner1->EstablishSession(ctx.GetSecureSessionManager(), &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner1, - nullptr, nullptr, &delegateCommissioner, - Optional::Missing()) == CHIP_NO_ERROR); + EXPECT_EQ(pairingCommissioner1->EstablishSession(GetSecureSessionManager(), &gCommissionerFabrics, + ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner1, + nullptr, nullptr, &delegateCommissioner, + Optional::Missing()), + CHIP_NO_ERROR); - ServiceEvents(ctx); + ServiceEvents(); chip::Platform::Delete(pairingCommissioner); chip::Platform::Delete(pairingCommissioner1); @@ -593,52 +562,49 @@ void TestCASESession::SecurePairingHandshakeServerTest(nlTestSuite * inSuite, vo gPairingServer.Shutdown(); } -void TestCASESession::ClientReceivesBusyTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, ClientReceivesBusyTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); - + TemporarySessionManager sessionManager(*this); TestCASESecurePairingDelegate delegateCommissioner1, delegateCommissioner2; CASESession pairingCommissioner1, pairingCommissioner2; pairingCommissioner1.SetGroupDataProvider(&gCommissionerGroupDataProvider); pairingCommissioner2.SetGroupDataProvider(&gCommissionerGroupDataProvider); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, - gPairingServer.ListenForSessionEstablishment(&ctx.GetExchangeManager(), &ctx.GetSecureSessionManager(), - &gDeviceFabrics, nullptr, nullptr, - &gDeviceGroupDataProvider) == CHIP_NO_ERROR); + EXPECT_EQ(gPairingServer.ListenForSessionEstablishment(&GetExchangeManager(), &GetSecureSessionManager(), &gDeviceFabrics, + nullptr, nullptr, &gDeviceGroupDataProvider), + CHIP_NO_ERROR); - ExchangeContext * contextCommissioner1 = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner1); - ExchangeContext * contextCommissioner2 = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner2); + ExchangeContext * contextCommissioner1 = NewUnauthenticatedExchangeToBob(&pairingCommissioner1); + ExchangeContext * contextCommissioner2 = NewUnauthenticatedExchangeToBob(&pairingCommissioner2); - NL_TEST_ASSERT(inSuite, - pairingCommissioner1.EstablishSession(sessionManager, &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner1, - nullptr, nullptr, &delegateCommissioner1, NullOptional) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - pairingCommissioner2.EstablishSession(sessionManager, &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner2, - nullptr, nullptr, &delegateCommissioner2, NullOptional) == CHIP_NO_ERROR); + EXPECT_EQ(pairingCommissioner1.EstablishSession(sessionManager, &gCommissionerFabrics, + ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner1, + nullptr, nullptr, &delegateCommissioner1, NullOptional), + CHIP_NO_ERROR); + EXPECT_EQ(pairingCommissioner2.EstablishSession(sessionManager, &gCommissionerFabrics, + ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner2, + nullptr, nullptr, &delegateCommissioner2, NullOptional), + CHIP_NO_ERROR); - ServiceEvents(ctx); + ServiceEvents(); // We should have one full handshake and one Sigma1 + Busy + ack. If that // ever changes (e.g. because our server starts supporting multiple parallel // handshakes), this test needs to be fixed so that the server is still // responding BUSY to the client. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == sTestCaseMessageCount + 3); - NL_TEST_ASSERT(inSuite, delegateCommissioner1.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner2.mNumPairingComplete == 0); + EXPECT_EQ(loopback.mSentMessageCount, sTestCaseMessageCount + 3); + EXPECT_EQ(delegateCommissioner1.mNumPairingComplete, 1u); + EXPECT_EQ(delegateCommissioner2.mNumPairingComplete, 0u); - NL_TEST_ASSERT(inSuite, delegateCommissioner1.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner2.mNumPairingErrors == 1); + EXPECT_EQ(delegateCommissioner1.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner2.mNumPairingErrors, 1u); - NL_TEST_ASSERT(inSuite, delegateCommissioner1.mNumBusyResponses == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner2.mNumBusyResponses == 1); + EXPECT_EQ(delegateCommissioner1.mNumBusyResponses, 0u); + EXPECT_EQ(delegateCommissioner2.mNumBusyResponses, 1u); gPairingServer.Shutdown(); } @@ -667,7 +633,7 @@ struct Sigma1Params static constexpr bool expectSuccess = true; }; -void TestCASESession::DestinationIdTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, DestinationIdTest) { // Validate example test vector from CASE section of spec @@ -702,20 +668,20 @@ void TestCASESession::DestinationIdTest(nlTestSuite * inSuite, void * inContext) CHIP_ERROR err = GenerateCaseDestinationId(ByteSpan(kIpkOperationalGroupKeyFromSpec), ByteSpan(kInitiatorRandomFromSpec), ByteSpan(kRootPubKeyFromSpec), kFabricIdFromSpec, kNodeIdFromSpec, destinationIdSpan); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == err); - NL_TEST_ASSERT(inSuite, destinationIdSpan.size() == sizeof(destinationIdBuf)); - NL_TEST_ASSERT(inSuite, destinationIdSpan.data_equal(ByteSpan(kExpectedDestinationIdFromSpec))); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_EQ(destinationIdSpan.size(), sizeof(destinationIdBuf)); + EXPECT_TRUE(destinationIdSpan.data_equal(ByteSpan(kExpectedDestinationIdFromSpec))); memset(destinationIdSpan.data(), 0, destinationIdSpan.size()); // Test changing input: should yield different - err = GenerateCaseDestinationId(ByteSpan(kIpkOperationalGroupKeyFromSpec), ByteSpan(kInitiatorRandomFromSpec), - ByteSpan(kRootPubKeyFromSpec), kFabricIdFromSpec, - kNodeIdFromSpec + 1, // <--- Change node ID - destinationIdSpan); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == err); - NL_TEST_ASSERT(inSuite, destinationIdSpan.size() == sizeof(destinationIdBuf)); - NL_TEST_ASSERT(inSuite, !destinationIdSpan.data_equal(ByteSpan(kExpectedDestinationIdFromSpec))); + EXPECT_EQ(GenerateCaseDestinationId(ByteSpan(kIpkOperationalGroupKeyFromSpec), ByteSpan(kInitiatorRandomFromSpec), + ByteSpan(kRootPubKeyFromSpec), kFabricIdFromSpec, + kNodeIdFromSpec + 1, // <--- Change node ID + destinationIdSpan), + CHIP_NO_ERROR); + EXPECT_EQ(destinationIdSpan.size(), sizeof(destinationIdBuf)); + EXPECT_FALSE(destinationIdSpan.data_equal(ByteSpan(kExpectedDestinationIdFromSpec))); } template @@ -770,12 +736,11 @@ static CHIP_ERROR EncodeSigma1(MutableByteSpan & buf) } // A macro, so we can tell which test failed based on line number. -#define TestSigma1Parsing(inSuite, mem, bufferSize, params) \ +#define TestSigma1Parsing(mem, bufferSize, params) \ do \ { \ MutableByteSpan buf(mem.Get(), bufferSize); \ - CHIP_ERROR err = EncodeSigma1(buf); \ - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); \ + EXPECT_EQ(EncodeSigma1(buf), CHIP_NO_ERROR); \ \ TLV::ContiguousBufferTLVReader reader; \ reader.Init(buf); \ @@ -788,12 +753,12 @@ static CHIP_ERROR EncodeSigma1(MutableByteSpan & buf) ByteSpan resumptionId; \ ByteSpan initiatorResumeMIC; \ CASESession session; \ - err = session.ParseSigma1(reader, initiatorRandom, initiatorSessionId, destinationId, initiatorEphPubKey, \ - resumptionRequested, resumptionId, initiatorResumeMIC); \ - NL_TEST_ASSERT(inSuite, (err == CHIP_NO_ERROR) == params::expectSuccess); \ + EXPECT_EQ(session.ParseSigma1(reader, initiatorRandom, initiatorSessionId, destinationId, initiatorEphPubKey, \ + resumptionRequested, resumptionId, initiatorResumeMIC) == CHIP_NO_ERROR, \ + params::expectSuccess); \ if (params::expectSuccess) \ { \ - NL_TEST_ASSERT(inSuite, resumptionRequested == (params::resumptionIdLen != 0 && params::initiatorResumeMICLen != 0)); \ + EXPECT_EQ(resumptionRequested, params::resumptionIdLen != 0 && params::initiatorResumeMICLen != 0); \ /* Add other verification tests here as desired */ \ } \ } while (0) @@ -883,30 +848,29 @@ struct Sigma1SessionIdTooBig : public BadSigma1ParamsBase static constexpr uint32_t initiatorSessionId = UINT16_MAX + 1; }; -void TestCASESession::Sigma1ParsingTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, Sigma1ParsingTest) { // 1280 bytes must be enough by definition. constexpr size_t bufferSize = 1280; chip::Platform::ScopedMemoryBuffer mem; - NL_TEST_ASSERT(inSuite, mem.Calloc(bufferSize)); - - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1Params); - - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1NoStructEnd); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1WrongTags); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooLongRandom); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooShortRandom); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooLongDest); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooShortDest); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooLongPubkey); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooShortPubkey); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1WithResumption); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooLongResumptionId); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooShortResumptionId); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooLongResumeMIC); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1TooShortResumeMIC); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1SessionIdMax); - TestSigma1Parsing(inSuite, mem, bufferSize, Sigma1SessionIdTooBig); + EXPECT_TRUE(mem.Calloc(bufferSize)); + + TestSigma1Parsing(mem, bufferSize, Sigma1Params); + TestSigma1Parsing(mem, bufferSize, Sigma1NoStructEnd); + TestSigma1Parsing(mem, bufferSize, Sigma1WrongTags); + TestSigma1Parsing(mem, bufferSize, Sigma1TooLongRandom); + TestSigma1Parsing(mem, bufferSize, Sigma1TooShortRandom); + TestSigma1Parsing(mem, bufferSize, Sigma1TooLongDest); + TestSigma1Parsing(mem, bufferSize, Sigma1TooShortDest); + TestSigma1Parsing(mem, bufferSize, Sigma1TooLongPubkey); + TestSigma1Parsing(mem, bufferSize, Sigma1TooShortPubkey); + TestSigma1Parsing(mem, bufferSize, Sigma1WithResumption); + TestSigma1Parsing(mem, bufferSize, Sigma1TooLongResumptionId); + TestSigma1Parsing(mem, bufferSize, Sigma1TooShortResumptionId); + TestSigma1Parsing(mem, bufferSize, Sigma1TooLongResumeMIC); + TestSigma1Parsing(mem, bufferSize, Sigma1TooShortResumeMIC); + TestSigma1Parsing(mem, bufferSize, Sigma1SessionIdMax); + TestSigma1Parsing(mem, bufferSize, Sigma1SessionIdTooBig); } struct SessionResumptionTestStorage : SessionResumptionStorage @@ -956,7 +920,7 @@ struct SessionResumptionTestStorage : SessionResumptionStorage Crypto::P256ECDHDerivedSecret * mSharedSecret = nullptr; }; -void TestCASESession::SessionResumptionStorage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, SessionResumptionStorage) { // Test the SessionResumptionStorage external interface. // @@ -967,7 +931,6 @@ void TestCASESession::SessionResumptionStorage(nlTestSuite * inSuite, void * inC // if the peers have mismatched session resumption information, we should // fall back to CASE. - TestContext & ctx = *reinterpret_cast(inContext); TestCASESecurePairingDelegate delegateCommissioner; chip::SessionResumptionStorage::ResumptionIdStorage resumptionIdA; chip::SessionResumptionStorage::ResumptionIdStorage resumptionIdB; @@ -976,19 +939,19 @@ void TestCASESession::SessionResumptionStorage(nlTestSuite * inSuite, void * inC // Create our fabric-scoped node IDs. const FabricInfo * fabricInfo = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); - NL_TEST_ASSERT(inSuite, fabricInfo != nullptr); + ASSERT_NE(fabricInfo, nullptr); ScopedNodeId initiator = fabricInfo->GetScopedNodeIdForNode(Node01_02); ScopedNodeId responder = fabricInfo->GetScopedNodeIdForNode(Node01_01); // Generate a resumption IDs. - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(resumptionIdA.data(), resumptionIdA.size())); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(resumptionIdB.data(), resumptionIdB.size())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(resumptionIdA.data(), resumptionIdA.size()), CHIP_NO_ERROR); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(resumptionIdB.data(), resumptionIdB.size()), CHIP_NO_ERROR); // Generate a shared secrets. sharedSecretA.SetLength(sharedSecretA.Capacity()); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(sharedSecretA.Bytes(), sharedSecretA.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(sharedSecretA.Bytes(), sharedSecretA.Length()), CHIP_NO_ERROR); sharedSecretB.SetLength(sharedSecretB.Capacity()); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(sharedSecretB.Bytes(), sharedSecretB.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(sharedSecretB.Bytes(), sharedSecretB.Length()), CHIP_NO_ERROR); struct { @@ -1028,38 +991,37 @@ void TestCASESession::SessionResumptionStorage(nlTestSuite * inSuite, void * inC }, }; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); for (size_t i = 0; i < sizeof(testVectors) / sizeof(testVectors[0]); ++i) { auto * pairingCommissioner = chip::Platform::New(); pairingCommissioner->SetGroupDataProvider(&gCommissionerGroupDataProvider); loopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, - gPairingServer.ListenForSessionEstablishment(&ctx.GetExchangeManager(), &ctx.GetSecureSessionManager(), - &gDeviceFabrics, &testVectors[i].responderStorage, nullptr, - &gDeviceGroupDataProvider) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(pairingCommissioner); + EXPECT_EQ(gPairingServer.ListenForSessionEstablishment(&GetExchangeManager(), &GetSecureSessionManager(), &gDeviceFabrics, + &testVectors[i].responderStorage, nullptr, + &gDeviceGroupDataProvider), + CHIP_NO_ERROR); + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(pairingCommissioner); auto establishmentReturnVal = pairingCommissioner->EstablishSession( - ctx.GetSecureSessionManager(), &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, + GetSecureSessionManager(), &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner, &testVectors[i].initiatorStorage, nullptr, &delegateCommissioner, Optional::Missing()); - ServiceEvents(ctx); - NL_TEST_ASSERT(inSuite, establishmentReturnVal == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == testVectors[i].expectedSentMessageCount); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == i + 1); + ServiceEvents(); + EXPECT_EQ(establishmentReturnVal, CHIP_NO_ERROR); + EXPECT_EQ(loopback.mSentMessageCount, testVectors[i].expectedSentMessageCount); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, i + 1); SessionHolder & holder = delegateCommissioner.GetSessionHolder(); - NL_TEST_ASSERT(inSuite, bool(holder)); - NL_TEST_ASSERT(inSuite, holder->GetPeer() == fabricInfo->GetScopedNodeIdForNode(Node01_01)); + EXPECT_TRUE(bool(holder)); + EXPECT_EQ(holder->GetPeer(), fabricInfo->GetScopedNodeIdForNode(Node01_01)); chip::Platform::Delete(pairingCommissioner); + gPairingServer.Shutdown(); } } #if CONFIG_BUILD_FOR_HOST_UNIT_TEST -void TestCASESession::SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuite * inSuite, void * inContext) +TEST_F_FROM_FIXTURE(TestCASESession, SimulateUpdateNOCInvalidatePendingEstablishment) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); - + TemporarySessionManager sessionManager(*this); TestCASESecurePairingDelegate delegateCommissioner; CASESession pairingCommissioner; pairingCommissioner.SetGroupDataProvider(&gCommissionerGroupDataProvider); @@ -1067,70 +1029,65 @@ void TestCASESession::SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuit TestCASESecurePairingDelegate delegateAccessory; CASESession pairingAccessory; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, - ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::CASE_Sigma1, - &pairingAccessory) == CHIP_NO_ERROR); + EXPECT_EQ(GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::CASE_Sigma1, + &pairingAccessory), + CHIP_NO_ERROR); // In order for all the test iterations below, we need to stop the CASE sigma handshake in the middle such // that the CASE session is in the process of being established. pairingCommissioner.SetStopSigmaHandshakeAt(MakeOptional(CASESession::State::kSentSigma1)); - ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(&pairingCommissioner); pairingAccessory.SetGroupDataProvider(&gDeviceGroupDataProvider); - NL_TEST_ASSERT(inSuite, - pairingAccessory.PrepareForSessionEstablishment( - sessionManager, &gDeviceFabrics, nullptr, nullptr, &delegateAccessory, ScopedNodeId(), - Optional::Missing()) == CHIP_NO_ERROR); + EXPECT_EQ(pairingAccessory.PrepareForSessionEstablishment(sessionManager, &gDeviceFabrics, nullptr, nullptr, &delegateAccessory, + ScopedNodeId(), Optional::Missing()), + CHIP_NO_ERROR); gDeviceFabrics.SendUpdateFabricNotificationForTest(gDeviceFabricIndex); - ServiceEvents(ctx); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); + ServiceEvents(); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); - NL_TEST_ASSERT(inSuite, - pairingCommissioner.EstablishSession(sessionManager, &gCommissionerFabrics, - ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner, - nullptr, nullptr, &delegateCommissioner, - Optional::Missing()) == CHIP_NO_ERROR); - ServiceEvents(ctx); + EXPECT_EQ(pairingCommissioner.EstablishSession( + sessionManager, &gCommissionerFabrics, ScopedNodeId{ Node01_01, gCommissionerFabricIndex }, contextCommissioner, + nullptr, nullptr, &delegateCommissioner, Optional::Missing()), + CHIP_NO_ERROR); + ServiceEvents(); // At this point the CASESession is in the process of establishing. Confirm that there are no errors and there are session // has not been established. - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 0); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 0); + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 0u); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 0u); // Simulating an update to the Fabric NOC for gCommissionerFabrics fabric table. // Confirm that CASESession on commisioner side has reported an error. gCommissionerFabrics.SendUpdateFabricNotificationForTest(gCommissionerFabricIndex); - ServiceEvents(ctx); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 1); + ServiceEvents(); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 1u); // Simulating an update to the Fabric NOC for gDeviceFabrics fabric table. // Confirm that CASESession on accessory side has reported an error. gDeviceFabrics.SendUpdateFabricNotificationForTest(gDeviceFabricIndex); - ServiceEvents(ctx); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 1); + ServiceEvents(); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 1u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 1u); // Sanity check that pairing did not complete. - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 0); + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 0u); } #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST -namespace { class ExpectErrorExchangeDelegate : public ExchangeDelegate { public: - ExpectErrorExchangeDelegate(nlTestSuite * suite, uint16_t expectedProtocolCode) : - mSuite(suite), mExpectedProtocolCode(expectedProtocolCode) - {} + ExpectErrorExchangeDelegate(uint16_t expectedProtocolCode) : mExpectedProtocolCode(expectedProtocolCode) {} private: CHIP_ERROR OnMessageReceived(ExchangeContext * ec, const PayloadHeader & payloadHeader, @@ -1138,15 +1095,14 @@ class ExpectErrorExchangeDelegate : public ExchangeDelegate { using namespace SecureChannel; - NL_TEST_ASSERT(mSuite, payloadHeader.HasMessageType(MsgType::StatusReport)); + EXPECT_TRUE(payloadHeader.HasMessageType(MsgType::StatusReport)); SecureChannel::StatusReport statusReport; - CHIP_ERROR err = statusReport.Parse(std::move(buf)); - NL_TEST_ASSERT(mSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(statusReport.Parse(std::move(buf)), CHIP_NO_ERROR); - NL_TEST_ASSERT(mSuite, statusReport.GetProtocolId() == SecureChannel::Id); - NL_TEST_ASSERT(mSuite, statusReport.GetGeneralCode() == GeneralStatusCode::kFailure); - NL_TEST_ASSERT(mSuite, statusReport.GetProtocolCode() == mExpectedProtocolCode); + EXPECT_EQ(statusReport.GetProtocolId(), SecureChannel::Id); + EXPECT_EQ(statusReport.GetGeneralCode(), GeneralStatusCode::kFailure); + EXPECT_EQ(statusReport.GetProtocolCode(), mExpectedProtocolCode); return CHIP_NO_ERROR; } @@ -1154,105 +1110,49 @@ class ExpectErrorExchangeDelegate : public ExchangeDelegate Messaging::ExchangeMessageDispatch & GetMessageDispatch() override { return SessionEstablishmentExchangeDispatch::Instance(); } - nlTestSuite * mSuite; uint16_t mExpectedProtocolCode; }; -} // anonymous namespace -void TestCASESession::Sigma1BadDestinationIdTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCASESession, Sigma1BadDestinationIdTest) { using SecureChannel::MsgType; - TestContext & ctx = *reinterpret_cast(inContext); - - SessionManager & sessionManager = ctx.GetSecureSessionManager(); + SessionManager & sessionManager = GetSecureSessionManager(); constexpr size_t bufferSize = 600; System::PacketBufferHandle data = chip::System::PacketBufferHandle::New(bufferSize); - NL_TEST_ASSERT(inSuite, !data.IsNull()); + ASSERT_FALSE(data.IsNull()); MutableByteSpan buf(data->Start(), data->AvailableDataLength()); // This uses a bogus destination id that is not going to match anything in practice. - CHIP_ERROR err = EncodeSigma1(buf); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(EncodeSigma1(buf), CHIP_NO_ERROR); data->SetDataLength(static_cast(buf.size())); - Optional session = sessionManager.CreateUnauthenticatedSession(ctx.GetAliceAddress(), GetDefaultMRPConfig()); - NL_TEST_ASSERT(inSuite, session.HasValue()); + Optional session = sessionManager.CreateUnauthenticatedSession(GetAliceAddress(), GetDefaultMRPConfig()); + EXPECT_TRUE(session.HasValue()); TestCASESecurePairingDelegate caseDelegate; CASESession caseSession; caseSession.SetGroupDataProvider(&gDeviceGroupDataProvider); - err = caseSession.PrepareForSessionEstablishment(sessionManager, &gDeviceFabrics, nullptr, nullptr, &caseDelegate, - ScopedNodeId(), NullOptional); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(caseSession.PrepareForSessionEstablishment(sessionManager, &gDeviceFabrics, nullptr, nullptr, &caseDelegate, + ScopedNodeId(), NullOptional), + CHIP_NO_ERROR); - err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(MsgType::CASE_Sigma1, &caseSession); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(MsgType::CASE_Sigma1, &caseSession), CHIP_NO_ERROR); - ExpectErrorExchangeDelegate delegate(inSuite, SecureChannel::kProtocolCodeNoSharedRoot); - ExchangeContext * exchange = ctx.GetExchangeManager().NewContext(session.Value(), &delegate); - NL_TEST_ASSERT(inSuite, exchange != nullptr); + ExpectErrorExchangeDelegate delegate(SecureChannel::kProtocolCodeNoSharedRoot); + ExchangeContext * exchange = GetExchangeManager().NewContext(session.Value(), &delegate); + ASSERT_NE(exchange, nullptr); - err = exchange->SendMessage(MsgType::CASE_Sigma1, std::move(data), SendMessageFlags::kExpectResponse); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(exchange->SendMessage(MsgType::CASE_Sigma1, std::move(data), SendMessageFlags::kExpectResponse), CHIP_NO_ERROR); - ServiceEvents(ctx); + ServiceEvents(); - NL_TEST_ASSERT(inSuite, caseDelegate.mNumPairingErrors == 1); - NL_TEST_ASSERT(inSuite, caseDelegate.mNumPairingComplete == 0); + EXPECT_EQ(caseDelegate.mNumPairingErrors, 1u); + EXPECT_EQ(caseDelegate.mNumPairingComplete, 0u); - ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(MsgType::CASE_Sigma1); + GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(MsgType::CASE_Sigma1); caseSession.Clear(); } } // namespace chip - -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("WaitInit", chip::TestCASESession::SecurePairingWaitTest), - NL_TEST_DEF("Start", chip::TestCASESession::SecurePairingStartTest), - NL_TEST_DEF("Handshake", chip::TestCASESession::SecurePairingHandshakeTest), - NL_TEST_DEF("ServerHandshake", chip::TestCASESession::SecurePairingHandshakeServerTest), - NL_TEST_DEF("ClientReceivesBusy", chip::TestCASESession::ClientReceivesBusyTest), - NL_TEST_DEF("Sigma1Parsing", chip::TestCASESession::Sigma1ParsingTest), - NL_TEST_DEF("DestinationId", chip::TestCASESession::DestinationIdTest), - NL_TEST_DEF("SessionResumptionStorage", chip::TestCASESession::SessionResumptionStorage), -#if CONFIG_BUILD_FOR_HOST_UNIT_TEST - // This is compiled for host tests which is enough test coverage to ensure updating NOC invalidates - // CASESession that are in the process of establishing. - NL_TEST_DEF("InvalidatePendingSessionEstablishment", chip::TestCASESession::SimulateUpdateNOCInvalidatePendingEstablishment), -#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST - NL_TEST_DEF("Sigma1BadDestinationId", chip::TestCASESession::Sigma1BadDestinationIdTest), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-SecurePairing-CASE", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - -/** - * Main - */ -int TestCASESessionTest() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestCASESessionTest) diff --git a/src/protocols/secure_channel/tests/TestCheckInCounter.cpp b/src/protocols/secure_channel/tests/TestCheckInCounter.cpp index e4a71777d17b97..57dbd4b3496cdd 100644 --- a/src/protocols/secure_channel/tests/TestCheckInCounter.cpp +++ b/src/protocols/secure_channel/tests/TestCheckInCounter.cpp @@ -56,7 +56,6 @@ void VerifyCheckInCounterValues(uint32_t startValue, uint32_t expectedValue, Che EXPECT_EQ(counter.GetValue(), startValue); // Test operation - CHIP_ERROR err = CHIP_NO_ERROR; switch (operation) { case CheckInCounterOperations::kInvalidateHalf: { @@ -68,7 +67,6 @@ void VerifyCheckInCounterValues(uint32_t startValue, uint32_t expectedValue, Che break; } default: { - err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; FAIL(); } }; diff --git a/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp b/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp index 82e755b783b4b8..59dcf3080a8ec3 100644 --- a/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp +++ b/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp @@ -15,16 +15,15 @@ * limitations under the License. */ +#include #include #include -#include -#include // DefaultSessionResumptionStorage is a partial implementation. // Use SimpleSessionResumptionStorage, which extends it, to test. #include -void TestSave(nlTestSuite * inSuite, void * inContext) +TEST(TestDefaultSessionResumptionStorage, TestSave) { chip::SimpleSessionResumptionStorage sessionStorage; chip::TestPersistentStorageDelegate storage; @@ -40,14 +39,11 @@ void TestSave(nlTestSuite * inSuite, void * inContext) // Populate test vectors. for (size_t i = 0; i < ArraySize(vectors); ++i) { - NL_TEST_ASSERT( - inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(vectors[i].resumptionId.data(), vectors[i].resumptionId.size())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(vectors[i].resumptionId.data(), vectors[i].resumptionId.size()), CHIP_NO_ERROR); *vectors[i].resumptionId.data() = static_cast(i); // set first byte to our index to ensure uniqueness for the FindByResumptionId call vectors[i].sharedSecret.SetLength(vectors[i].sharedSecret.Capacity()); - NL_TEST_ASSERT(inSuite, - CHIP_NO_ERROR == - chip::Crypto::DRBG_get_bytes(vectors[i].sharedSecret.Bytes(), vectors[i].sharedSecret.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(vectors[i].sharedSecret.Bytes(), vectors[i].sharedSecret.Length()), CHIP_NO_ERROR); vectors[i].node = chip::ScopedNodeId(static_cast(i + 1), static_cast(i + 1)); vectors[i].cats.values[0] = static_cast(rand()); vectors[i].cats.values[1] = static_cast(rand()); @@ -57,9 +53,8 @@ void TestSave(nlTestSuite * inSuite, void * inContext) // Fill storage. for (size_t i = 0; i < CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE; ++i) { - NL_TEST_ASSERT(inSuite, - sessionStorage.Save(vectors[i].node, vectors[i].resumptionId, vectors[i].sharedSecret, vectors[i].cats) == - CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.Save(vectors[i].node, vectors[i].resumptionId, vectors[i].sharedSecret, vectors[i].cats), + CHIP_NO_ERROR); } // Verify behavior for over-fill. @@ -69,9 +64,9 @@ void TestSave(nlTestSuite * inSuite, void * inContext) // case should be modified to match. { size_t last = ArraySize(vectors) - 1; - NL_TEST_ASSERT(inSuite, - sessionStorage.Save(vectors[last].node, vectors[last].resumptionId, vectors[last].sharedSecret, - vectors[last].cats) == CHIP_NO_ERROR); + EXPECT_EQ( + sessionStorage.Save(vectors[last].node, vectors[last].resumptionId, vectors[last].sharedSecret, vectors[last].cats), + CHIP_NO_ERROR); // Copy our data to our test vector index 0 to match // what is now in storage. vectors[0].node = vectors[last].node; @@ -89,28 +84,24 @@ void TestSave(nlTestSuite * inSuite, void * inContext) chip::CATValues outCats; // Verify retrieval by node. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByScopedNodeId(vector.node, outResumptionId, outSharedSecret, outCats) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, memcmp(vector.resumptionId.data(), outResumptionId.data(), vector.resumptionId.size()) == 0); - NL_TEST_ASSERT(inSuite, - memcmp(vector.sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vector.sharedSecret.Length()) == 0); - NL_TEST_ASSERT(inSuite, vector.cats.values[0] == outCats.values[0]); - NL_TEST_ASSERT(inSuite, vector.cats.values[1] == outCats.values[1]); - NL_TEST_ASSERT(inSuite, vector.cats.values[2] == outCats.values[2]); + EXPECT_EQ(sessionStorage.FindByScopedNodeId(vector.node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_EQ(memcmp(vector.resumptionId.data(), outResumptionId.data(), vector.resumptionId.size()), 0); + EXPECT_EQ(memcmp(vector.sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vector.sharedSecret.Length()), 0); + EXPECT_EQ(vector.cats.values[0], outCats.values[0]); + EXPECT_EQ(vector.cats.values[1], outCats.values[1]); + EXPECT_EQ(vector.cats.values[2], outCats.values[2]); // Validate retrieval by resumption ID. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByResumptionId(vector.resumptionId, outNode, outSharedSecret, outCats) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, vector.node == outNode); - NL_TEST_ASSERT(inSuite, - memcmp(vector.sharedSecret.Bytes(), outSharedSecret.ConstBytes(), vector.sharedSecret.Length()) == 0); - NL_TEST_ASSERT(inSuite, vector.cats.values[0] == outCats.values[0]); - NL_TEST_ASSERT(inSuite, vector.cats.values[1] == outCats.values[1]); - NL_TEST_ASSERT(inSuite, vector.cats.values[2] == outCats.values[2]); + EXPECT_EQ(sessionStorage.FindByResumptionId(vector.resumptionId, outNode, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_EQ(vector.node, outNode); + EXPECT_EQ(memcmp(vector.sharedSecret.Bytes(), outSharedSecret.ConstBytes(), vector.sharedSecret.Length()), 0); + EXPECT_EQ(vector.cats.values[0], outCats.values[0]); + EXPECT_EQ(vector.cats.values[1], outCats.values[1]); + EXPECT_EQ(vector.cats.values[2], outCats.values[2]); } } -void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) +TEST(TestDefaultSessionResumptionStorage, TestInPlaceSave) { chip::SimpleSessionResumptionStorage sessionStorage; chip::TestPersistentStorageDelegate storage; @@ -139,14 +130,11 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) // Populate test vectors. for (size_t i = 0; i < ArraySize(vectors); ++i) { - NL_TEST_ASSERT( - inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(vectors[i].resumptionId.data(), vectors[i].resumptionId.size())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(vectors[i].resumptionId.data(), vectors[i].resumptionId.size()), CHIP_NO_ERROR); *vectors[i].resumptionId.data() = static_cast(i); // set first byte to our index to ensure uniqueness for the FindByResumptionId call vectors[i].sharedSecret.SetLength(vectors[i].sharedSecret.Capacity()); - NL_TEST_ASSERT(inSuite, - CHIP_NO_ERROR == - chip::Crypto::DRBG_get_bytes(vectors[i].sharedSecret.Bytes(), vectors[i].sharedSecret.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(vectors[i].sharedSecret.Bytes(), vectors[i].sharedSecret.Length()), CHIP_NO_ERROR); vectors[i].node = nodes[i % ArraySize(nodes)]; vectors[i].cats.values[0] = static_cast(rand()); vectors[i].cats.values[1] = static_cast(rand()); @@ -156,9 +144,8 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) // Add one entry for each node. for (size_t i = 0; i < ArraySize(nodes); ++i) { - NL_TEST_ASSERT(inSuite, - sessionStorage.Save(vectors[i].node, vectors[i].resumptionId, vectors[i].sharedSecret, vectors[i].cats) == - CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.Save(vectors[i].node, vectors[i].resumptionId, vectors[i].sharedSecret, vectors[i].cats), + CHIP_NO_ERROR); } // Read back and verify values. @@ -170,37 +157,27 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) chip::CATValues outCats; // Verify retrieval by node. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByScopedNodeId(vectors[i].node, outResumptionId, outSharedSecret, outCats) == - CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - memcmp(vectors[i].resumptionId.data(), outResumptionId.data(), vectors[i].resumptionId.size()) == 0); - NL_TEST_ASSERT( - inSuite, - memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()) == 0); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[0] == outCats.values[0]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[1] == outCats.values[1]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[2] == outCats.values[2]); + EXPECT_EQ(sessionStorage.FindByScopedNodeId(vectors[i].node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_EQ(memcmp(vectors[i].resumptionId.data(), outResumptionId.data(), vectors[i].resumptionId.size()), 0); + EXPECT_EQ(memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()), 0); + EXPECT_EQ(vectors[i].cats.values[0], outCats.values[0]); + EXPECT_EQ(vectors[i].cats.values[1], outCats.values[1]); + EXPECT_EQ(vectors[i].cats.values[2], outCats.values[2]); // Validate retrieval by resumption ID. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByResumptionId(vectors[i].resumptionId, outNode, outSharedSecret, outCats) == - CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, vectors[i].node == outNode); - NL_TEST_ASSERT( - inSuite, - memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()) == 0); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[0] == outCats.values[0]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[1] == outCats.values[1]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[2] == outCats.values[2]); + EXPECT_EQ(sessionStorage.FindByResumptionId(vectors[i].resumptionId, outNode, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_EQ(vectors[i].node, outNode); + EXPECT_EQ(memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()), 0); + EXPECT_EQ(vectors[i].cats.values[0], outCats.values[0]); + EXPECT_EQ(vectors[i].cats.values[1], outCats.values[1]); + EXPECT_EQ(vectors[i].cats.values[2], outCats.values[2]); } // Now add all test vectors. This should overwrite each node's record // many times. for (auto & vector : vectors) { - NL_TEST_ASSERT(inSuite, - sessionStorage.Save(vector.node, vector.resumptionId, vector.sharedSecret, vector.cats) == CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.Save(vector.node, vector.resumptionId, vector.sharedSecret, vector.cats), CHIP_NO_ERROR); } // Read back and verify that only the last record for each node was retained. @@ -212,36 +189,27 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) chip::CATValues outCats; // Verify retrieval by node. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByScopedNodeId(vectors[i].node, outResumptionId, outSharedSecret, outCats) == - CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - memcmp(vectors[i].resumptionId.data(), outResumptionId.data(), vectors[i].resumptionId.size()) == 0); - NL_TEST_ASSERT( - inSuite, - memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()) == 0); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[0] == outCats.values[0]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[1] == outCats.values[1]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[2] == outCats.values[2]); + EXPECT_EQ(sessionStorage.FindByScopedNodeId(vectors[i].node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_EQ(memcmp(vectors[i].resumptionId.data(), outResumptionId.data(), vectors[i].resumptionId.size()), 0); + EXPECT_EQ(memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()), 0); + EXPECT_EQ(vectors[i].cats.values[0], outCats.values[0]); + EXPECT_EQ(vectors[i].cats.values[1], outCats.values[1]); + EXPECT_EQ(vectors[i].cats.values[2], outCats.values[2]); // Validate retrieval by resumption ID. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByResumptionId(vectors[i].resumptionId, outNode, outSharedSecret, outCats) == - CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, vectors[i].node == outNode); - NL_TEST_ASSERT( - inSuite, - memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()) == 0); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[0] == outCats.values[0]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[1] == outCats.values[1]); - NL_TEST_ASSERT(inSuite, vectors[i].cats.values[2] == outCats.values[2]); + EXPECT_EQ(sessionStorage.FindByResumptionId(vectors[i].resumptionId, outNode, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_EQ(vectors[i].node, outNode); + EXPECT_EQ(memcmp(vectors[i].sharedSecret.ConstBytes(), outSharedSecret.ConstBytes(), vectors[i].sharedSecret.Length()), 0); + EXPECT_EQ(vectors[i].cats.values[0], outCats.values[0]); + EXPECT_EQ(vectors[i].cats.values[1], outCats.values[1]); + EXPECT_EQ(vectors[i].cats.values[2], outCats.values[2]); } // Remove all records for all fabrics. If all three tables of (index, state, // links) are in sync, deleting for each fabric should clean error free. for (const auto & node : nodes) { - NL_TEST_ASSERT(inSuite, sessionStorage.DeleteAll(node.GetFabricIndex()) == CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.DeleteAll(node.GetFabricIndex()), CHIP_NO_ERROR); } // Verify that no entries can be located any longer for any node or @@ -254,12 +222,10 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) chip::CATValues outCats; // Verify all records for all nodes are gone. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByScopedNodeId(vector.node, outResumptionId, outSharedSecret, outCats) != CHIP_NO_ERROR); + EXPECT_NE(sessionStorage.FindByScopedNodeId(vector.node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); // Verify all records for all resumption IDs are gone. - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByResumptionId(vector.resumptionId, outNode, outSharedSecret, outCats) != CHIP_NO_ERROR); + EXPECT_NE(sessionStorage.FindByResumptionId(vector.resumptionId, outNode, outSharedSecret, outCats), CHIP_NO_ERROR); } // Verify no state table persistent storage entries were leaked. @@ -267,7 +233,7 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) { uint16_t size = 0; auto rv = storage.SyncGetKeyValue(chip::SimpleSessionResumptionStorage::GetStorageKey(node).KeyName(), nullptr, size); - NL_TEST_ASSERT(inSuite, rv == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(rv, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } // Verify no link table persistent storage entries were leaked. for (auto & vector : vectors) @@ -275,11 +241,11 @@ void TestInPlaceSave(nlTestSuite * inSuite, void * inContext) uint16_t size = 0; auto rv = storage.SyncGetKeyValue(chip::SimpleSessionResumptionStorage::GetStorageKey(vector.resumptionId).KeyName(), nullptr, size); - NL_TEST_ASSERT(inSuite, rv == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(rv, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } } -void TestDelete(nlTestSuite * inSuite, void * inContext) +TEST(TestDefaultSessionResumptionStorage, TestDelete) { chip::SimpleSessionResumptionStorage sessionStorage; chip::TestPersistentStorageDelegate storage; @@ -293,13 +259,12 @@ void TestDelete(nlTestSuite * inSuite, void * inContext) // Create a shared secret. We can use the same one for all entries. sharedSecret.SetLength(sharedSecret.Capacity()); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(sharedSecret.Bytes(), sharedSecret.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(sharedSecret.Bytes(), sharedSecret.Length()), CHIP_NO_ERROR); // Populate test vectors. for (size_t i = 0; i < ArraySize(vectors); ++i) { - NL_TEST_ASSERT( - inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(vectors[i].resumptionId.data(), vectors[i].resumptionId.size())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(vectors[i].resumptionId.data(), vectors[i].resumptionId.size()), CHIP_NO_ERROR); *vectors[i].resumptionId.data() = static_cast(i); // set first byte to our index to ensure uniqueness for the delete test vectors[i].node = chip::ScopedNodeId(static_cast(i + 1), static_cast(i + 1)); @@ -308,8 +273,7 @@ void TestDelete(nlTestSuite * inSuite, void * inContext) // Fill storage. for (auto & vector : vectors) { - NL_TEST_ASSERT(inSuite, - sessionStorage.Save(vector.node, vector.resumptionId, sharedSecret, chip::CATValues{}) == CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.Save(vector.node, vector.resumptionId, sharedSecret, chip::CATValues{}), CHIP_NO_ERROR); } // Delete values in turn from storage and verify they are removed. @@ -319,11 +283,9 @@ void TestDelete(nlTestSuite * inSuite, void * inContext) chip::SessionResumptionStorage::ResumptionIdStorage outResumptionId; chip::Crypto::P256ECDHDerivedSecret outSharedSecret; chip::CATValues outCats; - NL_TEST_ASSERT(inSuite, sessionStorage.Delete(vector.node) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByScopedNodeId(vector.node, outResumptionId, outSharedSecret, outCats) != CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - sessionStorage.FindByResumptionId(vector.resumptionId, outNode, outSharedSecret, outCats) != CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.Delete(vector.node), CHIP_NO_ERROR); + EXPECT_NE(sessionStorage.FindByScopedNodeId(vector.node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); + EXPECT_NE(sessionStorage.FindByResumptionId(vector.resumptionId, outNode, outSharedSecret, outCats), CHIP_NO_ERROR); } // Verify no state or link table persistent storage entries were leaked. @@ -333,17 +295,17 @@ void TestDelete(nlTestSuite * inSuite, void * inContext) { auto rv = storage.SyncGetKeyValue(chip::SimpleSessionResumptionStorage::GetStorageKey(vector.node).KeyName(), nullptr, size); - NL_TEST_ASSERT(inSuite, rv == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(rv, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } { auto rv = storage.SyncGetKeyValue(chip::SimpleSessionResumptionStorage::GetStorageKey(vector.resumptionId).KeyName(), nullptr, size); - NL_TEST_ASSERT(inSuite, rv == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(rv, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } } } -void TestDeleteAll(nlTestSuite * inSuite, void * inContext) +TEST(TestDefaultSessionResumptionStorage, TestDeleteAll) { chip::SimpleSessionResumptionStorage sessionStorage; chip::TestPersistentStorageDelegate storage; @@ -361,7 +323,7 @@ void TestDeleteAll(nlTestSuite * inSuite, void * inContext) // Create a shared secret. We can use the same one for all entries. sharedSecret.SetLength(sharedSecret.Capacity()); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(sharedSecret.Bytes(), sharedSecret.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(sharedSecret.Bytes(), sharedSecret.Length()), CHIP_NO_ERROR); // Populate test vectors. for (size_t i = 0; i < sizeof(vectors) / sizeof(vectors[0]); ++i) @@ -369,10 +331,9 @@ void TestDeleteAll(nlTestSuite * inSuite, void * inContext) vectors[i].fabricIndex = static_cast(i + 1); for (size_t j = 0; j < sizeof(vectors[0].nodes) / sizeof(vectors[0].nodes[0]); ++j) { - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - chip::Crypto::DRBG_get_bytes(vectors[i].nodes[j].resumptionId.data(), vectors[i].nodes[j].resumptionId.size())); + EXPECT_EQ( + chip::Crypto::DRBG_get_bytes(vectors[i].nodes[j].resumptionId.data(), vectors[i].nodes[j].resumptionId.size()), + CHIP_NO_ERROR); vectors[i].nodes[j].node = chip::ScopedNodeId(static_cast(j), vectors[i].fabricIndex); } } @@ -382,8 +343,7 @@ void TestDeleteAll(nlTestSuite * inSuite, void * inContext) { for (auto & node : vector.nodes) { - NL_TEST_ASSERT(inSuite, - sessionStorage.Save(node.node, node.resumptionId, sharedSecret, chip::CATValues{}) == CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.Save(node.node, node.resumptionId, sharedSecret, chip::CATValues{}), CHIP_NO_ERROR); } } @@ -397,16 +357,14 @@ void TestDeleteAll(nlTestSuite * inSuite, void * inContext) // Verify fabric node entries exist. for (const auto & node : vector.nodes) { - NL_TEST_ASSERT( - inSuite, sessionStorage.FindByScopedNodeId(node.node, outResumptionId, outSharedSecret, outCats) == CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.FindByScopedNodeId(node.node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); } // Delete fabric. - NL_TEST_ASSERT(inSuite, sessionStorage.DeleteAll(vector.fabricIndex) == CHIP_NO_ERROR); + EXPECT_EQ(sessionStorage.DeleteAll(vector.fabricIndex), CHIP_NO_ERROR); // Verify fabric node entries no longer exist. for (const auto & node : vector.nodes) { - NL_TEST_ASSERT( - inSuite, sessionStorage.FindByScopedNodeId(node.node, outResumptionId, outSharedSecret, outCats) != CHIP_NO_ERROR); + EXPECT_NE(sessionStorage.FindByScopedNodeId(node.node, outResumptionId, outSharedSecret, outCats), CHIP_NO_ERROR); } } // Verify no state or link table persistent storage entries were leaked. @@ -418,53 +376,13 @@ void TestDeleteAll(nlTestSuite * inSuite, void * inContext) { auto rv = storage.SyncGetKeyValue(chip::SimpleSessionResumptionStorage::GetStorageKey(node.node).KeyName(), nullptr, size); - NL_TEST_ASSERT(inSuite, rv == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(rv, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } { auto rv = storage.SyncGetKeyValue(chip::SimpleSessionResumptionStorage::GetStorageKey(node.resumptionId).KeyName(), nullptr, size); - NL_TEST_ASSERT(inSuite, rv == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + EXPECT_EQ(rv, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } } } } - -// Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("TestSave", TestSave), - NL_TEST_DEF("TestInPlaceSave", TestInPlaceSave), - NL_TEST_DEF("TestDelete", TestDelete), - NL_TEST_DEF("TestDeleteAll", TestDeleteAll), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-DefaultSessionResumptionStorage", - &sTests[0], - nullptr, - nullptr, -}; -// clang-format on - -/** - * Main - */ -int TestDefaultSessionResumptionStorage() -{ - // Run test suit against one context - nlTestRunner(&sSuite, nullptr); - - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestDefaultSessionResumptionStorage) diff --git a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp index c2e71591acda14..41b6539ecf0773 100644 --- a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp +++ b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp @@ -23,8 +23,7 @@ #include #include -#include -#include + #include #include #include @@ -35,8 +34,8 @@ #include #include +#include #include -#include #include @@ -48,8 +47,6 @@ using namespace chip::Transport; using namespace chip::Messaging; using namespace chip::Protocols; -using TestContext = chip::Test::LoopbackMessagingContext; - const char PAYLOAD[] = "Hello!"; class MockAppDelegate : public ExchangeDelegate @@ -67,109 +64,55 @@ class MockAppDelegate : public ExchangeDelegate int ReceiveHandlerCallCount = 0; }; -void MessageCounterSyncProcess(nlTestSuite * inSuite, void * inContext) +struct TestMessageCounterManager : public chip::Test::LoopbackMessagingContext, public ::testing::Test { - TestContext & ctx = *reinterpret_cast(inContext); + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } - CHIP_ERROR err = CHIP_NO_ERROR; + void SetUp() override { chip::Test::LoopbackMessagingContext::SetUp(); } + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } +}; + +TEST_F(TestMessageCounterManager, MessageCounterSyncProcess) +{ - SessionHandle localSession = ctx.GetSessionBobToAlice(); - SessionHandle peerSession = ctx.GetSessionAliceToBob(); + SessionHandle localSession = GetSessionBobToAlice(); + SessionHandle peerSession = GetSessionAliceToBob(); - Transport::SecureSession * localState = ctx.GetSecureSessionManager().GetSecureSession(localSession); - Transport::SecureSession * peerState = ctx.GetSecureSessionManager().GetSecureSession(peerSession); + Transport::SecureSession * localState = GetSecureSessionManager().GetSecureSession(localSession); + Transport::SecureSession * peerState = GetSecureSessionManager().GetSecureSession(peerSession); localState->GetSessionMessageCounter().GetPeerMessageCounter().Reset(); - err = ctx.GetMessageCounterManager().SendMsgCounterSyncReq(localSession, localState); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(GetMessageCounterManager().SendMsgCounterSyncReq(localSession, localState), CHIP_NO_ERROR); MessageCounter & peerCounter = peerState->GetSessionMessageCounter().GetLocalMessageCounter(); PeerMessageCounter & localCounter = localState->GetSessionMessageCounter().GetPeerMessageCounter(); - NL_TEST_ASSERT(inSuite, localCounter.IsSynchronized()); - NL_TEST_ASSERT(inSuite, localCounter.GetCounter() == peerCounter.Value()); + EXPECT_TRUE(localCounter.IsSynchronized()); + EXPECT_EQ(localCounter.GetCounter(), peerCounter.Value()); } -void CheckReceiveMessage(nlTestSuite * inSuite, void * inContext) +TEST_F(TestMessageCounterManager, CheckReceiveMessage) { - TestContext & ctx = *reinterpret_cast(inContext); - CHIP_ERROR err = CHIP_NO_ERROR; - - SessionHandle peerSession = ctx.GetSessionAliceToBob(); - Transport::SecureSession * peerState = ctx.GetSecureSessionManager().GetSecureSession(peerSession); + SessionHandle peerSession = GetSessionAliceToBob(); + Transport::SecureSession * peerState = GetSecureSessionManager().GetSecureSession(peerSession); peerState->GetSessionMessageCounter().GetPeerMessageCounter().Reset(); MockAppDelegate callback; - ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(chip::Protocols::Echo::MsgType::EchoRequest, &callback); + GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(chip::Protocols::Echo::MsgType::EchoRequest, &callback); uint16_t payload_len = sizeof(PAYLOAD); System::PacketBufferHandle msgBuf = MessagePacketBuffer::NewWithData(PAYLOAD, payload_len); - NL_TEST_ASSERT(inSuite, !msgBuf.IsNull()); + ASSERT_FALSE(msgBuf.IsNull()); - Messaging::ExchangeContext * ec = ctx.NewExchangeToAlice(nullptr); - NL_TEST_ASSERT(inSuite, ec != nullptr); + Messaging::ExchangeContext * ec = NewExchangeToAlice(nullptr); + ASSERT_NE(ec, nullptr); - err = ec->SendMessage(chip::Protocols::Echo::MsgType::EchoRequest, std::move(msgBuf), - Messaging::SendFlags{ Messaging::SendMessageFlags::kNoAutoRequestAck }); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, peerState->GetSessionMessageCounter().GetPeerMessageCounter().IsSynchronized()); - NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); + EXPECT_EQ(ec->SendMessage(chip::Protocols::Echo::MsgType::EchoRequest, std::move(msgBuf), + Messaging::SendFlags{ Messaging::SendMessageFlags::kNoAutoRequestAck }), + CHIP_NO_ERROR); + EXPECT_TRUE(peerState->GetSessionMessageCounter().GetPeerMessageCounter().IsSynchronized()); + EXPECT_EQ(callback.ReceiveHandlerCallCount, 1); } // Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("Test MessageCounterManager::MessageCounterSyncProcess", MessageCounterSyncProcess), - NL_TEST_DEF("Test MessageCounterManager::ReceiveMessage", CheckReceiveMessage), - NL_TEST_SENTINEL() -}; -// clang-format on - -int Initialize(void * aContext); -int Finalize(void * aContext); - -// clang-format off -nlTestSuite sSuite = -{ - "Test-MessageCounterManager", - &sTests[0], - Initialize, - Finalize -}; -// clang-format on - -/** - * Initialize the test suite. - */ -int Initialize(void * aContext) -{ - auto * ctx = static_cast(aContext); - VerifyOrReturnError(ctx->Init(&sSuite) == CHIP_NO_ERROR, FAILURE); - - return SUCCESS; -} - -/** - * Finalize the test suite. - */ -int Finalize(void * aContext) -{ - reinterpret_cast(aContext)->Shutdown(); - return SUCCESS; -} - } // namespace - -/** - * Main - */ -int TestMessageCounterManager() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestMessageCounterManager); diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index d610b304cec481..5b3f957d51bf84 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -22,15 +22,13 @@ */ #include -#include +#include #include #include #include #include #include -#include -#include #include #include #include @@ -85,15 +83,26 @@ constexpr Spake2pVerifierSerialized sTestSpake2p01_SerializedVerifier = { 0xB7, 0xC0, 0x7F, 0xCC, 0x06, 0x27, 0xA1, 0xB8, 0x57, 0x3A, 0x14, 0x9F, 0xCD, 0x1F, 0xA4, 0x66, 0xCF }; -class TestContext : public chip::Test::LoopbackMessagingContext +class TestSecurePairingDelegate; +class TestPASESession : public chip::Test::LoopbackMessagingContext, public ::testing::Test { public: // Performs shared setup for all tests in the test suite - static void SetUpTestSuite() + static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); } + static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); } + + void SetUp() override { ConfigInitializeNodes(false); - chip::Test::LoopbackMessagingContext::SetUpTestSuite(); + chip::Test::LoopbackMessagingContext::SetUp(); } + + void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); } + + void SecurePairingHandshakeTestCommon(SessionManager & sessionManager, PASESession & pairingCommissioner, + Optional mrpCommissionerConfig, + Optional mrpAccessoryConfig, + TestSecurePairingDelegate & delegateCommissioner); }; class PASETestLoopbackTransportDelegate : public Test::LoopbackTransportDelegate @@ -129,12 +138,11 @@ class MockAppDelegate : public ExchangeDelegate class TemporarySessionManager { public: - TemporarySessionManager(nlTestSuite * suite, TestContext & ctx) : mCtx(ctx) + TemporarySessionManager(TestPASESession & ctx) : mCtx(ctx) { - NL_TEST_ASSERT(suite, - CHIP_NO_ERROR == - mSessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &ctx.GetMessageCounterManager(), - &mStorage, &ctx.GetFabricTable(), ctx.GetSessionKeystore())); + EXPECT_EQ(CHIP_NO_ERROR, + mSessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &ctx.GetMessageCounterManager(), &mStorage, + &ctx.GetFabricTable(), ctx.GetSessionKeystore())); // The setup here is really weird: we are using one session manager for // the actual messages we send (the PASE handshake, so the // unauthenticated sessions) and a different one for allocating the PASE @@ -154,122 +162,114 @@ class TemporarySessionManager operator SessionManager &() { return mSessionManager; } private: - TestContext & mCtx; + TestPASESession & mCtx; TestPersistentStorageDelegate mStorage; SessionManager mSessionManager; }; using namespace System::Clock::Literals; -void SecurePairingWaitTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingWaitTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); // Test all combinations of invalid parameters TestSecurePairingDelegate delegate; PASESession pairing; - NL_TEST_ASSERT(inSuite, pairing.GetSecureSessionType() == SecureSession::Type::kPASE); + EXPECT_EQ(pairing.GetSecureSessionType(), SecureSession::Type::kPASE); - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); - NL_TEST_ASSERT(inSuite, - pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, ByteSpan(), - Optional::Missing(), - &delegate) == CHIP_ERROR_INVALID_ARGUMENT); - ctx.DrainAndServiceIO(); - - NL_TEST_ASSERT(inSuite, - pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, - ByteSpan(reinterpret_cast("saltSalt"), 8), - Optional::Missing(), - nullptr) == CHIP_ERROR_INVALID_ARGUMENT); - ctx.DrainAndServiceIO(); - - NL_TEST_ASSERT(inSuite, - pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, - ByteSpan(reinterpret_cast("saltSalt"), 8), - Optional::Missing(), - &delegate) == CHIP_ERROR_INVALID_ARGUMENT); - ctx.DrainAndServiceIO(); - - NL_TEST_ASSERT(inSuite, - pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, - ByteSpan(sTestSpake2p01_Salt), Optional::Missing(), - &delegate) == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, ByteSpan(), + Optional::Missing(), &delegate), + CHIP_ERROR_INVALID_ARGUMENT); + DrainAndServiceIO(); + + EXPECT_EQ(pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, + ByteSpan(reinterpret_cast("saltSalt"), 8), + Optional::Missing(), nullptr), + CHIP_ERROR_INVALID_ARGUMENT); + DrainAndServiceIO(); + + EXPECT_EQ(pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, + ByteSpan(reinterpret_cast("saltSalt"), 8), + Optional::Missing(), &delegate), + CHIP_ERROR_INVALID_ARGUMENT); + DrainAndServiceIO(); + + EXPECT_EQ(pairing.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, + ByteSpan(sTestSpake2p01_Salt), Optional::Missing(), &delegate), + CHIP_NO_ERROR); + DrainAndServiceIO(); } -void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingStartTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); // Test all combinations of invalid parameters TestSecurePairingDelegate delegate; PASESession pairing; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); - ExchangeContext * context = ctx.NewUnauthenticatedExchangeToBob(&pairing); + ExchangeContext * context = NewUnauthenticatedExchangeToBob(&pairing); - NL_TEST_ASSERT(inSuite, - pairing.Pair(sessionManager, sTestSpake2p01_PinCode, Optional::Missing(), nullptr, - nullptr) != CHIP_NO_ERROR); + EXPECT_NE( + pairing.Pair(sessionManager, sTestSpake2p01_PinCode, Optional::Missing(), nullptr, nullptr), + CHIP_NO_ERROR); loopback.Reset(); - NL_TEST_ASSERT(inSuite, - pairing.Pair(sessionManager, sTestSpake2p01_PinCode, Optional::Missing(), context, - &delegate) == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(pairing.Pair(sessionManager, sTestSpake2p01_PinCode, Optional::Missing(), context, + &delegate), + CHIP_NO_ERROR); + DrainAndServiceIO(); // There should have been two messages sent: PBKDFParamRequest and an ack. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2); + EXPECT_EQ(loopback.mSentMessageCount, 2u); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); - NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); loopback.Reset(); loopback.mSentMessageCount = 0; loopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; PASESession pairing1; - ExchangeContext * context1 = ctx.NewUnauthenticatedExchangeToBob(&pairing1); - NL_TEST_ASSERT(inSuite, - pairing1.Pair(sessionManager, sTestSpake2p01_PinCode, Optional::Missing(), - context1, &delegate) == CHIP_ERROR_BAD_REQUEST); - ctx.DrainAndServiceIO(); + ExchangeContext * context1 = NewUnauthenticatedExchangeToBob(&pairing1); + EXPECT_EQ(pairing1.Pair(sessionManager, sTestSpake2p01_PinCode, Optional::Missing(), context1, + &delegate), + CHIP_ERROR_BAD_REQUEST); + DrainAndServiceIO(); loopback.mMessageSendError = CHIP_NO_ERROR; } -void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, SessionManager & sessionManager, - PASESession & pairingCommissioner, - Optional mrpCommissionerConfig, - Optional mrpAccessoryConfig, - TestSecurePairingDelegate & delegateCommissioner) +void TestPASESession::SecurePairingHandshakeTestCommon(SessionManager & sessionManager, PASESession & pairingCommissioner, + Optional mrpCommissionerConfig, + Optional mrpAccessoryConfig, + TestSecurePairingDelegate & delegateCommissioner) { - TestContext & ctx = *reinterpret_cast(inContext); TestSecurePairingDelegate delegateAccessory; PASESession pairingAccessory; PASETestLoopbackTransportDelegate delegate; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.SetLoopbackTransportDelegate(&delegate); loopback.mSentMessageCount = 0; - ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(&pairingCommissioner); if (loopback.mNumMessagesToDrop != 0) { - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = contextCommissioner->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, rm != nullptr); - NL_TEST_ASSERT(inSuite, rc != nullptr); + ASSERT_NE(rm, nullptr); + ASSERT_NE(rc, nullptr); // Adding an if-else to avoid affecting non-ICD tests #if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 @@ -288,20 +288,19 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, S #endif // CHIP_CONFIG_ENABLE_ICD_SERVER } - NL_TEST_ASSERT(inSuite, - ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType( - Protocols::SecureChannel::MsgType::PBKDFParamRequest, &pairingAccessory) == CHIP_NO_ERROR); + EXPECT_EQ(GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::PBKDFParamRequest, + &pairingAccessory), + CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - pairingAccessory.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, - ByteSpan(sTestSpake2p01_Salt), mrpAccessoryConfig, - &delegateAccessory) == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(pairingAccessory.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, + ByteSpan(sTestSpake2p01_Salt), mrpAccessoryConfig, &delegateAccessory), + CHIP_NO_ERROR); + DrainAndServiceIO(); - NL_TEST_ASSERT(inSuite, - pairingCommissioner.Pair(sessionManager, sTestSpake2p01_PinCode, mrpCommissionerConfig, contextCommissioner, - &delegateCommissioner) == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + EXPECT_EQ(pairingCommissioner.Pair(sessionManager, sTestSpake2p01_PinCode, mrpCommissionerConfig, contextCommissioner, + &delegateCommissioner), + CHIP_NO_ERROR); + DrainAndServiceIO(); while (delegate.mMessageDropped) { @@ -318,145 +317,127 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, S // Wait some time so the dropped message will be retransmitted when we drain the IO. chip::test_utils::SleepMillis(waitTimeout.count()); delegate.mMessageDropped = false; - ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), ctx.GetExchangeManager().GetReliableMessageMgr()); - ctx.DrainAndServiceIO(); + ReliableMessageMgr::Timeout(&GetSystemLayer(), GetExchangeManager().GetReliableMessageMgr()); + DrainAndServiceIO(); }; // Standalone acks also increment the mSentMessageCount. But some messages could be acked // via piggybacked acks. So we cannot check for a specific value of mSentMessageCount. // Let's make sure atleast number is >= than the minimum messages required to complete the // handshake. - NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= sTestPaseMessageCount); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); + EXPECT_GE(loopback.mSentMessageCount, sTestPaseMessageCount); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 1u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 1u); if (mrpCommissionerConfig.HasValue()) { - NL_TEST_ASSERT(inSuite, - pairingAccessory.GetRemoteMRPConfig().mIdleRetransTimeout == - mrpCommissionerConfig.Value().mIdleRetransTimeout); - NL_TEST_ASSERT(inSuite, - pairingAccessory.GetRemoteMRPConfig().mActiveRetransTimeout == - mrpCommissionerConfig.Value().mActiveRetransTimeout); + EXPECT_EQ(pairingAccessory.GetRemoteMRPConfig().mIdleRetransTimeout, mrpCommissionerConfig.Value().mIdleRetransTimeout); + EXPECT_EQ(pairingAccessory.GetRemoteMRPConfig().mActiveRetransTimeout, mrpCommissionerConfig.Value().mActiveRetransTimeout); } if (mrpAccessoryConfig.HasValue()) { - NL_TEST_ASSERT(inSuite, - pairingCommissioner.GetRemoteMRPConfig().mIdleRetransTimeout == - mrpAccessoryConfig.Value().mIdleRetransTimeout); - NL_TEST_ASSERT(inSuite, - pairingCommissioner.GetRemoteMRPConfig().mActiveRetransTimeout == - mrpAccessoryConfig.Value().mActiveRetransTimeout); + EXPECT_EQ(pairingCommissioner.GetRemoteMRPConfig().mIdleRetransTimeout, mrpAccessoryConfig.Value().mIdleRetransTimeout); + EXPECT_EQ(pairingCommissioner.GetRemoteMRPConfig().mActiveRetransTimeout, mrpAccessoryConfig.Value().mActiveRetransTimeout); } // Now evict the PASE sessions. auto session = pairingCommissioner.CopySecureSession(); - NL_TEST_ASSERT(inSuite, session.HasValue()); + EXPECT_TRUE(session.HasValue()); session.Value()->AsSecureSession()->MarkForEviction(); session = pairingAccessory.CopySecureSession(); - NL_TEST_ASSERT(inSuite, session.HasValue()); + EXPECT_TRUE(session.HasValue()); session.Value()->AsSecureSession()->MarkForEviction(); // Evicting a session async notifies the PASESession's delegate. Normally // that notification is what would delete the PASESession, but in our case // that will happen as soon as things come off the stack. So make sure to // process the async bits before that happens. - ctx.DrainAndServiceIO(); + DrainAndServiceIO(); // And check that this did not result in any new notifications. - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 0u); + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 1u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 1u); loopback.SetLoopbackTransportDelegate(nullptr); } -void SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingHandshakeTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); - SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, - Optional::Missing(), + SecurePairingHandshakeTestCommon(sessionManager, pairingCommissioner, Optional::Missing(), Optional::Missing(), delegateCommissioner); } -void SecurePairingHandshakeWithCommissionerMRPTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingHandshakeWithCommissionerMRPTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); ReliableMessageProtocolConfig config(1000_ms32, 10000_ms32, 4000_ms16); - SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, - Optional::Value(config), + SecurePairingHandshakeTestCommon(sessionManager, pairingCommissioner, Optional::Value(config), Optional::Missing(), delegateCommissioner); } -void SecurePairingHandshakeWithDeviceMRPTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingHandshakeWithDeviceMRPTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); ReliableMessageProtocolConfig config(1000_ms32, 10000_ms32, 4000_ms16); - SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, - Optional::Missing(), + SecurePairingHandshakeTestCommon(sessionManager, pairingCommissioner, Optional::Missing(), Optional::Value(config), delegateCommissioner); } -void SecurePairingHandshakeWithAllMRPTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingHandshakeWithAllMRPTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); ReliableMessageProtocolConfig commissionerConfig(1000_ms32, 10000_ms32, 4000_ms16); ReliableMessageProtocolConfig deviceConfig(2000_ms32, 7000_ms32, 4000_ms16); - SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, + SecurePairingHandshakeTestCommon(sessionManager, pairingCommissioner, Optional::Value(commissionerConfig), Optional::Value(deviceConfig), delegateCommissioner); } -void SecurePairingHandshakeWithPacketLossTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingHandshakeWithPacketLossTest) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); loopback.mNumMessagesToDrop = 2; - SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, - Optional::Missing(), + SecurePairingHandshakeTestCommon(sessionManager, pairingCommissioner, Optional::Missing(), Optional::Missing(), delegateCommissioner); - NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2); - NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0); + EXPECT_EQ(loopback.mDroppedMessageCount, 2u); + EXPECT_EQ(loopback.mNumMessagesToDrop, 0u); } -void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, SecurePairingFailedHandshake) { - TestContext & ctx = *reinterpret_cast(inContext); - TemporarySessionManager sessionManager(inSuite, ctx); + TemporarySessionManager sessionManager(*this); TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; @@ -464,98 +445,60 @@ void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) TestSecurePairingDelegate delegateAccessory; PASESession pairingAccessory; - auto & loopback = ctx.GetLoopback(); + auto & loopback = GetLoopback(); loopback.Reset(); loopback.mSentMessageCount = 0; - ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); + ExchangeContext * contextCommissioner = NewUnauthenticatedExchangeToBob(&pairingCommissioner); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = contextCommissioner->GetReliableMessageContext(); - NL_TEST_ASSERT(inSuite, rm != nullptr); - NL_TEST_ASSERT(inSuite, rc != nullptr); + ASSERT_NE(rm, nullptr); + ASSERT_NE(rc, nullptr); contextCommissioner->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({ 64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL 64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL })); - NL_TEST_ASSERT(inSuite, - ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType( - Protocols::SecureChannel::MsgType::PBKDFParamRequest, &pairingAccessory) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, - pairingAccessory.WaitForPairing( - sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, ByteSpan(sTestSpake2p01_Salt), - Optional::Missing(), &delegateAccessory) == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); - - NL_TEST_ASSERT(inSuite, - pairingCommissioner.Pair(sessionManager, 4321, Optional::Missing(), - contextCommissioner, &delegateCommissioner) == CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); - - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 0); - NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingErrors == 1); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 0); - NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingErrors == 1); + EXPECT_EQ(GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::PBKDFParamRequest, + &pairingAccessory), + CHIP_NO_ERROR); + + EXPECT_EQ(pairingAccessory.WaitForPairing(sessionManager, sTestSpake2p01_PASEVerifier, sTestSpake2p01_IterationCount, + ByteSpan(sTestSpake2p01_Salt), Optional::Missing(), + &delegateAccessory), + CHIP_NO_ERROR); + DrainAndServiceIO(); + + EXPECT_EQ(pairingCommissioner.Pair(sessionManager, 4321, Optional::Missing(), + contextCommissioner, &delegateCommissioner), + CHIP_NO_ERROR); + DrainAndServiceIO(); + + EXPECT_EQ(delegateAccessory.mNumPairingComplete, 0u); + EXPECT_EQ(delegateAccessory.mNumPairingErrors, 1u); + EXPECT_EQ(delegateCommissioner.mNumPairingComplete, 0u); + EXPECT_EQ(delegateCommissioner.mNumPairingErrors, 1u); } -void PASEVerifierSerializeTest(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPASESession, PASEVerifierSerializeTest) { Spake2pVerifier verifier; - NL_TEST_ASSERT(inSuite, verifier.Deserialize(ByteSpan(sTestSpake2p01_SerializedVerifier)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, memcmp(&verifier, &sTestSpake2p01_PASEVerifier, sizeof(Spake2pVerifier)) == 0); + EXPECT_EQ(verifier.Deserialize(ByteSpan(sTestSpake2p01_SerializedVerifier)), CHIP_NO_ERROR); + EXPECT_EQ(memcmp(&verifier, &sTestSpake2p01_PASEVerifier, sizeof(Spake2pVerifier)), 0); Spake2pVerifierSerialized serializedVerifier; MutableByteSpan serializedVerifierSpan(serializedVerifier); - NL_TEST_ASSERT(inSuite, verifier.Serialize(serializedVerifierSpan) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, serializedVerifierSpan.size() == kSpake2p_VerifierSerialized_Length); - NL_TEST_ASSERT(inSuite, memcmp(serializedVerifier, sTestSpake2p01_SerializedVerifier, kSpake2p_VerifierSerialized_Length) == 0); + EXPECT_EQ(verifier.Serialize(serializedVerifierSpan), CHIP_NO_ERROR); + EXPECT_EQ(serializedVerifierSpan.size(), kSpake2p_VerifierSerialized_Length); + EXPECT_EQ(memcmp(serializedVerifier, sTestSpake2p01_SerializedVerifier, kSpake2p_VerifierSerialized_Length), 0); Spake2pVerifierSerialized serializedVerifier2; MutableByteSpan serializedVerifier2Span(serializedVerifier2); - NL_TEST_ASSERT(inSuite, chip::Crypto::DRBG_get_bytes(serializedVerifier, kSpake2p_VerifierSerialized_Length) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, verifier.Deserialize(ByteSpan(serializedVerifier)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, verifier.Serialize(serializedVerifier2Span) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, memcmp(serializedVerifier, serializedVerifier2, kSpake2p_VerifierSerialized_Length) == 0); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(serializedVerifier, kSpake2p_VerifierSerialized_Length), CHIP_NO_ERROR); + EXPECT_EQ(verifier.Deserialize(ByteSpan(serializedVerifier)), CHIP_NO_ERROR); + EXPECT_EQ(verifier.Serialize(serializedVerifier2Span), CHIP_NO_ERROR); + EXPECT_EQ(memcmp(serializedVerifier, serializedVerifier2, kSpake2p_VerifierSerialized_Length), 0); } - -// Test Suite - -static const nlTest sTests[] = { - NL_TEST_DEF("WaitInit", SecurePairingWaitTest), - NL_TEST_DEF("Start", SecurePairingStartTest), - NL_TEST_DEF("Handshake", SecurePairingHandshakeTest), - NL_TEST_DEF("Handshake with Commissioner MRP Parameters", SecurePairingHandshakeWithCommissionerMRPTest), - NL_TEST_DEF("Handshake with Device MRP Parameters", SecurePairingHandshakeWithDeviceMRPTest), - NL_TEST_DEF("Handshake with Both MRP Parameters", SecurePairingHandshakeWithAllMRPTest), - NL_TEST_DEF("Handshake with packet loss", SecurePairingHandshakeWithPacketLossTest), - NL_TEST_DEF("Failed Handshake", SecurePairingFailedHandshake), - NL_TEST_DEF("PASE Verifier Serialize", PASEVerifierSerializeTest), - NL_TEST_SENTINEL(), -}; - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-SecurePairing-PASE", - &sTests[0], - NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite), - NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite), - NL_TEST_WRAP_METHOD(TestContext, SetUp), - NL_TEST_WRAP_METHOD(TestContext, TearDown), -}; -// clang-format on - -} // anonymous namespace - -/** - * Main - */ -int TestPASESession() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestPASESession) +} // namespace diff --git a/src/protocols/secure_channel/tests/TestPairingSession.cpp b/src/protocols/secure_channel/tests/TestPairingSession.cpp index 4a3fe88d55c7aa..5a12f61fc5c69e 100644 --- a/src/protocols/secure_channel/tests/TestPairingSession.cpp +++ b/src/protocols/secure_channel/tests/TestPairingSession.cpp @@ -22,11 +22,11 @@ */ #include -#include +#include #include #include -#include + #include #include #include @@ -36,9 +36,16 @@ using namespace chip; using namespace chip::System::Clock; -class TestPairingSession : public PairingSession +class TestPairingSession : public PairingSession, public ::testing::Test { public: + static void SetUpTestSuite() + { + CHIP_ERROR error = chip::Platform::MemoryInit(); + ASSERT_EQ(error, CHIP_NO_ERROR); + } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } + Transport::SecureSession::Type GetSecureSessionType() const override { return Transport::SecureSession::Type::kPASE; } ScopedNodeId GetPeer() const override { return ScopedNodeId(); } ScopedNodeId GetLocalScopedNodeId() const override { return ScopedNodeId(); } @@ -56,10 +63,8 @@ class TestPairingSession : public PairingSession } }; -void PairingSessionEncodeDecodeMRPParams(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPairingSession, PairingSessionEncodeDecodeMRPParams) { - TestPairingSession session; - ReliableMessageProtocolConfig config(Milliseconds32(100), Milliseconds32(200), Milliseconds16(4000)); System::PacketBufferHandle buf = System::PacketBufferHandle::New(64, 0); @@ -67,108 +72,48 @@ void PairingSessionEncodeDecodeMRPParams(nlTestSuite * inSuite, void * inContext writer.Init(buf.Retain()); TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; - NL_TEST_ASSERT(inSuite, - writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, PairingSession::EncodeSessionParameters(TLV::ContextTag(1), config, writer) == CHIP_NO_ERROR); + EXPECT_EQ(PairingSession::EncodeSessionParameters(TLV::ContextTag(1), config, writer), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.EndContainer(outerContainerType) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.Finalize(&buf) == CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(outerContainerType), CHIP_NO_ERROR); + EXPECT_EQ(writer.Finalize(&buf), CHIP_NO_ERROR); System::PacketBufferTLVReader reader; TLV::TLVType containerType = TLV::kTLVType_Structure; reader.Init(std::move(buf)); - NL_TEST_ASSERT(inSuite, reader.Next(containerType, TLV::AnonymousTag()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, reader.EnterContainer(containerType) == CHIP_NO_ERROR); + EXPECT_EQ(reader.Next(containerType, TLV::AnonymousTag()), CHIP_NO_ERROR); + EXPECT_EQ(reader.EnterContainer(containerType), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, session.DecodeMRPParametersIfPresent(TLV::ContextTag(1), reader) == CHIP_NO_ERROR); + EXPECT_EQ(reader.Next(), CHIP_NO_ERROR); + EXPECT_EQ(DecodeMRPParametersIfPresent(TLV::ContextTag(1), reader), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, session.GetRemoteMRPConfig() == config); + EXPECT_EQ(GetRemoteMRPConfig(), config); } -void PairingSessionTryDecodeMissingMRPParams(nlTestSuite * inSuite, void * inContext) +TEST_F(TestPairingSession, PairingSessionTryDecodeMissingMRPParams) { - TestPairingSession session; - System::PacketBufferHandle buf = System::PacketBufferHandle::New(64, 0); System::PacketBufferTLVWriter writer; writer.Init(buf.Retain()); TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; - NL_TEST_ASSERT(inSuite, - writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.Put(TLV::ContextTag(1), static_cast(0x1234)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.EndContainer(outerContainerType) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, writer.Finalize(&buf) == CHIP_NO_ERROR); + EXPECT_EQ(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType), CHIP_NO_ERROR); + EXPECT_EQ(writer.Put(TLV::ContextTag(1), static_cast(0x1234)), CHIP_NO_ERROR); + EXPECT_EQ(writer.EndContainer(outerContainerType), CHIP_NO_ERROR); + EXPECT_EQ(writer.Finalize(&buf), CHIP_NO_ERROR); System::PacketBufferTLVReader reader; TLV::TLVType containerType = TLV::kTLVType_Structure; reader.Init(std::move(buf)); - NL_TEST_ASSERT(inSuite, reader.Next(containerType, TLV::AnonymousTag()) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, reader.EnterContainer(containerType) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, session.DecodeMRPParametersIfPresent(TLV::ContextTag(2), reader) == CHIP_NO_ERROR); + EXPECT_EQ(reader.Next(containerType, TLV::AnonymousTag()), CHIP_NO_ERROR); + EXPECT_EQ(reader.EnterContainer(containerType), CHIP_NO_ERROR); + EXPECT_EQ(reader.Next(), CHIP_NO_ERROR); + EXPECT_EQ(DecodeMRPParametersIfPresent(TLV::ContextTag(2), reader), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, session.GetRemoteMRPConfig() == GetDefaultMRPConfig()); + EXPECT_EQ(GetRemoteMRPConfig(), GetDefaultMRPConfig()); } // Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("Encode and Decode MRP params", PairingSessionEncodeDecodeMRPParams), - NL_TEST_DEF("Decode missing MRP params", PairingSessionTryDecodeMissingMRPParams), - - NL_TEST_SENTINEL() -}; -// clang-format on - -/** - * Set up the test suite. - */ -int TestPairingSession_Setup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -int TestPairingSession_Teardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-PairingSession", - &sTests[0], - TestPairingSession_Setup, - TestPairingSession_Teardown -}; -// clang-format on - -/** - * Main - */ -int TestPairingSessionInit() -{ - // Run test suit against one context - nlTestRunner(&sSuite, nullptr); - - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestPairingSessionInit) diff --git a/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp b/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp index cb511f6993c57d..ee107f695542a9 100644 --- a/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp +++ b/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp @@ -15,8 +15,7 @@ * limitations under the License. */ -#include -#include +#include #include #include @@ -26,27 +25,27 @@ constexpr chip::NodeId node1 = 12344321; constexpr chip::FabricIndex fabric2 = 14; constexpr chip::NodeId node2 = 11223344; -void TestLink(nlTestSuite * inSuite, void * inContext) +TEST(TestSimpleSessionResumptionStorage, TestLink) { chip::TestPersistentStorageDelegate storage; chip::SimpleSessionResumptionStorage sessionStorage; sessionStorage.Init(&storage); chip::SimpleSessionResumptionStorage::ResumptionIdStorage resumptionId; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(resumptionId.data(), resumptionId.size())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(resumptionId.data(), resumptionId.size()), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.SaveLink(resumptionId, chip::ScopedNodeId(node1, fabric1))); + EXPECT_EQ(sessionStorage.SaveLink(resumptionId, chip::ScopedNodeId(node1, fabric1)), CHIP_NO_ERROR); chip::ScopedNodeId node; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.LoadLink(resumptionId, node)); - NL_TEST_ASSERT(inSuite, node == chip::ScopedNodeId(node1, fabric1)); + EXPECT_EQ(sessionStorage.LoadLink(resumptionId, node), CHIP_NO_ERROR); + EXPECT_EQ(node, chip::ScopedNodeId(node1, fabric1)); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.DeleteLink(resumptionId)); + EXPECT_EQ(sessionStorage.DeleteLink(resumptionId), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == sessionStorage.LoadLink(resumptionId, node)); + EXPECT_EQ(sessionStorage.LoadLink(resumptionId, node), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } -void TestState(nlTestSuite * inSuite, void * inContext) +TEST(TestSimpleSessionResumptionStorage, TestState) { chip::TestPersistentStorageDelegate storage; chip::SimpleSessionResumptionStorage sessionStorage; @@ -55,31 +54,30 @@ void TestState(nlTestSuite * inSuite, void * inContext) chip::ScopedNodeId node(node1, fabric1); chip::SimpleSessionResumptionStorage::ResumptionIdStorage resumptionId; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(resumptionId.data(), resumptionId.size())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(resumptionId.data(), resumptionId.size()), CHIP_NO_ERROR); chip::Crypto::P256ECDHDerivedSecret sharedSecret; sharedSecret.SetLength(sharedSecret.Capacity()); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == chip::Crypto::DRBG_get_bytes(sharedSecret.Bytes(), sharedSecret.Length())); + EXPECT_EQ(chip::Crypto::DRBG_get_bytes(sharedSecret.Bytes(), sharedSecret.Length()), CHIP_NO_ERROR); chip::CATValues peerCATs; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.SaveState(node, resumptionId, sharedSecret, peerCATs)); + EXPECT_EQ(sessionStorage.SaveState(node, resumptionId, sharedSecret, peerCATs), CHIP_NO_ERROR); chip::SimpleSessionResumptionStorage::ResumptionIdStorage resumptionId2; chip::Crypto::P256ECDHDerivedSecret sharedSecret2; chip::CATValues peerCATs2; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.LoadState(node, resumptionId2, sharedSecret2, peerCATs2)); - NL_TEST_ASSERT(inSuite, resumptionId == resumptionId2); - NL_TEST_ASSERT(inSuite, memcmp(sharedSecret.Bytes(), sharedSecret2.Bytes(), sharedSecret.Length()) == 0); + EXPECT_EQ(sessionStorage.LoadState(node, resumptionId2, sharedSecret2, peerCATs2), CHIP_NO_ERROR); + EXPECT_EQ(resumptionId, resumptionId2); + EXPECT_EQ(memcmp(sharedSecret.Bytes(), sharedSecret2.Bytes(), sharedSecret.Length()), 0); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.DeleteState(node)); + EXPECT_EQ(sessionStorage.DeleteState(node), CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, - CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == - sessionStorage.LoadState(node, resumptionId2, sharedSecret2, peerCATs2)); + EXPECT_EQ(sessionStorage.LoadState(node, resumptionId2, sharedSecret2, peerCATs2), + CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); } -void TestIndex(nlTestSuite * inSuite, void * inContext) +TEST(TestSimpleSessionResumptionStorage, TestIndex) { chip::TestPersistentStorageDelegate storage; chip::SimpleSessionResumptionStorage sessionStorage; @@ -88,63 +86,26 @@ void TestIndex(nlTestSuite * inSuite, void * inContext) chip::ScopedNodeId node(node1, fabric1); chip::DefaultSessionResumptionStorage::SessionIndex index0o; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.LoadIndex(index0o)); - NL_TEST_ASSERT(inSuite, index0o.mSize == 0); + EXPECT_EQ(sessionStorage.LoadIndex(index0o), CHIP_NO_ERROR); + EXPECT_EQ(index0o.mSize, 0u); chip::DefaultSessionResumptionStorage::SessionIndex index1; index1.mSize = 0; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.SaveIndex(index1)); + EXPECT_EQ(sessionStorage.SaveIndex(index1), CHIP_NO_ERROR); chip::DefaultSessionResumptionStorage::SessionIndex index1o; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.LoadIndex(index1o)); - NL_TEST_ASSERT(inSuite, index1o.mSize == 0); + EXPECT_EQ(sessionStorage.LoadIndex(index1o), CHIP_NO_ERROR); + EXPECT_EQ(index1o.mSize, 0u); chip::DefaultSessionResumptionStorage::SessionIndex index2; index2.mSize = 2; index2.mNodes[0] = chip::ScopedNodeId(node1, fabric1); index2.mNodes[1] = chip::ScopedNodeId(node2, fabric2); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.SaveIndex(index2)); + EXPECT_EQ(CHIP_NO_ERROR, sessionStorage.SaveIndex(index2)); chip::DefaultSessionResumptionStorage::SessionIndex index2o; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == sessionStorage.LoadIndex(index2o)); - NL_TEST_ASSERT(inSuite, index2o.mSize == 2); - NL_TEST_ASSERT(inSuite, index2o.mNodes[0] == chip::ScopedNodeId(node1, fabric1)); - NL_TEST_ASSERT(inSuite, index2o.mNodes[1] == chip::ScopedNodeId(node2, fabric2)); + EXPECT_EQ(CHIP_NO_ERROR, sessionStorage.LoadIndex(index2o)); + EXPECT_EQ(index2o.mSize, 2u); + EXPECT_EQ(index2o.mNodes[0], chip::ScopedNodeId(node1, fabric1)); + EXPECT_EQ(index2o.mNodes[1], chip::ScopedNodeId(node2, fabric2)); } // Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("TestLink", TestLink), - NL_TEST_DEF("TestState", TestState), - NL_TEST_DEF("TestIndex", TestState), - - NL_TEST_SENTINEL() -}; -// clang-format on - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-SimpleSessionResumptionStorage", - &sTests[0], - nullptr, - nullptr, -}; -// clang-format on - -/** - * Main - */ -int TestSimpleSessionResumptionStorage() -{ - // Run test suit against one context - nlTestRunner(&sSuite, nullptr); - - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestSimpleSessionResumptionStorage) diff --git a/src/protocols/secure_channel/tests/TestStatusReport.cpp b/src/protocols/secure_channel/tests/TestStatusReport.cpp index 093453029b156b..65bc639dcca7c3 100644 --- a/src/protocols/secure_channel/tests/TestStatusReport.cpp +++ b/src/protocols/secure_channel/tests/TestStatusReport.cpp @@ -19,19 +19,29 @@ #include #include #include -#include + #include #include #include #include -#include +#include using namespace chip; using namespace chip::Protocols; using namespace chip::Protocols::SecureChannel; -void TestStatusReport_NoData(nlTestSuite * inSuite, void * inContext) +struct TestStatusReport : public ::testing::Test +{ + static void SetUpTestSuite() + { + CHIP_ERROR error = chip::Platform::MemoryInit(); + ASSERT_EQ(error, CHIP_NO_ERROR); + } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + +TEST_F(TestStatusReport, NoData) { GeneralStatusCode generalCode = GeneralStatusCode::kSuccess; auto protocolId = SecureChannel::Id; @@ -44,20 +54,19 @@ void TestStatusReport_NoData(nlTestSuite * inSuite, void * inContext) testReport.WriteToBuffer(bbuf); System::PacketBufferHandle msgBuf = bbuf.Finalize(); - NL_TEST_ASSERT(inSuite, !msgBuf.IsNull()); + ASSERT_FALSE(msgBuf.IsNull()); StatusReport reportToParse; - CHIP_ERROR err = reportToParse.Parse(std::move(msgBuf)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, reportToParse.GetGeneralCode() == generalCode); - NL_TEST_ASSERT(inSuite, reportToParse.GetProtocolId() == protocolId); - NL_TEST_ASSERT(inSuite, reportToParse.GetProtocolCode() == protocolCode); + EXPECT_EQ(reportToParse.Parse(std::move(msgBuf)), CHIP_NO_ERROR); + EXPECT_EQ(reportToParse.GetGeneralCode(), generalCode); + EXPECT_EQ(reportToParse.GetProtocolId(), protocolId); + EXPECT_EQ(reportToParse.GetProtocolCode(), protocolCode); const System::PacketBufferHandle & data = reportToParse.GetProtocolData(); - NL_TEST_ASSERT(inSuite, data.IsNull()); + EXPECT_TRUE(data.IsNull()); } -void TestStatusReport_WithData(nlTestSuite * inSuite, void * inContext) +TEST_F(TestStatusReport, WithData) { GeneralStatusCode generalCode = GeneralStatusCode::kFailure; auto protocolId = SecureChannel::Id; @@ -73,39 +82,34 @@ void TestStatusReport_WithData(nlTestSuite * inSuite, void * inContext) testReport.WriteToBuffer(bbuf); System::PacketBufferHandle msgBuf = bbuf.Finalize(); - NL_TEST_ASSERT(inSuite, !msgBuf.IsNull()); + ASSERT_FALSE(msgBuf.IsNull()); StatusReport reportToParse; - CHIP_ERROR err = reportToParse.Parse(std::move(msgBuf)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, reportToParse.GetGeneralCode() == generalCode); - NL_TEST_ASSERT(inSuite, reportToParse.GetProtocolId() == protocolId); - NL_TEST_ASSERT(inSuite, reportToParse.GetProtocolCode() == protocolCode); + EXPECT_EQ(reportToParse.Parse(std::move(msgBuf)), CHIP_NO_ERROR); + EXPECT_EQ(reportToParse.GetGeneralCode(), generalCode); + EXPECT_EQ(reportToParse.GetProtocolId(), protocolId); + EXPECT_EQ(reportToParse.GetProtocolCode(), protocolCode); const System::PacketBufferHandle & rcvData = reportToParse.GetProtocolData(); - if (rcvData.IsNull()) - { - NL_TEST_ASSERT(inSuite, false); - return; - } - NL_TEST_ASSERT(inSuite, rcvData->DataLength() == dataLen); - NL_TEST_ASSERT(inSuite, !memcmp(rcvData->Start(), data, dataLen)); + ASSERT_FALSE(rcvData.IsNull()); + EXPECT_EQ(rcvData->DataLength(), dataLen); + EXPECT_EQ(memcmp(rcvData->Start(), data, dataLen), 0); } -void TestBadStatusReport(nlTestSuite * inSuite, void * inContext) +TEST_F(TestStatusReport, TestBadStatusReport) { StatusReport report; System::PacketBufferHandle badMsg = System::PacketBufferHandle::New(10); CHIP_ERROR err = report.Parse(std::move(badMsg)); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); StatusReport report2; badMsg = nullptr; err = report2.Parse(std::move(badMsg)); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); + EXPECT_NE(err, CHIP_NO_ERROR); } -void TestMakeBusyStatusReport(nlTestSuite * inSuite, void * inContext) +TEST_F(TestStatusReport, TestMakeBusyStatusReport) { GeneralStatusCode generalCode = GeneralStatusCode::kBusy; auto protocolId = SecureChannel::Id; @@ -113,81 +117,22 @@ void TestMakeBusyStatusReport(nlTestSuite * inSuite, void * inContext) System::Clock::Milliseconds16 minimumWaitTime = System::Clock::Milliseconds16(5000); System::PacketBufferHandle handle = StatusReport::MakeBusyStatusReportMessage(minimumWaitTime); - NL_TEST_ASSERT(inSuite, !handle.IsNull()); + ASSERT_FALSE(handle.IsNull()); StatusReport reportToParse; - CHIP_ERROR err = reportToParse.Parse(std::move(handle)); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == err); - NL_TEST_ASSERT(inSuite, reportToParse.GetGeneralCode() == generalCode); - NL_TEST_ASSERT(inSuite, reportToParse.GetProtocolId() == protocolId); - NL_TEST_ASSERT(inSuite, reportToParse.GetProtocolCode() == protocolCode); + EXPECT_EQ(reportToParse.Parse(std::move(handle)), CHIP_NO_ERROR); + EXPECT_EQ(reportToParse.GetGeneralCode(), generalCode); + EXPECT_EQ(reportToParse.GetProtocolId(), protocolId); + EXPECT_EQ(reportToParse.GetProtocolCode(), protocolCode); const System::PacketBufferHandle & rcvData = reportToParse.GetProtocolData(); - NL_TEST_ASSERT(inSuite, !rcvData.IsNull()); - NL_TEST_ASSERT(inSuite, rcvData->DataLength() == sizeof(minimumWaitTime)); + ASSERT_FALSE(rcvData.IsNull()); + EXPECT_EQ(rcvData->DataLength(), sizeof(minimumWaitTime)); uint16_t readMinimumWaitTime = 0; Encoding::LittleEndian::Reader reader(rcvData->Start(), rcvData->DataLength()); - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == reader.Read16(&readMinimumWaitTime).StatusCode()); - NL_TEST_ASSERT(inSuite, System::Clock::Milliseconds16(readMinimumWaitTime) == minimumWaitTime); + EXPECT_EQ(reader.Read16(&readMinimumWaitTime).StatusCode(), CHIP_NO_ERROR); + EXPECT_EQ(System::Clock::Milliseconds16(readMinimumWaitTime), minimumWaitTime); } // Test Suite - -/** - * Test Suite that lists all the test functions. - */ -// clang-format off -static const nlTest sTests[] = -{ - NL_TEST_DEF("TestStatusReport_NoData", TestStatusReport_NoData), - NL_TEST_DEF("TestStatusReport_WithData", TestStatusReport_WithData), - NL_TEST_DEF("TestBadStatusReport", TestBadStatusReport), - NL_TEST_DEF("TestMakeBusyStatusReport", TestMakeBusyStatusReport), - - NL_TEST_SENTINEL() -}; -// clang-format on - -/** - * Set up the test suite. - */ -static int TestSetup(void * inContext) -{ - CHIP_ERROR error = chip::Platform::MemoryInit(); - if (error != CHIP_NO_ERROR) - return FAILURE; - return SUCCESS; -} - -/** - * Tear down the test suite. - */ -static int TestTeardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -// clang-format off -static nlTestSuite sSuite = -{ - "Test-CHIP-StatusReport", - &sTests[0], - TestSetup, - TestTeardown, -}; -// clang-format on - -/** - * Main - */ -int TestStatusReport() -{ - // Run test suit against one context - nlTestRunner(&sSuite, nullptr); - - return (nlTestRunnerStats(&sSuite)); -} - -CHIP_REGISTER_TEST_SUITE(TestStatusReport) diff --git a/src/pybindings/pycontroller/build-chip-wheel.py b/src/pybindings/pycontroller/build-chip-wheel.py index a61b591d5c5368..61bdf373e8615c 100644 --- a/src/pybindings/pycontroller/build-chip-wheel.py +++ b/src/pybindings/pycontroller/build-chip-wheel.py @@ -60,7 +60,6 @@ def __init__(self, name): chipPackageVer = args.build_number installScripts = [ - # InstalledScriptInfo('chip-device-ctrl.py'), # InstalledScriptInfo('chip-repl.py'), ] diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 1db208fa39f40b..42fddd7e31ee4b 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -80,9 +80,20 @@ def record_warning(location, problem): provisional_cluster_ids = [Clusters.ContentControl.id, Clusters.ScenesManagement.id, Clusters.BallastConfiguration.id, Clusters.EnergyPreference.id, Clusters.DeviceEnergyManagement.id, Clusters.DeviceEnergyManagementMode.id, Clusters.PulseWidthModulation.id, Clusters.ProxyConfiguration.id, Clusters.ProxyDiscovery.id, Clusters.ProxyValid.id] + # TODO: Remove this once the latest 1.3 lands with the clusters removed from the DM XML and change the warning below about missing DM XMLs into a proper error + # These are clusters that weren't part of the 1.3 spec that landed in the SDK before the branch cut + provisional_cluster_ids.extend([Clusters.DemandResponseLoadControl.id]) + # These clusters are zigbee only. I don't even know why they're part of the codegen, but we should get rid of them. + provisional_cluster_ids.extend([Clusters.BarrierControl.id, Clusters.OnOffSwitchConfiguration.id, + Clusters.BinaryInputBasic.id, Clusters.ElectricalMeasurement.id]) for endpoint_id, endpoint in self.endpoints_tlv.items(): for cluster_id, cluster in endpoint.items(): cluster_location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id) + + if not allow_provisional and cluster_id in provisional_cluster_ids: + record_error(location=cluster_location, problem='Provisional cluster found on device') + continue + if cluster_id not in self.xml_clusters.keys(): if (cluster_id & 0xFFFF_0000) != 0: # manufacturer cluster @@ -92,9 +103,6 @@ def record_warning(location, problem): problem='Standard cluster found on device, but is not present in spec data') continue - if not allow_provisional and cluster_id in provisional_cluster_ids: - record_error(location=cluster_location, problem='Provisional cluster found on device') - feature_map = cluster[GlobalAttributeIds.FEATURE_MAP_ID] attribute_list = cluster[GlobalAttributeIds.ATTRIBUTE_LIST_ID] all_command_list = cluster[GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID] + \ diff --git a/src/python_testing/TC_IDM_1_2.py b/src/python_testing/TC_IDM_1_2.py index 8f329daca51101..87ede456dacb1a 100644 --- a/src/python_testing/TC_IDM_1_2.py +++ b/src/python_testing/TC_IDM_1_2.py @@ -236,8 +236,11 @@ async def test_TC_IDM_1_2(self): # Lucky candidate ArmFailSafe is at it again - command side effect is to set breadcrumb attribute cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900, breadcrumb=2) - await self.default_controller.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=cmd, suppressResponse=True) - # TODO: Once the above issue is resolved, this needs a check to ensure that no response was received. + try: + await self.default_controller.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=cmd, suppressResponse=True) + # TODO: Once the above issue is resolved, this needs a check to ensure that (always) no response was received. + except ChipStackError: + logging.info("DUT correctly supressed the response") # Verify that the command had the correct side effect even if a response was sent breadcrumb = await self.read_single_attribute_check_success( diff --git a/src/python_testing/TC_IDM_1_4.py b/src/python_testing/TC_IDM_1_4.py index 507b5d74254abf..34d75f7d8f6184 100644 --- a/src/python_testing/TC_IDM_1_4.py +++ b/src/python_testing/TC_IDM_1_4.py @@ -74,7 +74,11 @@ async def test_TC_IDM_1_4(self): cap_for_batch_commands = 100 number_of_commands_to_send = min(max_paths_per_invoke + 1, cap_for_batch_commands) - invalid_command_id = 0xffff_ffff + # Use a valid (according to MEI definition) command-id (in this case belonging to Test Vendor MC with prefix 0xfff4) + # which should never be existing on a prodiction device. We use this decodable id to prevent hitting issues with the + # specification being not clearly defined in respect to decoding vs processing the invoke requests. + invalid_command_id = 0xfff4_00ff + list_of_commands_to_send = [] for endpoint_index in range(number_of_commands_to_send): # Using Toggle command to form the base as it is a command that doesn't take diff --git a/src/python_testing/TC_OPSTATE_1_1.py b/src/python_testing/TC_OPSTATE_1_1.py deleted file mode 100644 index 67caefc85862b5..00000000000000 --- a/src/python_testing/TC_OPSTATE_1_1.py +++ /dev/null @@ -1,53 +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. -# - - -import chip.clusters as Clusters -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo - - -class TC_OPSTATE_1_1(MatterBaseTest, TC_OPSTATE_BASE): - def __init__(self, *args): - super().__init__(*args) - - test_info = TestInfo( - pics_code="OPSTATE", - cluster=Clusters.OperationalState - ) - - super().setup_base(test_info=test_info) - - def steps_TC_OPSTATE_1_1(self) -> list[TestStep]: - return self.STEPS_TC_OPSTATE_BASE_1_1() - - def pics_TC_OPSTATE_1_1(self) -> list[str]: - return ["OPSTATE.S"] - - @async_test_body - async def test_TC_OPSTATE_1_1(self): - endpoint = self.matter_test_config.endpoint - cluster_revision = 2 - feature_map = 0 - - await self.TEST_TC_OPSTATE_BASE_1_1(endpoint=endpoint, - cluster_revision=cluster_revision, - feature_map=feature_map) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_1_1.py b/src/python_testing/TC_OVENOPSTATE_1_1.py deleted file mode 100644 index 3e6b0a27fbab5d..00000000000000 --- a/src/python_testing/TC_OVENOPSTATE_1_1.py +++ /dev/null @@ -1,53 +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. -# - - -import chip.clusters as Clusters -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo - - -class TC_OVENOPSTATE_1_1(MatterBaseTest, TC_OPSTATE_BASE): - def __init__(self, *args): - super().__init__(*args) - - test_info = TestInfo( - pics_code="OVENOPSTATE", - cluster=Clusters.OvenCavityOperationalState - ) - - super().setup_base(test_info=test_info) - - def steps_TC_OVENOPSTATE_1_1(self) -> list[TestStep]: - return self.STEPS_TC_OPSTATE_BASE_1_1() - - def pics_TC_OVENOPSTATE_1_1(self) -> list[str]: - return ["OVENOPSTATE.S"] - - @async_test_body - async def test_TC_OVENOPSTATE_1_1(self): - endpoint = self.matter_test_config.endpoint - cluster_revision = 1 - feature_map = 0 - - await self.TEST_TC_OPSTATE_BASE_1_1(endpoint=endpoint, - cluster_revision=cluster_revision, - feature_map=feature_map) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py index d85d1ae53cb928..6680ada707a85e 100644 --- a/src/python_testing/TC_RVCRUNM_2_2.py +++ b/src/python_testing/TC_RVCRUNM_2_2.py @@ -154,7 +154,8 @@ async def test_TC_RVCRUNM_2_2(self): if self.mode_a not in self.supported_run_modes_dut or \ self.mode_b not in self.supported_run_modes_dut: - asserts.fail("PIXIT.RVCRUNM.MODE_A and PIXIT.RVCRUNM.MODE_B must be valid supported modes.") + asserts.fail( + f"PIXIT.RVCRUNM.MODE_A and PIXIT.RVCRUNM.MODE_B must be valid supported modes. Valid modes: {self.supported_run_modes_dut}, MODE_A: {self.mode_a}, MODE_B: {self.mode_b}") for tag in self.supported_run_modes[self.mode_a].modeTags: if tag.value == Clusters.RvcRunMode.Enums.ModeTag.kIdle: diff --git a/src/python_testing/TC_SC_3_6.py b/src/python_testing/TC_SC_3_6.py index a6994cbf288539..ec09d4bb8e815e 100644 --- a/src/python_testing/TC_SC_3_6.py +++ b/src/python_testing/TC_SC_3_6.py @@ -20,6 +20,7 @@ import queue import time from threading import Event +from typing import List import chip.clusters as Clusters from chip.clusters import ClusterObjects as ClustersObjects @@ -123,6 +124,24 @@ async def test_TC_SC_3_6(self): ) asserts.assert_greater_equal(capability_minima.caseSessionsPerFabric, 3) + logging.info("Pre-condition: Remove all pre-existing fabrics on the device that do not belong to the TH") + commissioned_fabric_count: int = await self.read_single_attribute( + dev_ctrl, node_id=self.dut_node_id, + endpoint=0, attribute=Clusters.OperationalCredentials.Attributes.CommissionedFabrics) + + if commissioned_fabric_count > 1: + fabrics: List[Clusters.OperationalCredentials.Structs.FabricDescriptorStruct] = await self.read_single_attribute( + dev_ctrl, node_id=self.dut_node_id, endpoint=0, + attribute=Clusters.OperationalCredentials.Attributes.Fabrics, fabricFiltered=False) + current_fabric_index = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.CurrentFabricIndex) + for fabric in fabrics: + if fabric.fabricIndex == current_fabric_index: + continue + # This is not the test client's fabric, so remove it. + logging.info(f"Removing extra fabric at {fabric.fabricIndex} from device.") + await dev_ctrl.SendCommand( + self.dut_node_id, 0, Clusters.OperationalCredentials.Commands.RemoveFabric(fabricIndex=fabric.fabricIndex)) + logging.info("Pre-conditions: use existing fabric to configure new fabrics so that total is %d fabrics" % num_fabrics_to_commission) diff --git a/src/python_testing/TestConformanceSupport.py b/src/python_testing/TestConformanceSupport.py index b383f1acb63cc7..f71eb3ed1d531f 100644 --- a/src/python_testing/TestConformanceSupport.py +++ b/src/python_testing/TestConformanceSupport.py @@ -17,7 +17,7 @@ import xml.etree.ElementTree as ElementTree -from conformance_support import ConformanceDecision, ConformanceParseParameters, parse_callable_from_xml +from conformance_support import ConformanceDecision, ConformanceException, ConformanceParseParameters, parse_callable_from_xml from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -616,6 +616,61 @@ def test_conformance_otherwise(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.PROVISIONAL) asserts.assert_equal(str(xml_callable), 'AB & !CD, P') + def test_conformance_greater(self): + # AB, [CD] + xml = ('' + '' + '' + '' + '' + '') + et = ElementTree.fromstring(xml) + xml_callable = parse_callable_from_xml(et, self.params) + # TODO: switch this to check greater than once the update to the base is done (#33422) + asserts.assert_equal(xml_callable(0x00, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(str(xml_callable), 'attr1 > 1') + + # Ensure that we can only have greater terms with exactly 2 value + xml = ('' + '' + '' + '' + '' + '' + '') + et = ElementTree.fromstring(xml) + try: + xml_callable = parse_callable_from_xml(et, self.params) + asserts.fail("Incorrectly parsed bad greaterTerm XML with > 2 values") + except ConformanceException: + pass + + xml = ('' + '' + '' + '' + '') + et = ElementTree.fromstring(xml) + try: + xml_callable = parse_callable_from_xml(et, self.params) + asserts.fail("Incorrectly parsed bad greaterTerm XML with < 2 values") + except ConformanceException: + pass + + # Only attributes and literals allowed because arithmetic operations require values + xml = ('' + '' + '' + '' + '' + '') + et = ElementTree.fromstring(xml) + try: + xml_callable = parse_callable_from_xml(et, self.params) + asserts.fail("Incorrectly parsed greater term with feature value") + except ConformanceException: + pass + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TestIdChecks.py b/src/python_testing/TestIdChecks.py new file mode 100644 index 00000000000000..8969807d5819e3 --- /dev/null +++ b/src/python_testing/TestIdChecks.py @@ -0,0 +1,214 @@ +# +# 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. +# + +from global_attribute_ids import (AttributeIdType, ClusterIdType, DeviceTypeIdType, attribute_id_type, cluster_id_type, + device_type_id_type, is_valid_attribute_id, is_valid_cluster_id, is_valid_device_type_id) +from matter_testing_support import MatterBaseTest, default_matter_test_main +from mobly import asserts + + +class TestIdChecks(MatterBaseTest): + def test_device_type_ids(self): + standard_good = [0x0000_0000, 0x0000_BFFF] + standard_bad = [0x0000_C000] + + manufacturer_good = [0x0001_0000, 0x0001_BFFF, 0xFFF0_0000, 0xFFF0_BFFF] + manufacturer_bad = [0x0001_C000, 0xFFF0_C000] + + test_good = [0xFFF1_0000, 0xFFF1_BFFF, 0xFFF4_0000, 0xFFF4_BFFF] + test_bad = [0xFFF1_C000, 0xFFF4_C000] + + prefix_bad = [0xFFF5_0000, 0xFFF5_BFFFF, 0xFFF5_C000] + + def check_standard(id): + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting standard {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kStandard, msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=False), msg) + + def check_manufacturer(id): + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kManufacturer, msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=False), msg) + + def check_test(id): + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kTest, msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_device_type_id(id_type, allow_test=False), msg) + + def check_all_bad(id): + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kInvalid, msg) + asserts.assert_false(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_device_type_id(id_type, allow_test=False), msg) + + for id in standard_good: + check_standard(id) + + for id in standard_bad: + check_all_bad(id) + + for id in manufacturer_good: + check_manufacturer(id) + + for id in manufacturer_bad: + check_all_bad(id) + + for id in test_good: + check_test(id) + + for id in test_bad: + check_all_bad(id) + + for id in prefix_bad: + check_all_bad(id) + + def test_cluster_ids(self): + standard_good = [0x0000_0000, 0x0000_7FFF] + standard_bad = [0x0000_8000] + + manufacturer_good = [0x0001_FC00, 0x0001_FFFE, 0xFFF0_FC00, 0xFFF0_FFFE] + manufacturer_bad = [0x0001_0000, 0x0001_7FFF, 0x0001_FFFF, 0xFFF0_0000, 0xFFF0_7FFF, 0xFFF0_FFFF] + + test_good = [0xFFF1_FC00, 0xFFF1_FFFE, 0xFFF4_FC00, 0xFFF4_FFFE] + test_bad = [0xFFF1_0000, 0xFFF1_7FFF, 0xFFF1_FFFF, 0xFFF4_0000, 0xFFF4_7FFF, 0xFFF4_FFFF] + + prefix_bad = [0xFFF5_0000, 0xFFF5_FC00, 0xFFF5_FFFF] + + def check_standard(id): + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting standard {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kStandard, msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=False), msg) + + def check_manufacturer(id): + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kManufacturer, msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=False), msg) + + def check_test(id): + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kTest, msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_cluster_id(id_type, allow_test=False), msg) + + def check_all_bad(id): + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kInvalid, msg) + asserts.assert_false(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_cluster_id(id_type, allow_test=False), msg) + + for id in standard_good: + check_standard(id) + + for id in standard_bad: + check_all_bad(id) + + for id in manufacturer_good: + check_manufacturer(id) + + for id in manufacturer_bad: + check_all_bad(id) + + for id in test_good: + check_test(id) + + for id in test_bad: + check_all_bad(id) + + for id in prefix_bad: + check_all_bad(id) + + def test_attribute_ids(self): + standard_global_good = [0x0000_F000, 0x0000_FFFE] + standard_global_bad = [0x0000_FFFF] + standard_non_global_good = [0x0000_0000, 0x0000_4FFF] + standard_non_global_bad = [0x0000_5000] + manufacturer_good = [0x0001_0000, 0x0001_4FFF, 0xFFF0_0000, 0xFFF0_4FFF] + manufacturer_bad = [0x0001_5000, 0x0001_F000, 0x0001_FFFFF, 0xFFF0_5000, 0xFFF0_F000, 0xFFF0_FFFF] + test_good = [0xFFF1_0000, 0xFFF1_4FFF, 0xFFF4_0000, 0xFFF4_4FFF] + test_bad = [0xFFF1_5000, 0xFFF1_F000, 0xFFF1_FFFFF, 0xFFF4_5000, 0xFFF4_F000, 0xFFF4_FFFF] + prefix_bad = [0xFFF5_0000, 0xFFF5_4FFF, 0xFFF5_5000, 0xFFF5_F000, 0xFFF5_FFFF] + + def check_standard_global(id): + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting standard global {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kStandardGlobal, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=False), msg) + + def check_standard_non_global(id): + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting standard non-global {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kStandardNonGlobal, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=False), msg) + + def check_manufacturer(id): + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kManufacturer, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=False), msg) + + def check_test(id): + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kTest, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_attribute_id(id_type, allow_test=False), msg) + + def check_all_bad(id): + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kInvalid, msg) + asserts.assert_false(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_attribute_id(id_type, allow_test=False), msg) + + for id in standard_global_good: + check_standard_global(id) + for id in standard_global_bad: + check_all_bad(id) + for id in standard_non_global_good: + check_standard_non_global(id) + for id in standard_non_global_bad: + check_all_bad(id) + for id in manufacturer_good: + check_manufacturer(id) + for id in manufacturer_bad: + check_all_bad(id) + for id in test_good: + check_test(id) + for id in test_bad: + check_all_bad(id) + for id in prefix_bad: + check_all_bad(id) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/conformance_support.py b/src/python_testing/conformance_support.py index 89157c226351b1..025c1afa678995 100644 --- a/src/python_testing/conformance_support.py +++ b/src/python_testing/conformance_support.py @@ -33,10 +33,12 @@ AND_TERM = 'andTerm' OR_TERM = 'orTerm' NOT_TERM = 'notTerm' +GREATER_TERM = 'greaterTerm' FEATURE_TAG = 'feature' ATTRIBUTE_TAG = 'attribute' COMMAND_TAG = 'command' CONDITION_TAG = 'condition' +LITERAL_TAG = 'literal' class ConformanceException(Exception): @@ -123,6 +125,18 @@ def __str__(self): return 'P' +class literal: + def __init__(self, value: str): + self.value = int(value) + + def __call__(self): + # This should never be called + raise ConformanceException('Literal conformance function should not be called - this is simply a value holder') + + def __str__(self): + return str(self.value) + + class feature: def __init__(self, requiredFeature: uint, code: str): self.requiredFeature = requiredFeature @@ -267,8 +281,25 @@ def __str__(self): op_strs = [str(op) for op in self.op_list] return f'({" | ".join(op_strs)})' -# TODO: add xor operation once it's required -# TODO: how would equal and unequal operations work here? + +class greater_operation: + def _type_ok(self, op: Callable): + return type(op) == attribute or type(op) == literal + + def __init__(self, op1: Callable, op2: Callable): + if not self._type_ok(op1) or not self._type_ok(op2): + raise ConformanceException('Arithmetic operations can only have attribute or literal value children') + self.op1 = op1 + self.op2 = op2 + + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + # For now, this is fully optional, need to implement this properly later, but it requires access to the actual attribute values + # We need to reach into the attribute, but can't use it directly because the attribute callable is an EXISTENCE check and + # the arithmetic functions require a value. + return ConformanceDecision.OPTIONAL + + def __str__(self): + return f'{str(self.op1)} > {str(self.op2)}' class otherwise: @@ -325,6 +356,8 @@ def parse_callable_from_xml(element: ElementTree.Element, params: ConformancePar return command(params.command_map[element.get('name')], element.get('name')) elif element.tag == CONDITION_TAG and element.get('name').lower() == 'zigbee': return zigbee() + elif element.tag == LITERAL_TAG: + return literal(element.get('value')) else: raise ConformanceException( f'Unexpected xml conformance element with no children {str(element.tag)} {str(element.attrib)}') @@ -354,5 +387,9 @@ def parse_callable_from_xml(element: ElementTree.Element, params: ConformancePar return not_operation(ops[0]) elif element.tag == OTHERWISE_CONFORM: return otherwise(ops) + elif element.tag == GREATER_TERM: + if len(ops) != 2: + raise ConformanceException(f'Greater than term found with more than two subelements {list(element)}') + return greater_operation(ops[0], ops[1]) else: raise ConformanceException(f'Unexpected conformance tag with children {element}') diff --git a/src/python_testing/global_attribute_ids.py b/src/python_testing/global_attribute_ids.py index 851148bd8f290f..e692adfdfb5a10 100644 --- a/src/python_testing/global_attribute_ids.py +++ b/src/python_testing/global_attribute_ids.py @@ -17,7 +17,7 @@ # This file should be removed once we have a good way to get this from the codegen or XML -from enum import IntEnum +from enum import Enum, IntEnum, auto class GlobalAttributeIds(IntEnum): @@ -38,3 +38,110 @@ def to_name(self) -> str: return "FeatureMap" if self == GlobalAttributeIds.CLUSTER_REVISION_ID: return "ClusterRevision" + + +class DeviceTypeIdType(Enum): + kInvalid = auto(), + kStandard = auto(), + kManufacturer = auto(), + kTest = auto(), + + +class ClusterIdType(Enum): + kInvalid = auto() + kStandard = auto(), + kManufacturer = auto(), + kTest = auto(), + + +class AttributeIdType(Enum): + kInvalid = auto() + kStandardGlobal = auto(), + kStandardNonGlobal = auto(), + kManufacturer = auto(), + kTest = auto(), + +# ID helper classes - this allows us to use the values from the prefix and suffix table directly +# because the class handles the non-inclusive range. + + +class IdRange(): + def __init__(self, min, max): + self.min_max = range(min, max+1) + + def __contains__(self, key): + return key in self.min_max + + +class PrefixIdRange(IdRange): + def __contains__(self, id: int): + return super().__contains__(id >> 16) + + +class SuffixIdRange(IdRange): + def __contains__(self, id: int): + return super().__contains__(id & 0xFFFF) + + +STANDARD_PREFIX = PrefixIdRange(0x0000, 0x0000) +MANUFACTURER_PREFIX = PrefixIdRange(0x0001, 0xFFF0) +TEST_PREFIX = PrefixIdRange(0xFFF1, 0xFFF4) + +DEVICE_TYPE_ID_RANGE_SUFFIX = SuffixIdRange(0x0000, 0xBFFF) +CLUSTER_ID_STANDARD_RANGE_SUFFIX = SuffixIdRange(0x0000, 0x7FFF) +CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX = SuffixIdRange(0xFC00, 0xFFFE) +ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0xF000, 0xFFFE) +ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0x0000, 0x4FFF) + + +def device_type_id_type(id: int) -> DeviceTypeIdType: + if id in STANDARD_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX: + return DeviceTypeIdType.kStandard + if id in MANUFACTURER_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX: + return DeviceTypeIdType.kManufacturer + if id in TEST_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX: + return DeviceTypeIdType.kTest + return DeviceTypeIdType.kInvalid + + +def is_valid_device_type_id(id_type: DeviceTypeIdType, allow_test=False) -> bool: + valid = [DeviceTypeIdType.kStandard, DeviceTypeIdType.kManufacturer] + if allow_test: + valid.append(DeviceTypeIdType.kTest) + return id_type in valid + + +def cluster_id_type(id: int) -> ClusterIdType: + if id in STANDARD_PREFIX and id in CLUSTER_ID_STANDARD_RANGE_SUFFIX: + return ClusterIdType.kStandard + if id in MANUFACTURER_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX: + return ClusterIdType.kManufacturer + if id in TEST_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX: + return ClusterIdType.kTest + return ClusterIdType.kInvalid + + +def is_valid_cluster_id(id_type: ClusterIdType, allow_test: bool = False) -> bool: + valid = [ClusterIdType.kStandard, ClusterIdType.kManufacturer] + if allow_test: + valid.append(ClusterIdType.kTest) + return id_type in valid + + +def attribute_id_type(id: int) -> AttributeIdType: + if id in STANDARD_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kStandardNonGlobal + if id in STANDARD_PREFIX and id in ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kStandardGlobal + if id in MANUFACTURER_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kManufacturer + if id in TEST_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kTest + return AttributeIdType.kInvalid + + +def is_valid_attribute_id(id_type: AttributeIdType, allow_test: bool = False): + valid = [AttributeIdType.kStandardGlobal, AttributeIdType.kStandardNonGlobal, AttributeIdType.kManufacturer] + if allow_test: + valid.append(AttributeIdType.kTest) + return id_type in valid diff --git a/src/setup_payload/python/Base38.py b/src/setup_payload/python/Base38.py index 23113f7ed25c8d..834ae9e1d520e7 100644 --- a/src/setup_payload/python/Base38.py +++ b/src/setup_payload/python/Base38.py @@ -24,6 +24,7 @@ RADIX = len(CODES) BASE38_CHARS_NEEDED_IN_CHUNK = [2, 4, 5] MAX_BYTES_IN_CHUNK = 3 +MAX_ENCODED_BYTES_IN_CHUNK = 5 def encode(bytes): @@ -47,3 +48,25 @@ def encode(bytes): base38_chars_needed -= 1 return qrcode + + +def decode(qrcode): + total_chars = len(qrcode) + decoded_bytes = bytearray() + + for i in range(0, total_chars, MAX_ENCODED_BYTES_IN_CHUNK): + if (i + MAX_ENCODED_BYTES_IN_CHUNK) > total_chars: + chars_in_chunk = total_chars - i + else: + chars_in_chunk = MAX_ENCODED_BYTES_IN_CHUNK + + value = 0 + for j in range(i + chars_in_chunk - 1, i - 1, -1): + value = value * RADIX + CODES.index(qrcode[j]) + + bytes_in_chunk = BASE38_CHARS_NEEDED_IN_CHUNK.index(chars_in_chunk) + 1 + for k in range(0, bytes_in_chunk): + decoded_bytes.append(value & 0xFF) + value = value >> 8 + + return decoded_bytes diff --git a/src/setup_payload/python/README.md b/src/setup_payload/python/README.md index 068bf553fb7e6b..a39496104300d1 100644 --- a/src/setup_payload/python/README.md +++ b/src/setup_payload/python/README.md @@ -1,19 +1,22 @@ -## Python tool to generate Matter onboarding codes +## Python tool to generate and parse Matter onboarding codes -Generates Manual Pairing Code and QR Code +Generates and parses Manual Pairing Code and QR Code #### example usage: +- Parse + ``` -./generate_setup_payload.py -h -./generate_setup_payload.py -d 3840 -p 20202021 -cf 0 -dm 2 -vid 65521 -pid 32768 +./SetupPayload.py parse MT:U9VJ0OMV172PX813210 +./SetupPayload.py parse 34970112332 ``` -- Output +- Generate ``` -Manualcode : 34970112332 -QRCode : MT:Y.K9042C00KA0648G00 +./SetupPayload.py generate --help +./SetupPayload.py generate -d 3840 -p 20202021 +./SetupPayload.py generate -d 3840 -p 20202021 --vendor-id 65521 --product-id 32768 -cf 0 -dm 2 ``` For more details please refer Matter Specification diff --git a/src/setup_payload/python/SetupPayload.py b/src/setup_payload/python/SetupPayload.py new file mode 100755 index 00000000000000..82a58d957eff08 --- /dev/null +++ b/src/setup_payload/python/SetupPayload.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import enum + +import Base38 +import click +from bitarray import bitarray +from bitarray.util import int2ba, zeros +from construct import BitsInteger, BitStruct, Enum +from stdnum.verhoeff import calc_check_digit + +# Format for constructing manualcode +manualcode_format = BitStruct( + 'version' / BitsInteger(1), + 'vid_pid_present' / BitsInteger(1), + 'discriminator' / BitsInteger(4), + 'pincode_lsb' / BitsInteger(14), + 'pincode_msb' / BitsInteger(13), + 'vid' / BitsInteger(16), + 'pid' / BitsInteger(16), + 'padding' / BitsInteger(7), # this is intentional as BitStruct only takes 8-bit aligned data +) + +# Format for constructing qrcode +# qrcode bytes are packed as lsb....msb, hence the order is reversed +qrcode_format = BitStruct( + 'padding' / BitsInteger(4), + 'pincode' / BitsInteger(27), + 'discriminator' / BitsInteger(12), + 'discovery' / BitsInteger(8), + 'flow' / Enum(BitsInteger(2), + Standard=0, UserIntent=1, Custom=2), + 'pid' / BitsInteger(16), + 'vid' / BitsInteger(16), + 'version' / BitsInteger(3), +) + + +class CommissioningFlow(enum.IntEnum): + Standard = 0, + UserIntent = 1, + Custom = 2 + + +class SetupPayload: + def __init__(self, discriminator, pincode, rendezvous=4, flow=CommissioningFlow.Standard, vid=0, pid=0): + self.long_discriminator = discriminator + self.short_discriminator = discriminator >> 8 + self.pincode = pincode + self.discovery = rendezvous + self.flow = flow + self.vid = vid + self.pid = pid + + def p_print(self): + print('{:<{}} :{}'.format('Flow', 24, self.flow)) + print('{:<{}} :{}'.format('Pincode', 24, self.pincode)) + print('{:<{}} :{}'.format('Short Discriminator', 24, self.short_discriminator)) + if self.long_discriminator: + print('{:<{}} :{}'.format('Long Discriminator', 24, self.long_discriminator)) + if self.discovery: + print('{:<{}} :{}'.format('Discovery Capabilities', 24, self.discovery)) + if self.vid is not None and self.pid is not None: + print('{:<{}} :{:<{}} (0x{:04x})'.format('Vendor Id', 24, self.vid, 6, self.vid)) + print('{:<{}} :{:<{}} (0x{:04x})'.format('Product Id', 24, self.pid, 6, self.pid)) + + def qrcode_dict(self): + return { + 'version': 0, + 'vid': self.vid, + 'pid': self.pid, + 'flow': int(self.flow), + 'discovery': self.discovery, + 'discriminator': self.long_discriminator, + 'pincode': self.pincode, + 'padding': 0, + } + + def manualcode_dict(self): + return { + 'version': 0, + 'vid_pid_present': 0 if self.flow == CommissioningFlow.Standard else 1, + 'discriminator': self.short_discriminator, + 'pincode_lsb': self.pincode & 0x3FFF, # 14 ls-bits + 'pincode_msb': self.pincode >> 14, # 13 ms-bits + 'vid': 0 if self.flow == CommissioningFlow.Standard else self.vid, + 'pid': 0 if self.flow == CommissioningFlow.Standard else self.pid, + 'padding': 0, + } + + def generate_qrcode(self): + data = qrcode_format.build(self.qrcode_dict()) + b38_encoded = Base38.encode(data[::-1]) # reversing + return 'MT:{}'.format(b38_encoded) + + def generate_manualcode(self): + CHUNK1_START = 0 + CHUNK1_LEN = 4 + CHUNK2_START = CHUNK1_START + CHUNK1_LEN + CHUNK2_LEN = 16 + CHUNK3_START = CHUNK2_START + CHUNK2_LEN + CHUNK3_LEN = 13 + + bytes = manualcode_format.build(self.manualcode_dict()) + bits = bitarray() + bits.frombytes(bytes) + + chunk1 = str(int(bits[CHUNK1_START:CHUNK1_START + CHUNK1_LEN].to01(), 2)).zfill(1) + chunk2 = str(int(bits[CHUNK2_START:CHUNK2_START + CHUNK2_LEN].to01(), 2)).zfill(5) + chunk3 = str(int(bits[CHUNK3_START:CHUNK3_START + CHUNK3_LEN].to01(), 2)).zfill(4) + chunk4 = str(self.vid).zfill(5) if self.flow != CommissioningFlow.Standard else '' + chunk5 = str(self.pid).zfill(5) if self.flow != CommissioningFlow.Standard else '' + payload = '{}{}{}{}{}'.format(chunk1, chunk2, chunk3, chunk4, chunk5) + return '{}{}'.format(payload, calc_check_digit(payload)) + + @staticmethod + def from_container(container, is_qrcode): + payload = None + if is_qrcode: + payload = SetupPayload(container['discriminator'], container['pincode'], + container['discovery'], CommissioningFlow(container['flow'].__int__()), + container['vid'], container['pid']) + else: + payload = SetupPayload(discriminator=container['discriminator'], + pincode=(container['pincode_msb'] << 14) | container['pincode_lsb'], + vid=container['vid'] if container['vid_pid_present'] else None, + pid=container['pid'] if container['vid_pid_present'] else None) + payload.short_discriminator = container['discriminator'] + payload.long_discriminator = None + payload.discovery = None + payload.flow = 2 if container['vid_pid_present'] else 0 + + return payload + + @staticmethod + def parse_qrcode(payload): + payload = payload[3:] # remove 'MT:' + b38_decoded = Base38.decode(payload)[::-1] + container = qrcode_format.parse(b38_decoded) + return SetupPayload.from_container(container, is_qrcode=True) + + @staticmethod + def parse_manualcode(payload): + payload_len = len(payload) + if payload_len != 11 and payload_len != 21: + print('Invalid length') + return None + + # if first digit is greater than 7 the its not v1 + if int(str(payload)[0]) > 7: + print('incorrect first digit') + return None + + if calc_check_digit(payload[:-1]) != str(payload)[-1]: + print('check digit mismatch') + return None + + # vid_pid_present bit position + is_long = int(str(payload)[0]) & (1 << 2) + + bits = int2ba(int(payload[0]), length=4) + bits += int2ba(int(payload[1:6]), length=16) + bits += int2ba(int(payload[6:10]), length=13) + bits += int2ba(int(payload[10:15]), length=16) if is_long else zeros(16) + bits += int2ba(int(payload[15:20]), length=16) if is_long else zeros(16) + bits += zeros(7) # padding + + container = manualcode_format.parse(bits.tobytes()) + return SetupPayload.from_container(container, is_qrcode=False) + + @staticmethod + def parse(payload): + if payload.startswith('MT:'): + return SetupPayload.parse_qrcode(payload) + else: + return SetupPayload.parse_manualcode(payload) + + +@click.group() +def cli(): + pass + + +@cli.command() +@click.argument('payload') +def parse(payload): + click.echo(f'Parsing payload: {payload}') + SetupPayload.parse(payload).p_print() + + +@cli.command() +@click.option('--discriminator', '-d', required=True, type=click.IntRange(0, 0xFFF), help='Discriminator') +@click.option('--passcode', '-p', required=True, type=click.IntRange(1, 0x5F5E0FE), help='setup pincode') +@click.option('--vendor-id', '-vid', type=click.IntRange(0, 0xFFFF), default=0, help='Vendor ID') +@click.option('--product-id', '-pid', type=click.IntRange(0, 0xFFFF), default=0, help='Product ID') +@click.option('--discovery-cap-bitmask', '-dm', type=click.IntRange(0, 7), default=4, help='Commissionable device discovery capability bitmask. 0:SoftAP, 1:BLE, 2:OnNetwork. Default: OnNetwork') +@click.option('--commissioning-flow', '-cf', type=click.IntRange(0, 2), default=0, help='Commissioning flow, 0:Standard, 1:User-Intent, 2:Custom') +def generate(passcode, discriminator, vendor_id, product_id, discovery_cap_bitmask, commissioning_flow): + payload = SetupPayload(discriminator, passcode, discovery_cap_bitmask, commissioning_flow, vendor_id, product_id) + print("Manualcode : {}".format(payload.generate_manualcode())) + print("QRCode : {}".format(payload.generate_qrcode())) + + +if __name__ == '__main__': + cli() diff --git a/src/setup_payload/python/generate_setup_payload.py b/src/setup_payload/python/generate_setup_payload.py deleted file mode 100755 index 28a834651214b1..00000000000000 --- a/src/setup_payload/python/generate_setup_payload.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2022 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import argparse -import enum -import sys - -import Base38 -from bitarray import bitarray -from stdnum.verhoeff import calc_check_digit - -# See section 5.1.4.1 Manual Pairing Code in the Matter specification v1.0 -MANUAL_DISCRIMINATOR_LEN = 4 -PINCODE_LEN = 27 - -MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_LEN = 2 -MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_POS = 0 -MANUAL_CHUNK1_VID_PID_PRESENT_BIT_POS = MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_POS + MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_LEN -MANUAL_CHUNK1_LEN = 1 - -MANUAL_CHUNK2_DISCRIMINATOR_LSBITS_LEN = 2 -MANUAL_CHUNK2_PINCODE_LSBITS_LEN = 14 -MANUAL_CHUNK2_PINCODE_LSBITS_POS = 0 -MANUAL_CHUNK2_DISCRIMINATOR_LSBITS_POS = MANUAL_CHUNK2_PINCODE_LSBITS_POS + MANUAL_CHUNK2_PINCODE_LSBITS_LEN -MANUAL_CHUNK2_LEN = 5 - -MANUAL_CHUNK3_PINCODE_MSBITS_LEN = 13 -MANUAL_CHUNK3_PINCODE_MSBITS_POS = 0 -MANUAL_CHUNK3_LEN = 4 - -MANUAL_VID_LEN = 5 -MANUAL_PID_LEN = 5 - -# See section 5.1.3. QR Code in the Matter specification v1.0 -QRCODE_VERSION_LEN = 3 -QRCODE_DISCRIMINATOR_LEN = 12 -QRCODE_VID_LEN = 16 -QRCODE_PID_LEN = 16 -QRCODE_COMMISSIONING_FLOW_LEN = 2 -QRCODE_DISCOVERY_CAP_BITMASK_LEN = 8 -QRCODE_PADDING_LEN = 4 -QRCODE_VERSION = 0 -QRCODE_PADDING = 0 - -INVALID_PASSCODES = [00000000, 11111111, 22222222, 33333333, 44444444, 55555555, - 66666666, 77777777, 88888888, 99999999, 12345678, 87654321] - - -class CommissioningFlow(enum.IntEnum): - Standard = 0, - UserIntent = 1, - Custom = 2 - - -class SetupPayload: - def __init__(self, discriminator, pincode, rendezvous=4, flow=CommissioningFlow.Standard, vid=0, pid=0): - self.long_discriminator = discriminator - self.short_discriminator = discriminator >> 8 - self.pincode = pincode - self.rendezvous = rendezvous - self.flow = flow - self.vid = vid - self.pid = pid - - def manual_chunk1(self): - discriminator_shift = (MANUAL_DISCRIMINATOR_LEN - MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_LEN) - discriminator_mask = (1 << MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_LEN) - 1 - discriminator_chunk = (self.short_discriminator >> discriminator_shift) & discriminator_mask - vid_pid_present_flag = 0 if self.flow == CommissioningFlow.Standard else 1 - return (discriminator_chunk << MANUAL_CHUNK1_DISCRIMINATOR_MSBITS_POS) | (vid_pid_present_flag << MANUAL_CHUNK1_VID_PID_PRESENT_BIT_POS) - - def manual_chunk2(self): - discriminator_mask = (1 << MANUAL_CHUNK2_DISCRIMINATOR_LSBITS_LEN) - 1 - pincode_mask = (1 << MANUAL_CHUNK2_PINCODE_LSBITS_LEN) - 1 - discriminator_chunk = self.short_discriminator & discriminator_mask - return ((self.pincode & pincode_mask) << MANUAL_CHUNK2_PINCODE_LSBITS_POS) | (discriminator_chunk << MANUAL_CHUNK2_DISCRIMINATOR_LSBITS_POS) - - def manual_chunk3(self): - pincode_shift = PINCODE_LEN - MANUAL_CHUNK3_PINCODE_MSBITS_LEN - pincode_mask = (1 << MANUAL_CHUNK3_PINCODE_MSBITS_LEN) - 1 - return ((self.pincode >> pincode_shift) & pincode_mask) << MANUAL_CHUNK3_PINCODE_MSBITS_POS - - def generate_manualcode(self): - payload = str(self.manual_chunk1()).zfill(MANUAL_CHUNK1_LEN) - payload += str(self.manual_chunk2()).zfill(MANUAL_CHUNK2_LEN) - payload += str(self.manual_chunk3()).zfill(MANUAL_CHUNK3_LEN) - - if self.flow != CommissioningFlow.Standard: - payload += str(self.vid).zfill(MANUAL_VID_LEN) - payload += str(self.pid).zfill(MANUAL_PID_LEN) - - payload += calc_check_digit(payload) - return payload - - def generate_qrcode(self): - qrcode_bit_string = '{0:b}'.format(QRCODE_PADDING).zfill(QRCODE_PADDING_LEN) - qrcode_bit_string += '{0:b}'.format(self.pincode).zfill(PINCODE_LEN) - qrcode_bit_string += '{0:b}'.format(self.long_discriminator).zfill(QRCODE_DISCRIMINATOR_LEN) - qrcode_bit_string += '{0:b}'.format(self.rendezvous).zfill(QRCODE_DISCOVERY_CAP_BITMASK_LEN) - qrcode_bit_string += '{0:b}'.format(int(self.flow)).zfill(QRCODE_COMMISSIONING_FLOW_LEN) - qrcode_bit_string += '{0:b}'.format(self.pid).zfill(QRCODE_PID_LEN) - qrcode_bit_string += '{0:b}'.format(self.vid).zfill(QRCODE_VID_LEN) - qrcode_bit_string += '{0:b}'.format(QRCODE_VERSION).zfill(QRCODE_VERSION_LEN) - - qrcode_bits = bitarray(qrcode_bit_string) - bytes = list(qrcode_bits.tobytes()) - bytes.reverse() - return 'MT:{}'.format(Base38.encode(bytes)) - - -def validate_args(args): - def check_int_range(value, min_value, max_value, name): - if value and ((value < min_value) or (value > max_value)): - print('{} is out of range, should be in range from {} to {}'.format(name, min_value, max_value)) - sys.exit(1) - - if args.passcode is not None: - if ((args.passcode < 0x0000001 and args.passcode > 0x5F5E0FE) or (args.passcode in INVALID_PASSCODES)): - print('Invalid passcode:' + str(args.passcode)) - sys.exit(1) - - check_int_range(args.discriminator, 0x0000, 0x0FFF, 'Discriminator') - check_int_range(args.product_id, 0x0000, 0xFFFF, 'Product id') - check_int_range(args.vendor_id, 0x0000, 0xFFFF, 'Vendor id') - check_int_range(args.discovery_cap_bitmask, 0x0001, 0x0007, 'Discovery Capability Mask') - - -def main(): - def any_base_int(s): return int(s, 0) - parser = argparse.ArgumentParser(description='Matter Manual and QRCode Setup Payload Generator Tool') - parser.add_argument('-d', '--discriminator', type=any_base_int, required=True, - help='The discriminator for pairing, range: 0x00-0x0FFF') - parser.add_argument('-p', '--passcode', type=any_base_int, required=True, - help='The setup passcode for pairing, range: 0x01-0x5F5E0FE') - parser.add_argument('-vid', '--vendor-id', type=any_base_int, default=0, help='Vendor id') - parser.add_argument('-pid', '--product-id', type=any_base_int, default=0, help='Product id') - parser.add_argument('-cf', '--commissioning-flow', type=any_base_int, default=0, - help='Device commissioning flow, 0:Standard, 1:User-Intent, 2:Custom. \ - Default is 0.', choices=[0, 1, 2]) - parser.add_argument('-dm', '--discovery-cap-bitmask', type=any_base_int, default=4, - help='Commissionable device discovery capability bitmask. \ - 0:SoftAP, 1:BLE, 2:OnNetwork. Default: OnNetwork') - args = parser.parse_args() - validate_args(args) - - payloads = SetupPayload(args.discriminator, args.passcode, args.discovery_cap_bitmask, - CommissioningFlow(args.commissioning_flow), args.vendor_id, args.product_id) - manualcode = payloads.generate_manualcode() - qrcode = payloads.generate_qrcode() - - print("Manualcode : {}".format(manualcode)) - print("QRCode : {}".format(qrcode)) - - -if __name__ == '__main__': - main() diff --git a/src/setup_payload/python/requirements.txt b/src/setup_payload/python/requirements.txt index 43800d601c7736..1026fa98d061c5 100644 --- a/src/setup_payload/python/requirements.txt +++ b/src/setup_payload/python/requirements.txt @@ -1,2 +1,4 @@ -bitarray==2.6.0 +bitarray>=2.8.1 +click>=8.1.3 +construct>=2.10.68 python_stdnum==1.18 diff --git a/src/setup_payload/tests/BUILD.gn b/src/setup_payload/tests/BUILD.gn index b08d18a5a4fc15..23022aad8ffafc 100644 --- a/src/setup_payload/tests/BUILD.gn +++ b/src/setup_payload/tests/BUILD.gn @@ -34,6 +34,7 @@ chip_test_suite("tests") { cflags = [ "-Wconversion" ] public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", "${chip_root}/src/setup_payload", ] diff --git a/src/setup_payload/tests/TestAdditionalDataPayload.cpp b/src/setup_payload/tests/TestAdditionalDataPayload.cpp index 36ec0e6a970b90..d59eac34a0b20b 100644 --- a/src/setup_payload/tests/TestAdditionalDataPayload.cpp +++ b/src/setup_payload/tests/TestAdditionalDataPayload.cpp @@ -28,6 +28,7 @@ #include +#include #include #include #include diff --git a/src/setup_payload/tests/TestManualCode.cpp b/src/setup_payload/tests/TestManualCode.cpp index 0b9be9a906011e..abf6a530b51b3e 100644 --- a/src/setup_payload/tests/TestManualCode.cpp +++ b/src/setup_payload/tests/TestManualCode.cpp @@ -22,15 +22,15 @@ * */ -#include +#include #include +#include +#include #include #include #include -#include - #include #include #include diff --git a/src/setup_payload/tests/TestQRCode.cpp b/src/setup_payload/tests/TestQRCode.cpp index 6482b9ad0e7b0a..44c50d9e1e8f5b 100644 --- a/src/setup_payload/tests/TestQRCode.cpp +++ b/src/setup_payload/tests/TestQRCode.cpp @@ -26,7 +26,9 @@ #include -#include +#include + +#include #include using namespace chip; diff --git a/src/setup_payload/tests/TestQRCodeTLV.cpp b/src/setup_payload/tests/TestQRCodeTLV.cpp index cdf6048a49b9a0..7ea2b974070275 100644 --- a/src/setup_payload/tests/TestQRCodeTLV.cpp +++ b/src/setup_payload/tests/TestQRCodeTLV.cpp @@ -16,9 +16,11 @@ */ #include "TestHelpers.h" -#include +#include + #include +#include #include using namespace chip; diff --git a/src/setup_payload/tests/run_python_setup_payload_gen_test.py b/src/setup_payload/tests/run_python_setup_payload_gen_test.py deleted file mode 100644 index b52000c1a6fd98..00000000000000 --- a/src/setup_payload/tests/run_python_setup_payload_gen_test.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import re -import subprocess -import sys - -CHIP_TOPDIR = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('src', 'setup_payload', 'tests'))] -sys.path.insert(0, os.path.join(CHIP_TOPDIR, 'src', 'setup_payload', 'python')) -from generate_setup_payload import CommissioningFlow, SetupPayload # noqa: E402 - - -def payload_param_dict(): - return { - 'Version': None, - 'VendorID': None, - 'ProductID': None, - 'Custom flow': None, - 'Discovery Bitmask': None, - 'Short discriminator': None, - 'Long discriminator': None, - 'Passcode': None - } - - -def remove_escape_sequence(data): - ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') - result = ansi_escape.sub('', data) - return result - - -def parse_setup_payload(chip_tool, payload): - cmd_args = [chip_tool, 'payload', 'parse-setup-payload', payload] - data = subprocess.check_output(cmd_args).decode('utf-8') - data = remove_escape_sequence(data) - parsed_params = payload_param_dict() - for key in parsed_params: - k_st = data.find(key) - if k_st == -1: - continue - - # 1 is for ":" - k_end = k_st + len(key) + 1 - - k_nl = data.find('\n', k_end) - parsed_params[key] = data[k_end:k_nl].split()[0] - - return parsed_params - - -def generate_payloads(in_params): - payloads = SetupPayload(in_params['Long discriminator'], in_params['Passcode'], - in_params['Discovery Bitmask'], CommissioningFlow(in_params['Custom flow']), - in_params['VendorID'], in_params['ProductID']) - manualcode = payloads.generate_manualcode() - qrcode = payloads.generate_qrcode() - return manualcode, qrcode - - -def verify_payloads(in_params, manualcode_params, qrcode_params): - assert in_params['Version'] == int(manualcode_params['Version'], 0) - assert in_params['Passcode'] == int(manualcode_params['Passcode'], 0) - assert in_params['Short discriminator'] == int(manualcode_params['Short discriminator'], 0) - if in_params['Custom flow'] != 0: - assert in_params['VendorID'] == int(manualcode_params['VendorID'], 0) - assert in_params['ProductID'] == int(manualcode_params['ProductID'], 0) - - assert in_params['Version'] == int(qrcode_params['Version'], 0) - assert in_params['VendorID'] == int(qrcode_params['VendorID'], 0) - assert in_params['ProductID'] == int(qrcode_params['ProductID'], 0) - assert in_params['Custom flow'] == int(qrcode_params['Custom flow'], 0) - assert in_params['Discovery Bitmask'] == int(qrcode_params['Discovery Bitmask'], 0) - assert in_params['Passcode'] == int(qrcode_params['Passcode'], 0) - assert in_params['Long discriminator'] == int(qrcode_params['Long discriminator'], 0) - - -def get_payload_params(discriminator, passcode, discovery=4, flow=0, vid=0, pid=0, version=0): - p = payload_param_dict() - p['Version'] = version - p['VendorID'] = vid - p['ProductID'] = pid - p['Custom flow'] = flow - p['Discovery Bitmask'] = discovery - p['Long discriminator'] = discriminator - p['Short discriminator'] = discriminator >> 8 - p['Passcode'] = passcode - return p - - -def run_tests(chip_tool): - test_data_set = [ - get_payload_params(3840, 20202021), - get_payload_params(3781, 12349876, flow=1, vid=1, pid=1), - get_payload_params(2310, 23005908, flow=2, vid=0xFFF3, pid=0x8098), - get_payload_params(3091, 43338551, discovery=2, flow=2, vid=0x1123, pid=0x0012), - get_payload_params(80, 54757432, discovery=6, flow=2, vid=0x2345, pid=0x1023), - get_payload_params(174, 81235604, discovery=7, flow=1, vid=0x45, pid=0x10), - ] - - for test_params in test_data_set: - manualcode, qrcode = generate_payloads(test_params) - manualcode_params = parse_setup_payload(chip_tool, manualcode) - qrcode_params = parse_setup_payload(chip_tool, qrcode) - - print("Input parameters:", test_params) - print("Manualcode:", manualcode) - print("QRCode:", qrcode) - print("Manualcode parsed by chip-tool:", manualcode_params) - print("QRCode parsed by chip-tool:", qrcode_params) - print("") - - verify_payloads(test_params, manualcode_params, qrcode_params) - - -def main(): - if len(sys.argv) == 2: - chip_tool = sys.argv[1] - run_tests(chip_tool) - - -if __name__ == '__main__': - main() diff --git a/src/setup_payload/tests/run_python_setup_payload_test.py b/src/setup_payload/tests/run_python_setup_payload_test.py new file mode 100644 index 00000000000000..da62a45c05fe97 --- /dev/null +++ b/src/setup_payload/tests/run_python_setup_payload_test.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import re +import subprocess +import sys + +CHIP_TOPDIR = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('src', 'setup_payload', 'tests'))] +sys.path.insert(0, os.path.join(CHIP_TOPDIR, 'src', 'setup_payload', 'python')) +from SetupPayload import CommissioningFlow, SetupPayload # noqa: E402 + + +def payload_param_dict(): + return { + 'Version': None, + 'VendorID': None, + 'ProductID': None, + 'Custom flow': None, + 'Discovery Bitmask': None, + 'Short discriminator': None, + 'Long discriminator': None, + 'Passcode': None + } + + +def remove_escape_sequence(data): + ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') + result = ansi_escape.sub('', data) + return result + + +def chip_tool_parse_setup_payload(chip_tool, payload): + cmd_args = [chip_tool, 'payload', 'parse-setup-payload', payload] + data = subprocess.check_output(cmd_args).decode('utf-8') + data = remove_escape_sequence(data) + parsed_params = payload_param_dict() + for key in parsed_params: + k_st = data.find(key) + if k_st == -1: + continue + + # 1 is for ":" + k_end = k_st + len(key) + 1 + + k_nl = data.find('\n', k_end) + parsed_params[key] = data[k_end:k_nl].split()[0] + + return parsed_params + + +def generate_payloads(in_params): + payloads = SetupPayload(in_params['Long discriminator'], in_params['Passcode'], + in_params['Discovery Bitmask'], CommissioningFlow(in_params['Custom flow']), + in_params['VendorID'], in_params['ProductID']) + manualcode = payloads.generate_manualcode() + qrcode = payloads.generate_qrcode() + return manualcode, qrcode + + +def verify_generated_payloads(in_params, manualcode_params, qrcode_params): + assert in_params['Version'] == int(manualcode_params['Version'], 0) + assert in_params['Passcode'] == int(manualcode_params['Passcode'], 0) + assert in_params['Short discriminator'] == int(manualcode_params['Short discriminator'], 0) + if in_params['Custom flow'] != 0: + assert in_params['VendorID'] == int(manualcode_params['VendorID'], 0) + assert in_params['ProductID'] == int(manualcode_params['ProductID'], 0) + + assert in_params['Version'] == int(qrcode_params['Version'], 0) + assert in_params['VendorID'] == int(qrcode_params['VendorID'], 0) + assert in_params['ProductID'] == int(qrcode_params['ProductID'], 0) + assert in_params['Custom flow'] == int(qrcode_params['Custom flow'], 0) + assert in_params['Discovery Bitmask'] == int(qrcode_params['Discovery Bitmask'], 0) + assert in_params['Passcode'] == int(qrcode_params['Passcode'], 0) + assert in_params['Long discriminator'] == int(qrcode_params['Long discriminator'], 0) + + +def get_payload_params(discriminator, passcode, discovery=4, flow=0, vid=0, pid=0, version=0, short_discriminator=None): + p = payload_param_dict() + p['Version'] = version + p['VendorID'] = vid + p['ProductID'] = pid + p['Custom flow'] = flow + p['Discovery Bitmask'] = discovery + p['Long discriminator'] = discriminator + p['Short discriminator'] = short_discriminator if short_discriminator is not None else (discriminator >> 8) + p['Passcode'] = passcode + return p + + +def test_code_generation(chip_tool): + test_data_set = [ + get_payload_params(3840, 20202021), + get_payload_params(3781, 12349876, flow=1, vid=1, pid=1), + get_payload_params(2310, 23005908, flow=2, vid=0xFFF3, pid=0x8098), + get_payload_params(3091, 43338551, discovery=2, flow=2, vid=0x1123, pid=0x0012), + get_payload_params(80, 54757432, discovery=6, flow=2, vid=0x2345, pid=0x1023), + get_payload_params(174, 81235604, discovery=7, flow=1, vid=0x45, pid=0x10), + ] + + for test_params in test_data_set: + manualcode, qrcode = generate_payloads(test_params) + manualcode_params = chip_tool_parse_setup_payload(chip_tool, manualcode) + qrcode_params = chip_tool_parse_setup_payload(chip_tool, qrcode) + + verify_generated_payloads(test_params, manualcode_params, qrcode_params) + + +def test_onboardingcode_parsing(): + # This test dataset is generated using `chip-tool payload parse-setup-payload ` + + test_data_set = [ + { + 'code': '34970112332', + 'res': get_payload_params(discriminator=None, passcode=20202021, discovery=None, + flow=0, vid=None, pid=None, version=0, short_discriminator=15), + }, + { + 'code': '745492075300001000013', + 'res': get_payload_params(discriminator=None, passcode=12349876, discovery=None, + flow=2, vid=1, pid=1, version=0, short_discriminator=14), + }, + { + 'code': '619156140465523329207', + 'res': get_payload_params(discriminator=None, passcode=23005908, discovery=None, + flow=2, vid=65523, pid=32920, version=0, short_discriminator=9), + }, + { + 'code': '702871264504387000187', + 'res': get_payload_params(discriminator=None, passcode=43338551, discovery=None, + flow=2, vid=4387, pid=18, version=0, short_discriminator=12), + }, + { + 'code': '402104334209029041311', + 'res': get_payload_params(discriminator=None, passcode=54757432, discovery=None, + flow=2, vid=9029, pid=4131, version=0, short_discriminator=0), + }, + { + 'code': '403732495800069000166', + 'res': get_payload_params(discriminator=None, passcode=81235604, discovery=None, + flow=2, vid=69, pid=16, version=0, short_discriminator=0), + }, + { + 'code': 'MT:U9VJ0OMV172PX813210', + 'res': get_payload_params(discriminator=3431, passcode=49910688, discovery=2, + flow=0, vid=4891, pid=2, version=0, short_discriminator=None), + }, + { + 'code': 'MT:00000CQM00KA0648G00', + 'res': get_payload_params(discriminator=3840, passcode=20202021, discovery=4, + flow=0, vid=0, pid=0, version=0, short_discriminator=None), + }, + { + 'code': 'MT:A3L90ARR15G6N57Y900', + 'res': get_payload_params(discriminator=3781, passcode=12349876, discovery=4, + flow=1, vid=1, pid=1, version=0, short_discriminator=None), + }, + { + 'code': 'MT:MZWA6G6026O2XP0II00', + 'res': get_payload_params(discriminator=2310, passcode=23005908, discovery=4, + flow=2, vid=65523, pid=32920, version=0, short_discriminator=None), + }, + { + 'code': 'MT:KSNK4M5113-JPR4UY00', + 'res': get_payload_params(discriminator=3091, passcode=43338551, discovery=2, + flow=2, vid=4387, pid=18, version=0, short_discriminator=12), + }, + { + 'code': 'MT:0A.T0P--00Y0OJ0.510', + 'res': get_payload_params(discriminator=80, passcode=54757432, discovery=6, + flow=2, vid=9029, pid=4131, version=0, short_discriminator=None), + }, + { + 'code': 'MT:EPX0482F26DAVY09R10', + 'res': get_payload_params(discriminator=174, passcode=81235604, discovery=7, + flow=1, vid=69, pid=16, version=0, short_discriminator=None), + }, + ] + + for test_payload in test_data_set: + payload = SetupPayload.parse(test_payload['code']) + + assert payload.long_discriminator == test_payload['res']['Long discriminator'] + assert payload.short_discriminator == test_payload['res']['Short discriminator'] + assert payload.pincode == test_payload['res']['Passcode'] + assert payload.discovery == test_payload['res']['Discovery Bitmask'] + assert payload.flow == test_payload['res']['Custom flow'] + assert payload.vid == test_payload['res']['VendorID'] + assert payload.pid == test_payload['res']['ProductID'] + + +def main(): + if len(sys.argv) == 2: + chip_tool = sys.argv[1] + test_code_generation(chip_tool) + test_onboardingcode_parsing() + + +if __name__ == '__main__': + main() diff --git a/src/system/SystemPacketBuffer.cpp b/src/system/SystemPacketBuffer.cpp index 59e1e822901db0..f8dda8b01ab84e 100644 --- a/src/system/SystemPacketBuffer.cpp +++ b/src/system/SystemPacketBuffer.cpp @@ -508,37 +508,64 @@ void PacketBuffer::AddRef() PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aReservedSize) { - // Adding three 16-bit-int sized numbers together will never overflow - // assuming int is at least 32 bits. - static_assert(INT_MAX >= INT32_MAX, "int is not big enough"); + // Sanity check for kStructureSize to ensure that it matches the PacketBuffer size. static_assert(PacketBuffer::kStructureSize == sizeof(PacketBuffer), "PacketBuffer size mismatch"); - static_assert(PacketBuffer::kStructureSize < UINT16_MAX, "Check for overflow more carefully"); - static_assert(SIZE_MAX >= INT_MAX, "Our additions might not fit in size_t"); - static_assert(PacketBuffer::kMaxSizeWithoutReserve <= UINT32_MAX, "PacketBuffer may have size not fitting uint32_t"); + // Setting a static upper bound on kStructureSize to ensure the summation of all the sizes does not overflow. + static_assert(PacketBuffer::kStructureSize <= UINT16_MAX, "kStructureSize should not exceed UINT16_MAX."); + // Setting a static upper bound on the maximum buffer size allocation for regular sized messages (not large). + static_assert(PacketBuffer::kMaxSizeWithoutReserve <= UINT16_MAX, "kMaxSizeWithoutReserve should not exceed UINT16_MAX."); + + // Ensure that aAvailableSize is bound within a max and is not big enough to cause overflow during + // subsequent addition of all the sizes. + if (aAvailableSize > UINT32_MAX) + { + ChipLogError(chipSystemLayer, + "PacketBuffer: AvailableSize of a buffer cannot exceed UINT32_MAX. aAvailableSize = 0x" ChipLogFormatX64, + ChipLogValueX64(static_cast(aAvailableSize))); + return PacketBufferHandle(); + } + + // Cast all to uint64_t and add. This cannot overflow because we have + // ensured that the maximal value of the summation is + // UINT32_MAX + UINT16_MAX + UINT16_MAX, which should always fit in + // a uint64_t variable. + uint64_t sumOfSizes = static_cast(aAvailableSize) + static_cast(aReservedSize) + + static_cast(PacketBuffer::kStructureSize); + uint64_t sumOfAvailAndReserved = static_cast(aAvailableSize) + static_cast(aReservedSize); + + // Ensure that the sum fits in a size_t so that casting into size_t variables, + // viz., lBlockSize and lAllocSize, is safe. + if (!CanCastTo(sumOfSizes)) + { + ChipLogError(chipSystemLayer, + "PacketBuffer: Sizes of allocation request are invalid. (aAvailableSize = " ChipLogFormatX64 + ", aReservedSize = " ChipLogFormatX64 ")", + ChipLogValueX64(static_cast(aAvailableSize)), ChipLogValueX64(static_cast(aReservedSize))); + return PacketBufferHandle(); + } + #if CHIP_SYSTEM_CONFIG_USE_LWIP // LwIP based APIs have a maximum buffer size of UINT16_MAX. Ensure that // limit is met during allocation. - VerifyOrDieWithMsg(aAvailableSize + aReservedSize < UINT16_MAX, chipSystemLayer, - "LwIP based systems can handle only up to UINT16_MAX!"); + VerifyOrDieWithMsg(sumOfAvailAndReserved < UINT16_MAX, chipSystemLayer, "LwIP based systems can handle only up to UINT16_MAX!"); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP - // When `aAvailableSize` fits in uint16_t (as tested below) and size_t is at least 32 bits (as asserted above), - // these additions will not overflow. - const size_t lAllocSize = aReservedSize + aAvailableSize; - const size_t lBlockSize = PacketBuffer::kStructureSize + lAllocSize; + // sumOfAvailAndReserved is no larger than sumOfSizes, which we checked can be cast to + // size_t. + const size_t lAllocSize = static_cast(sumOfAvailAndReserved); PacketBuffer * lPacket; CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_PacketBufferNew, return PacketBufferHandle()); - // TODO: Change the max to a lower value - if (aAvailableSize > UINT32_MAX || lAllocSize > PacketBuffer::kMaxSizeWithoutReserve || lBlockSize > UINT32_MAX) + if (lAllocSize > PacketBuffer::kMaxSizeWithoutReserve) { - ChipLogError(chipSystemLayer, "PacketBuffer: allocation too large."); + ChipLogError(chipSystemLayer, "PacketBuffer: allocation exceeding buffer capacity limits."); return PacketBufferHandle(); } #if CHIP_SYSTEM_CONFIG_USE_LWIP - + // This cast is safe because lAllocSize is no larger than + // kMaxSizeWithoutReserve, which fits in uint16_t. lPacket = static_cast( pbuf_alloc(PBUF_RAW, static_cast(lAllocSize), CHIP_SYSTEM_PACKETBUFFER_LWIP_PBUF_TYPE)); @@ -546,7 +573,6 @@ PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aRese #elif CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL - static_cast(lBlockSize); #if !CHIP_SYSTEM_CONFIG_NO_LOCKING && CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING if (!sBufferPoolMutex.isInitialized()) { @@ -565,8 +591,10 @@ PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aRese UNLOCK_BUF_POOL(); #elif CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP - - lPacket = reinterpret_cast(chip::Platform::MemoryAlloc(lBlockSize)); + // sumOfSizes is essentially (kStructureSize + lAllocSize) which we already + // checked to fit in a size_t. + const size_t lBlockSize = static_cast(sumOfSizes); + lPacket = reinterpret_cast(chip::Platform::MemoryAlloc(lBlockSize)); SYSTEM_STATS_INCREMENT(chip::System::Stats::kSystemLayer_NumPacketBufs); #else diff --git a/src/system/tests/BUILD.gn b/src/system/tests/BUILD.gn index 2f2fd4de0a6a6d..01965170ab9b0c 100644 --- a/src/system/tests/BUILD.gn +++ b/src/system/tests/BUILD.gn @@ -46,6 +46,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/inet", + "${chip_root}/src/lib/support/tests:pw-test-macros", "${chip_root}/src/platform", "${chip_root}/src/system", ] diff --git a/src/system/tests/TestSystemPacketBuffer.cpp b/src/system/tests/TestSystemPacketBuffer.cpp index c71ad542d6225a..bf1456487307a3 100644 --- a/src/system/tests/TestSystemPacketBuffer.cpp +++ b/src/system/tests/TestSystemPacketBuffer.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -192,16 +193,6 @@ class TestSystemPacketBuffer : public ::testing::Test void CheckSetStart(); }; -/* - * Run fixture's class function as a test. - */ -#define TEST_F_FROM_FIXTURE(test_fixture, test_name) \ - TEST_F(test_fixture, test_name) \ - { \ - test_name(); \ - } \ - void test_fixture::test_name() - /** * Allocate memory for a test buffer and configure according to test buffer configuration. */ diff --git a/src/test_driver/nrfconnect/main/runner.cpp b/src/test_driver/nrfconnect/main/runner.cpp index 1cd57d0bbbd406..d779f1d5300d09 100644 --- a/src/test_driver/nrfconnect/main/runner.cpp +++ b/src/test_driver/nrfconnect/main/runner.cpp @@ -35,8 +35,9 @@ extern "C" int main(void) VerifyOrDie(settings_subsys_init() == 0); LOG_INF("Starting CHIP tests!"); - int status = RunRegisteredUnitTests(); + int status = 0; status += chip::test::RunAllTests(); + status += RunRegisteredUnitTests(); LOG_INF("CHIP test status: %d", status); _exit(status); diff --git a/src/test_driver/openiotsdk/unit-tests/test_components.txt b/src/test_driver/openiotsdk/unit-tests/test_components.txt index 8c59caffcf8de4..54f47dfa47c557 100644 --- a/src/test_driver/openiotsdk/unit-tests/test_components.txt +++ b/src/test_driver/openiotsdk/unit-tests/test_components.txt @@ -20,3 +20,5 @@ SecureChannelTests ICDServerTests DataModelTests InetLayerTests +AppTests +MessagingLayerTests diff --git a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt index 55ebc4e3cd7e7e..6c038b398d914f 100644 --- a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt +++ b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt @@ -1,3 +1 @@ -AppTests -MessagingLayerTests -SecureChannelTestsNL +AppTestsNL \ No newline at end of file diff --git a/src/test_driver/tizen/chip_tests/BUILD.gn b/src/test_driver/tizen/chip_tests/BUILD.gn index 01b0e5e70246be..829371df7cc620 100644 --- a/src/test_driver/tizen/chip_tests/BUILD.gn +++ b/src/test_driver/tizen/chip_tests/BUILD.gn @@ -30,7 +30,6 @@ tizen_qemu_mkisofs("chip-tests-runner") { # rebuild of the ISO image, so the test will be run with old # binaries. assets_non_tracked = [ rebase_path("${root_build_dir}/tests") ] - assets_non_tracked_exclude_globs = [ "*.map" ] } tizen_qemu_run("chip-tests") { diff --git a/src/transport/GroupSession.h b/src/transport/GroupSession.h index f20ff069ab029f..1c5ffecd2be3c9 100644 --- a/src/transport/GroupSession.h +++ b/src/transport/GroupSession.h @@ -75,6 +75,13 @@ class IncomingGroupSession : public Session, public ReferenceCounted; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WiFiNetworkManagement + +namespace ThreadNetworkDirectory { +namespace Attributes { + +namespace PreferredExtendedPanID { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace PreferredExtendedPanID + +namespace ThreadNetworkTableSize { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +} // namespace ThreadNetworkTableSize + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDirectory::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ThreadNetworkDirectory + namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index e51fb1999e9ce8..7ebe0abeca5474 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -5316,6 +5316,59 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace WiFiNetworkManagement { +namespace Attributes { + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WiFiNetworkManagement + +namespace ThreadNetworkDirectory { +namespace Attributes { + +namespace PreferredExtendedPanID { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int64u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace PreferredExtendedPanID + +namespace ThreadNetworkTableSize { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value); // int8u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +} // namespace ThreadNetworkTableSize + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ThreadNetworkDirectory + namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 350190a22e5762..e260c824886cd6 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -533,6 +533,16 @@ void emberAfTotalVolatileOrganicCompoundsConcentrationMeasurementClusterInitCall */ void emberAfRadonConcentrationMeasurementClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWiFiNetworkManagementClusterInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfThreadNetworkDirectoryClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -4488,6 +4498,82 @@ chip::Protocols::InteractionModel::Status MatterRadonConcentrationMeasurementClu */ void emberAfRadonConcentrationMeasurementClusterServerTickCallback(chip::EndpointId endpoint); +// +// Wi-Fi Network Management Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWiFiNetworkManagementClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterWiFiNetworkManagementClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWiFiNetworkManagementClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterWiFiNetworkManagementClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterWiFiNetworkManagementClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfWiFiNetworkManagementClusterServerTickCallback(chip::EndpointId endpoint); + +// +// Thread Network Directory Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfThreadNetworkDirectoryClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterThreadNetworkDirectoryClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfThreadNetworkDirectoryClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterThreadNetworkDirectoryClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterThreadNetworkDirectoryClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfThreadNetworkDirectoryClusterServerTickCallback(chip::EndpointId endpoint); + // // Wake on LAN Cluster // @@ -6115,6 +6201,24 @@ bool emberAfColorControlClusterMoveColorTemperatureCallback( bool emberAfColorControlClusterStepColorTemperatureCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ColorControl::Commands::StepColorTemperature::DecodableType & commandData); +/** + * @brief Thread Network Directory Cluster AddNetwork Command callback (from client) + */ +bool emberAfThreadNetworkDirectoryClusterAddNetworkCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::DecodableType & commandData); +/** + * @brief Thread Network Directory Cluster RemoveNetwork Command callback (from client) + */ +bool emberAfThreadNetworkDirectoryClusterRemoveNetworkCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::DecodableType & commandData); +/** + * @brief Thread Network Directory Cluster GetOperationalDataset Command callback (from client) + */ +bool emberAfThreadNetworkDirectoryClusterGetOperationalDatasetCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::DecodableType & commandData); /** * @brief Channel Cluster ChangeChannel Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 42a54b95ee944f..df8ddd16ba31e3 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -4309,6 +4309,10 @@ enum class Feature : uint32_t }; } // namespace RadonConcentrationMeasurement +namespace WiFiNetworkManagement {} // namespace WiFiNetworkManagement + +namespace ThreadNetworkDirectory {} // namespace ThreadNetworkDirectory + namespace WakeOnLan {} // namespace WakeOnLan namespace Channel { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 32b62631ed30fd..0e3ec1d0347e1f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -22865,6 +22865,350 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace RadonConcentrationMeasurement +namespace WiFiNetworkManagement { + +namespace Commands { +namespace NetworkPassphraseRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + } +} +} // namespace NetworkPassphraseRequest. +namespace NetworkPassphraseResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kPassphrase), passphrase); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kPassphrase)) + { + err = DataModel::Decode(reader, passphrase); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace NetworkPassphraseResponse. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::Ssid::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, ssid); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace WiFiNetworkManagement +namespace ThreadNetworkDirectory { +namespace Structs { + +namespace ThreadNetworkStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kExtendedPanID), extendedPanID); + encoder.Encode(to_underlying(Fields::kNetworkName), networkName); + encoder.Encode(to_underlying(Fields::kChannel), channel); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kExtendedPanID)) + { + err = DataModel::Decode(reader, extendedPanID); + } + else if (__context_tag == to_underlying(Fields::kNetworkName)) + { + err = DataModel::Decode(reader, networkName); + } + else if (__context_tag == to_underlying(Fields::kChannel)) + { + err = DataModel::Decode(reader, channel); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace ThreadNetworkStruct +} // namespace Structs + +namespace Commands { +namespace AddNetwork { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kOperationalDataset), operationalDataset); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kOperationalDataset)) + { + err = DataModel::Decode(reader, operationalDataset); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace AddNetwork. +namespace RemoveNetwork { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kExtendedPanID), extendedPanID); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kExtendedPanID)) + { + err = DataModel::Decode(reader, extendedPanID); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace RemoveNetwork. +namespace GetOperationalDataset { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kExtendedPanID), extendedPanID); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kExtendedPanID)) + { + err = DataModel::Decode(reader, extendedPanID); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace GetOperationalDataset. +namespace OperationalDatasetResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kOperationalDataset), operationalDataset); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kOperationalDataset)) + { + err = DataModel::Decode(reader, operationalDataset); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace OperationalDatasetResponse. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::PreferredExtendedPanID::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, preferredExtendedPanID); + case Attributes::ThreadNetworks::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, threadNetworks); + case Attributes::ThreadNetworkTableSize::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, threadNetworkTableSize); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events { +namespace NetworkChanged { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kExtendedPanID), extendedPanID)); + return aWriter.EndContainer(outer); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kExtendedPanID)) + { + err = DataModel::Decode(reader, extendedPanID); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace NetworkChanged. +} // namespace Events + +} // namespace ThreadNetworkDirectory namespace WakeOnLan { namespace Commands {} // namespace Commands @@ -29889,6 +30233,17 @@ bool CommandNeedsTimedInvoke(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::ThreadNetworkDirectory::Id: { + switch (aCommand) + { + case Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Id: + case Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Id: + case Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Id: + return true; + default: + return false; + } + } case Clusters::AccountLogin::Id: { switch (aCommand) { @@ -30345,6 +30700,20 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::WiFiNetworkManagement::Id: { + switch (aCommand) + { + default: + return false; + } + } + case Clusters::ThreadNetworkDirectory::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::Channel::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 89c36f3c6f147d..65450ac4489324 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -34846,6 +34846,475 @@ struct TypeInfo }; } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace WiFiNetworkManagement { + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace NetworkPassphraseRequest { +struct Type; +struct DecodableType; +} // namespace NetworkPassphraseRequest + +namespace NetworkPassphraseResponse { +struct Type; +struct DecodableType; +} // namespace NetworkPassphraseResponse + +} // namespace Commands + +namespace Commands { +namespace NetworkPassphraseRequest { +enum class Fields : uint8_t +{ +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::NetworkPassphraseRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::NetworkPassphraseRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace NetworkPassphraseRequest +namespace NetworkPassphraseResponse { +enum class Fields : uint8_t +{ + kPassphrase = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::NetworkPassphraseResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } + + chip::ByteSpan passphrase; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::NetworkPassphraseResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } + + chip::ByteSpan passphrase; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace NetworkPassphraseResponse +} // namespace Commands + +namespace Attributes { + +namespace Ssid { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::Ssid::Id; } + static constexpr bool MustUseTimedWrite() { return false; } + static constexpr size_t MaxLength() { return 32; } +}; +} // namespace Ssid +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::Ssid::TypeInfo::DecodableType ssid; + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace WiFiNetworkManagement +namespace ThreadNetworkDirectory { +namespace Structs { +namespace ThreadNetworkStruct { +enum class Fields : uint8_t +{ + kExtendedPanID = 0, + kNetworkName = 1, + kChannel = 2, +}; + +struct Type +{ +public: + uint64_t extendedPanID = static_cast(0); + chip::CharSpan networkName; + uint16_t channel = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace ThreadNetworkStruct +} // namespace Structs + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace AddNetwork { +struct Type; +struct DecodableType; +} // namespace AddNetwork + +namespace RemoveNetwork { +struct Type; +struct DecodableType; +} // namespace RemoveNetwork + +namespace GetOperationalDataset { +struct Type; +struct DecodableType; +} // namespace GetOperationalDataset + +namespace OperationalDatasetResponse { +struct Type; +struct DecodableType; +} // namespace OperationalDatasetResponse + +} // namespace Commands + +namespace Commands { +namespace AddNetwork { +enum class Fields : uint8_t +{ + kOperationalDataset = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::AddNetwork::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + chip::ByteSpan operationalDataset; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return true; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::AddNetwork::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + chip::ByteSpan operationalDataset; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace AddNetwork +namespace RemoveNetwork { +enum class Fields : uint8_t +{ + kExtendedPanID = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::RemoveNetwork::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + uint64_t extendedPanID = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return true; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::RemoveNetwork::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + uint64_t extendedPanID = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace RemoveNetwork +namespace GetOperationalDataset { +enum class Fields : uint8_t +{ + kExtendedPanID = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GetOperationalDataset::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + uint64_t extendedPanID = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return true; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GetOperationalDataset::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + uint64_t extendedPanID = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GetOperationalDataset +namespace OperationalDatasetResponse { +enum class Fields : uint8_t +{ + kOperationalDataset = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::OperationalDatasetResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + chip::ByteSpan operationalDataset; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::OperationalDatasetResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + chip::ByteSpan operationalDataset; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace OperationalDatasetResponse +} // namespace Commands + +namespace Attributes { + +namespace PreferredExtendedPanID { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::PreferredExtendedPanID::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace PreferredExtendedPanID +namespace ThreadNetworks { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList< + chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::DecodableType>; + using DecodableArgType = const chip::app::DataModel::DecodableList< + chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::DecodableType> &; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ThreadNetworks::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ThreadNetworks +namespace ThreadNetworkTableSize { +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ThreadNetworkTableSize::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ThreadNetworkTableSize +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::PreferredExtendedPanID::TypeInfo::DecodableType preferredExtendedPanID; + Attributes::ThreadNetworks::TypeInfo::DecodableType threadNetworks; + Attributes::ThreadNetworkTableSize::TypeInfo::DecodableType threadNetworkTableSize = static_cast(0); + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +namespace Events { +namespace NetworkChanged { +static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; + +enum class Fields : uint8_t +{ + kExtendedPanID = 0, +}; + +struct Type +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::NetworkChanged::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + static constexpr bool kIsFabricScoped = false; + + uint64_t extendedPanID = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +struct DecodableType +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::NetworkChanged::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } + + uint64_t extendedPanID = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +} // namespace NetworkChanged +} // namespace Events +} // namespace ThreadNetworkDirectory namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 8ff6313abe5940..9f676664b5e5fb 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -6583,6 +6583,82 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace RadonConcentrationMeasurement +namespace WiFiNetworkManagement { +namespace Attributes { + +namespace Ssid { +static constexpr AttributeId Id = 0x00000001; +} // namespace Ssid + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WiFiNetworkManagement + +namespace ThreadNetworkDirectory { +namespace Attributes { + +namespace PreferredExtendedPanID { +static constexpr AttributeId Id = 0x00000000; +} // namespace PreferredExtendedPanID + +namespace ThreadNetworks { +static constexpr AttributeId Id = 0x00000001; +} // namespace ThreadNetworks + +namespace ThreadNetworkTableSize { +static constexpr AttributeId Id = 0x00000002; +} // namespace ThreadNetworkTableSize + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ThreadNetworkDirectory + namespace WakeOnLan { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index f457887220abad..b85aded17ec764 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -325,6 +325,12 @@ static constexpr ClusterId Id = 0x0000042E; namespace RadonConcentrationMeasurement { static constexpr ClusterId Id = 0x0000042F; } // namespace RadonConcentrationMeasurement +namespace WiFiNetworkManagement { +static constexpr ClusterId Id = 0x00000451; +} // namespace WiFiNetworkManagement +namespace ThreadNetworkDirectory { +static constexpr ClusterId Id = 0x00000453; +} // namespace ThreadNetworkDirectory namespace WakeOnLan { static constexpr ClusterId Id = 0x00000503; } // namespace WakeOnLan diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index da8b04c98c1963..27de98be5e9dee 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1381,6 +1381,42 @@ static constexpr CommandId Id = 0x0000004C; } // namespace Commands } // namespace ColorControl +namespace WiFiNetworkManagement { +namespace Commands { + +namespace NetworkPassphraseRequest { +static constexpr CommandId Id = 0x00000000; +} // namespace NetworkPassphraseRequest + +namespace NetworkPassphraseResponse { +static constexpr CommandId Id = 0x00000001; +} // namespace NetworkPassphraseResponse + +} // namespace Commands +} // namespace WiFiNetworkManagement + +namespace ThreadNetworkDirectory { +namespace Commands { + +namespace AddNetwork { +static constexpr CommandId Id = 0x00000000; +} // namespace AddNetwork + +namespace RemoveNetwork { +static constexpr CommandId Id = 0x00000001; +} // namespace RemoveNetwork + +namespace GetOperationalDataset { +static constexpr CommandId Id = 0x00000002; +} // namespace GetOperationalDataset + +namespace OperationalDatasetResponse { +static constexpr CommandId Id = 0x00000003; +} // namespace OperationalDatasetResponse + +} // namespace Commands +} // namespace ThreadNetworkDirectory + namespace Channel { namespace Commands { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h index 28e5799188e843..1592020a008379 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h @@ -611,6 +611,16 @@ static constexpr EventId Id = 0x00000010; } // namespace Events } // namespace PumpConfigurationAndControl +namespace ThreadNetworkDirectory { +namespace Events { + +namespace NetworkChanged { +static constexpr EventId Id = 0x00000000; +} // namespace NetworkChanged + +} // namespace Events +} // namespace ThreadNetworkDirectory + namespace TargetNavigator { namespace Events { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 8a3081edc0dc1b..6552c1be593c49 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -135,6 +135,8 @@ | Pm10ConcentrationMeasurement | 0x042D | | TotalVolatileOrganicCompoundsConcentrationMeasurement | 0x042E | | RadonConcentrationMeasurement | 0x042F | +| WiFiNetworkManagement | 0x0451 | +| ThreadNetworkDirectory | 0x0453 | | WakeOnLan | 0x0503 | | Channel | 0x0504 | | TargetNavigator | 0x0505 | @@ -11017,6 +11019,198 @@ class ColorControlStepColorTemperature : public ClusterCommand | Events: | | \*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*\ +| Cluster WiFiNetworkManagement | 0x0451 | +|------------------------------------------------------------------------------| +| Commands: | | +| * NetworkPassphraseRequest | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * Ssid | 0x0001 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command NetworkPassphraseRequest + */ +class WiFiNetworkManagementNetworkPassphraseRequest : public ClusterCommand +{ +public: + WiFiNetworkManagementNetworkPassphraseRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("network-passphrase-request", credsIssuerConfig) + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Type mRequest; +}; + +/*----------------------------------------------------------------------------*\ +| Cluster ThreadNetworkDirectory | 0x0453 | +|------------------------------------------------------------------------------| +| Commands: | | +| * AddNetwork | 0x00 | +| * RemoveNetwork | 0x01 | +| * GetOperationalDataset | 0x02 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * PreferredExtendedPanID | 0x0000 | +| * ThreadNetworks | 0x0001 | +| * ThreadNetworkTableSize | 0x0002 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +| * NetworkChanged | 0x0000 | +\*----------------------------------------------------------------------------*/ + +/* + * Command AddNetwork + */ +class ThreadNetworkDirectoryAddNetwork : public ClusterCommand +{ +public: + ThreadNetworkDirectoryAddNetwork(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("add-network", credsIssuerConfig) + { + AddArgument("OperationalDataset", &mRequest.operationalDataset); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Type mRequest; +}; + +/* + * Command RemoveNetwork + */ +class ThreadNetworkDirectoryRemoveNetwork : public ClusterCommand +{ +public: + ThreadNetworkDirectoryRemoveNetwork(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("remove-network", credsIssuerConfig) + { + AddArgument("ExtendedPanID", 0, UINT64_MAX, &mRequest.extendedPanID); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Type mRequest; +}; + +/* + * Command GetOperationalDataset + */ +class ThreadNetworkDirectoryGetOperationalDataset : public ClusterCommand +{ +public: + ThreadNetworkDirectoryGetOperationalDataset(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("get-operational-dataset", credsIssuerConfig) + { + AddArgument("ExtendedPanID", 0, UINT64_MAX, &mRequest.extendedPanID); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster WakeOnLan | 0x0503 | |------------------------------------------------------------------------------| @@ -24507,6 +24701,134 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands, Credentia commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::WiFiNetworkManagement; + + const char * clusterName = "WiFiNetworkManagement"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "ssid", Attributes::Ssid::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "ssid", Attributes::Ssid::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "ssid", Attributes::Ssid::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} +void registerClusterThreadNetworkDirectory(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::ThreadNetworkDirectory; + + const char * clusterName = "ThreadNetworkDirectory"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "preferred-extended-pan-id", Attributes::PreferredExtendedPanID::Id, credsIssuerConfig), // + make_unique(Id, "thread-networks", Attributes::ThreadNetworks::Id, credsIssuerConfig), // + make_unique(Id, "thread-network-table-size", Attributes::ThreadNetworkTableSize::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>(Id, "preferred-extended-pan-id", 0, UINT64_MAX, + Attributes::PreferredExtendedPanID::Id, + WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>>( + Id, "thread-networks", Attributes::ThreadNetworks::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "thread-network-table-size", 0, UINT8_MAX, Attributes::ThreadNetworkTableSize::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "preferred-extended-pan-id", Attributes::PreferredExtendedPanID::Id, + credsIssuerConfig), // + make_unique(Id, "thread-networks", Attributes::ThreadNetworks::Id, credsIssuerConfig), // + make_unique(Id, "thread-network-table-size", Attributes::ThreadNetworkTableSize::Id, + credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "network-changed", Events::NetworkChanged::Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "network-changed", Events::NetworkChanged::Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterWakeOnLan(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::WakeOnLan; @@ -26861,6 +27183,8 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterPm10ConcentrationMeasurement(commands, credsIssuerConfig); registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(commands, credsIssuerConfig); registerClusterRadonConcentrationMeasurement(commands, credsIssuerConfig); + registerClusterWiFiNetworkManagement(commands, credsIssuerConfig); + registerClusterThreadNetworkDirectory(commands, credsIssuerConfig); registerClusterWakeOnLan(commands, credsIssuerConfig); registerClusterChannel(commands, credsIssuerConfig); registerClusterTargetNavigator(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 89f34d0cee3714..661735e8d0cffc 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -3986,6 +3986,45 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::W ComplexArgumentParser::Finalize(request.coolSetpoint); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadNetworkStruct.extendedPanID", "extendedPanID", + value.isMember("extendedPanID"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ThreadNetworkStruct.networkName", "networkName", value.isMember("networkName"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ThreadNetworkStruct.channel", "channel", value.isMember("channel"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extendedPanID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extendedPanID, value["extendedPanID"])); + valueCopy.removeMember("extendedPanID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "networkName"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.networkName, value["networkName"])); + valueCopy.removeMember("networkName"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "channel"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.channel, value["channel"])); + valueCopy.removeMember("channel"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.extendedPanID); + ComplexArgumentParser::Finalize(request.networkName); + ComplexArgumentParser::Finalize(request.channel); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Channel::Structs::ProgramCastStruct::Type & request, Json::Value & value) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index a9ac94c6cecb77..7263b234708be5 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -455,6 +455,12 @@ static CHIP_ERROR Setup(const char * label, static void Finalize(chip::app::Clusters::Thermostat::Structs::WeeklyScheduleTransitionStruct::Type & request); +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Channel::Structs::ProgramCastStruct::Type & request, Json::Value & value); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index fde5089bab8a7c..8cd52cb458c885 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -3528,6 +3528,40 @@ DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("ExtendedPanID", indent + 1, value.extendedPanID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ExtendedPanID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("NetworkName", indent + 1, value.networkName); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'NetworkName'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Channel", indent + 1, value.channel); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Channel'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::Channel::Structs::ProgramCastStruct::DecodableType & value) { @@ -6969,6 +7003,22 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const ThreadNetworkDirectory::Events::NetworkChanged::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = DataModelLogger::LogValue("ExtendedPanID", indent + 1, value.extendedPanID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ExtendedPanID'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const TargetNavigator::Events::TargetUpdated::DecodableType & value) { @@ -7719,6 +7769,22 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("passphrase", indent + 1, value.passphrase)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("operationalDataset", indent + 1, value.operationalDataset)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const Channel::Commands::ChangeChannelResponse::DecodableType & value) { @@ -16089,6 +16155,100 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case WiFiNetworkManagement::Id: { + switch (path.mAttributeId) + { + case WiFiNetworkManagement::Attributes::Ssid::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SSID", 1, value); + } + case WiFiNetworkManagement::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case WiFiNetworkManagement::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case WiFiNetworkManagement::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case WiFiNetworkManagement::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case WiFiNetworkManagement::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case WiFiNetworkManagement::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } + case ThreadNetworkDirectory::Id: { + switch (path.mAttributeId) + { + case ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("PreferredExtendedPanID", 1, value); + } + case ThreadNetworkDirectory::Attributes::ThreadNetworks::Id: { + chip::app::DataModel::DecodableList< + chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::DecodableType> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ThreadNetworks", 1, value); + } + case ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::Id: { + uint8_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ThreadNetworkTableSize", 1, value); + } + case ThreadNetworkDirectory::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case ThreadNetworkDirectory::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case ThreadNetworkDirectory::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case ThreadNetworkDirectory::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case ThreadNetworkDirectory::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case ThreadNetworkDirectory::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case WakeOnLan::Id: { switch (path.mAttributeId) { @@ -18438,6 +18598,28 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case WiFiNetworkManagement::Id: { + switch (path.mCommandId) + { + case WiFiNetworkManagement::Commands::NetworkPassphraseResponse::Id: { + WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("NetworkPassphraseResponse", 1, value); + } + } + break; + } + case ThreadNetworkDirectory::Id: { + switch (path.mCommandId) + { + case ThreadNetworkDirectory::Commands::OperationalDatasetResponse::Id: { + ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("OperationalDatasetResponse", 1, value); + } + } + break; + } case Channel::Id: { switch (path.mCommandId) { @@ -19369,6 +19551,17 @@ CHIP_ERROR DataModelLogger::LogEvent(const chip::app::EventHeader & header, chip } break; } + case ThreadNetworkDirectory::Id: { + switch (header.mPath.mEventId) + { + case ThreadNetworkDirectory::Events::NetworkChanged::Id: { + chip::app::Clusters::ThreadNetworkDirectory::Events::NetworkChanged::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("NetworkChanged", 1, value); + } + } + break; + } case TargetNavigator::Id: { switch (header.mPath.mEventId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 1c790b5e002039..5a562d72f6fd08 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -284,6 +284,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::WeeklyScheduleTransitionStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Channel::Structs::ProgramCastStruct::DecodableType & value); @@ -602,6 +605,8 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::PumpConfigurationAndControl::Events::AirDetection::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::PumpConfigurationAndControl::Events::TurbineOperation::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadNetworkDirectory::Events::NetworkChanged::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::TargetNavigator::Events::TargetUpdated::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, @@ -735,6 +740,12 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Commands::GetCredentialStatusResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Commands::GetWeeklyScheduleResponse::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Channel::Commands::ChangeChannelResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index c3034217db9c05..92f8095b738474 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -137,6 +137,8 @@ | Pm10ConcentrationMeasurement | 0x042D | | TotalVolatileOrganicCompoundsConcentrationMeasurement | 0x042E | | RadonConcentrationMeasurement | 0x042F | +| WiFiNetworkManagement | 0x0451 | +| ThreadNetworkDirectory | 0x0453 | | WakeOnLan | 0x0503 | | Channel | 0x0504 | | TargetNavigator | 0x0505 | @@ -143040,6 +143042,1674 @@ class SubscribeAttributeRadonConcentrationMeasurementClusterRevision : public Su } }; +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster WiFiNetworkManagement | 0x0451 | +|------------------------------------------------------------------------------| +| Commands: | | +| * NetworkPassphraseRequest | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * Ssid | 0x0001 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command NetworkPassphraseRequest + */ +class WiFiNetworkManagementNetworkPassphraseRequest : public ClusterCommand { +public: + WiFiNetworkManagementNetworkPassphraseRequest() + : ClusterCommand("network-passphrase-request") + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWiFiNetworkManagementClusterNetworkPassphraseRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster networkPassphraseRequestWithParams:params completion: + ^(MTRWiFiNetworkManagementClusterNetworkPassphraseResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::WiFiNetworkManagement::Commands::NetworkPassphraseResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute Ssid + */ +class ReadWiFiNetworkManagementSsid : public ReadAttribute { +public: + ReadWiFiNetworkManagementSsid() + : ReadAttribute("ssid") + { + } + + ~ReadWiFiNetworkManagementSsid() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::Ssid::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSSIDWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.SSID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement SSID read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementSsid : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementSsid() + : SubscribeAttribute("ssid") + { + } + + ~SubscribeAttributeWiFiNetworkManagementSsid() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::Ssid::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSSIDWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.SSID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadWiFiNetworkManagementGeneratedCommandList : public ReadAttribute { +public: + ReadWiFiNetworkManagementGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadWiFiNetworkManagementGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeWiFiNetworkManagementGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadWiFiNetworkManagementAcceptedCommandList : public ReadAttribute { +public: + ReadWiFiNetworkManagementAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadWiFiNetworkManagementAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeWiFiNetworkManagementAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadWiFiNetworkManagementEventList : public ReadAttribute { +public: + ReadWiFiNetworkManagementEventList() + : ReadAttribute("event-list") + { + } + + ~ReadWiFiNetworkManagementEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementEventList : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeWiFiNetworkManagementEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadWiFiNetworkManagementAttributeList : public ReadAttribute { +public: + ReadWiFiNetworkManagementAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadWiFiNetworkManagementAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeWiFiNetworkManagementAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadWiFiNetworkManagementFeatureMap : public ReadAttribute { +public: + ReadWiFiNetworkManagementFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadWiFiNetworkManagementFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeWiFiNetworkManagementFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadWiFiNetworkManagementClusterRevision : public ReadAttribute { +public: + ReadWiFiNetworkManagementClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadWiFiNetworkManagementClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeWiFiNetworkManagementClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster ThreadNetworkDirectory | 0x0453 | +|------------------------------------------------------------------------------| +| Commands: | | +| * AddNetwork | 0x00 | +| * RemoveNetwork | 0x01 | +| * GetOperationalDataset | 0x02 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * PreferredExtendedPanID | 0x0000 | +| * ThreadNetworks | 0x0001 | +| * ThreadNetworkTableSize | 0x0002 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +| * NetworkChanged | 0x0000 | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command AddNetwork + */ +class ThreadNetworkDirectoryAddNetwork : public ClusterCommand { +public: + ThreadNetworkDirectoryAddNetwork() + : ClusterCommand("add-network") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("OperationalDataset", &mRequest.operationalDataset); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadNetworkDirectoryClusterAddNetworkParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.operationalDataset = [NSData dataWithBytes:mRequest.operationalDataset.data() length:mRequest.operationalDataset.size()]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster addNetworkWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command RemoveNetwork + */ +class ThreadNetworkDirectoryRemoveNetwork : public ClusterCommand { +public: + ThreadNetworkDirectoryRemoveNetwork() + : ClusterCommand("remove-network") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("ExtendedPanID", 0, UINT64_MAX, &mRequest.extendedPanID); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadNetworkDirectoryClusterRemoveNetworkParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.extendedPanID = [NSNumber numberWithUnsignedLongLong:mRequest.extendedPanID]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster removeNetworkWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command GetOperationalDataset + */ +class ThreadNetworkDirectoryGetOperationalDataset : public ClusterCommand { +public: + ThreadNetworkDirectoryGetOperationalDataset() + : ClusterCommand("get-operational-dataset") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("ExtendedPanID", 0, UINT64_MAX, &mRequest.extendedPanID); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRThreadNetworkDirectoryClusterGetOperationalDatasetParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.extendedPanID = [NSNumber numberWithUnsignedLongLong:mRequest.extendedPanID]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster getOperationalDatasetWithParams:params completion: + ^(MTRThreadNetworkDirectoryClusterOperationalDatasetResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute PreferredExtendedPanID + */ +class ReadThreadNetworkDirectoryPreferredExtendedPanID : public ReadAttribute { +public: + ReadThreadNetworkDirectoryPreferredExtendedPanID() + : ReadAttribute("preferred-extended-pan-id") + { + } + + ~ReadThreadNetworkDirectoryPreferredExtendedPanID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributePreferredExtendedPanIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.PreferredExtendedPanID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory PreferredExtendedPanID read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteThreadNetworkDirectoryPreferredExtendedPanID : public WriteAttribute { +public: + WriteThreadNetworkDirectoryPreferredExtendedPanID() + : WriteAttribute("preferred-extended-pan-id") + { + AddArgument("attr-name", "preferred-extended-pan-id"); + AddArgument("attr-value", 0, UINT64_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteThreadNetworkDirectoryPreferredExtendedPanID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedLongLong:mValue.Value()]; + } + + [cluster writeAttributePreferredExtendedPanIDWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("ThreadNetworkDirectory PreferredExtendedPanID write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeThreadNetworkDirectoryPreferredExtendedPanID : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryPreferredExtendedPanID() + : SubscribeAttribute("preferred-extended-pan-id") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryPreferredExtendedPanID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::PreferredExtendedPanID::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributePreferredExtendedPanIDWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.PreferredExtendedPanID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ThreadNetworks + */ +class ReadThreadNetworkDirectoryThreadNetworks : public ReadAttribute { +public: + ReadThreadNetworkDirectoryThreadNetworks() + : ReadAttribute("thread-networks") + { + } + + ~ReadThreadNetworkDirectoryThreadNetworks() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::ThreadNetworks::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeThreadNetworksWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.ThreadNetworks response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory ThreadNetworks read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryThreadNetworks : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryThreadNetworks() + : SubscribeAttribute("thread-networks") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryThreadNetworks() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::ThreadNetworks::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeThreadNetworksWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.ThreadNetworks response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ThreadNetworkTableSize + */ +class ReadThreadNetworkDirectoryThreadNetworkTableSize : public ReadAttribute { +public: + ReadThreadNetworkDirectoryThreadNetworkTableSize() + : ReadAttribute("thread-network-table-size") + { + } + + ~ReadThreadNetworkDirectoryThreadNetworkTableSize() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeThreadNetworkTableSizeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.ThreadNetworkTableSize response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory ThreadNetworkTableSize read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryThreadNetworkTableSize : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryThreadNetworkTableSize() + : SubscribeAttribute("thread-network-table-size") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryThreadNetworkTableSize() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::ThreadNetworkTableSize::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeThreadNetworkTableSizeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.ThreadNetworkTableSize response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadThreadNetworkDirectoryGeneratedCommandList : public ReadAttribute { +public: + ReadThreadNetworkDirectoryGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadThreadNetworkDirectoryGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadThreadNetworkDirectoryAcceptedCommandList : public ReadAttribute { +public: + ReadThreadNetworkDirectoryAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadThreadNetworkDirectoryAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadThreadNetworkDirectoryEventList : public ReadAttribute { +public: + ReadThreadNetworkDirectoryEventList() + : ReadAttribute("event-list") + { + } + + ~ReadThreadNetworkDirectoryEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryEventList : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadThreadNetworkDirectoryAttributeList : public ReadAttribute { +public: + ReadThreadNetworkDirectoryAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadThreadNetworkDirectoryAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadThreadNetworkDirectoryFeatureMap : public ReadAttribute { +public: + ReadThreadNetworkDirectoryFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadThreadNetworkDirectoryFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadThreadNetworkDirectoryClusterRevision : public ReadAttribute { +public: + ReadThreadNetworkDirectoryClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadThreadNetworkDirectoryClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ThreadNetworkDirectory ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeThreadNetworkDirectoryClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeThreadNetworkDirectoryClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeThreadNetworkDirectoryClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ThreadNetworkDirectory.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ | Cluster WakeOnLan | 0x0503 | |------------------------------------------------------------------------------| @@ -187891,6 +189561,119 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWiFiNetworkManagement(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::WiFiNetworkManagement; + + const char * clusterName = "WiFiNetworkManagement"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} +void registerClusterThreadNetworkDirectory(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::ThreadNetworkDirectory; + + const char * clusterName = "ThreadNetworkDirectory"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterWakeOnLan(Commands & commands) { using namespace chip::app::Clusters::WakeOnLan; @@ -189301,6 +191084,8 @@ void registerClusters(Commands & commands) registerClusterPm10ConcentrationMeasurement(commands); registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(commands); registerClusterRadonConcentrationMeasurement(commands); + registerClusterWiFiNetworkManagement(commands); + registerClusterThreadNetworkDirectory(commands); registerClusterWakeOnLan(commands); registerClusterChannel(commands); registerClusterTargetNavigator(commands);