diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index dc152c1a714f19..4297e791326786 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -26,14 +26,14 @@ on: run-codeql: required: false type: boolean - + concurrency: group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} cancel-in-progress: true env: CHIP_NO_LOG_TIMESTAMPS: true - + jobs: build_linux_gcc_debug: name: Build on Linux (gcc_debug) @@ -210,7 +210,7 @@ jobs: ./scripts/run_in_build_env.sh \ "./scripts/run-clang-tidy-on-compile-commands.py \ --compile-database out/sanitizers/compile_commands.json \ - --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|-ReadImpl|-InvokeSubscribeImpl|CodegenDataModel_Write' \ + --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|-ReadImpl|-InvokeSubscribeImpl|CodegenDataModel_Write|QuieterReporting' \ check \ " - name: Clean output @@ -243,7 +243,7 @@ jobs: run: | rm -rf ./zzz_pregenerated mv scripts/codegen.py.renamed scripts/codegen.py - mv scripts/tools/zap/generate.py.renamed scripts/tools/zap/generate.py + mv scripts/tools/zap/generate.py.renamed scripts/tools/zap/generate.py - name: Run fake linux tests with build_examples run: | ./scripts/run_in_build_env.sh \ @@ -253,7 +253,7 @@ jobs: uses: ./.github/actions/perform-codeql-analysis with: language: cpp - + - name: Uploading core files uses: actions/upload-artifact@v4 if: ${{ failure() && !env.ACT }} @@ -430,7 +430,7 @@ jobs: ./scripts/run_in_build_env.sh \ "./scripts/run-clang-tidy-on-compile-commands.py \ --compile-database out/default/compile_commands.json \ - --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|CodegenDataModel_Write' \ + --file-exclude-regex '/(repo|zzz_generated|lwip/standalone)/|CodegenDataModel_Write|QuieterReporting' \ check \ " - name: Uploading diagnostic logs @@ -445,7 +445,7 @@ jobs: uses: ./.github/actions/perform-codeql-analysis with: language: cpp - + # TODO Log Upload https://github.com/project-chip/connectedhomeip/issues/2227 # TODO https://github.com/project-chip/connectedhomeip/issues/1512 diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 05d434b0a67792..07ab55d1315bb5 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -60,14 +60,14 @@ jobs: run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ - --target nxp-k32w0-lighting \ - --target nxp-k32w0-lighting-factory \ - --target nxp-k32w0-lighting-rotating-id \ - --target nxp-k32w0-contact-sensor \ - --target nxp-k32w0-contact-sensor-low-power \ - --target nxp-k32w0-contact-sensor-low-power-factory \ - --target nxp-k32w1-lighting \ - --target nxp-k32w1-contact-sensor-low-power \ + --target nxp-k32w0-freertos-lighting \ + --target nxp-k32w0-freertos-lighting-factory \ + --target nxp-k32w0-freertos-lighting-rotating-id \ + --target nxp-k32w0-freertos-contact-sensor \ + --target nxp-k32w0-freertos-contact-sensor-low-power \ + --target nxp-k32w0-freertos-contact-sensor-low-power-factory \ + --target nxp-k32w1-freertos-lighting \ + --target nxp-k32w1-freertos-contact-sensor-low-power \ build \ --copy-artifacts-to out/artifacts \ " @@ -75,21 +75,21 @@ jobs: run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release light \ - out/artifacts/nxp-k32w0-lighting/chip-k32w0x-light-example.elf \ + out/artifacts/nxp-k32w0-freertos-lighting/chip-k32w0x-light-example.elf \ /tmp/bloat_reports/ .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w1+release light \ - out/artifacts/nxp-k32w1-lighting/chip-k32w1-light-example.elf \ + out/artifacts/nxp-k32w1-freertos-lighting/chip-k32w1-light-example.elf \ /tmp/bloat_reports/ - name: Get contact sensor size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release contact \ - out/artifacts/nxp-k32w0-contact-sensor-low-power/chip-k32w0x-contact-example.elf \ + out/artifacts/nxp-k32w0-freertos-contact-sensor-low-power/chip-k32w0x-contact-example.elf \ /tmp/bloat_reports/ .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w1+release contact \ - out/artifacts/nxp-k32w1-contact-sensor-low-power/chip-k32w1-contact-example.elf \ + out/artifacts/nxp-k32w1-freertos-contact-sensor-low-power/chip-k32w1-contact-example.elf \ /tmp/bloat_reports/ - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 866a30f17c4419..7a3d516f06c64b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -112,6 +112,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/clusters-extensions.xml \ src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml \ @@ -494,7 +495,7 @@ jobs: - name: Run Tests run: | mkdir -p out/trace_data - scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --quiet --app-args "--trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script-args "--log-level INFO -t 3600 --disable-test ClusterObjectTests.TestTimedRequestTimeout --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/controller/python/test/test_scripts/mobile-device-test.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_3.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_4.py' diff --git a/data_model/1.3/clusters/ACL-Cluster.xml b/data_model/1.3/clusters/ACL-Cluster.xml index a193ef2ac3206f..deed8c409337a5 100644 --- a/data_model/1.3/clusters/ACL-Cluster.xml +++ b/data_model/1.3/clusters/ACL-Cluster.xml @@ -169,19 +169,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/AdminCommissioningCluster.xml b/data_model/1.3/clusters/AdminCommissioningCluster.xml index ccbb579134dc00..8e95e46f128db0 100644 --- a/data_model/1.3/clusters/AdminCommissioningCluster.xml +++ b/data_model/1.3/clusters/AdminCommissioningCluster.xml @@ -91,12 +91,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/AlarmBase.xml b/data_model/1.3/clusters/AlarmBase.xml index fd0ccb5bc19d46..e374dcc382d208 100644 --- a/data_model/1.3/clusters/AlarmBase.xml +++ b/data_model/1.3/clusters/AlarmBase.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ApplicationBasic.xml b/data_model/1.3/clusters/ApplicationBasic.xml index ee39b8a421209d..28e47e7800352e 100644 --- a/data_model/1.3/clusters/ApplicationBasic.xml +++ b/data_model/1.3/clusters/ApplicationBasic.xml @@ -92,29 +92,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -125,14 +125,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ApplicationLauncher.xml b/data_model/1.3/clusters/ApplicationLauncher.xml index 57d6858dd8ce14..27fa528a81e8cf 100644 --- a/data_model/1.3/clusters/ApplicationLauncher.xml +++ b/data_model/1.3/clusters/ApplicationLauncher.xml @@ -103,14 +103,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/BallastConfiguration.xml b/data_model/1.3/clusters/BallastConfiguration.xml index 0f37d86067e994..9dbf4e61887d76 100644 --- a/data_model/1.3/clusters/BallastConfiguration.xml +++ b/data_model/1.3/clusters/BallastConfiguration.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + + + @@ -116,12 +118,12 @@ Davis, CA 95616, USA - + - + @@ -141,12 +143,12 @@ Davis, CA 95616, USA - + - + @@ -155,7 +157,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/BasicInformationCluster.xml b/data_model/1.3/clusters/BasicInformationCluster.xml index 137e8b70408bf8..69a882a09490d8 100644 --- a/data_model/1.3/clusters/BasicInformationCluster.xml +++ b/data_model/1.3/clusters/BasicInformationCluster.xml @@ -174,100 +174,100 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -276,29 +276,29 @@ Davis, CA 95616, USA - + - + - + - + - + diff --git a/data_model/1.3/clusters/Binding-Cluster.xml b/data_model/1.3/clusters/Binding-Cluster.xml index 444c99b315348d..055725f0b9ee47 100644 --- a/data_model/1.3/clusters/Binding-Cluster.xml +++ b/data_model/1.3/clusters/Binding-Cluster.xml @@ -97,7 +97,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/BooleanState.xml b/data_model/1.3/clusters/BooleanState.xml index 5bb29f53ae0c3e..ddb16e26a1d6ad 100644 --- a/data_model/1.3/clusters/BooleanState.xml +++ b/data_model/1.3/clusters/BooleanState.xml @@ -68,7 +68,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/BooleanStateConfiguration.xml b/data_model/1.3/clusters/BooleanStateConfiguration.xml index 01444d565294b3..719cd9569b5ae2 100644 --- a/data_model/1.3/clusters/BooleanStateConfiguration.xml +++ b/data_model/1.3/clusters/BooleanStateConfiguration.xml @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + @@ -122,7 +122,7 @@ Davis, CA 95616, USA - + @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -155,7 +155,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Channel.xml b/data_model/1.3/clusters/Channel.xml index 17144c9032c3e5..6177bfe6a652cc 100644 --- a/data_model/1.3/clusters/Channel.xml +++ b/data_model/1.3/clusters/Channel.xml @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + @@ -315,7 +315,7 @@ Davis, CA 95616, USA - + @@ -366,6 +366,7 @@ Davis, CA 95616, USA + @@ -400,6 +401,7 @@ Davis, CA 95616, USA + @@ -412,6 +414,7 @@ Davis, CA 95616, USA + @@ -437,6 +440,7 @@ Davis, CA 95616, USA + diff --git a/data_model/1.3/clusters/ColorControl.xml b/data_model/1.3/clusters/ColorControl.xml index 456b3ff14cfff9..ebf29e0b51e758 100644 --- a/data_model/1.3/clusters/ColorControl.xml +++ b/data_model/1.3/clusters/ColorControl.xml @@ -74,16 +74,16 @@ Davis, CA 95616, USA - + - + - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + @@ -99,7 +99,7 @@ Davis, CA 95616, USA - + @@ -112,7 +112,7 @@ Davis, CA 95616, USA - + @@ -120,7 +120,7 @@ Davis, CA 95616, USA - + @@ -155,7 +155,7 @@ Davis, CA 95616, USA - + @@ -174,7 +174,7 @@ Davis, CA 95616, USA - + @@ -191,110 +191,110 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -319,7 +319,7 @@ Davis, CA 95616, USA - + @@ -334,7 +334,7 @@ Davis, CA 95616, USA - + @@ -349,12 +349,12 @@ Davis, CA 95616, USA - + - + @@ -375,27 +375,27 @@ Davis, CA 95616, USA - + - + - + - + @@ -439,11 +439,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ConcentrationMeasurement.xml b/data_model/1.3/clusters/ConcentrationMeasurement.xml index 4b51cffa124321..b622a3560b4ff0 100644 --- a/data_model/1.3/clusters/ConcentrationMeasurement.xml +++ b/data_model/1.3/clusters/ConcentrationMeasurement.xml @@ -62,16 +62,16 @@ Davis, CA 95616, USA - - - - - - - - - - + + + + + + + + + + @@ -181,7 +181,7 @@ Davis, CA 95616, USA - + @@ -189,7 +189,7 @@ Davis, CA 95616, USA - + @@ -197,7 +197,7 @@ Davis, CA 95616, USA - + @@ -205,7 +205,7 @@ Davis, CA 95616, USA - + @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -221,7 +221,7 @@ Davis, CA 95616, USA - + @@ -229,7 +229,7 @@ Davis, CA 95616, USA - + @@ -244,14 +244,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ContentControl.xml b/data_model/1.3/clusters/ContentControl.xml index b2539cf445c289..6848886c43ac02 100644 --- a/data_model/1.3/clusters/ContentControl.xml +++ b/data_model/1.3/clusters/ContentControl.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/ContentLauncher.xml b/data_model/1.3/clusters/ContentLauncher.xml index 9a5674efa8eb64..b4d6e7fa26500c 100644 --- a/data_model/1.3/clusters/ContentLauncher.xml +++ b/data_model/1.3/clusters/ContentLauncher.xml @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Descriptor-Cluster.xml b/data_model/1.3/clusters/Descriptor-Cluster.xml index 659b2ffaa5ddc0..d648f1c7f1be91 100644 --- a/data_model/1.3/clusters/Descriptor-Cluster.xml +++ b/data_model/1.3/clusters/Descriptor-Cluster.xml @@ -84,20 +84,20 @@ Davis, CA 95616, USA - + - + - + @@ -108,7 +108,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/DeviceEnergyManagement.xml b/data_model/1.3/clusters/DeviceEnergyManagement.xml index f74d7e572550cc..0fe30cc92e5506 100644 --- a/data_model/1.3/clusters/DeviceEnergyManagement.xml +++ b/data_model/1.3/clusters/DeviceEnergyManagement.xml @@ -64,7 +64,9 @@ Davis, CA 95616, USA - + + + @@ -473,6 +475,63 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/1.3/clusters/DiagnosticsEthernet.xml b/data_model/1.3/clusters/DiagnosticsEthernet.xml index dfcd3d11c41f52..fd2bb0341ca06c 100644 --- a/data_model/1.3/clusters/DiagnosticsEthernet.xml +++ b/data_model/1.3/clusters/DiagnosticsEthernet.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -108,57 +110,57 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/DiagnosticsGeneral.xml b/data_model/1.3/clusters/DiagnosticsGeneral.xml index 4da912b03dc3df..ff78100fe3a7d3 100644 --- a/data_model/1.3/clusters/DiagnosticsGeneral.xml +++ b/data_model/1.3/clusters/DiagnosticsGeneral.xml @@ -223,17 +223,17 @@ Davis, CA 95616, USA - + - + - + @@ -310,7 +310,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.3/clusters/DiagnosticsSoftware.xml b/data_model/1.3/clusters/DiagnosticsSoftware.xml index 7cb3c9ff39ad2f..c7ee8ee842bf02 100644 --- a/data_model/1.3/clusters/DiagnosticsSoftware.xml +++ b/data_model/1.3/clusters/DiagnosticsSoftware.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/DiagnosticsThread.xml b/data_model/1.3/clusters/DiagnosticsThread.xml index 120efaddf8c08e..1da3eba21a4e4e 100644 --- a/data_model/1.3/clusters/DiagnosticsThread.xml +++ b/data_model/1.3/clusters/DiagnosticsThread.xml @@ -63,7 +63,9 @@ Davis, CA 95616, USA - + + + @@ -257,38 +259,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -305,356 +307,356 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/DiagnosticsWiFi.xml b/data_model/1.3/clusters/DiagnosticsWiFi.xml index b3951d967dc31f..6ef28ee4cc09e0 100644 --- a/data_model/1.3/clusters/DiagnosticsWiFi.xml +++ b/data_model/1.3/clusters/DiagnosticsWiFi.xml @@ -55,14 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + + + @@ -141,81 +143,81 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/DoorLock.xml b/data_model/1.3/clusters/DoorLock.xml index fcf86f3a95aa24..11b5de565e2afb 100644 --- a/data_model/1.3/clusters/DoorLock.xml +++ b/data_model/1.3/clusters/DoorLock.xml @@ -570,7 +570,7 @@ Davis, CA 95616, USA - + @@ -738,7 +738,7 @@ Davis, CA 95616, USA - + @@ -753,7 +753,7 @@ Davis, CA 95616, USA - + @@ -779,167 +779,167 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -950,7 +950,7 @@ Davis, CA 95616, USA - + @@ -961,7 +961,7 @@ Davis, CA 95616, USA - + @@ -973,7 +973,7 @@ Davis, CA 95616, USA - + @@ -986,7 +986,7 @@ Davis, CA 95616, USA - + @@ -994,12 +994,12 @@ Davis, CA 95616, USA - + - + @@ -1009,21 +1009,21 @@ Davis, CA 95616, USA - + - + - + @@ -1033,7 +1033,7 @@ Davis, CA 95616, USA - + @@ -1043,14 +1043,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml b/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml index f8bbec4c03db95..9a4012eebc5327 100644 --- a/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/1.3/clusters/ElectricalEnergyMeasurement.xml @@ -135,12 +135,12 @@ Davis, CA 95616, USA - + - + @@ -150,7 +150,7 @@ Davis, CA 95616, USA - + @@ -160,7 +160,7 @@ Davis, CA 95616, USA - + @@ -170,7 +170,7 @@ Davis, CA 95616, USA - + @@ -180,7 +180,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ElectricalPowerMeasurement.xml b/data_model/1.3/clusters/ElectricalPowerMeasurement.xml index cfb8ce9018e73c..3f4e79ccdefcec 100644 --- a/data_model/1.3/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/1.3/clusters/ElectricalPowerMeasurement.xml @@ -170,39 +170,39 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -210,7 +210,7 @@ Davis, CA 95616, USA - + @@ -218,13 +218,13 @@ Davis, CA 95616, USA - + - + @@ -232,7 +232,7 @@ Davis, CA 95616, USA - + @@ -240,7 +240,7 @@ Davis, CA 95616, USA - + @@ -248,7 +248,7 @@ Davis, CA 95616, USA - + @@ -256,7 +256,7 @@ Davis, CA 95616, USA - + @@ -264,7 +264,7 @@ Davis, CA 95616, USA - + @@ -273,7 +273,7 @@ Davis, CA 95616, USA - + @@ -282,7 +282,7 @@ Davis, CA 95616, USA - + @@ -290,7 +290,7 @@ Davis, CA 95616, USA - + @@ -298,7 +298,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/EnergyEVSE.xml b/data_model/1.3/clusters/EnergyEVSE.xml index 4b881f5a1135a4..13052281c5157c 100644 --- a/data_model/1.3/clusters/EnergyEVSE.xml +++ b/data_model/1.3/clusters/EnergyEVSE.xml @@ -252,7 +252,7 @@ Davis, CA 95616, USA - + @@ -265,37 +265,37 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -303,33 +303,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -337,14 +337,14 @@ Davis, CA 95616, USA - + - + @@ -352,14 +352,14 @@ Davis, CA 95616, USA - + - + @@ -367,7 +367,7 @@ Davis, CA 95616, USA - + @@ -375,23 +375,23 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/1.3/clusters/EnergyPreference.xml b/data_model/1.3/clusters/EnergyPreference.xml index eafb527a868b22..c43161d8dff6f9 100644 --- a/data_model/1.3/clusters/EnergyPreference.xml +++ b/data_model/1.3/clusters/EnergyPreference.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -102,7 +104,7 @@ Davis, CA 95616, USA - + @@ -110,7 +112,7 @@ Davis, CA 95616, USA - + @@ -118,7 +120,7 @@ Davis, CA 95616, USA - + @@ -127,7 +129,7 @@ Davis, CA 95616, USA - + @@ -135,7 +137,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/FanControl.xml b/data_model/1.3/clusters/FanControl.xml index 224f811261f68b..1016b8923ba308 100644 --- a/data_model/1.3/clusters/FanControl.xml +++ b/data_model/1.3/clusters/FanControl.xml @@ -119,36 +119,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -187,13 +187,13 @@ Davis, CA 95616, USA - + - + @@ -201,13 +201,13 @@ Davis, CA 95616, USA - + - + @@ -218,7 +218,7 @@ Davis, CA 95616, USA - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + @@ -234,7 +234,7 @@ Davis, CA 95616, USA - + @@ -242,7 +242,7 @@ Davis, CA 95616, USA - + @@ -250,7 +250,7 @@ Davis, CA 95616, USA - + @@ -258,7 +258,7 @@ Davis, CA 95616, USA - + @@ -266,7 +266,7 @@ Davis, CA 95616, USA - + @@ -274,7 +274,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/FlowMeasurement.xml b/data_model/1.3/clusters/FlowMeasurement.xml index 71178874d57c14..717641eacb84eb 100644 --- a/data_model/1.3/clusters/FlowMeasurement.xml +++ b/data_model/1.3/clusters/FlowMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/GeneralCommissioningCluster.xml b/data_model/1.3/clusters/GeneralCommissioningCluster.xml index e440222780ea02..285bb4455d8f49 100644 --- a/data_model/1.3/clusters/GeneralCommissioningCluster.xml +++ b/data_model/1.3/clusters/GeneralCommissioningCluster.xml @@ -109,7 +109,7 @@ Davis, CA 95616, USA - + @@ -119,12 +119,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/Group-Key-Management-Cluster.xml b/data_model/1.3/clusters/Group-Key-Management-Cluster.xml index c1819628e34d7b..4e9ae482a064ed 100644 --- a/data_model/1.3/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/1.3/clusters/Group-Key-Management-Cluster.xml @@ -167,7 +167,7 @@ Davis, CA 95616, USA - + @@ -179,12 +179,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/Groups.xml b/data_model/1.3/clusters/Groups.xml index 1f168e13fad933..6c53c1a602f255 100644 --- a/data_model/1.3/clusters/Groups.xml +++ b/data_model/1.3/clusters/Groups.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ICDManagement.xml b/data_model/1.3/clusters/ICDManagement.xml index 512dfd119efef7..b1b478a166ee80 100644 --- a/data_model/1.3/clusters/ICDManagement.xml +++ b/data_model/1.3/clusters/ICDManagement.xml @@ -120,24 +120,24 @@ Davis, CA 95616, USA - + - + - + - + @@ -145,14 +145,14 @@ Davis, CA 95616, USA - + - + @@ -160,7 +160,7 @@ Davis, CA 95616, USA - + @@ -171,7 +171,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/IlluminanceMeasurement.xml b/data_model/1.3/clusters/IlluminanceMeasurement.xml index d3228b845ca058..02aa466de6b8a6 100644 --- a/data_model/1.3/clusters/IlluminanceMeasurement.xml +++ b/data_model/1.3/clusters/IlluminanceMeasurement.xml @@ -83,20 +83,20 @@ Davis, CA 95616, USA - + - + - + @@ -107,7 +107,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml b/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml index 98106b6fc33e40..b915e77bb5a01f 100644 --- a/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/1.3/clusters/Label-Cluster-FixedLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml b/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml index 0ca5566f0dc132..43148b6dc9186f 100644 --- a/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/1.3/clusters/Label-Cluster-LabelCluster.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml b/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml index eba0099ffb59d2..40dac53a4242cd 100644 --- a/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/1.3/clusters/Label-Cluster-UserLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LaundryDryerControls.xml b/data_model/1.3/clusters/LaundryDryerControls.xml index af4f787c0432b7..d860d2ef9dcf21 100644 --- a/data_model/1.3/clusters/LaundryDryerControls.xml +++ b/data_model/1.3/clusters/LaundryDryerControls.xml @@ -88,7 +88,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LaundryWasherControls.xml b/data_model/1.3/clusters/LaundryWasherControls.xml index 6c4f4bc0b0c3a5..2718142b74f991 100644 --- a/data_model/1.3/clusters/LaundryWasherControls.xml +++ b/data_model/1.3/clusters/LaundryWasherControls.xml @@ -108,7 +108,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LevelControl.xml b/data_model/1.3/clusters/LevelControl.xml index fa6cbe397a672a..2753325511ada6 100644 --- a/data_model/1.3/clusters/LevelControl.xml +++ b/data_model/1.3/clusters/LevelControl.xml @@ -68,7 +68,9 @@ Davis, CA 95616, USA - + + + @@ -120,7 +122,7 @@ Davis, CA 95616, USA - + @@ -153,7 +155,7 @@ Davis, CA 95616, USA - + @@ -184,28 +186,28 @@ Davis, CA 95616, USA - + - + - + - + - + diff --git a/data_model/1.3/clusters/LocalizationConfiguration.xml b/data_model/1.3/clusters/LocalizationConfiguration.xml index 66809f545389be..7ddfba8efcc9cb 100644 --- a/data_model/1.3/clusters/LocalizationConfiguration.xml +++ b/data_model/1.3/clusters/LocalizationConfiguration.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -75,7 +75,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LocalizationTimeFormat.xml b/data_model/1.3/clusters/LocalizationTimeFormat.xml index db8b809b0341a9..2ede281c7352a9 100644 --- a/data_model/1.3/clusters/LocalizationTimeFormat.xml +++ b/data_model/1.3/clusters/LocalizationTimeFormat.xml @@ -125,12 +125,12 @@ Davis, CA 95616, USA - + - + @@ -138,7 +138,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/LocalizationUnit.xml b/data_model/1.3/clusters/LocalizationUnit.xml index 2c6e1ecbd648e6..0157ebb53b0d39 100644 --- a/data_model/1.3/clusters/LocalizationUnit.xml +++ b/data_model/1.3/clusters/LocalizationUnit.xml @@ -84,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/MediaPlayback.xml b/data_model/1.3/clusters/MediaPlayback.xml index 03175277dc12c5..dae60d7a1b2572 100644 --- a/data_model/1.3/clusters/MediaPlayback.xml +++ b/data_model/1.3/clusters/MediaPlayback.xml @@ -223,7 +223,7 @@ Davis, CA 95616, USA - + @@ -231,7 +231,7 @@ Davis, CA 95616, USA - + @@ -239,7 +239,7 @@ Davis, CA 95616, USA - + @@ -254,7 +254,7 @@ Davis, CA 95616, USA - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -270,7 +270,7 @@ Davis, CA 95616, USA - + @@ -279,7 +279,7 @@ Davis, CA 95616, USA - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/MicrowaveOvenControl.xml b/data_model/1.3/clusters/MicrowaveOvenControl.xml index ecc9d23b143d4b..5c92c309d6de00 100644 --- a/data_model/1.3/clusters/MicrowaveOvenControl.xml +++ b/data_model/1.3/clusters/MicrowaveOvenControl.xml @@ -89,7 +89,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + @@ -110,7 +110,7 @@ Davis, CA 95616, USA - + @@ -118,7 +118,7 @@ Davis, CA 95616, USA - + @@ -127,7 +127,7 @@ Davis, CA 95616, USA - + @@ -148,7 +148,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ModeBase.xml b/data_model/1.3/clusters/ModeBase.xml index dcd6cf1c448028..0fcc581d07aaf1 100644 --- a/data_model/1.3/clusters/ModeBase.xml +++ b/data_model/1.3/clusters/ModeBase.xml @@ -99,25 +99,25 @@ Require at least one standard mode tag. Define reserved ranges for base/derived - + - + - + - + @@ -134,7 +134,6 @@ Require at least one standard mode tag. Define reserved ranges for base/derived - diff --git a/data_model/1.3/clusters/ModeSelect.xml b/data_model/1.3/clusters/ModeSelect.xml index cfdf7adb92761c..76ebf5874af273 100644 --- a/data_model/1.3/clusters/ModeSelect.xml +++ b/data_model/1.3/clusters/ModeSelect.xml @@ -97,38 +97,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml b/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml index e167e8649650ba..ff849a081ff573 100644 --- a/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/1.3/clusters/Mode_DeviceEnergyManagement.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/NetworkCommissioningCluster.xml b/data_model/1.3/clusters/NetworkCommissioningCluster.xml index 855947e5dda349..fdd404312f446d 100644 --- a/data_model/1.3/clusters/NetworkCommissioningCluster.xml +++ b/data_model/1.3/clusters/NetworkCommissioningCluster.xml @@ -161,13 +161,13 @@ Davis, CA 95616, USA - + - + - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -274,7 +274,7 @@ Davis, CA 95616, USA - + @@ -285,7 +285,7 @@ Davis, CA 95616, USA - + @@ -296,29 +296,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -326,14 +326,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/OTARequestor.xml b/data_model/1.3/clusters/OTARequestor.xml index f6a5ff0365abed..3a562c9f18a046 100644 --- a/data_model/1.3/clusters/OTARequestor.xml +++ b/data_model/1.3/clusters/OTARequestor.xml @@ -149,7 +149,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OccupancySensing.xml b/data_model/1.3/clusters/OccupancySensing.xml index 48756121d24769..b576e91078e663 100644 --- a/data_model/1.3/clusters/OccupancySensing.xml +++ b/data_model/1.3/clusters/OccupancySensing.xml @@ -103,7 +103,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OnOff.xml b/data_model/1.3/clusters/OnOff.xml index 9366985e5ce35e..1072b96d56a243 100644 --- a/data_model/1.3/clusters/OnOff.xml +++ b/data_model/1.3/clusters/OnOff.xml @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -168,7 +168,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OperationalCredentialCluster.xml b/data_model/1.3/clusters/OperationalCredentialCluster.xml index 2aa070f96b2573..b3811db4a5774a 100644 --- a/data_model/1.3/clusters/OperationalCredentialCluster.xml +++ b/data_model/1.3/clusters/OperationalCredentialCluster.xml @@ -155,26 +155,26 @@ Davis, CA 95616, USA - + - + - + - + @@ -183,7 +183,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/OperationalState.xml b/data_model/1.3/clusters/OperationalState.xml index 3648a8c81ec8f4..44567fa726f6fd 100644 --- a/data_model/1.3/clusters/OperationalState.xml +++ b/data_model/1.3/clusters/OperationalState.xml @@ -114,19 +114,19 @@ Davis, CA 95616, USA - + - + - + @@ -179,7 +179,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.3/clusters/PowerSourceCluster.xml b/data_model/1.3/clusters/PowerSourceCluster.xml index 1c01cc548bfdee..4596880e32b938 100644 --- a/data_model/1.3/clusters/PowerSourceCluster.xml +++ b/data_model/1.3/clusters/PowerSourceCluster.xml @@ -556,32 +556,32 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -589,21 +589,21 @@ Davis, CA 95616, USA - + - + - + @@ -624,14 +624,14 @@ Davis, CA 95616, USA - + - + @@ -639,7 +639,7 @@ Davis, CA 95616, USA - + @@ -659,7 +659,7 @@ Davis, CA 95616, USA - + @@ -680,7 +680,7 @@ Davis, CA 95616, USA - + @@ -688,7 +688,7 @@ Davis, CA 95616, USA - + @@ -696,7 +696,7 @@ Davis, CA 95616, USA - + @@ -704,7 +704,7 @@ Davis, CA 95616, USA - + @@ -712,7 +712,7 @@ Davis, CA 95616, USA - + @@ -720,7 +720,7 @@ Davis, CA 95616, USA - + @@ -730,7 +730,7 @@ Davis, CA 95616, USA - + @@ -744,7 +744,7 @@ Davis, CA 95616, USA - + @@ -757,7 +757,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml b/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml index 6a47ce1b54cdbd..5348f6f0b091b6 100644 --- a/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/1.3/clusters/PowerSourceConfigurationCluster.xml @@ -67,7 +67,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/PowerTopology.xml b/data_model/1.3/clusters/PowerTopology.xml index 4ebdda614a4aec..b958d03c01aeb1 100644 --- a/data_model/1.3/clusters/PowerTopology.xml +++ b/data_model/1.3/clusters/PowerTopology.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + @@ -92,7 +92,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/PressureMeasurement.xml b/data_model/1.3/clusters/PressureMeasurement.xml index a46e911253941f..bf9b6a9286e381 100644 --- a/data_model/1.3/clusters/PressureMeasurement.xml +++ b/data_model/1.3/clusters/PressureMeasurement.xml @@ -75,19 +75,19 @@ Davis, CA 95616, USA - + - + - + @@ -98,7 +98,7 @@ Davis, CA 95616, USA - + @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml b/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml index 8ad566ec8527b2..c33ed5cd03b841 100644 --- a/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml +++ b/data_model/1.3/clusters/ProxyConfiguration-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -82,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml b/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml index 6fa4a9eb6f3a06..159bdff7333853 100644 --- a/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml +++ b/data_model/1.3/clusters/ProxyDiscovery-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/1.3/clusters/PumpConfigurationControl.xml b/data_model/1.3/clusters/PumpConfigurationControl.xml index 79fafe659c95e2..b197f63bb4373f 100644 --- a/data_model/1.3/clusters/PumpConfigurationControl.xml +++ b/data_model/1.3/clusters/PumpConfigurationControl.xml @@ -175,22 +175,22 @@ Davis, CA 95616, USA - + - + - + - + @@ -202,7 +202,7 @@ Davis, CA 95616, USA - + @@ -214,7 +214,7 @@ Davis, CA 95616, USA - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + @@ -238,7 +238,7 @@ Davis, CA 95616, USA - + @@ -250,7 +250,7 @@ Davis, CA 95616, USA - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -274,7 +274,7 @@ Davis, CA 95616, USA - + @@ -286,7 +286,7 @@ Davis, CA 95616, USA - + @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -312,62 +312,62 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/1.3/clusters/ResourceMonitoring.xml b/data_model/1.3/clusters/ResourceMonitoring.xml index 6b0e8f3a203ded..09cc479618295f 100644 --- a/data_model/1.3/clusters/ResourceMonitoring.xml +++ b/data_model/1.3/clusters/ResourceMonitoring.xml @@ -62,8 +62,8 @@ Davis, CA 95616, USA - - + + @@ -73,7 +73,7 @@ Davis, CA 95616, USA - + @@ -103,13 +103,13 @@ Davis, CA 95616, USA - + - + @@ -136,7 +136,7 @@ Davis, CA 95616, USA - + @@ -152,13 +152,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/Scenes.xml b/data_model/1.3/clusters/Scenes.xml index 9150a754d3041a..2bbd2e246a06cc 100644 --- a/data_model/1.3/clusters/Scenes.xml +++ b/data_model/1.3/clusters/Scenes.xml @@ -1,61 +1,61 @@ - @@ -165,12 +165,12 @@ Davis, CA 95616, USA - + - + @@ -398,4 +398,4 @@ Davis, CA 95616, USA - + \ No newline at end of file diff --git a/data_model/1.3/clusters/SmokeCOAlarm.xml b/data_model/1.3/clusters/SmokeCOAlarm.xml index 25c034ac94082c..4ba9bd2708b476 100644 --- a/data_model/1.3/clusters/SmokeCOAlarm.xml +++ b/data_model/1.3/clusters/SmokeCOAlarm.xml @@ -163,31 +163,31 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -196,12 +196,12 @@ Davis, CA 95616, USA - + - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/Switch.xml b/data_model/1.3/clusters/Switch.xml index c7b607c637c74c..14912208782baa 100644 --- a/data_model/1.3/clusters/Switch.xml +++ b/data_model/1.3/clusters/Switch.xml @@ -95,19 +95,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/TemperatureControl.xml b/data_model/1.3/clusters/TemperatureControl.xml index 3f5fa9c00332d6..2f2527ce4ad0fa 100644 --- a/data_model/1.3/clusters/TemperatureControl.xml +++ b/data_model/1.3/clusters/TemperatureControl.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + @@ -94,7 +94,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/TemperatureMeasurement.xml b/data_model/1.3/clusters/TemperatureMeasurement.xml index 176fad6b246a60..0935b18edab675 100644 --- a/data_model/1.3/clusters/TemperatureMeasurement.xml +++ b/data_model/1.3/clusters/TemperatureMeasurement.xml @@ -71,19 +71,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/Thermostat.xml b/data_model/1.3/clusters/Thermostat.xml index 75640c697e0478..66d927c3bc6ad0 100644 --- a/data_model/1.3/clusters/Thermostat.xml +++ b/data_model/1.3/clusters/Thermostat.xml @@ -472,12 +472,12 @@ Davis, CA 95616, USA - + - + @@ -489,7 +489,7 @@ Davis, CA 95616, USA - + @@ -497,7 +497,7 @@ Davis, CA 95616, USA - + @@ -505,7 +505,7 @@ Davis, CA 95616, USA - + @@ -513,7 +513,7 @@ Davis, CA 95616, USA - + @@ -521,7 +521,7 @@ Davis, CA 95616, USA - + @@ -529,7 +529,7 @@ Davis, CA 95616, USA - + @@ -537,13 +537,13 @@ Davis, CA 95616, USA - + - + @@ -553,7 +553,7 @@ Davis, CA 95616, USA - + @@ -561,7 +561,7 @@ Davis, CA 95616, USA - + @@ -569,7 +569,7 @@ Davis, CA 95616, USA - + @@ -580,7 +580,7 @@ Davis, CA 95616, USA - + @@ -591,7 +591,7 @@ Davis, CA 95616, USA - + @@ -599,7 +599,7 @@ Davis, CA 95616, USA - + @@ -607,7 +607,7 @@ Davis, CA 95616, USA - + @@ -615,7 +615,7 @@ Davis, CA 95616, USA - + @@ -623,7 +623,7 @@ Davis, CA 95616, USA - + @@ -631,19 +631,19 @@ Davis, CA 95616, USA - + - + - + @@ -663,7 +663,7 @@ Davis, CA 95616, USA - + @@ -671,33 +671,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -713,7 +713,7 @@ Davis, CA 95616, USA - + @@ -722,7 +722,7 @@ Davis, CA 95616, USA - + @@ -730,7 +730,7 @@ Davis, CA 95616, USA - + @@ -738,7 +738,7 @@ Davis, CA 95616, USA - + @@ -746,7 +746,7 @@ Davis, CA 95616, USA - + @@ -757,7 +757,7 @@ Davis, CA 95616, USA - + @@ -768,7 +768,7 @@ Davis, CA 95616, USA - + @@ -779,29 +779,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -811,18 +811,18 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/TimeSync.xml b/data_model/1.3/clusters/TimeSync.xml index 9d4057db8bdb85..a506a647aeb8a3 100644 --- a/data_model/1.3/clusters/TimeSync.xml +++ b/data_model/1.3/clusters/TimeSync.xml @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -228,14 +228,14 @@ Davis, CA 95616, USA - + - + @@ -244,7 +244,7 @@ Davis, CA 95616, USA - + @@ -253,21 +253,21 @@ Davis, CA 95616, USA - + - + - + @@ -280,7 +280,7 @@ Davis, CA 95616, USA - + @@ -288,7 +288,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ValidProxies-Cluster.xml b/data_model/1.3/clusters/ValidProxies-Cluster.xml index b9db8e1762647f..c5740c90e52433 100644 --- a/data_model/1.3/clusters/ValidProxies-Cluster.xml +++ b/data_model/1.3/clusters/ValidProxies-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -75,7 +77,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/ValveConfigurationControl.xml b/data_model/1.3/clusters/ValveConfigurationControl.xml index b0f2ec91b0fa95..86e511505fd12b 100644 --- a/data_model/1.3/clusters/ValveConfigurationControl.xml +++ b/data_model/1.3/clusters/ValveConfigurationControl.xml @@ -108,55 +108,55 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -168,7 +168,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/WakeOnLAN.xml b/data_model/1.3/clusters/WakeOnLAN.xml index 4f6e032c084b38..7f5c08bdd624ad 100644 --- a/data_model/1.3/clusters/WakeOnLAN.xml +++ b/data_model/1.3/clusters/WakeOnLAN.xml @@ -68,13 +68,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/1.3/clusters/WaterContentMeasurement.xml b/data_model/1.3/clusters/WaterContentMeasurement.xml index 85d44793c93ae4..af11c9cf8d514c 100644 --- a/data_model/1.3/clusters/WaterContentMeasurement.xml +++ b/data_model/1.3/clusters/WaterContentMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/1.3/clusters/WindowCovering.xml b/data_model/1.3/clusters/WindowCovering.xml index af59da5a9f72de..88d7e3dc512cba 100644 --- a/data_model/1.3/clusters/WindowCovering.xml +++ b/data_model/1.3/clusters/WindowCovering.xml @@ -391,13 +391,13 @@ Davis, CA 95616, USA - + - + @@ -408,7 +408,7 @@ Davis, CA 95616, USA - + @@ -419,7 +419,7 @@ Davis, CA 95616, USA - + @@ -431,7 +431,7 @@ Davis, CA 95616, USA - + @@ -443,27 +443,27 @@ Davis, CA 95616, USA - + - + - + - + @@ -473,7 +473,7 @@ Davis, CA 95616, USA - + @@ -484,13 +484,13 @@ Davis, CA 95616, USA - + - + @@ -500,7 +500,7 @@ Davis, CA 95616, USA - + @@ -510,13 +510,13 @@ Davis, CA 95616, USA - + - + @@ -527,7 +527,7 @@ Davis, CA 95616, USA - + @@ -538,7 +538,7 @@ Davis, CA 95616, USA - + @@ -550,7 +550,7 @@ Davis, CA 95616, USA - + @@ -562,7 +562,7 @@ Davis, CA 95616, USA - + @@ -574,7 +574,7 @@ Davis, CA 95616, USA - + @@ -595,7 +595,7 @@ Davis, CA 95616, USA - + @@ -607,7 +607,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/clusters/cluster_ids.json b/data_model/1.3/clusters/cluster_ids.json index 40a46edd00722e..82a258ee0c6d7f 100644 --- a/data_model/1.3/clusters/cluster_ids.json +++ b/data_model/1.3/clusters/cluster_ids.json @@ -22,7 +22,7 @@ "51": "General Diagnostics", "52": "Software Diagnostics", "53": "Thread Network Diagnostics", - "54": "Wi", + "54": "Wi-Fi Network Diagnostics", "55": "Ethernet Network Diagnostics", "56": "Time Synchronization", "57": "Bridged Device Basic Information", @@ -88,7 +88,7 @@ "1037": "Carbon Dioxide Concentration Measurement", "1043": "Nitrogen Dioxide Concentration Measurement", "1045": "Ozone Concentration Measurement", - "1066": "PM2", + "1066": "PM2.5 Concentration Measurement", "1067": "Formaldehyde Concentration Measurement", "1068": "PM1 Concentration Measurement", "1069": "PM10 Concentration Measurement", diff --git a/data_model/1.3/device_types/AirQualitySensor.xml b/data_model/1.3/device_types/AirQualitySensor.xml index 602781819d1696..bf56eb754f24c6 100644 --- a/data_model/1.3/device_types/AirQualitySensor.xml +++ b/data_model/1.3/device_types/AirQualitySensor.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/device_types/DimmablePlug-InUnit.xml b/data_model/1.3/device_types/DimmablePlug-InUnit.xml index 4d344bfc9fb89c..65f6b6e1dd2e9c 100644 --- a/data_model/1.3/device_types/DimmablePlug-InUnit.xml +++ b/data_model/1.3/device_types/DimmablePlug-InUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/1.3/device_types/DoorLockController.xml b/data_model/1.3/device_types/DoorLockController.xml index 4d031a37be1eec..64d26eba8d8eeb 100644 --- a/data_model/1.3/device_types/DoorLockController.xml +++ b/data_model/1.3/device_types/DoorLockController.xml @@ -74,10 +74,7 @@ Davis, CA 95616, USA - - - - + diff --git a/data_model/1.3/device_types/OnOffPlug-inUnit.xml b/data_model/1.3/device_types/OnOffPlug-inUnit.xml index 3be1ed0f9eb13d..888f365bed0b83 100644 --- a/data_model/1.3/device_types/OnOffPlug-inUnit.xml +++ b/data_model/1.3/device_types/OnOffPlug-inUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/1.3/device_types/RootNodeDeviceType.xml b/data_model/1.3/device_types/RootNodeDeviceType.xml index c2028f07d91548..0288e8848cb321 100644 --- a/data_model/1.3/device_types/RootNodeDeviceType.xml +++ b/data_model/1.3/device_types/RootNodeDeviceType.xml @@ -124,7 +124,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.3/device_types/Thermostat.xml b/data_model/1.3/device_types/Thermostat.xml index 49ba4b6779f084..62c7060bf03584 100644 --- a/data_model/1.3/device_types/Thermostat.xml +++ b/data_model/1.3/device_types/Thermostat.xml @@ -83,16 +83,10 @@ Davis, CA 95616, USA - - - - + - - - - + diff --git a/data_model/1.3/scraper_version b/data_model/1.3/scraper_version index e8ea05db81420d..c813fe116c9f9e 100644 --- a/data_model/1.3/scraper_version +++ b/data_model/1.3/scraper_version @@ -1 +1 @@ -1.2.4 +1.2.5 diff --git a/data_model/1.3/spec_sha b/data_model/1.3/spec_sha index 274f0d55122714..9166e9f7a4977c 100644 --- a/data_model/1.3/spec_sha +++ b/data_model/1.3/spec_sha @@ -1 +1 @@ -ab9cf4653d40fe9193bbc7fe9febf74c08bf7dfa +6b8d0a46a59d5ec5e2d2662e0b4a0b4810118bd6 diff --git a/data_model/master/clusters/ACL-Cluster.xml b/data_model/master/clusters/ACL-Cluster.xml index 5c4c96a687cb13..d5fbf419ba4daf 100644 --- a/data_model/master/clusters/ACL-Cluster.xml +++ b/data_model/master/clusters/ACL-Cluster.xml @@ -180,19 +180,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/AdminCommissioningCluster.xml b/data_model/master/clusters/AdminCommissioningCluster.xml index ccbb579134dc00..8e95e46f128db0 100644 --- a/data_model/master/clusters/AdminCommissioningCluster.xml +++ b/data_model/master/clusters/AdminCommissioningCluster.xml @@ -91,12 +91,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/AlarmBase.xml b/data_model/master/clusters/AlarmBase.xml index fd0ccb5bc19d46..e374dcc382d208 100644 --- a/data_model/master/clusters/AlarmBase.xml +++ b/data_model/master/clusters/AlarmBase.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ApplicationBasic.xml b/data_model/master/clusters/ApplicationBasic.xml index ee39b8a421209d..28e47e7800352e 100644 --- a/data_model/master/clusters/ApplicationBasic.xml +++ b/data_model/master/clusters/ApplicationBasic.xml @@ -92,29 +92,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -125,14 +125,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ApplicationLauncher.xml b/data_model/master/clusters/ApplicationLauncher.xml index 57d6858dd8ce14..27fa528a81e8cf 100644 --- a/data_model/master/clusters/ApplicationLauncher.xml +++ b/data_model/master/clusters/ApplicationLauncher.xml @@ -103,14 +103,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/BallastConfiguration.xml b/data_model/master/clusters/BallastConfiguration.xml index 0f37d86067e994..9dbf4e61887d76 100644 --- a/data_model/master/clusters/BallastConfiguration.xml +++ b/data_model/master/clusters/BallastConfiguration.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + + + @@ -116,12 +118,12 @@ Davis, CA 95616, USA - + - + @@ -141,12 +143,12 @@ Davis, CA 95616, USA - + - + @@ -155,7 +157,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/BasicInformationCluster.xml b/data_model/master/clusters/BasicInformationCluster.xml index 428c683a0ea803..538b4f5e9e9f8b 100644 --- a/data_model/master/clusters/BasicInformationCluster.xml +++ b/data_model/master/clusters/BasicInformationCluster.xml @@ -54,8 +54,6 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA - -:xrefstyle: basic --> @@ -182,100 +180,100 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -284,35 +282,35 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -322,6 +320,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/master/clusters/Binding-Cluster.xml b/data_model/master/clusters/Binding-Cluster.xml index 444c99b315348d..055725f0b9ee47 100644 --- a/data_model/master/clusters/Binding-Cluster.xml +++ b/data_model/master/clusters/Binding-Cluster.xml @@ -97,7 +97,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/BooleanState.xml b/data_model/master/clusters/BooleanState.xml index 5bb29f53ae0c3e..ddb16e26a1d6ad 100644 --- a/data_model/master/clusters/BooleanState.xml +++ b/data_model/master/clusters/BooleanState.xml @@ -68,7 +68,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/BooleanStateConfiguration.xml b/data_model/master/clusters/BooleanStateConfiguration.xml index 01444d565294b3..719cd9569b5ae2 100644 --- a/data_model/master/clusters/BooleanStateConfiguration.xml +++ b/data_model/master/clusters/BooleanStateConfiguration.xml @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + @@ -122,7 +122,7 @@ Davis, CA 95616, USA - + @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -155,7 +155,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Channel.xml b/data_model/master/clusters/Channel.xml index 17144c9032c3e5..6177bfe6a652cc 100644 --- a/data_model/master/clusters/Channel.xml +++ b/data_model/master/clusters/Channel.xml @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + @@ -315,7 +315,7 @@ Davis, CA 95616, USA - + @@ -366,6 +366,7 @@ Davis, CA 95616, USA + @@ -400,6 +401,7 @@ Davis, CA 95616, USA + @@ -412,6 +414,7 @@ Davis, CA 95616, USA + @@ -437,6 +440,7 @@ Davis, CA 95616, USA + diff --git a/data_model/master/clusters/ColorControl.xml b/data_model/master/clusters/ColorControl.xml index 90d999fa20b4ac..6901b6ee4130c6 100644 --- a/data_model/master/clusters/ColorControl.xml +++ b/data_model/master/clusters/ColorControl.xml @@ -65,7 +65,8 @@ Davis, CA 95616, USA - + @@ -111,19 +112,10 @@ Davis, CA 95616, USA - + - - - - - - - - - - + @@ -252,7 +244,7 @@ Davis, CA 95616, USA - + @@ -260,7 +252,7 @@ Davis, CA 95616, USA - + @@ -268,13 +260,13 @@ Davis, CA 95616, USA - + - + @@ -282,7 +274,7 @@ Davis, CA 95616, USA - + @@ -299,7 +291,7 @@ Davis, CA 95616, USA - + @@ -307,7 +299,7 @@ Davis, CA 95616, USA - + @@ -317,13 +309,13 @@ Davis, CA 95616, USA - + - + @@ -337,7 +329,7 @@ Davis, CA 95616, USA - + @@ -351,7 +343,7 @@ Davis, CA 95616, USA - + @@ -364,7 +356,7 @@ Davis, CA 95616, USA - + @@ -378,7 +370,7 @@ Davis, CA 95616, USA - + @@ -392,7 +384,7 @@ Davis, CA 95616, USA - + @@ -405,7 +397,7 @@ Davis, CA 95616, USA - + @@ -419,7 +411,7 @@ Davis, CA 95616, USA - + @@ -433,7 +425,7 @@ Davis, CA 95616, USA - + @@ -446,7 +438,7 @@ Davis, CA 95616, USA - + @@ -460,7 +452,7 @@ Davis, CA 95616, USA - + @@ -474,7 +466,7 @@ Davis, CA 95616, USA - + @@ -487,7 +479,7 @@ Davis, CA 95616, USA - + @@ -501,7 +493,7 @@ Davis, CA 95616, USA - + @@ -515,7 +507,7 @@ Davis, CA 95616, USA - + @@ -528,7 +520,7 @@ Davis, CA 95616, USA - + @@ -542,7 +534,7 @@ Davis, CA 95616, USA - + @@ -556,7 +548,7 @@ Davis, CA 95616, USA - + @@ -589,7 +581,7 @@ Davis, CA 95616, USA - + @@ -604,7 +596,7 @@ Davis, CA 95616, USA - + @@ -619,24 +611,24 @@ Davis, CA 95616, USA - + - + - + - + @@ -644,7 +636,7 @@ Davis, CA 95616, USA - + @@ -652,7 +644,7 @@ Davis, CA 95616, USA - + @@ -696,11 +688,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ConcentrationMeasurement.xml b/data_model/master/clusters/ConcentrationMeasurement.xml index 4b51cffa124321..b622a3560b4ff0 100644 --- a/data_model/master/clusters/ConcentrationMeasurement.xml +++ b/data_model/master/clusters/ConcentrationMeasurement.xml @@ -62,16 +62,16 @@ Davis, CA 95616, USA - - - - - - - - - - + + + + + + + + + + @@ -181,7 +181,7 @@ Davis, CA 95616, USA - + @@ -189,7 +189,7 @@ Davis, CA 95616, USA - + @@ -197,7 +197,7 @@ Davis, CA 95616, USA - + @@ -205,7 +205,7 @@ Davis, CA 95616, USA - + @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -221,7 +221,7 @@ Davis, CA 95616, USA - + @@ -229,7 +229,7 @@ Davis, CA 95616, USA - + @@ -244,14 +244,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ContentControl.xml b/data_model/master/clusters/ContentControl.xml index b2539cf445c289..6848886c43ac02 100644 --- a/data_model/master/clusters/ContentControl.xml +++ b/data_model/master/clusters/ContentControl.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/ContentLauncher.xml b/data_model/master/clusters/ContentLauncher.xml index 9a5674efa8eb64..b4d6e7fa26500c 100644 --- a/data_model/master/clusters/ContentLauncher.xml +++ b/data_model/master/clusters/ContentLauncher.xml @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -307,7 +307,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/DemandResponseLoadControl.xml b/data_model/master/clusters/DemandResponseLoadControl.xml index c20a7c3b7f013f..1acd1ea26c6088 100644 --- a/data_model/master/clusters/DemandResponseLoadControl.xml +++ b/data_model/master/clusters/DemandResponseLoadControl.xml @@ -311,51 +311,51 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/Descriptor-Cluster.xml b/data_model/master/clusters/Descriptor-Cluster.xml index 94d262473d4c9c..9c0bcf0b2348e3 100644 --- a/data_model/master/clusters/Descriptor-Cluster.xml +++ b/data_model/master/clusters/Descriptor-Cluster.xml @@ -85,20 +85,20 @@ Davis, CA 95616, USA - + - + - + @@ -109,7 +109,7 @@ Davis, CA 95616, USA - + @@ -117,7 +117,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/DeviceEnergyManagement.xml b/data_model/master/clusters/DeviceEnergyManagement.xml index ee1b2f0f2725e6..efc027f27cdeee 100644 --- a/data_model/master/clusters/DeviceEnergyManagement.xml +++ b/data_model/master/clusters/DeviceEnergyManagement.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + + + @@ -118,6 +120,7 @@ Davis, CA 95616, USA + @@ -472,12 +475,12 @@ Davis, CA 95616, USA - + - + @@ -495,14 +498,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/DiagnosticsEthernet.xml b/data_model/master/clusters/DiagnosticsEthernet.xml index dfcd3d11c41f52..fd2bb0341ca06c 100644 --- a/data_model/master/clusters/DiagnosticsEthernet.xml +++ b/data_model/master/clusters/DiagnosticsEthernet.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -108,57 +110,57 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/DiagnosticsGeneral.xml b/data_model/master/clusters/DiagnosticsGeneral.xml index 4da912b03dc3df..ff78100fe3a7d3 100644 --- a/data_model/master/clusters/DiagnosticsGeneral.xml +++ b/data_model/master/clusters/DiagnosticsGeneral.xml @@ -223,17 +223,17 @@ Davis, CA 95616, USA - + - + - + @@ -310,7 +310,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/DiagnosticsSoftware.xml b/data_model/master/clusters/DiagnosticsSoftware.xml index 7cb3c9ff39ad2f..c7ee8ee842bf02 100644 --- a/data_model/master/clusters/DiagnosticsSoftware.xml +++ b/data_model/master/clusters/DiagnosticsSoftware.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/DiagnosticsThread.xml b/data_model/master/clusters/DiagnosticsThread.xml index 120efaddf8c08e..1da3eba21a4e4e 100644 --- a/data_model/master/clusters/DiagnosticsThread.xml +++ b/data_model/master/clusters/DiagnosticsThread.xml @@ -63,7 +63,9 @@ Davis, CA 95616, USA - + + + @@ -257,38 +259,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -305,356 +307,356 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/DiagnosticsWiFi.xml b/data_model/master/clusters/DiagnosticsWiFi.xml index b3951d967dc31f..6ef28ee4cc09e0 100644 --- a/data_model/master/clusters/DiagnosticsWiFi.xml +++ b/data_model/master/clusters/DiagnosticsWiFi.xml @@ -55,14 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + + + @@ -141,81 +143,81 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/DoorLock.xml b/data_model/master/clusters/DoorLock.xml index ea4b9fe1ebbbf8..138d40bdd544d6 100644 --- a/data_model/master/clusters/DoorLock.xml +++ b/data_model/master/clusters/DoorLock.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - @@ -703,7 +703,7 @@ Davis, CA 95616, USA - + @@ -871,7 +871,7 @@ Davis, CA 95616, USA - + @@ -886,7 +886,7 @@ Davis, CA 95616, USA - + @@ -912,153 +912,156 @@ Davis, CA 95616, USA - + - + - + - + + - + + - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1069,7 +1072,7 @@ Davis, CA 95616, USA - + @@ -1080,7 +1083,7 @@ Davis, CA 95616, USA - + @@ -1092,7 +1095,7 @@ Davis, CA 95616, USA - + @@ -1106,7 +1109,7 @@ Davis, CA 95616, USA - + @@ -1114,12 +1117,12 @@ Davis, CA 95616, USA - + - + @@ -1129,21 +1132,21 @@ Davis, CA 95616, USA - + - + - + @@ -1153,7 +1156,7 @@ Davis, CA 95616, USA - + @@ -1163,14 +1166,14 @@ Davis, CA 95616, USA - + - + @@ -1180,7 +1183,7 @@ Davis, CA 95616, USA - + @@ -1188,7 +1191,7 @@ Davis, CA 95616, USA - + @@ -1196,7 +1199,7 @@ Davis, CA 95616, USA - + @@ -1207,7 +1210,7 @@ Davis, CA 95616, USA - + @@ -1215,7 +1218,7 @@ Davis, CA 95616, USA - + @@ -1226,7 +1229,7 @@ Davis, CA 95616, USA - + @@ -1234,21 +1237,21 @@ Davis, CA 95616, USA - + - + - + @@ -1872,18 +1875,12 @@ Davis, CA 95616, USA - - - - - - + + + + + + @@ -2034,18 +2031,12 @@ Davis, CA 95616, USA - - - - - - + + + + + + diff --git a/data_model/master/clusters/ElectricalEnergyMeasurement.xml b/data_model/master/clusters/ElectricalEnergyMeasurement.xml index d89b19472a6bbb..77e05665b2d031 100644 --- a/data_model/master/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/master/clusters/ElectricalEnergyMeasurement.xml @@ -124,12 +124,12 @@ Davis, CA 95616, USA - + - + @@ -139,7 +139,7 @@ Davis, CA 95616, USA - + @@ -149,7 +149,7 @@ Davis, CA 95616, USA - + @@ -159,7 +159,7 @@ Davis, CA 95616, USA - + @@ -169,7 +169,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ElectricalPowerMeasurement.xml b/data_model/master/clusters/ElectricalPowerMeasurement.xml index 89ad5fa3255fcd..ba9dd22f3fa799 100644 --- a/data_model/master/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/master/clusters/ElectricalPowerMeasurement.xml @@ -170,39 +170,39 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -210,7 +210,7 @@ Davis, CA 95616, USA - + @@ -218,13 +218,13 @@ Davis, CA 95616, USA - + - + @@ -232,7 +232,7 @@ Davis, CA 95616, USA - + @@ -240,7 +240,7 @@ Davis, CA 95616, USA - + @@ -248,7 +248,7 @@ Davis, CA 95616, USA - + @@ -256,7 +256,7 @@ Davis, CA 95616, USA - + @@ -264,7 +264,7 @@ Davis, CA 95616, USA - + @@ -273,7 +273,7 @@ Davis, CA 95616, USA - + @@ -282,7 +282,7 @@ Davis, CA 95616, USA - + @@ -290,7 +290,7 @@ Davis, CA 95616, USA - + @@ -298,7 +298,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/EnergyCalendar.xml b/data_model/master/clusters/EnergyCalendar.xml index 40a8a87f04ec17..5e9b3b782a435c 100644 --- a/data_model/master/clusters/EnergyCalendar.xml +++ b/data_model/master/clusters/EnergyCalendar.xml @@ -196,17 +196,17 @@ Davis, CA 95616, USA - + - + - + @@ -215,70 +215,70 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/EnergyEVSE.xml b/data_model/master/clusters/EnergyEVSE.xml index 53605899d05550..e481e06aa4e5d4 100644 --- a/data_model/master/clusters/EnergyEVSE.xml +++ b/data_model/master/clusters/EnergyEVSE.xml @@ -254,7 +254,12 @@ Davis, CA 95616, USA - + + + + + + @@ -262,7 +267,7 @@ Davis, CA 95616, USA - + @@ -275,37 +280,37 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -313,33 +318,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -347,14 +352,14 @@ Davis, CA 95616, USA - + - + @@ -362,14 +367,14 @@ Davis, CA 95616, USA - + - + @@ -377,7 +382,7 @@ Davis, CA 95616, USA - + @@ -385,23 +390,23 @@ Davis, CA 95616, USA - + - + - + - + @@ -525,7 +530,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/EnergyPreference.xml b/data_model/master/clusters/EnergyPreference.xml index 37559dfbc30850..cd2b722607a45b 100644 --- a/data_model/master/clusters/EnergyPreference.xml +++ b/data_model/master/clusters/EnergyPreference.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -102,7 +104,7 @@ Davis, CA 95616, USA - + @@ -110,7 +112,7 @@ Davis, CA 95616, USA - + @@ -118,7 +120,7 @@ Davis, CA 95616, USA - + @@ -127,7 +129,7 @@ Davis, CA 95616, USA - + @@ -135,7 +137,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/EnergyPrice.xml b/data_model/master/clusters/EnergyPrice.xml index fa46810900890f..a4efa28e1b0dbf 100644 --- a/data_model/master/clusters/EnergyPrice.xml +++ b/data_model/master/clusters/EnergyPrice.xml @@ -166,7 +166,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/FanControl.xml b/data_model/master/clusters/FanControl.xml index 12d57967801646..daae13aff910d4 100644 --- a/data_model/master/clusters/FanControl.xml +++ b/data_model/master/clusters/FanControl.xml @@ -120,36 +120,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -188,36 +188,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -225,7 +225,7 @@ Davis, CA 95616, USA - + @@ -233,7 +233,7 @@ Davis, CA 95616, USA - + @@ -241,7 +241,7 @@ Davis, CA 95616, USA - + @@ -249,7 +249,7 @@ Davis, CA 95616, USA - + @@ -257,7 +257,7 @@ Davis, CA 95616, USA - + @@ -265,7 +265,7 @@ Davis, CA 95616, USA - + @@ -273,7 +273,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/FlowMeasurement.xml b/data_model/master/clusters/FlowMeasurement.xml index d488b5899b05f0..85879977faa509 100644 --- a/data_model/master/clusters/FlowMeasurement.xml +++ b/data_model/master/clusters/FlowMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/GeneralCommissioningCluster.xml b/data_model/master/clusters/GeneralCommissioningCluster.xml index 519285af02f103..ed10afa8406a5a 100644 --- a/data_model/master/clusters/GeneralCommissioningCluster.xml +++ b/data_model/master/clusters/GeneralCommissioningCluster.xml @@ -65,7 +65,7 @@ Davis, CA 95616, USA - + @@ -130,7 +130,7 @@ Davis, CA 95616, USA - + @@ -140,12 +140,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/Group-Key-Management-Cluster.xml b/data_model/master/clusters/Group-Key-Management-Cluster.xml index c1819628e34d7b..35de0890bd87d3 100644 --- a/data_model/master/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/master/clusters/Group-Key-Management-Cluster.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -167,7 +167,7 @@ Davis, CA 95616, USA - + @@ -179,12 +179,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/Groups.xml b/data_model/master/clusters/Groups.xml index 1f168e13fad933..6c53c1a602f255 100644 --- a/data_model/master/clusters/Groups.xml +++ b/data_model/master/clusters/Groups.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Humidistat.xml b/data_model/master/clusters/Humidistat.xml index b709b5d50d2f24..c3aac1dab85a20 100644 --- a/data_model/master/clusters/Humidistat.xml +++ b/data_model/master/clusters/Humidistat.xml @@ -174,17 +174,17 @@ Davis, CA 95616, USA - + - + - + @@ -192,7 +192,7 @@ Davis, CA 95616, USA - + @@ -200,7 +200,7 @@ Davis, CA 95616, USA - + @@ -208,7 +208,7 @@ Davis, CA 95616, USA - + @@ -228,28 +228,28 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/ICDManagement.xml b/data_model/master/clusters/ICDManagement.xml index 0f15a2729052fa..d4731fb545ad9a 100644 --- a/data_model/master/clusters/ICDManagement.xml +++ b/data_model/master/clusters/ICDManagement.xml @@ -115,7 +115,7 @@ Davis, CA 95616, USA - + @@ -125,24 +125,24 @@ Davis, CA 95616, USA - + - + - + - + @@ -150,14 +150,14 @@ Davis, CA 95616, USA - + - + @@ -165,7 +165,7 @@ Davis, CA 95616, USA - + @@ -176,7 +176,7 @@ Davis, CA 95616, USA - + @@ -190,7 +190,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Identify.xml b/data_model/master/clusters/Identify.xml index dbb9daca72fce4..0ab68abb8b1635 100644 --- a/data_model/master/clusters/Identify.xml +++ b/data_model/master/clusters/Identify.xml @@ -122,7 +122,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/IlluminanceMeasurement.xml b/data_model/master/clusters/IlluminanceMeasurement.xml index 75cf30cd35d931..f24df314ca2ead 100644 --- a/data_model/master/clusters/IlluminanceMeasurement.xml +++ b/data_model/master/clusters/IlluminanceMeasurement.xml @@ -83,20 +83,20 @@ Davis, CA 95616, USA - + - + - + @@ -107,7 +107,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml index 98106b6fc33e40..b915e77bb5a01f 100644 --- a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Label-Cluster-LabelCluster.xml b/data_model/master/clusters/Label-Cluster-LabelCluster.xml index 0ca5566f0dc132..43148b6dc9186f 100644 --- a/data_model/master/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-LabelCluster.xml @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml index eba0099ffb59d2..40dac53a4242cd 100644 --- a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml @@ -70,7 +70,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LaundryDryerControls.xml b/data_model/master/clusters/LaundryDryerControls.xml index af4f787c0432b7..d860d2ef9dcf21 100644 --- a/data_model/master/clusters/LaundryDryerControls.xml +++ b/data_model/master/clusters/LaundryDryerControls.xml @@ -88,7 +88,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LaundryWasherControls.xml b/data_model/master/clusters/LaundryWasherControls.xml index ff001c3a405652..6fbfc0a882d3d1 100644 --- a/data_model/master/clusters/LaundryWasherControls.xml +++ b/data_model/master/clusters/LaundryWasherControls.xml @@ -109,7 +109,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LevelControl.xml b/data_model/master/clusters/LevelControl.xml index c98db485e6e00a..5da823bc1dceb0 100644 --- a/data_model/master/clusters/LevelControl.xml +++ b/data_model/master/clusters/LevelControl.xml @@ -65,7 +65,9 @@ Davis, CA 95616, USA - + @@ -118,13 +120,13 @@ Davis, CA 95616, USA - + - + @@ -152,7 +154,7 @@ Davis, CA 95616, USA - + @@ -183,28 +185,29 @@ Davis, CA 95616, USA - + - + - + - + + - + diff --git a/data_model/master/clusters/LocalizationConfiguration.xml b/data_model/master/clusters/LocalizationConfiguration.xml index 66809f545389be..7ddfba8efcc9cb 100644 --- a/data_model/master/clusters/LocalizationConfiguration.xml +++ b/data_model/master/clusters/LocalizationConfiguration.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -75,7 +75,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LocalizationTimeFormat.xml b/data_model/master/clusters/LocalizationTimeFormat.xml index db8b809b0341a9..2ede281c7352a9 100644 --- a/data_model/master/clusters/LocalizationTimeFormat.xml +++ b/data_model/master/clusters/LocalizationTimeFormat.xml @@ -125,12 +125,12 @@ Davis, CA 95616, USA - + - + @@ -138,7 +138,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/LocalizationUnit.xml b/data_model/master/clusters/LocalizationUnit.xml index 2c6e1ecbd648e6..0157ebb53b0d39 100644 --- a/data_model/master/clusters/LocalizationUnit.xml +++ b/data_model/master/clusters/LocalizationUnit.xml @@ -84,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/MediaPlayback.xml b/data_model/master/clusters/MediaPlayback.xml index 03175277dc12c5..dae60d7a1b2572 100644 --- a/data_model/master/clusters/MediaPlayback.xml +++ b/data_model/master/clusters/MediaPlayback.xml @@ -223,7 +223,7 @@ Davis, CA 95616, USA - + @@ -231,7 +231,7 @@ Davis, CA 95616, USA - + @@ -239,7 +239,7 @@ Davis, CA 95616, USA - + @@ -254,7 +254,7 @@ Davis, CA 95616, USA - + @@ -262,7 +262,7 @@ Davis, CA 95616, USA - + @@ -270,7 +270,7 @@ Davis, CA 95616, USA - + @@ -279,7 +279,7 @@ Davis, CA 95616, USA - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/MicrowaveOvenControl.xml b/data_model/master/clusters/MicrowaveOvenControl.xml index b927685e534e0c..360b9edeaa55f1 100644 --- a/data_model/master/clusters/MicrowaveOvenControl.xml +++ b/data_model/master/clusters/MicrowaveOvenControl.xml @@ -89,7 +89,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + @@ -110,7 +110,7 @@ Davis, CA 95616, USA - + @@ -118,7 +118,7 @@ Davis, CA 95616, USA - + @@ -127,7 +127,7 @@ Davis, CA 95616, USA - + @@ -148,7 +148,7 @@ Davis, CA 95616, USA - + @@ -157,21 +157,21 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/ModeBase.xml b/data_model/master/clusters/ModeBase.xml index 48b4d4adac1634..4a70ad670d0dca 100644 --- a/data_model/master/clusters/ModeBase.xml +++ b/data_model/master/clusters/ModeBase.xml @@ -99,25 +99,25 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/ModeSelect.xml b/data_model/master/clusters/ModeSelect.xml index cfdf7adb92761c..76ebf5874af273 100644 --- a/data_model/master/clusters/ModeSelect.xml +++ b/data_model/master/clusters/ModeSelect.xml @@ -97,38 +97,38 @@ Davis, CA 95616, USA - + - + - + - + - + - + diff --git a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml index 9cb426eb51785d..08c4044617d716 100644 --- a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/Mode_EVSE.xml b/data_model/master/clusters/Mode_EVSE.xml index ffce1a6a2980ce..f139ab3cbfaf9a 100644 --- a/data_model/master/clusters/Mode_EVSE.xml +++ b/data_model/master/clusters/Mode_EVSE.xml @@ -79,4 +79,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/NetworkCommissioningCluster.xml b/data_model/master/clusters/NetworkCommissioningCluster.xml index cb6e935dcd189e..63efd6c3d3cbb2 100644 --- a/data_model/master/clusters/NetworkCommissioningCluster.xml +++ b/data_model/master/clusters/NetworkCommissioningCluster.xml @@ -125,22 +125,22 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -167,16 +167,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -299,7 +299,7 @@ Davis, CA 95616, USA - + @@ -310,7 +310,7 @@ Davis, CA 95616, USA - + @@ -321,29 +321,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -351,14 +351,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/NetworkIdentityManagement.xml b/data_model/master/clusters/NetworkIdentityManagement.xml index 0cb3ee17251741..b432b8b68f6b23 100644 --- a/data_model/master/clusters/NetworkIdentityManagement.xml +++ b/data_model/master/clusters/NetworkIdentityManagement.xml @@ -99,26 +99,26 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/OTARequestor.xml b/data_model/master/clusters/OTARequestor.xml index f6a5ff0365abed..3a562c9f18a046 100644 --- a/data_model/master/clusters/OTARequestor.xml +++ b/data_model/master/clusters/OTARequestor.xml @@ -149,7 +149,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OccupancySensing.xml b/data_model/master/clusters/OccupancySensing.xml index 2aae8530b1d512..2852ce812f9308 100644 --- a/data_model/master/clusters/OccupancySensing.xml +++ b/data_model/master/clusters/OccupancySensing.xml @@ -63,7 +63,7 @@ Davis, CA 95616, USA - - + - + @@ -164,7 +164,7 @@ Davis, CA 95616, USA - + @@ -178,7 +178,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OnOff.xml b/data_model/master/clusters/OnOff.xml index a12de2b2e25eb8..b06c96a64376ac 100644 --- a/data_model/master/clusters/OnOff.xml +++ b/data_model/master/clusters/OnOff.xml @@ -145,7 +145,7 @@ Davis, CA 95616, USA - + @@ -168,7 +168,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OperationalCredentialCluster.xml b/data_model/master/clusters/OperationalCredentialCluster.xml index 2aa070f96b2573..b3811db4a5774a 100644 --- a/data_model/master/clusters/OperationalCredentialCluster.xml +++ b/data_model/master/clusters/OperationalCredentialCluster.xml @@ -155,26 +155,26 @@ Davis, CA 95616, USA - + - + - + - + @@ -183,7 +183,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OperationalState.xml b/data_model/master/clusters/OperationalState.xml index 124362e459e429..06c77fc29a2c19 100644 --- a/data_model/master/clusters/OperationalState.xml +++ b/data_model/master/clusters/OperationalState.xml @@ -115,19 +115,19 @@ Davis, CA 95616, USA - + - + - + @@ -180,7 +180,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/PowerSourceCluster.xml b/data_model/master/clusters/PowerSourceCluster.xml index 1c01cc548bfdee..4596880e32b938 100644 --- a/data_model/master/clusters/PowerSourceCluster.xml +++ b/data_model/master/clusters/PowerSourceCluster.xml @@ -556,32 +556,32 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -589,21 +589,21 @@ Davis, CA 95616, USA - + - + - + @@ -624,14 +624,14 @@ Davis, CA 95616, USA - + - + @@ -639,7 +639,7 @@ Davis, CA 95616, USA - + @@ -659,7 +659,7 @@ Davis, CA 95616, USA - + @@ -680,7 +680,7 @@ Davis, CA 95616, USA - + @@ -688,7 +688,7 @@ Davis, CA 95616, USA - + @@ -696,7 +696,7 @@ Davis, CA 95616, USA - + @@ -704,7 +704,7 @@ Davis, CA 95616, USA - + @@ -712,7 +712,7 @@ Davis, CA 95616, USA - + @@ -720,7 +720,7 @@ Davis, CA 95616, USA - + @@ -730,7 +730,7 @@ Davis, CA 95616, USA - + @@ -744,7 +744,7 @@ Davis, CA 95616, USA - + @@ -757,7 +757,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PowerSourceConfigurationCluster.xml b/data_model/master/clusters/PowerSourceConfigurationCluster.xml index 6a47ce1b54cdbd..5348f6f0b091b6 100644 --- a/data_model/master/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/master/clusters/PowerSourceConfigurationCluster.xml @@ -67,7 +67,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PowerTopology.xml b/data_model/master/clusters/PowerTopology.xml index 4ebdda614a4aec..b958d03c01aeb1 100644 --- a/data_model/master/clusters/PowerTopology.xml +++ b/data_model/master/clusters/PowerTopology.xml @@ -83,7 +83,7 @@ Davis, CA 95616, USA - + @@ -92,7 +92,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PressureMeasurement.xml b/data_model/master/clusters/PressureMeasurement.xml index a46e911253941f..bf9b6a9286e381 100644 --- a/data_model/master/clusters/PressureMeasurement.xml +++ b/data_model/master/clusters/PressureMeasurement.xml @@ -75,19 +75,19 @@ Davis, CA 95616, USA - + - + - + @@ -98,7 +98,7 @@ Davis, CA 95616, USA - + @@ -106,7 +106,7 @@ Davis, CA 95616, USA - + @@ -114,7 +114,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ProxyConfiguration-Cluster.xml b/data_model/master/clusters/ProxyConfiguration-Cluster.xml index 8ad566ec8527b2..c33ed5cd03b841 100644 --- a/data_model/master/clusters/ProxyConfiguration-Cluster.xml +++ b/data_model/master/clusters/ProxyConfiguration-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -82,7 +84,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ProxyDiscovery-Cluster.xml b/data_model/master/clusters/ProxyDiscovery-Cluster.xml index 6fa4a9eb6f3a06..159bdff7333853 100644 --- a/data_model/master/clusters/ProxyDiscovery-Cluster.xml +++ b/data_model/master/clusters/ProxyDiscovery-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + diff --git a/data_model/master/clusters/PumpConfigurationControl.xml b/data_model/master/clusters/PumpConfigurationControl.xml index c3f79ce8108975..95ede00d0eb72e 100644 --- a/data_model/master/clusters/PumpConfigurationControl.xml +++ b/data_model/master/clusters/PumpConfigurationControl.xml @@ -176,22 +176,22 @@ Davis, CA 95616, USA - + - + - + - + @@ -203,7 +203,7 @@ Davis, CA 95616, USA - + @@ -215,7 +215,7 @@ Davis, CA 95616, USA - + @@ -227,7 +227,7 @@ Davis, CA 95616, USA - + @@ -239,7 +239,7 @@ Davis, CA 95616, USA - + @@ -251,7 +251,7 @@ Davis, CA 95616, USA - + @@ -263,7 +263,7 @@ Davis, CA 95616, USA - + @@ -275,7 +275,7 @@ Davis, CA 95616, USA - + @@ -287,7 +287,7 @@ Davis, CA 95616, USA - + @@ -300,7 +300,7 @@ Davis, CA 95616, USA - + @@ -313,62 +313,62 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + diff --git a/data_model/master/clusters/ResourceMonitoring.xml b/data_model/master/clusters/ResourceMonitoring.xml index 43bf28868f3709..feb6394fd6b47d 100644 --- a/data_model/master/clusters/ResourceMonitoring.xml +++ b/data_model/master/clusters/ResourceMonitoring.xml @@ -62,9 +62,9 @@ Davis, CA 95616, USA - - - + + + @@ -74,7 +74,7 @@ Davis, CA 95616, USA - + @@ -104,13 +104,13 @@ Davis, CA 95616, USA - + - + @@ -137,7 +137,7 @@ Davis, CA 95616, USA - + @@ -153,13 +153,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/Scenes.xml b/data_model/master/clusters/Scenes.xml index bf68f8528fa159..1479d3ffd7de86 100644 --- a/data_model/master/clusters/Scenes.xml +++ b/data_model/master/clusters/Scenes.xml @@ -62,7 +62,9 @@ Davis, CA 95616, USA - + + + @@ -165,12 +167,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/ServiceArea.xml b/data_model/master/clusters/ServiceArea.xml index 7963d93b7eb222..4980fc5ad40274 100644 --- a/data_model/master/clusters/ServiceArea.xml +++ b/data_model/master/clusters/ServiceArea.xml @@ -86,6 +86,34 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -152,26 +180,26 @@ Davis, CA 95616, USA - + - + - + - + @@ -179,7 +207,7 @@ Davis, CA 95616, USA - + @@ -196,7 +224,6 @@ Davis, CA 95616, USA - @@ -215,7 +242,6 @@ Davis, CA 95616, USA - diff --git a/data_model/master/clusters/SmokeCOAlarm.xml b/data_model/master/clusters/SmokeCOAlarm.xml index 25c034ac94082c..4ba9bd2708b476 100644 --- a/data_model/master/clusters/SmokeCOAlarm.xml +++ b/data_model/master/clusters/SmokeCOAlarm.xml @@ -163,31 +163,31 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -196,12 +196,12 @@ Davis, CA 95616, USA - + - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Switch.xml b/data_model/master/clusters/Switch.xml index c7c94524bed52c..bb2066269b4f94 100644 --- a/data_model/master/clusters/Switch.xml +++ b/data_model/master/clusters/Switch.xml @@ -116,19 +116,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/TemperatureControl.xml b/data_model/master/clusters/TemperatureControl.xml index 3f5fa9c00332d6..2f2527ce4ad0fa 100644 --- a/data_model/master/clusters/TemperatureControl.xml +++ b/data_model/master/clusters/TemperatureControl.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + @@ -94,7 +94,7 @@ Davis, CA 95616, USA - + @@ -102,7 +102,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/TemperatureMeasurement.xml b/data_model/master/clusters/TemperatureMeasurement.xml index 176fad6b246a60..0935b18edab675 100644 --- a/data_model/master/clusters/TemperatureMeasurement.xml +++ b/data_model/master/clusters/TemperatureMeasurement.xml @@ -71,19 +71,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/Thermostat.xml b/data_model/master/clusters/Thermostat.xml index 7345fc2e2c9177..4374bc3f1c8a7d 100644 --- a/data_model/master/clusters/Thermostat.xml +++ b/data_model/master/clusters/Thermostat.xml @@ -113,11 +113,6 @@ Davis, CA 95616, USA - - - - - @@ -503,12 +498,12 @@ Davis, CA 95616, USA - + - + @@ -559,15 +554,6 @@ Davis, CA 95616, USA - - - - - - - - - @@ -660,12 +646,12 @@ Davis, CA 95616, USA - + - + @@ -677,7 +663,7 @@ Davis, CA 95616, USA - + @@ -685,7 +671,7 @@ Davis, CA 95616, USA - + @@ -693,7 +679,7 @@ Davis, CA 95616, USA - + @@ -701,7 +687,7 @@ Davis, CA 95616, USA - + @@ -709,7 +695,7 @@ Davis, CA 95616, USA - + @@ -717,7 +703,7 @@ Davis, CA 95616, USA - + @@ -725,13 +711,13 @@ Davis, CA 95616, USA - + - + @@ -740,7 +726,7 @@ Davis, CA 95616, USA - + @@ -748,7 +734,7 @@ Davis, CA 95616, USA - + @@ -756,7 +742,7 @@ Davis, CA 95616, USA - + @@ -767,7 +753,7 @@ Davis, CA 95616, USA - + @@ -778,7 +764,7 @@ Davis, CA 95616, USA - + @@ -786,7 +772,7 @@ Davis, CA 95616, USA - + @@ -794,7 +780,7 @@ Davis, CA 95616, USA - + @@ -802,7 +788,7 @@ Davis, CA 95616, USA - + @@ -810,7 +796,7 @@ Davis, CA 95616, USA - + @@ -818,19 +804,19 @@ Davis, CA 95616, USA - + - + - + @@ -850,7 +836,7 @@ Davis, CA 95616, USA - + @@ -858,33 +844,33 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -900,7 +886,7 @@ Davis, CA 95616, USA - + @@ -909,7 +895,7 @@ Davis, CA 95616, USA - + @@ -917,7 +903,7 @@ Davis, CA 95616, USA - + @@ -925,7 +911,7 @@ Davis, CA 95616, USA - + @@ -933,7 +919,7 @@ Davis, CA 95616, USA - + @@ -944,7 +930,7 @@ Davis, CA 95616, USA - + @@ -955,7 +941,7 @@ Davis, CA 95616, USA - + @@ -966,29 +952,29 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -998,25 +984,25 @@ Davis, CA 95616, USA - + - + - + - + @@ -1025,7 +1011,7 @@ Davis, CA 95616, USA - + @@ -1033,35 +1019,35 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -1069,7 +1055,7 @@ Davis, CA 95616, USA - + @@ -1078,7 +1064,7 @@ Davis, CA 95616, USA - + @@ -1087,7 +1073,7 @@ Davis, CA 95616, USA - + @@ -1104,16 +1090,9 @@ Davis, CA 95616, USA - + - - - - - - - @@ -1243,11 +1222,6 @@ Davis, CA 95616, USA - - - - - @@ -1280,11 +1254,5 @@ Davis, CA 95616, USA - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/ThreadBorderRouterManagement.xml b/data_model/master/clusters/ThreadBorderRouterManagement.xml index f1e88f8ab86e70..b22d4038219647 100644 --- a/data_model/master/clusters/ThreadBorderRouterManagement.xml +++ b/data_model/master/clusters/ThreadBorderRouterManagement.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -79,20 +79,26 @@ Davis, CA 95616, USA + - + - + - + + + + + + @@ -105,14 +111,14 @@ Davis, CA 95616, USA - + - + @@ -123,7 +129,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ThreadNetworkDirectory.xml b/data_model/master/clusters/ThreadNetworkDirectory.xml index 3a770c36a214f9..aeabdcf19f93d1 100644 --- a/data_model/master/clusters/ThreadNetworkDirectory.xml +++ b/data_model/master/clusters/ThreadNetworkDirectory.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - + @@ -74,7 +74,7 @@ Davis, CA 95616, USA - + @@ -82,19 +82,19 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/master/clusters/TimeSync.xml b/data_model/master/clusters/TimeSync.xml index 9d4057db8bdb85..a506a647aeb8a3 100644 --- a/data_model/master/clusters/TimeSync.xml +++ b/data_model/master/clusters/TimeSync.xml @@ -213,7 +213,7 @@ Davis, CA 95616, USA - + @@ -228,14 +228,14 @@ Davis, CA 95616, USA - + - + @@ -244,7 +244,7 @@ Davis, CA 95616, USA - + @@ -253,21 +253,21 @@ Davis, CA 95616, USA - + - + - + @@ -280,7 +280,7 @@ Davis, CA 95616, USA - + @@ -288,7 +288,7 @@ Davis, CA 95616, USA - + @@ -296,7 +296,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ValidProxies-Cluster.xml b/data_model/master/clusters/ValidProxies-Cluster.xml index b9db8e1762647f..c5740c90e52433 100644 --- a/data_model/master/clusters/ValidProxies-Cluster.xml +++ b/data_model/master/clusters/ValidProxies-Cluster.xml @@ -60,7 +60,9 @@ Davis, CA 95616, USA - + + + @@ -75,7 +77,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ValveConfigurationControl.xml b/data_model/master/clusters/ValveConfigurationControl.xml index e8dcece07432d3..736672bc78f716 100644 --- a/data_model/master/clusters/ValveConfigurationControl.xml +++ b/data_model/master/clusters/ValveConfigurationControl.xml @@ -109,55 +109,55 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -169,7 +169,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/WakeOnLAN.xml b/data_model/master/clusters/WakeOnLAN.xml index 4f6e032c084b38..7f5c08bdd624ad 100644 --- a/data_model/master/clusters/WakeOnLAN.xml +++ b/data_model/master/clusters/WakeOnLAN.xml @@ -68,13 +68,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/WaterContentMeasurement.xml b/data_model/master/clusters/WaterContentMeasurement.xml index 85d44793c93ae4..af11c9cf8d514c 100644 --- a/data_model/master/clusters/WaterContentMeasurement.xml +++ b/data_model/master/clusters/WaterContentMeasurement.xml @@ -70,19 +70,19 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/WaterHeaterManagement.xml b/data_model/master/clusters/WaterHeaterManagement.xml index 52e1020f164472..ee38a0058b50fb 100644 --- a/data_model/master/clusters/WaterHeaterManagement.xml +++ b/data_model/master/clusters/WaterHeaterManagement.xml @@ -74,6 +74,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -112,7 +120,7 @@ Davis, CA 95616, USA - + @@ -137,7 +145,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/WiFiNetworkManagement.xml b/data_model/master/clusters/WiFiNetworkManagement.xml index e1c03fbc7061d4..cfa10af25f0dd6 100644 --- a/data_model/master/clusters/WiFiNetworkManagement.xml +++ b/data_model/master/clusters/WiFiNetworkManagement.xml @@ -57,18 +57,18 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - + - + diff --git a/data_model/master/clusters/WindowCovering.xml b/data_model/master/clusters/WindowCovering.xml index 7ec63dd442d8ae..2f087914405cf3 100644 --- a/data_model/master/clusters/WindowCovering.xml +++ b/data_model/master/clusters/WindowCovering.xml @@ -392,13 +392,13 @@ Davis, CA 95616, USA - + - + @@ -409,7 +409,7 @@ Davis, CA 95616, USA - + @@ -420,7 +420,7 @@ Davis, CA 95616, USA - + @@ -432,7 +432,7 @@ Davis, CA 95616, USA - + @@ -444,27 +444,27 @@ Davis, CA 95616, USA - + - + - + - + @@ -474,7 +474,7 @@ Davis, CA 95616, USA - + @@ -485,13 +485,13 @@ Davis, CA 95616, USA - + - + @@ -501,7 +501,7 @@ Davis, CA 95616, USA - + @@ -511,13 +511,13 @@ Davis, CA 95616, USA - + - + @@ -528,7 +528,7 @@ Davis, CA 95616, USA - + @@ -539,7 +539,7 @@ Davis, CA 95616, USA - + @@ -551,7 +551,7 @@ Davis, CA 95616, USA - + @@ -563,7 +563,7 @@ Davis, CA 95616, USA - + @@ -575,7 +575,7 @@ Davis, CA 95616, USA - + @@ -596,7 +596,7 @@ Davis, CA 95616, USA - + @@ -608,7 +608,7 @@ Davis, CA 95616, USA - + @@ -653,11 +653,11 @@ Davis, CA 95616, USA - + - + @@ -688,11 +688,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml index 42ae5c4fe44cee..4801cbf88800ae 100644 --- a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml @@ -115,20 +115,20 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/master/clusters/cluster_ids.json b/data_model/master/clusters/cluster_ids.json index c7654179ede2b5..e04a90b04a76d8 100644 --- a/data_model/master/clusters/cluster_ids.json +++ b/data_model/master/clusters/cluster_ids.json @@ -21,7 +21,7 @@ "51": "General Diagnostics", "52": "Software Diagnostics", "53": "Thread Network Diagnostics", - "54": "Wi", + "54": "Wi-Fi Network Diagnostics", "55": "Ethernet Network Diagnostics", "56": "Time Synchronization", "57": "Bridged Device Basic Information", @@ -95,14 +95,14 @@ "1037": "Carbon Dioxide Concentration Measurement", "1043": "Nitrogen Dioxide Concentration Measurement", "1045": "Ozone Concentration Measurement", - "1066": "PM2", + "1066": "PM2.5 Concentration Measurement", "1067": "Formaldehyde Concentration Measurement", "1068": "PM1 Concentration Measurement", "1069": "PM10 Concentration Measurement", "1070": "Total Volatile Organic Compounds Concentration Measurement", "1071": "Radon Concentration Measurement", "1104": "Network Identity Management", - "1105": "Wi", + "1105": "Wi-Fi Network Management", "1106": "Thread Border Router Management", "1107": "Thread Network Directory", "1283": "Wake on LAN", diff --git a/data_model/master/device_types/AirQualitySensor.xml b/data_model/master/device_types/AirQualitySensor.xml index 602781819d1696..bf56eb754f24c6 100644 --- a/data_model/master/device_types/AirQualitySensor.xml +++ b/data_model/master/device_types/AirQualitySensor.xml @@ -86,7 +86,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/DimmablePlug-InUnit.xml b/data_model/master/device_types/DimmablePlug-InUnit.xml index 4d344bfc9fb89c..65f6b6e1dd2e9c 100644 --- a/data_model/master/device_types/DimmablePlug-InUnit.xml +++ b/data_model/master/device_types/DimmablePlug-InUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/NetworkInfraManager.xml b/data_model/master/device_types/NetworkInfraManager.xml index 800ca8ce10ace6..a4d17e11c0faaa 100644 --- a/data_model/master/device_types/NetworkInfraManager.xml +++ b/data_model/master/device_types/NetworkInfraManager.xml @@ -62,7 +62,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/OnOffPlug-inUnit.xml b/data_model/master/device_types/OnOffPlug-inUnit.xml index 3be1ed0f9eb13d..888f365bed0b83 100644 --- a/data_model/master/device_types/OnOffPlug-inUnit.xml +++ b/data_model/master/device_types/OnOffPlug-inUnit.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/RootNodeDeviceType.xml b/data_model/master/device_types/RootNodeDeviceType.xml index 875a633f9ba9b8..7dfd31996cc8e5 100644 --- a/data_model/master/device_types/RootNodeDeviceType.xml +++ b/data_model/master/device_types/RootNodeDeviceType.xml @@ -123,7 +123,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/SecondaryNetworkInterface.xml b/data_model/master/device_types/SecondaryNetworkInterface.xml index 186faac2718079..51b4dc0e2ec4fa 100644 --- a/data_model/master/device_types/SecondaryNetworkInterface.xml +++ b/data_model/master/device_types/SecondaryNetworkInterface.xml @@ -69,7 +69,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/scraper_version b/data_model/master/scraper_version index e8ea05db81420d..c813fe116c9f9e 100644 --- a/data_model/master/scraper_version +++ b/data_model/master/scraper_version @@ -1 +1 @@ -1.2.4 +1.2.5 diff --git a/data_model/master/spec_sha b/data_model/master/spec_sha index f0b38ddc8c8aac..51aac4d9e877f4 100644 --- a/data_model/master/spec_sha +++ b/data_model/master/spec_sha @@ -1 +1 @@ -b3652909bdf595c7634cea1da0f1e58f837ea35f +358a64a52ea9583f19be23c7da0e33f19d4b1ee0 diff --git a/docs/guides/esp32/providers.md b/docs/guides/esp32/providers.md index 5174e1ccaceb11..59b91b624a49fc 100644 --- a/docs/guides/esp32/providers.md +++ b/docs/guides/esp32/providers.md @@ -15,6 +15,8 @@ Below are the providers that have been implemented: - [Device Info Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32DeviceInfoProvider.h#L31) This provider provides fixed labels, supported calendar types, and supported locales from the factory partition. +- [Supported Modes](https://github.com/project-chip/connectedhomeip/blob/master/examples/platform/esp32/mode-support/static-supported-modes-manager.h#L28) + This provider offers the supported modes for the mode-select cluster. More information can be found in the [factory data guide](factory_data.md). diff --git a/docs/guides/fabric_synchronization_guide.md b/docs/guides/fabric_synchronization_guide.md new file mode 100644 index 00000000000000..36107744a97930 --- /dev/null +++ b/docs/guides/fabric_synchronization_guide.md @@ -0,0 +1,164 @@ +# Fabric Synchronization Guide + +- [Fabric Synchronization Guide](#fabric-synchronization-guide) + - [Fabric Sync Example Applications](#fabric-sync-example-applications) + - [Run Fabric Sync Demo on RP4](#run-fabric-sync-demo-on-rp4) + +## Fabric Sync Example Applications + +Fabric-Admin and Fabric-Bridge example applications are provided to demonstrate +Fabric Synchronization feature. You can find them in the examples. + +![matter_fabric_synchronization](images/matter_fabric_synchronization.png) + +Fabric-Admin example app implements the Fabric Administrator role and +communicates with the Fabric-Bridge-App on the other side, facilitating the +Fabric Synchronization process. + +Fabric-Bridge-App example app implements the Aggregator device type with Fabric +Synchronization condition met and demonstrates the end-to-end Fabric +Synchronization feature using dynamic endpoints. + +Fabric Synchronization can be triggered from either side. The initiator of the +Fabric Synchronization process, who shares their devices, takes on the +Commissioner role. The recipient of the Fabric Synchronization request, who +receives the shared devices, assumes the Commissionee role. This flexibility +enables a seamless and efficient synchronization process. + +### Building the Example Application + +- Building the Fabric-Admin Application + + [Fabric-Admin](https://github.com/project-chip/connectedhomeip/tree/master/examples/fabric-admin/README.md) + +* Building the Fabric-Bridge Application + + [Fabric-Bridge](https://github.com/project-chip/connectedhomeip/tree/master/examples/fabric-bridge-app/linux/README.md) + +## Run Fabric Sync Demo on RP4 + +### Setup Fabric Source + +Connect to the Fabric Source server: + +``` +ssh ubuntu@xxx.xxx.xxx.xxx +``` + +Password: + +Run the Fabric Source script: + +``` +./run_fabric_source.sh +``` + +### Setup Fabric Sink + +Connect to the Fabric Sink server: + +``` +ssh ubuntu@xxx.xxx.xxx.xxx +``` + +Password: + +Run the Fabric Sink script: + +``` +./run_fabric_sink.sh +``` + +### Fabric Sync Setup + +Enable Fabric Auto Sync: + +In Fabric-Sync console: + +``` +fabricsync enable-auto-sync 1 +``` + +Pair the Fabric-Source bridge to Fabric-Sync with node ID 1: + +``` +fabricsync add-bridge 1 +``` + +### Pair Light Example to Fabric-Source + +Pair the Light Example with node ID 3 using its payload number: + +``` +pairing already-discovered 3 20202021 5540 +``` + +After the Light Example is successfully paired in Fabric-Source, it will be +synced to Fabric-Sink with a new assigned node ID. + +Toggle the Light Example: + +From Fabric-Source: + +``` +onoff on 1 +onoff off 1 +``` + +From Fabric-Sink: (Use the node ID assigned) + +``` +onoff on x 1 +onoff off x 1 +``` + +### Remove Light Example from Fabric-Source + +Unpair the Light Example: + +``` +pairing unpair +``` + +After the Light Example is successfully unpaired from Fabric-Source, it will +also be removed from the Fabric-Sink. + +### Pair Commercial Switch to Fabric-Source + +Pair the switch using its payload number: + +In Fabric-Source console: + +``` +pairing code-wifi +``` + +After the switch is successfully paired in Fabric-Source, it will be synced to +Fabric-Sink with a new assigned node ID. + +Toggle the switch: + +From Fabric-Source: + +``` +onoff on 1 +onoff off 1 +``` + +From Fabric-Sink: (Use the node ID assigned) + +``` +onoff on 1 +onoff off 1 +``` + +### Remove Switch from Fabric-Source + +Unpair the switch: + +``` +pairing unpair +``` + +After the switch is successfully unpaired from Fabric-Source, it will also be +removed from the Fabric-Sink. diff --git a/docs/guides/images/matter_fabric_synchronization.png b/docs/guides/images/matter_fabric_synchronization.png new file mode 100644 index 00000000000000..95c99c4fe150b9 Binary files /dev/null and b/docs/guides/images/matter_fabric_synchronization.png differ diff --git a/docs/spec_clusters.md b/docs/spec_clusters.md index 976b9f85e42c19..ef58f016154446 100644 --- a/docs/spec_clusters.md +++ b/docs/spec_clusters.md @@ -26,7 +26,7 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |51 |0x0033 |General Diagnostics | |52 |0x0034 |Software Diagnostics | |53 |0x0035 |Thread Network Diagnostics | -|54 |0x0036 |Wi | +|54 |0x0036 |Wi-Fi Network Diagnostics | |55 |0x0037 |Ethernet Network Diagnostics | |56 |0x0038 |Time Synchronization | |57 |0x0039 |Bridged Device Basic Information | @@ -92,7 +92,7 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |1037 |0x040D |Carbon Dioxide Concentration Measurement | |1043 |0x0413 |Nitrogen Dioxide Concentration Measurement | |1045 |0x0415 |Ozone Concentration Measurement | -|1066 |0x042A |PM2 | +|1066 |0x042A |PM2.5 Concentration Measurement | |1067 |0x042B |Formaldehyde Concentration Measurement | |1068 |0x042C |PM1 Concentration Measurement | |1069 |0x042D |PM10 Concentration Measurement | diff --git a/docs/testing/python.md b/docs/testing/python.md index 06051fee4fb33b..354490c896c445 100644 --- a/docs/testing/python.md +++ b/docs/testing/python.md @@ -24,33 +24,39 @@ Python tests located in src/python_testing essential to define arguments at the top of the test script. This section should include various parameters and their respective values, which will guide the test runner on how to execute the tests. -- All test classes inherit from MatterBaseTest in +- All test classes inherit from `MatterBaseTest` in [matter_testing_support.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/matter_testing_support.py) - - support for commissioning using the python controller - - default controller (self.default_controller) of type ChipDeviceCtrl - - MatterBaseTest inherits from the Mobly BaseTestClass -- Test function(s) (start with test\_) and are all run automatically - - To run in the test harness, the test name must be test_TC_PICSCODE\_#\_# - - more information about integration with the test harness can be + - Support for commissioning using the python controller + - Default controller (`self.default_controller`) of type `ChipDeviceCtrl` + - `MatterBaseTest` inherits from the Mobly BaseTestClass +- Test method(s) (start with test\_) and are all run automatically + - To run in the test harness, the test method name must be + `test_TC_PICSCODE_#_#` + - More information about integration with the test harness can be found in [Test Harness helpers](#test-harness-helpers) section - - any tests that use async function (read / write / commands) should be + - Any tests that use async method (read / write / commands) should be decorated with the @async_test_body decorator -- Use ChipDeviceCtrl to interact with the DUT - - Controller API is in ChipDeviceCtrl.py (see API doc in file) - - some support functions in matter_testing_support.py +- Use `ChipDeviceCtrl` to interact with the DUT + - Controller API is in `ChipDeviceCtrl.py` (see API doc in file) + - Some support methods in `matter_testing_support.py` - Use Mobly assertions for failing tests -- self.step() along with a steps\_ function to mark test plan steps for cert +- `self.step()` along with a `steps_*` method to mark test plan steps for cert tests ### A simple test ``` +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === class TC_MYTEST_1_1(MatterBaseTest): @@ -74,69 +80,19 @@ default_matter_test_main() --- -In this test, asserts.assert_equal is used to fail the test on condition failure -(throws an exception). +In this test, `asserts.assert_equal` is used to fail the test on equality +assertion failure (throws an exception). -Because the test requires the use of the async function -read_single_attribute_check_success, the test is decorated with the +Because the test requires the use of the async method +`read_single_attribute_check_success`, the test is decorated with the `@async_test_body` decorator -The default_matter_test_main() function is used to run the test on the command +The `default_matter_test_main()` function is used to run the test on the command line. These two lines should appear verbatim at the bottom of every python test file. -## Defining the test arguments - -Below is the format: - -``` -# test-runner-runs: -# test-runner-run//app: ${TYPE_OF_APP} -# test-runner-run//factoryreset: -# test-runner-run//quiet: -# test-runner-run//app-args: -# test-runner-run//script-args: -``` - -### Description of Parameters - -- test-runner-runs: Specifies the identifier for the run. This can be any - unique identifier. - - - Example: run1 - -- test-runner-run//app: Indicates the application to be used - in the test. Different app types as needed could be referenced from section - [name: Generate an argument environment file ] of the file - [.github/workflows/tests.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.github/workflows/tests.yaml) - - - Example: \${TYPE_OF_APP} - -- test-runner-run//factoryreset: Determines whether a factory - reset should be performed before the test. - - - Example: True - -- test-runner-run//quiet: Sets the verbosity level of the test - run. When set to True, the test run will be quieter. - - - Example: True - -- test-runner-run//app-args: Specifies the arguments to be - passed to the application during the test. - - - Example: --discriminator 1234 --KVS kvs1 --trace-to - json:\${TRACE_APP}.json - -- test-runner-run//script-args: Specifies the arguments to be - passed to the test script. - - Example: --storage-path admin_storage.json --commissioning-method - on-network --discriminator 1234 --passcode 20202021 --trace-to - json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto - -This structured format ensures that all necessary configurations are clearly -defined and easily understood, allowing for consistent and reliable test -execution. +The structured comments above the class definition are used to set up the CI for +the tests. Please see [Running tests in CI](#running-tests-in-ci). ## Cluster Codegen @@ -156,12 +112,12 @@ always: Each `Clusters.` will include the appropriate sub-classes (if defined for the cluster): -- Enums -- Bitmaps -- Structs -- Attributes -- Commands -- Events +- `Enums` +- `Bitmaps` +- `Structs` +- `Attributes` +- `Commands` +- `Events` ### Attributes @@ -176,42 +132,41 @@ Each `Clusters..Attributes.` class has: Example: -- class - Clusters.OnOff.Attributes.OnTime - - used for Read commands -- instance - Clusters.OnOff.Attributes.OnTime(5) - - sets the value to 5 - - pass the instance to write commands to write the value +- class - `Clusters.OnOff.Attributes.OnTime` + - Used for Read commands +- instance - `Clusters.OnOff.Attributes.OnTime(5)` + - Sets the value to `5` + - Pass the instance to Write method to write the value ### Commands -Commands derive from ClusterCommand +Commands derive from `ClusterCommand`. Each `Clusters..Commands.` class has: -- cluster_id -- command_id -- is_client -- response_type (None for status response) -- descriptor +- `cluster_id` +- `command_id` +- `is_client` +- `response_type` (None for status response) +- `descriptor` - data members (if required) Example: -- Clusters.OnOff.Commands.OnWithTimedOff(onOffControl=0, onTime=5, - offWaitTime=8) -- Clusters.OnOff.Commands.OnWithTimedOff() - - command with no fields +- `Clusters.OnOff.Commands.OnWithTimedOff(onOffControl=0, onTime=5, offWaitTime=8)` +- `Clusters.OnOff.Commands.OnWithTimedOff()` + - Command with no fields ### Events -Events derive from ClusterEvent +Events derive from `ClusterEvent`. Each `Clusters..Events.` class has: -- cluster_id -- event_id -- descriptor -- data members if required +- `cluster_id` +- `event_id` +- `descriptor` +- Other data members if required Example: @@ -219,16 +174,16 @@ Example: ### Enums -Enums derive from MatterIntEnum +Enums derive from `MatterIntEnum`. Each `Clusters..Enum.` has -- k -- kUnknownEnumValue (used for testing, do not transmit) +- `k` constants +- `kUnknownEnumValue` (used for testing, do not transmit) Example: -- Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister +- `Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister` ### Bitmaps @@ -238,26 +193,28 @@ Each `Clusters..Bitmaps.` has: - k Special class: -- class Feature(IntFlag) - contains the feature map bitmaps +- class `Feature(IntFlag)` - contains the feature map bitmaps Example: -- Clusters.LaundryWasherControls.Bitmaps.Feature.kSpin +- `Clusters.LaundryWasherControls.Bitmaps.Feature.kSpin` ### Structs -Structs derive from ClusterObject +Structs derive from `ClusterObject`. Each `Clusters..Structs.` has: -- descriptor -- data members +- A "descriptor" +- Data members -Example +Example: -- Clusters.BasicInformation.Structs.ProductAppearanceStruct( -- finish=Clusters.BasicInformation.Enums.ProductFinishEnum.kFabric, -- primaryColor=Clusters.BasicInformation.Enums.ColorEnum.kBlack) +``` +Clusters.BasicInformation.Structs.ProductAppearanceStruct( + finish=Clusters.BasicInformation.Enums.ProductFinishEnum.kFabric, + primaryColor=Clusters.BasicInformation.Enums.ColorEnum.kBlack) +``` ## Accessing Clusters and Cluster Elements by ID @@ -266,14 +223,14 @@ has a set of objects that map ID to the code generated object. `chip.clusters.ClusterObjects.ALL_CLUSTERS` -- dict[int, Cluster] - maps cluster ID to Cluster class -- cluster = chip.clusters.ClusterObjects.ALL_CLUSTERS[cluster_id] +- `dict[int, Cluster]` - maps cluster ID to Cluster class + - `cluster = chip.clusters.ClusterObjects.ALL_CLUSTERS[cluster_id]` `chip.clusters.ClusterObjects.ALL_ATTRIBUTES` -- dict[int, dict[int, ClusterAttributeDescriptor]] - maps cluster ID to a dict - of attribute ID to attribute class -- attr = chip.clusters.ClusterObjects.ALL_ATTRIBUTES[cluster_id][attribute_id] +- `dict[int, dict[int, ClusterAttributeDescriptor]]` - maps cluster ID to a + dict of attribute ID to attribute class + - `attr = chip.clusters.ClusterObjects.ALL_ATTRIBUTES[cluster_id][attribute_id]` `chip.clusters.ClusterObjects.ALL_ACCEPTED_COMMANDS/ALL_GENERATED_COMMANDS` @@ -282,15 +239,15 @@ has a set of objects that map ID to the code generated object. ## ChipDeviceCtrl API -The ChipDeviceCtrl API is implemented in +The `ChipDeviceCtrl` API is implemented in [ChipDeviceCtrl.py](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/chip/ChipDeviceCtrl.py). -The ChipDeviceCtrl implements a python-based controller that can be used to +The `ChipDeviceCtrl` implements a python-based controller that can be used to commission and control devices. The API is documented here in the [ChipDeviceCtrl API documentation](./ChipDeviceCtrlAPI.md) The API doc gives full descriptions of the APIs being used. The most commonly -used functions are linked below +used methods are linked below. ### [Read](./ChipDeviceCtrlAPI.md#read) @@ -299,7 +256,7 @@ used functions are linked below ### [ReadAttribute](./ChipDeviceCtrlAPI.md#readattribute) -- convenience wrapper for Read for attributes +- Convenience wrapper for Read for attributes Examples: Wildcard read (all clusters, all endpoints): @@ -323,8 +280,9 @@ Multi-path ### [ReadEvent](./ChipDeviceCtrlAPI.md#readevent) -- convenience wrapper for Read -- Similar to ReadAttribute, but the tuple includes urgency as the last number +- Convenience wrapper for `Read` +- Similar to `ReadAttribute`, but the tuple includes urgency as the last + argument Example: @@ -337,19 +295,19 @@ Clusters.TimeSynchronization.Events.MissingTrustedTimeSource, urgent)]) ### Subscriptions -Subscriptions are handled in the Read / ReadAttribute / ReadEvent APIs. To -initiate a subscription, set the `reportInterval` tuple to set the floor and -ceiling. The `keepSubscriptions` and `autoResubscribe` parameters also apply to -subscriptions. +Subscriptions are handled in the `Read` / `ReadAttribute` / `ReadEvent` APIs. To +initiate a subscription, set the `reportInterval` tuple argument to set the +floor and ceiling. The `keepSubscriptions` and `autoResubscribe` arguments also +apply to subscriptions. Subscription return `ClusterAttribute.SubscriptionTransaction`. This can be used to set callbacks. The object is returned after the priming data read is complete, and the values there are used to populate the cache. The attribute callbacks are called on update. -- SetAttributeUpdateCallback +- `SetAttributeUpdateCallback` - Callable[[TypedAttributePath, SubscriptionTransaction], None] -- SetEventUpdateCallback +- `SetEventUpdateCallback` - Callable[[EventReadResult, SubscriptionTransaction], None] - await changes in the main loop using a trigger mechanism from the callback. @@ -387,7 +345,7 @@ asserts.assert_equal(ret[0].status, Status.Success, “write failed”) ### [SendCommand](./ChipDeviceCtrlAPI.md#sendcommand) -- Instantiate the command with the values you need to populate +- Instantiate the command object with the values you need to populate - If there is a non-status return, it’s returned from the command - If there is a pure status return it will return nothing - Raises InteractionModelError on failure @@ -403,62 +361,63 @@ pai = await dev_ctrl.SendCommand(nodeid, 0, Clusters.OperationalCredentials.Comm - Because we tend to do a lot of single read / single commands in tests, we added a couple of helpers in MatterBaseTest that use some of the default values - - read_single_attribute_check_success - - read_single_attribute_expect_error - - send_single_cmd -- step() function to mark step progress for the test harness -- skip / skip_step / skip_remaining_steps functions for test harness + - `read_single_attribute_check_success()` + - `read_single_attribute_expect_error()` + - `send_single_cmd()` +- `step()` method to mark step progress for the test harness +- `skip()` / `skip_step()` / `skip_remaining_steps()` methods for test harness integration -- check_pics / pics_guard to handle pics +- `check_pics()` / `pics_guard()` to handle pics ## Mobly helpers The test system is based on Mobly, and the [matter_testing_support.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/matter_testing_support.py) -class provides some helpers for Mobly integration +class provides some helpers for Mobly integration. -- default_matter_test_main - - Sets up commissioning and finds all tests, parses command arguments +- `default_matter_test_main` + - Sets up commissioning and finds all tests, parses command-line arguments use as: ``` if __name__ == "__main__": -default_matter_test_main() + default_matter_test_main() ``` -- Mobly will run all functions starting with test\_ by default - - use --tests command line argument to specify -- Setup / teardown functions - - setup_class / teardown_class - - setup_test / teardown_test - - Don’t forget to call the super() if you override these +- Mobly will run all methods starting with `test_` prefix by default + - use `--tests` command line argument to specify exact name,s +- Setup and teardown methods + - `setup_class` / `teardown_class` + - `setup_test` / `teardown_test` + - Don’t forget to call the `super()` if you override these ## Test harness helpers -The python testing system also includes several functions for integrations with +The python testing system also includes several methods for integrations with the test harness. To integrate with the test harness, you can define the -following functions on your class to allow the test harness UI to properly work +following methods on your class to allow the test harness UI to properly work through your tests. -All of these functions are demonstrated in the +All of these methods are demonstrated in the [hello_example.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/hello_test.py) reference. -- step enumeration - - define a function called `steps_YourFunctionName` to allow the test +- Steps enumeration: + - Define a method called `steps_` to allow the test harness to display the steps - - use the self.step(``) function to walk through the steps -- test description - - define a function called `desc_YourFunctionName` to send back a string + - Use the `self.step()` method to walk through the steps +- Test description: + - Define a method called `desc_` to send back a string with the test description -- top level PICS - - To guard your test on a top level PICS, define a function called - `pics_YourFunctionName` to send back a list of pics. If this function is - omitted, the test will be run for every endpoint on every device. -- overriding the default timeout - - if the test is exceptionally long running, define a property function - `default_timeout` to adjust the timeout. The default is 90 seconds +- Top-level PICS: + - To guard your test on a top level PICS, define a method called + `pics_` to send back a list of PICS. If this method + is omitted, the test will be run for every endpoint on every device. +- Overriding the default timeout: + - If the test is exceptionally long running, define a property getter + method `default_timeout` to adjust the timeout. The default is 90 + seconds. Deferred failures: For some tests, it makes sense to perform the entire test before failing and collect all the errors so the developers can address all the @@ -466,13 +425,13 @@ failures without needing to re-run the test multiple times. For example, tests that look at every attribute on the cluster and perform independent operations on them etc. -For such tests, use the ProblemNotice format and the convenience functions: +For such tests, use the ProblemNotice format and the convenience methods: -- self.record_error -- self.record_warning +- `self.record_error` +- `self.record_warning` -These functions keep track of the problems, and will print them at the end of -the test. The test will not be failed until the assert is called. +These methods keep track of the problems, and will print them at the end of the +test. The test will not be failed until an assert is called. A good example of this type of test can be found in the device basic composition tests, where all the test steps are independent and performed on a single read. @@ -481,16 +440,21 @@ See ## Command line arguments -- Use help to get a full list -- --commissioning-method - - need to re-commission to python controller as chip-tool and python +- Use `--help` to get a full list +- `--storage-path` + - Used to set a local storage file path for persisted data to avoid + clashing files. It is suggested to always provide this argument. Default + value is `admin_storage.json` in current directory. +- `--commissioning-method` + - Need to re-commission to python controller as chip-tool and python commissioner do not share a credentials -- --discriminator, --passcode, --qr-code, --manual-code -- --tests to select tests -- --PICS -- --int-arg, --bool-arg, --float-arg, --string-arg, --json-arg, --hex-arg - - specify as key:value ex --bool-arg pixit_name:False - - used for custom arguments to scripts (PIXITs) +- `--discriminator`, `--passcode`, `--qr-code`, `--manual-code` +- `--tests` to select tests +- `--PICS` +- `--int-arg`, `--bool-arg`, `--float-arg`, `--string-arg`, `--json-arg`, + `--hex-arg` + - Specify as key:value ex --bool-arg pixit_name:False + - Used for custom arguments to scripts (PIXITs) ## PICS and PIXITS @@ -504,7 +468,7 @@ See comments - pixit_value = self.user_params.get("pixit_name", default) -## Support functions +## Support functionality To create a controller on a new fabric: @@ -512,7 +476,7 @@ To create a controller on a new fabric: new_CA = self.certificate_authority_manager.NewCertificateAuthority() new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, -fabricId=self.matter_test_config.fabric_id + 1) + fabricId=self.matter_test_config.fabric_id + 1) TH2 = new_fabric_admin.NewController(nodeId=112233) ``` @@ -524,22 +488,22 @@ params = self.OpenCommissioningWindow(dev_ctrl=self.default_controller, node_id= ``` To create a new controller on the SAME fabric, allocate a new controller from -the fabric admin +the fabric admin. Fabric admin for default controller: ``` -fa=self.certificate_authority_manager.activeCaList[0].adminList[0] -second_ctrl = fa.new_fabric_admin.NewController(nodeId=node_id) + fa = self.certificate_authority_manager.activeCaList[0].adminList[0] + second_ctrl = fa.new_fabric_admin.NewController(nodeId=node_id) ``` -## other support functions +## Other support utilities -- basic_composition_support +- `basic_composition_support` - wildcard read, whole device analysis -- CommissioningFlowBlocks +- `CommissioningFlowBlocks` - various commissioning support for core tests -- spec_parsing_support +- `spec_parsing_support` - parsing data model XML into python readable format # Running tests locally @@ -564,12 +528,12 @@ or bootstrap.sh should be used for for the first setup, activate.sh may be used for subsequent setups as it is faster. -Next build the python wheels and create / activate a venv (called `py` here, but -any name may be used) +Next build the python wheels and create / activate a venv (called `pyenv` here, +but any name may be used) ``` -./scripts/build_python.sh -i py -source py/bin/activate +./scripts/build_python.sh -i pyenv +source pyenv/bin/activate ``` ## Running tests @@ -589,11 +553,11 @@ python3 src/python_testing/TC_ACE_1_2.py --commissioning-method on-network --qr- ``` Some tests require additional arguments (ex. PIXITs or configuration variables -for the CI). These arguments can be passed as sets of key-value pairs using the -`---arg` command line arguments. For example +for the CI). These arguments can be passed as sets of key/value pairs using the +`---arg:` command line arguments. For example: ``` ---int-arg PIXIT.ACE.APPENDPOINT:1 PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff PIXIT.ACE.APPATTRIBUTE:OnOff +--int-arg PIXIT.ACE.APPENDPOINT:1 --int-arg PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff --string-arg PIXIT.ACE.APPATTRIBUTE:OnOff ``` ## Local host app testing @@ -605,8 +569,75 @@ example DUT on the host and includes factory reset support # Running tests in CI -- add to .github/workflows/tests.yaml repl_tests_linux -- don’t forget to set the PICS file to the ci-pics-values -- if there are things in your test that will fail on CI (ex. test vendor +- Add test to the `repl_tests_linux` section of `.github/workflows/tests.yaml` +- Don’t forget to set the PICS file to the ci-pics-values +- If there are steps in your test that will fail on CI (e.g. test vendor checks), gate them on the PICS_SDK_CI_ONLY - - is_ci = self.check_pics('PICS_SDK_CI_ONLY') + - `is_ci = self.check_pics('PICS_SDK_CI_ONLY')` + +The CI test runner uses a structured environment setup that can be declared +using structured comments at the top of the test file. To use this structured +format, use the `--load-from-env` flag with the `run_python_tests.py` runner. + +Ex: +`scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ICDM_2_1.py'` + +## Defining the CI test arguments + +Below is the format of the structured environment definition comments: + +``` +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: +# test-runner-run//app: ${TYPE_OF_APP} +# test-runner-run//factoryreset: +# test-runner-run//quiet: +# test-runner-run//app-args: +# test-runner-run//script-args: +# === END CI TEST ARGUMENTS === +``` + +NOTE: The `=== BEGIN CI TEST ARGUMENTS ===` and `=== END CI TEST ARGUMENTS ===` +markers must be present. + +### Description of Parameters + +- `test-runner-runs`: Specifies the identifier for the run. This can be any + unique identifier. + + - Example: `run1` + +- `test-runner-run//app`: Indicates the application to be used + in the test. Different app types as needed could be referenced from section + [name: Generate an argument environment file ] of the file + [.github/workflows/tests.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.github/workflows/tests.yaml) + + - Example: `${TYPE_OF_APP}` + +- `test-runner-run//factoryreset`: Determines whether a + factory reset should be performed before the test. + + - Example: `True` + +- `test-runner-run//quiet`: Sets the verbosity level of the + test run. When set to True, the test run will be quieter. + + - Example: `True` + +- `test-runner-run//app-args`: Specifies the arguments to be + passed to the application during the test. + + - Example: + `--discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json` + +- `test-runner-run//script-args`: Specifies the arguments to + be passed to the test script. + - Example: + `--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto` + +This structured format ensures that all necessary configurations are clearly +defined and easily understood, allowing for consistent and reliable test +execution. diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index 5f2a2e262111ac..dc439fa2f37607 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -131,6 +131,7 @@ Generally regenerate using one of: | 1294 | 0x50E | AccountLogin | | 1295 | 0x50F | ContentControl | | 1296 | 0x510 | ContentAppObserver | +| 1873 | 0x751 | CommissionerControl | | 2820 | 0xB04 | ElectricalMeasurement | | 4294048773 | 0xFFF1FC05 | UnitTesting | | 4294048774 | 0xFFF1FC06 | FaultInjection | diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index dc41290765313a..7fd1d548609257 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -34,6 +34,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/mode-support" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" @@ -105,6 +106,8 @@ set(SRC_DIRS_LIST ) +set(EXCLUDE_SRCS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp") + if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index b85f47d883c620..af94d2b2d36afe 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -121,6 +122,13 @@ static void InitServer(intptr_t context) #if CONFIG_DEVICE_TYPE_M5STACK SetupPretendDevices(); #endif + CHIP_ERROR err = + app::Clusters::ModeSelect::StaticSupportedModesManager::getStaticSupportedModesManagerInstance().InitEndpointArray( + FIXED_ENDPOINT_COUNT); + if (err != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to initialize endpoint array for supported-modes, err:%" CHIP_ERROR_FORMAT, err.Format()); + } app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); } diff --git a/examples/all-clusters-app/nxp/zephyr/.gitignore b/examples/all-clusters-app/nxp/zephyr/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/all-clusters-app/nxp/zephyr/CMakeLists.txt b/examples/all-clusters-app/nxp/zephyr/CMakeLists.txt new file mode 100644 index 00000000000000..2fa2d558a2724a --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/CMakeLists.txt @@ -0,0 +1,115 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ALL_CLUSTERS_NXP_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_COMMON_DIR ${CHIP_ROOT}/examples/platform/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR ${CHIP_ROOT}/examples/platform/nxp/zephyr REALPATH) + +# Perform common operations like detecting extra overlays in the platform folder for the target board +# This must be called before find_package(Zephyr) +include(${CHIP_ROOT}/config/nxp/app/pre-zephyr.cmake) + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nxp/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) + +project(chip-nxp-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nxp/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app + PRIVATE + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include +) + +target_sources(app + PRIVATE + main/main.cpp + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/AppTask.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/source/CHIPDeviceManager.cpp + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/DeviceCallbacks.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/source/CommonDeviceCallbacks.cpp + ${ALL_CLUSTERS_NXP_COMMON_DIR}/main/ZclCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskZephyr.cpp + ${EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR}/factory_data/source/AppFactoryDataExample.cpp +) + +target_compile_definitions(app PUBLIC + "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\"" +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorZephyr.cpp + ) + target_include_directories(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/include/ + ) +endif() + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/all-clusters-app.zap +) + +if(CONFIG_CHIP_LIB_SHELL) + target_compile_definitions(app PRIVATE ENABLE_CHIP_SHELL) + target_include_directories(app PRIVATE + ${CHIP_ROOT}/examples/shell/shell_common/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/include + ) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIZephyr.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_misc.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_otcli.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_server.cpp + ) +endif() + +target_sources(app + PRIVATE + ${ALL_CLUSTERS_COMMON_DIR}/src/smco-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/source/ICDUtil.cpp +) diff --git a/examples/all-clusters-app/nxp/zephyr/Kconfig b/examples/all-clusters-app/nxp/zephyr/Kconfig new file mode 100644 index 00000000000000..748835a9d0fe6b --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/Kconfig @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +mainmenu "Matter NXP All Clusters Example Application" + +rsource "../../../../config/nxp/chip-module/Kconfig.features" +rsource "../../../../config/nxp/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/all-clusters-app/nxp/zephyr/README.md b/examples/all-clusters-app/nxp/zephyr/README.md new file mode 100644 index 00000000000000..45f71ee76c077b --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/README.md @@ -0,0 +1,609 @@ +# CHIP NXP Zephyr All-clusters Application + +The all-clusters example implements a server which can be accessed by a CHIP +controller and can accept basic cluster commands. + +The example is based on +[Project CHIP](https://github.com/project-chip/connectedhomeip) and the NXP +Zephyr SDK, and provides a prototype application that demonstrates device +commissioning and different cluster control. + +
+ +- [Introduction](#introduction) +- [Building](#building) +- [Flashing and debugging](#flashing-and-debugging) +- [Factory data](#factory-data) +- [Manufacturing data](#generate-factory-data) +- [OTA Software Update](#ota-software-update) +- [Testing the example](#testing-the-example) +- [Using Matter CLI in NXP Zephyr examples](#using-matter-cli-in-nxp-zephyr-examples) + +
+ + + +## Introduction + +The Zephyr application provides a working demonstration of supported board +integration from Zephyr, built using the Project CHIP codebase and the +NXP/Zephyr SDK. + +The example supports: + +- Matter over Wi-Fi + +The supported boards are: + +- `rd_rw612_bga` + + + +## Building + +In order to build the Project CHIP example, we recommend using a Linux +distribution (the demo-application was compiled on Ubuntu 20.04). + +Prerequisites: + +- Follow instruction from [BUILDING.md](../../../../docs/guides/BUILDING.md) + to setup the Matter environment +- Follow instruction from + [Getting Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) + to setup a Zephyr workspace, however, the west init command to use is as + follows: + +```shell +$ west init zephyrproject -m https://github.com/nxp-zephyr-ear/zephyr.git --mr zephyr_rw61x_v3.6_RFP +``` + +> **Note**: Currently, supported NXP platforms in Zephyr targeting Matter are +> not available in the official Zephyr repo, you'll have to use the NXP fork +> `https://github.com/nxp-zephyr-ear/zephyr` github repo. Reach to your NXP +> contact for more details. + +Steps to build the example, targeting `rd_rw612_bga` board: + +1. Activate your Matter env: + +```shell +source /scripts/activate.sh +``` + +2. Source zephyr-env.sh: + +```shell +source /zephyr-env.sh +``` + +3. Run west build command: + +```shell +west build -b rd_rw612_bga -p +``` + +By default, a folder `build` will be created in the same folder you run the +command from. The binaries will be created in `build/zephyr` with the name +`zephyr.elf` and `zephyr.bin`. + +You can get more details on `west build` with +[Zephyr's building guide](https://docs.zephyrproject.org/latest/develop/west/build-flash-debug.html#building-west-build) + + + +## Flashing and debugging + +### Flashing without debugging + +`west` can be used to flash a target, as an example for `rd_rw612_bga` board: + +```shell +west flash -i +``` + +You can get more details on `west flash` with +[Zephyr's flashing guide](https://docs.zephyrproject.org/latest/develop/west/build-flash-debug.html#flashing-west-flash) + +> **Note**: `west flash` will not start a debug session, it will only flash and +> reset the device + +### Flash and debug + +To debug a Matter with Zephyr application, you could use several methods: + +- [MCUXpresso IDE (version >= 11.6.0)](https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE) +- `west debug` + [Zephyr's debugging guide](https://docs.zephyrproject.org/latest/develop/west/build-flash-debug.html#id29) + +> **Note**: As the build provides an elf file, any compatible debugging tool can +> be used. + + + +## Factory data + +NXP Zephyr examples are not using factory data support by default. Please refer +the the section below to build with factory data. + +You may refer to `src/platform/nxp/zephyr/boards//.overlay` file +to obtain the memory region used by this partition. + +For example, the factory data partition on `rd_rw612_bga` is reserved in the +last sector of the `flexspi` flash of `RD BGA` board, at `0x1BFFF000`. + +``` +&flexspi { + status = "okay"; + + mx25u51245g: mx25u51245g@0 { + ... + factory_partition: partition@3FFF000 { + label = "factory-data"; + reg = <0x03FFF000 DT_SIZE_K(4)>; + }; + }; +}; +``` + +> **Note**: You may also refer to +> `src/platform/nxp/zephyr/boards//.overlay` file to check other +> memory partitions used by the platform, such as the file system partition +> mentioned with the `storage` label. + +### Build with factory data support + +To build the example with factory data support, you can add +`-DFILE_SUFFIX=fdata` in the west build command line. + +Example: + +```bash +west build -b rd_rw612_bga -p -- -DFILE_SUFFIX=fdata +``` + +`prj_fdata.conf` configuration file will enable `CONFIG_CHIP_FACTORY_DATA` +Kconfig so the application will load the factory data at boot. + + + +### Generate factory data + +#### Automatically (recommended) + +The factory data can be generated automatically during the build of the +application. To do so, you can use the configuration +`CONFIG_CHIP_FACTORY_DATA_BUILD=y` in `prj_fdata.conf`. + +You will have to specify the source of the certificates to be used for the +factory data. Please refer to `CHIP_FACTORY_DATA_CERT_SOURCE` Kconfig for more +info. + +> **Note**: The application demonstrates the usage of encrypted Matter factory +> data storage. Matter factory data should be encrypted using an AES 128 +> software key before flashing them to the device flash. You can encrypt the +> factory data automatically during the build by enabling +> `CHIP_ENCRYPTED_FACTORY_DATA` Kconfig. See also +> `CHIP_ENCRYPTED_FACTORY_DATA_AES128_KEY` Kconfig if you want to use a specific +> key. + +The resulting factory data will be provided along `zephyr.bin` as a binary file +named `factory_data.bin`. In order to flash it to your device, you need to know +the partition address: please refer to `factory_partition` defined in +`src/platform/nxp/zephyr/boards//.overlay`. + +#### Manually + +See +[Guide for writing manufacturing data on NXP devices](../../../../docs/guides/nxp/nxp_manufacturing_flow.md) + + + +## OTA Software Update + +See +[Guide for OTA Software Update on NXP devices using Zephyr SDK](../../../../docs/guides/nxp/nxp_zephyr_ota_software_update.md) + + + +## Testing the example + +To know how to commission a device over BLE, follow the instructions from +[chip-tool's README.md 'Commission a device over BLE'](../../../chip-tool/README.md#commission-a-device-over-ble). + + + +## Using Matter CLI in NXP Zephyr examples + +Some Matter examples for the development kits from NXP include a command-line +interface that allows access to application logs and +[Zephyr shell](https://docs.zephyrproject.org/1.13.0/subsystems/shell.html). + +Depending on the platform, the CLI console and the logs can be split on two +different interfaces. + +You may refer to `boards/.overlay` file to check how the board is +configured for the example. The binding `zephyr,console` is used to print the +logs, while the binding `zephyr,shell-uart` is used for the CLI. If the logs and +the CLI are split among two serial interfaces, you will have to open both ports. + +As an example, the Matter CLI on `rd_rw612_bga` is configured to be output on +`flexcomm3` with a baudrate of `115200`. The logs are configured to be output on +`flexcomm0` with a baudrate of `115200`. + +> **Note**: `flexcomm3` is wired to the USB `FTDI` port of the `RD BGA` board by +> default. `flexcomm0` is wired to `GPIO2` (RX) and `GPIO3` (TX). Those pins are +> accessible on `HD2` pin header. + +To access the CLI console, use a serial terminal emulator of your choice, like +Minicom or GNU Screen. Use the baud rate set to `115200`. + +### Example: Starting the CLI console with Minicom + +For example, to start using the CLI console with Minicom, run the following +command with `/dev/ttyACM0` replaced with the device node name of your +development kit: + +``` +minicom -D /dev/ttyACM0 -b 115200 +``` + +When you reboot the kit, you will see the boot logs in the console, similar to +the following messages: + +```shell +uart:~$ MAC Address: C0:95:DA:00:00:6E +... +wlan-version +wlan-mac +wlan-thread-info +wlan-net-stats +... +*** Booting Zephyr OS build zephyr-v3.4.0-187-g2ddf1330209b *** +I: Init CHIP stack +... +``` + +This means that the console is working correctly and you can start using shell +commands. For example, issuing the `kernel threads` command will print +information about all running threads: + +```shell +uart:~$ kernel threads +Scheduler: 277 since last call +Threads: + 0x20006518 CHIP + options: 0x0, priority: -1 timeout: 536896912 + state: pending + stack size 8192, unused 7256, usage 936 / 8192 (11 %) + + 0x20004ab0 SDC RX + options: 0x0, priority: -10 timeout: 536890152 + state: pending + stack size 1024, unused 848, usage 176 / 1024 (17 %) +... +``` + +## Listing all commands + +To list all available commands, use the Tab key, which is normally used for the +command completion feature. + +Pressing the Tab key in an empty command line prints the list of available +commands: + +```shell +uart:~$ + clear device help history + hwinfo kernel matter resize + retval shell +``` + +Pressing the Tab key with a command entered in the command line cycles through +available options for the given command. + +You can also run the `help` command: + +```shell +uart:~$ help +Please press the button to see all available commands. +You can also use the button to prompt or auto-complete all commands or its subcommands. +You can try to call commands with <-h> or <--help> parameter for more information. + +Shell supports following meta-keys: + Ctrl + (a key from: abcdefklnpuw) + Alt + (a key from: bf) +Please refer to shell documentation for more details. + +Available commands: + clear :Clear screen. + device :Device commands + help :Prints the help message. + history :Command history. + hwinfo :HWINFO commands + kernel :Kernel commands + matter :Matter commands + resize :Console gets terminal screen size or assumes default in case + the readout fails. It must be executed after each terminal + width change to ensure correct text display. + retval :Print return value of most recent command + shell :Useful, not Unix-like shell commands. +``` + +## Using General purpose commands + +### `kernel` command group + +#### `reboot` subcommand + +Performs either a warm or cold reset. Difference between warm and cold resets +may vary from a platform to another, but on default Cortex-M architectures, both +methods are the same, so use either one if nothing is specific to your platform. + +```shell +uart:~$ kernel reboot cold|warm +``` + +## Using Matter-specific commands + +The NXP Zephyr examples let you use several Matter-specific CLI commands. + +These commands are not available by default and to enable using them, set the +`CONFIG_CHIP_LIB_SHELL=y` Kconfig option in the `prj.conf` file of the given +example. + +Every invoked command must be preceded by the `matter` prefix. + +See the following subsections for the description of each Matter-specific +command. + +### `device` command group + +Handles a group of commands that are used to manage the device. You must use +this command together with one of the additional subcommands listed below. + +#### `factoryreset` subcommand + +Performs device factory reset that is hardware reset preceded by erasing of the +whole Matter settings stored in a non-volatile memory. + +```shell +uart:~$ matter device factoryreset +Performing factory reset ... +``` + +### `onboardingcodes` command group + +Handles a group of commands that are used to view information about device +onboarding codes. The `onboardingcodes` command takes one required parameter for +the rendezvous type, then an optional parameter for printing a specific type of +onboarding code. + +The full format of the command is as follows: + +``` +onboardingcodes none|softap|ble|onnetwork [qrcode|qrcodeurl|manualpairingcode] +``` + +#### `none` subcommand + +Prints all onboarding codes. For example: + +```shell +uart:~$ matter onboardingcodes none +QRCode: MT:W0GU2OTB00KA0648G00 +QRCodeUrl: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3AW0GU2OTB00KA0648G00 +ManualPairingCode: 34970112332 +``` + +#### `none qrcode` subcommand + +Prints the device onboarding QR code payload. Takes no arguments. + +```shell +uart:~$ matter onboardingcodes none qrcode +MT:W0GU2OTB00KA0648G00 +``` + +#### `none qrcodeurl` subcommand + +Prints the URL to view the device onboarding QR code in a web browser. Takes no +arguments. + +```shell +uart:~$ matter onboardingcodes none qrcodeurl +https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3AW0GU2OTB00KA0648G00 +``` + +#### `none manualpairingcode` subcommand + +Prints the pairing code for the manual onboarding of a device. Takes no +arguments. + +```shell +uart:~$ matter onboardingcodes none manualpairingcode +34970112332 +``` + +### `config` command group + +Handles a group of commands that are used to view device configuration +information. You can use this command without any subcommand to print all +available configuration data or to add a specific subcommand. + +```shell +uart:~$ matter config +VendorId: 65521 (0xFFF1) +ProductId: 32768 (0x8000) +HardwareVersion: 1 (0x1) +FabricId: +PinCode: 020202021 +Discriminator: f00 +DeviceId: +``` + +The `config` command can also take the subcommands listed below. + +#### `pincode` subcommand + +Prints the PIN code for device setup. Takes no arguments. + +```shell +uart:~$ matter config pincode +020202021 +``` + +#### `discriminator` subcommand + +Prints the device setup discriminator. Takes no arguments. + +```shell +uart:~$ matter config discriminator +f00 +``` + +#### `vendorid` subcommand + +Prints the vendor ID of the device. Takes no arguments. + +```shell +uart:~$ matter config vendorid +65521 (0xFFFF1) +``` + +#### `productid` subcommand + +Prints the product ID of the device. Takes no arguments. + +```shell +uart:~$ matter config productid +32768 (0x8000) +``` + +#### `hardwarever` subcommand + +Prints the hardware version of the device. Takes no arguments. + +```shell +uart:~$ matter config hardwarever +1 (0x1) +``` + +#### `deviceid` subcommand + +Prints the device identifier. Takes no arguments. + +#### `fabricid` subcommand + +Prints the fabric identifier. Takes no arguments. + +### `ble` command group + +Handles a group of commands that are used to control the device Bluetooth LE +transport state. You must use this command together with one of the additional +subcommands listed below. + +#### `help` subcommand + +Prints help information about the `ble` command group. + +```shell +uart:~$ matter ble help + help Usage: ble + adv Enable or disable advertisement. Usage: ble adv +``` + +#### `adv start` subcommand + +Enables Bluetooth LE advertising. + +```shell +uart:~$ matter ble adv start +Starting BLE advertising +``` + +#### `adv stop` subcommand + +Disables Bluetooth LE advertising. + +```shell +uart:~$ matter ble adv stop +Stopping BLE advertising +``` + +#### `adv status` subcommand + +Prints the information about the current Bluetooth LE advertising status. + +```shell +uart:~$ matter ble adv state +BLE advertising is disabled + +``` + +### `dns` command group + +Handles a group of commands that are used to trigger performing DNS queries. You +must use this command together with one of the additional subcommands listed +below. + +#### `browse` subcommand + +Browses for DNS services of `_matterc_udp` type and prints the received +response. Takes no argument. + +```shell +uart:~$ matter dns browse +Browsing ... +DNS browse succeeded: + Hostname: 0E824F0CA6DE309C + Vendor ID: 9050 + Product ID: 20043 + Long discriminator: 3840 + Device type: 0 + Device name: + Commissioning mode: 0 + IP addresses: + fd08:b65e:db8e:f9c7:2cc2:2043:1366:3b31 +``` + +#### `resolve` subcommand + +Resolves the specified Matter node service given by the _fabric-id_ and +_node-id_. + +```shell +uart:~$ matter dns resolve fabric-id node-id +Resolving ... +DNS resolve for 000000014A77CBB3-0000000000BC5C01 succeeded: + IP address: fd08:b65e:db8e:f9c7:8052:1a8e:4dd4:e1f3 + Port: 5540 +``` + +### `stat` command group + +Handles a group of commands that are used to get and reset the peak usage of +critical system resources used by Matter. These commands are only available when +the `CONFIG_CHIP_STATISTICS=y` Kconfig option is set. + +#### `peak` subcommand + +Prints the peak usage of system resources. + +```shell +uart:~$ matter stat peak +Packet Buffers: 1 +Timers: 2 +TCP endpoints: 0 +UDP endpoints: 1 +Exchange contexts: 0 +Unsolicited message handlers: 5 +Platform events: 2 +``` + +#### `reset` subcommand + +Resets the peak usage of system resources. + +```shell +uart:~$ matter stat reset +``` diff --git a/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga.overlay b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga.overlay new file mode 100644 index 00000000000000..86bb20739527cd --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: //www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm3; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; diff --git a/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf new file mode 100644 index 00000000000000..73d139c3948d95 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +CONFIG_SETTINGS_NVS_SECTOR_COUNT=16 + +# 0xA226 +CONFIG_CHIP_DEVICE_PRODUCT_ID=41510 +CONFIG_CHIP_DEVICE_PRODUCT_URL="https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radio-1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612" +CONFIG_CHIP_DEVICE_PRODUCT_LABEL="RW612" +CONFIG_CHIP_DEVICE_PART_NUMBER="RW612" diff --git a/examples/all-clusters-app/nxp/zephyr/main/include/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/zephyr/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..f6c88ccef18162 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/main/include/CHIPProjectConfig.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 diff --git a/examples/all-clusters-app/nxp/zephyr/main/main.cpp b/examples/all-clusters-app/nxp/zephyr/main/main.cpp new file mode 100644 index 00000000000000..9be47dfe0a95d8 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/main/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (err == CHIP_NO_ERROR) + { + err = chip::NXP::App::GetAppTask().Start(); + } + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/all-clusters-app/nxp/zephyr/prj.conf b/examples/all-clusters-app/nxp/zephyr/prj.conf new file mode 100644 index 00000000000000..936bc5984f4f35 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/prj.conf @@ -0,0 +1,59 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="All Clusters" +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0x800 + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="NXPAllClusters" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +# enable NET commands if desired +#CONFIG_NET_SHELL=y +CONFIG_CHIP_STATISTICS=y diff --git a/examples/all-clusters-app/nxp/zephyr/prj_fdata.conf b/examples/all-clusters-app/nxp/zephyr/prj_fdata.conf new file mode 100644 index 00000000000000..a82618a5f46078 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/prj_fdata.conf @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="NXPAllClusters" + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +CONFIG_CHIP_STATISTICS=y + +# Factory data configuration +CONFIG_CHIP_DEVICE_VENDOR_ID=4151 +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xA00 +CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE=14014 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="All Clusters" +CONFIG_CHIP_DEVICE_TYPE=115 +CONFIG_CHIP_DEVICE_MANUFACTURING_DATE="2023-01-01" +CONFIG_CHIP_DEVICE_SERIAL_NUMBER="12345678" +CONFIG_CHIP_DEVICE_PRODUCT_COLOR="Green" +CONFIG_CHIP_DEVICE_PRODUCT_FINISH="Matte" + +# Use factory data provider for device info +CONFIG_CHIP_FACTORY_DATA=y +# Generate factor data raw binary during the build process +# CONFIG_CHIP_FACTORY_DATA_BUILD=y +# Generate test certificates for factory data during the build process +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y +# Spake2p verifier will be generated during factory data generation +# CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=y + +# Example of using pre-generated certificates +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT="/Chip-Test-CD-1037-A226.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT="/Chip-DAC-NXP-1037-A226-Cert.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY="/Chip-DAC-NXP-1037-A226-Key.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT="/Chip-PAI-NXP-1037-A226-Cert.der" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y diff --git a/examples/all-clusters-app/nxp/zephyr/prj_ota.conf b/examples/all-clusters-app/nxp/zephyr/prj_ota.conf new file mode 100644 index 00000000000000..bdc65e94fabf70 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/prj_ota.conf @@ -0,0 +1,31 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Options needed for OTA are located on this file +# This file should contain only options specific for this sample +# or overrides the default ones. + +CONFIG_CHIP_OTA_REQUESTOR=y + +# To generate an OTA image based on the application +CONFIG_CHIP_OTA_IMAGE_BUILD=y + +# By default, MCUBOOT bootloader uses a signature key provided in their repository. +# Change the key to the appropriate one. +# Note: You need to use the same signature key used by MCUBOOT, i.e BOOT_SIGNATURE_KEY_FILE. +# Default CONFIG_BOOT_SIGNATURE_KEY_FILE is defined in config/nxp/app/bootloader.conf +CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" diff --git a/examples/all-clusters-app/nxp/zephyr/third_party/connectedhomeip b/examples/all-clusters-app/nxp/zephyr/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/all-clusters-app/nxp/zephyr/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/common/m5stack-tft/repo b/examples/common/m5stack-tft/repo index d99f5ef8df180a..a6299b6c7c0b2e 160000 --- a/examples/common/m5stack-tft/repo +++ b/examples/common/m5stack-tft/repo @@ -1 +1 @@ -Subproject commit d99f5ef8df180ab34b3d9fff6888d5bede7665c5 +Subproject commit a6299b6c7c0b2e3eb62fa08ee4bf7155c39bad1f diff --git a/examples/common/tracing/decoder/logging/ToCertificateString.cpp b/examples/common/tracing/decoder/logging/ToCertificateString.cpp index 423544a9cc2a0c..1abd27ef788c59 100644 --- a/examples/common/tracing/decoder/logging/ToCertificateString.cpp +++ b/examples/common/tracing/decoder/logging/ToCertificateString.cpp @@ -35,7 +35,7 @@ const char * ToCertificate(const chip::ByteSpan & source, chip::MutableCharSpan { // Reset the buffer memset(destination.data(), '\0', destination.size()); - + int snprintf_len = 0; if (source.size() == 0) { return destination.data(); @@ -70,7 +70,8 @@ const char * ToCertificate(const chip::ByteSpan & source, chip::MutableCharSpan ChipLogError(DataManagement, "Certificate size is greater than 400 bytes"); } - snprintf(destination.data(), destination.size(), "%s", str.Get()); + snprintf_len = snprintf(destination.data(), destination.size(), "%s", str.Get()); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write certificate");); } else { @@ -83,15 +84,23 @@ const char * ToCertificate(const chip::ByteSpan & source, chip::MutableCharSpan size_t inIndex = 0; size_t outIndex = strlen(header) + 1; - snprintf(destination.data(), destination.size(), "%s\n", header); + snprintf_len = snprintf(destination.data(), destination.size(), "%s\n", header); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write header");); for (; inIndex < base64DataLen; inIndex += 64) { - auto charsPrinted = snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%.64s\n", &str[inIndex]); - outIndex += static_cast(charsPrinted); + snprintf_len = snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%.64s\n", &str[inIndex]); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write certificate");); + + outIndex += static_cast(snprintf_len); } - snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%s", footer); + snprintf_len = snprintf(&destination.data()[outIndex], destination.size() - outIndex, "%s", footer); + VerifyOrExit(snprintf_len >= 0, ChipLogError(DataManagement, "Failed to write footer");); + } +exit: + if (snprintf_len < 0) + { + memset(destination.data(), '\0', destination.size()); } - return destination.data(); } diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index 7dc5b848e22324..6cb580ded9c35f 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -39,7 +39,7 @@ class CHIPCommandBridge : public Command { { AddArgument("commissioner-name", &mCommissionerName); AddArgument("commissioner-nodeId", 0, UINT64_MAX, &mCommissionerNodeId, - "Sets the commisser node ID of the given " + "Sets the commissioner node ID of the given " "commissioner-name. Interactive mode will only set a single commissioner on the inital command. " "The commissioner node ID will be persisted until a different one is specified."); AddArgument("paa-trust-store-path", &mPaaTrustStorePath, diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm index 9723199ed007a4..52f0fd4bb10a17 100644 --- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm +++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm @@ -36,7 +36,7 @@ - (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommission ChipLogError(chipTool, "MTRCommissioningStatusDiscoveringMoreDevices: This should not happen."); break; case MTRCommissioningStatusUnknown: - ChipLogError(chipTool, "Uknown Pairing Status"); + ChipLogError(chipTool, "Unknown Pairing Status"); break; } } diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index f03c4f3f699838..00ca1204cc1f19 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -19,9 +19,11 @@ #include "RpcClient.h" #include "RpcClientProcessor.h" +#include +#include +#include #include #include -#include #include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" #include "pw_assert/check.h" @@ -36,16 +38,45 @@ using namespace chip; namespace { // Constants +constexpr uint32_t kRpcTimeoutMs = 1000; constexpr uint32_t kDefaultChannelId = 1; // Fabric Bridge Client rpc::pw_rpc::nanopb::FabricBridge::Client fabricBridgeClient(rpc::client::GetDefaultRpcClient(), kDefaultChannelId); -pw::rpc::NanopbUnaryReceiver<::pw_protobuf_Empty> addSynchronizedDeviceCall; -pw::rpc::NanopbUnaryReceiver<::pw_protobuf_Empty> removeSynchronizedDeviceCall; + +std::mutex responseMutex; +std::condition_variable responseCv; +bool responseReceived = false; +CHIP_ERROR responseError = CHIP_NO_ERROR; + +// By passing the `call` parameter into WaitForResponse we are explicitly trying to insure the caller takes into consideration that +// the lifetime of the `call` object when calling WaitForResponse +template +CHIP_ERROR WaitForResponse(CallType & call) +{ + std::unique_lock lock(responseMutex); + responseReceived = false; + responseError = CHIP_NO_ERROR; + + if (responseCv.wait_for(lock, std::chrono::milliseconds(kRpcTimeoutMs), [] { return responseReceived; })) + { + return responseError; + } + else + { + fprintf(stderr, "RPC Response timed out!"); + return CHIP_ERROR_TIMEOUT; + } +} // Callback function to be called when the RPC response is received void OnAddDeviceResponseCompleted(const pw_protobuf_Empty & response, pw::Status status) { + std::lock_guard lock(responseMutex); + responseReceived = true; + responseError = status.ok() ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + responseCv.notify_one(); + if (status.ok()) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice RPC call succeeded!"); @@ -59,6 +90,11 @@ void OnAddDeviceResponseCompleted(const pw_protobuf_Empty & response, pw::Status // Callback function to be called when the RPC response is received void OnRemoveDeviceResponseCompleted(const pw_protobuf_Empty & response, pw::Status status) { + std::lock_guard lock(responseMutex); + responseReceived = true; + responseError = status.ok() ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + responseCv.notify_one(); + if (status.ok()) { ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice RPC call succeeded!"); @@ -81,52 +117,38 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice"); - if (addSynchronizedDeviceCall.active()) - { - ChipLogError(NotSpecified, "Add Synchronized Device operation is in progress\n"); - return CHIP_ERROR_BUSY; - } - chip_rpc_SynchronizedDevice device; device.node_id = nodeId; - // By assigning the returned call to the global 'addSynchronizedDeviceCall', the RPC - // call is kept alive until it completes. When a response is received, it - // will be logged by the handler function and the call will complete. - addSynchronizedDeviceCall = fabricBridgeClient.AddSynchronizedDevice(device, OnAddDeviceResponseCompleted); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricBridgeClient.AddSynchronizedDevice(device, OnAddDeviceResponseCompleted); - if (!addSynchronizedDeviceCall.active()) + if (!call.active()) { // The RPC call was not sent. This could occur due to, for example, an invalid channel ID. Handle if necessary. return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; + return WaitForResponse(call); } CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId) { ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice"); - if (removeSynchronizedDeviceCall.active()) - { - ChipLogError(NotSpecified, "Remove Synchronized Device operation is in progress\n"); - return CHIP_ERROR_BUSY; - } - chip_rpc_SynchronizedDevice device; device.node_id = nodeId; - // By assigning the returned call to the global 'removeSynchronizedDeviceCall', the RPC - // call is kept alive until it completes. When a response is received, it - // will be logged by the handler function and the call will complete. - removeSynchronizedDeviceCall = fabricBridgeClient.RemoveSynchronizedDevice(device, OnRemoveDeviceResponseCompleted); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricBridgeClient.RemoveSynchronizedDevice(device, OnRemoveDeviceResponseCompleted); - if (!removeSynchronizedDeviceCall.active()) + if (!call.active()) { // The RPC call was not sent. This could occur due to, for example, an invalid channel ID. Handle if necessary. return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; + return WaitForResponse(call); } diff --git a/examples/fabric-admin/rpc/RpcClient.h b/examples/fabric-admin/rpc/RpcClient.h index eb28c19bee7d3e..a1754b3846d508 100644 --- a/examples/fabric-admin/rpc/RpcClient.h +++ b/examples/fabric-admin/rpc/RpcClient.h @@ -41,7 +41,7 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort); * * @param nodeId The Node ID of the device to be added. * @return CHIP_ERROR An error code indicating the success or failure of the operation. - * - CHIP_NO_ERROR: The RPC command was successfully sent. + * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another operation is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. */ @@ -56,7 +56,7 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId); * * @param nodeId The Node ID of the device to be removed. * @return CHIP_ERROR An error code indicating the success or failure of the operation. - * - CHIP_NO_ERROR: The RPC command was successfully sent. + * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another operation is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. */ diff --git a/examples/fabric-admin/scripts/run_fabric_sink.sh b/examples/fabric-admin/scripts/run_fabric_sink.sh new file mode 100755 index 00000000000000..3013965479268a --- /dev/null +++ b/examples/fabric-admin/scripts/run_fabric_sink.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Default paths +DEFAULT_CHOICES=( + "./fabric-admin" + "out/debug/standalone/fabric-admin" + "out/linux-x64-fabric-admin/fabric-admin" + "out/darwin-arm64-fabric-admin/fabric-admin" +) +FABRIC_ADMIN_LOG="/tmp/fabric_admin.log" +FABRIC_ADMIN_PATH="" + +# Function to find fabric-admin binary +find_fabric_admin() { + local choices=("$@") + for path in "${choices[@]}"; do + if [[ -e "$path" ]]; then + echo "$path" + return 0 + fi + done + return 1 +} + +# Parse arguments +VERBOSE=false +SPECIFIED_PATH="" + +for arg in "$@"; do + case $arg in + --verbose) + VERBOSE=true + ;; + --path=*) + SPECIFIED_PATH="${arg#*=}" + ;; + esac +done + +# Use specified path if provided +if [[ -n "$SPECIFIED_PATH" ]]; then + if [[ -e "$SPECIFIED_PATH" ]]; then + FABRIC_ADMIN_PATH="$SPECIFIED_PATH" + else + echo >&2 "Specified path does not exist: $SPECIFIED_PATH" + exit 1 + fi +else + FABRIC_ADMIN_PATH=$(find_fabric_admin "${DEFAULT_CHOICES[@]}") + if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the fabric-admin binary" + exit 1 + fi +fi + +echo "PATH IS: $FABRIC_ADMIN_PATH" + +# Kill fabric-admin if it is running +echo "Checking for running fabric-admin process..." +fabric_admin_pid=$(pgrep -f "$FABRIC_ADMIN_PATH") +if [[ -n "$fabric_admin_pid" ]]; then + echo "Found fabric-admin with PID $fabric_admin_pid, attempting to kill..." + kill -9 "$fabric_admin_pid" + echo "Killed fabric-admin with PID $fabric_admin_pid" +fi + +# Remove /tmp/chip_* files and directories +echo "Removing /tmp/chip_* files and directories..." +sudo rm -rf /tmp/chip_* +echo "Removed /tmp/chip_* files and directories" + +# Start fabric-admin with or without log file path based on --verbose option +echo "Starting fabric-admin..." +if [ "$VERBOSE" = true ]; then + "$FABRIC_ADMIN_PATH" +else + "$FABRIC_ADMIN_PATH" --log-file-path "$FABRIC_ADMIN_LOG" +fi diff --git a/examples/fabric-admin/scripts/run_fabric_source.sh b/examples/fabric-admin/scripts/run_fabric_source.sh new file mode 100755 index 00000000000000..95df7a135bb596 --- /dev/null +++ b/examples/fabric-admin/scripts/run_fabric_source.sh @@ -0,0 +1,116 @@ +#!/bin/bash + +# Get the path to the current script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Default paths +DEFAULT_ADMIN_CHOICES=( + "./fabric-admin" + "out/debug/standalone/fabric-admin" + "out/linux-x64-fabric-admin/fabric-admin" + "out/darwin-arm64-fabric-admin/fabric-admin" +) +DEFAULT_BRIDGE_CHOICES=( + "./fabric-bridge-app" + "out/debug/standalone/fabric-bridge-app" + "out/linux-x64-fabric-bridge-app/fabric-bridge-app" + "out/darwin-arm64-fabric-bridge-app/fabric-bridge-app" +) +FABRIC_ADMIN_LOG="/tmp/fabric_admin.log" +FABRIC_BRIDGE_APP_LOG="/tmp/fabric_bridge_app.log" +FABRIC_ADMIN_PATH="" +FABRIC_BRIDGE_APP_PATH="" + +# Function to find a binary +find_binary() { + local choices=("$@") + for path in "${choices[@]}"; do + if [[ -e "$path" ]]; then + echo "$path" + return 0 + fi + done + return 1 +} + +# Parse arguments +VERBOSE=false +SPECIFIED_ADMIN_PATH="" +SPECIFIED_BRIDGE_PATH="" + +for arg in "$@"; do + case $arg in + --verbose) + VERBOSE=true + ;; + --admin-path=*) + SPECIFIED_ADMIN_PATH="${arg#*=}" + ;; + --bridge-path=*) + SPECIFIED_BRIDGE_PATH="${arg#*=}" + ;; + esac +done + +# Use specified paths if provided +if [[ -n "$SPECIFIED_ADMIN_PATH" ]]; then + if [[ -e "$SPECIFIED_ADMIN_PATH" ]]; then + FABRIC_ADMIN_PATH="$SPECIFIED_ADMIN_PATH" + else + echo >&2 "Specified admin path does not exist: $SPECIFIED_ADMIN_PATH" + exit 1 + fi +else + FABRIC_ADMIN_PATH=$(find_binary "${DEFAULT_ADMIN_CHOICES[@]}") + if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the fabric-admin binary" + exit 1 + fi +fi + +if [[ -n "$SPECIFIED_BRIDGE_PATH" ]]; then + if [[ -e "$SPECIFIED_BRIDGE_PATH" ]]; then + FABRIC_BRIDGE_APP_PATH="$SPECIFIED_BRIDGE_PATH" + else + echo >&2 "Specified bridge path does not exist: $SPECIFIED_BRIDGE_PATH" + exit 1 + fi +else + FABRIC_BRIDGE_APP_PATH=$(find_binary "${DEFAULT_BRIDGE_CHOICES[@]}") + if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the fabric-bridge-app binary" + exit 1 + fi +fi + +echo "Admin path: $FABRIC_ADMIN_PATH" +echo "Bridge path: $FABRIC_BRIDGE_APP_PATH" + +# Determine the path to stop_fabric_source.sh based on the location of run_fabric_source.sh +RUN_FABRIC_SOURCE_PATH=$(find_binary "$SCRIPT_DIR/run_fabric_source.sh") +if [[ $? -ne 0 ]]; then + echo >&2 "Could not find the run_fabric_source.sh script" + exit 1 +fi +STOP_FABRIC_SOURCE_PATH="${RUN_FABRIC_SOURCE_PATH/run_fabric_source/stop_fabric_source}" + +# Stop any running instances and clean up +if [[ -e "$STOP_FABRIC_SOURCE_PATH" ]]; then + "$STOP_FABRIC_SOURCE_PATH" +else + echo >&2 "Could not find the stop_fabric_source.sh script" + exit 1 +fi + +# Start fabric-bridge-app if available and redirect its output to /dev/null +if [ -f "$FABRIC_BRIDGE_APP_PATH" ]; then + "$FABRIC_BRIDGE_APP_PATH" >"$FABRIC_BRIDGE_APP_LOG" 2>&1 & + echo "Started fabric-bridge-app" +fi + +# Start fabric-admin with or without log file path based on --verbose option +if [ "$VERBOSE" = true ]; then + "$FABRIC_ADMIN_PATH" +else + "$FABRIC_ADMIN_PATH" --log-file-path "$FABRIC_ADMIN_LOG" +fi diff --git a/examples/fabric-admin/scripts/stop_fabric_source.sh b/examples/fabric-admin/scripts/stop_fabric_source.sh new file mode 100755 index 00000000000000..85fff9e3a878cc --- /dev/null +++ b/examples/fabric-admin/scripts/stop_fabric_source.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +FABRIC_ADMIN_PATH="/fabric-admin" +FABRIC_BRIDGE_APP_PATH="/fabric-bridge-app" + +# Kill fabric-admin if it is running +fabric_admin_pid=$(pgrep -f "$FABRIC_ADMIN_PATH") +if [ ! -z "$fabric_admin_pid" ]; then + kill -9 "$fabric_admin_pid" + echo "Killed fabric-admin with PID $fabric_admin_pid" +fi + +# Kill fabric-bridge-app if it is running +fabric_bridge_app_pid=$(pgrep -f "$FABRIC_BRIDGE_APP_PATH") +if [ ! -z "$fabric_bridge_app_pid" ]; then + kill -9 "$fabric_bridge_app_pid" + echo "Killed fabric-bridge-app with PID $fabric_bridge_app_pid" +fi + +# Remove /tmp/chip_* files and directories +sudo rm -rf /tmp/chip_* +echo "Removed /tmp/chip_* files and directories" diff --git a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn index 70d9586b699c0f..3bc4c23b9e0f92 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn +++ b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn @@ -13,13 +13,32 @@ # limitations under the License. import("//build_overrides/chip.gni") - import("${chip_root}/src/app/chip_data_model.gni") +config("config") { + include_dirs = [ "include" ] +} + chip_data_model("fabric-bridge-common") { zap_file = "fabric-bridge-app.zap" - is_server = true - cflags = [ "-DDYNAMIC_ENDPOINT_COUNT=16" ] } + +source_set("fabric-bridge-lib") { + public_configs = [ ":config" ] + + sources = [ + "include/CHIPProjectAppConfig.h", + "include/Device.h", + "include/DeviceManager.h", + "src/Device.cpp", + "src/DeviceManager.cpp", + "src/ZCLCallbacks.cpp", + ] + + deps = [ + "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common", + "${chip_root}/src/lib", + ] +} diff --git a/examples/fabric-bridge-app/linux/include/Device.h b/examples/fabric-bridge-app/fabric-bridge-common/include/Device.h similarity index 100% rename from examples/fabric-bridge-app/linux/include/Device.h rename to examples/fabric-bridge-app/fabric-bridge-common/include/Device.h diff --git a/examples/fabric-bridge-app/linux/include/DeviceManager.h b/examples/fabric-bridge-app/fabric-bridge-common/include/DeviceManager.h similarity index 100% rename from examples/fabric-bridge-app/linux/include/DeviceManager.h rename to examples/fabric-bridge-app/fabric-bridge-common/include/DeviceManager.h diff --git a/examples/fabric-bridge-app/linux/Device.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/Device.cpp similarity index 100% rename from examples/fabric-bridge-app/linux/Device.cpp rename to examples/fabric-bridge-app/fabric-bridge-common/src/Device.cpp diff --git a/examples/fabric-bridge-app/linux/DeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/DeviceManager.cpp similarity index 100% rename from examples/fabric-bridge-app/linux/DeviceManager.cpp rename to examples/fabric-bridge-app/fabric-bridge-common/src/DeviceManager.cpp diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp new file mode 100644 index 00000000000000..7a9521fa7820a7 --- /dev/null +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DeviceManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) +#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION (2u) +#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP (0u) + +// External attribute read callback function +Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength) +{ + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + AttributeId attributeId = attributeMetadata->attributeId; + + Device * dev = DeviceMgr().GetDevice(endpointIndex); + if (dev != nullptr && clusterId == app::Clusters::BridgedDeviceBasicInformation::Id) + { + using namespace app::Clusters::BridgedDeviceBasicInformation::Attributes; + ChipLogProgress(NotSpecified, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, + maxReadLength); + + if ((attributeId == Reachable::Id) && (maxReadLength == 1)) + { + *buffer = dev->IsReachable() ? 1 : 0; + } + else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) + { + MutableByteSpan zclNameSpan(buffer, maxReadLength); + MakeZclCharString(zclNameSpan, dev->GetName()); + } + else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) + { + uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; + memcpy(buffer, &rev, sizeof(rev)); + } + else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) + { + uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; + memcpy(buffer, &featureMap, sizeof(featureMap)); + } + else + { + return Protocols::InteractionModel::Status::Failure; + } + return Protocols::InteractionModel::Status::Success; + } + + return Protocols::InteractionModel::Status::Failure; +} + +// External attribute write callback function +Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer) +{ + uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); + Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; + + Device * dev = DeviceMgr().GetDevice(endpointIndex); + if (dev != nullptr && dev->IsReachable()) + { + ChipLogProgress(NotSpecified, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); + ret = Protocols::InteractionModel::Status::Success; + } + + return ret; +} diff --git a/examples/fabric-bridge-app/linux/BUILD.gn b/examples/fabric-bridge-app/linux/BUILD.gn index 2b408d52625fea..d0f60f30fbb2b9 100644 --- a/examples/fabric-bridge-app/linux/BUILD.gn +++ b/examples/fabric-bridge-app/linux/BUILD.gn @@ -33,15 +33,12 @@ if (bridge_enable_pw_rpc) { executable("fabric-bridge-app") { sources = [ "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h", - "Device.cpp", - "DeviceManager.cpp", - "include/Device.h", - "include/DeviceManager.h", "main.cpp", ] deps = [ "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common", + "${chip_root}/examples/fabric-bridge-app/fabric-bridge-common:fabric-bridge-lib", "${chip_root}/examples/platform/linux:app-main", "${chip_root}/src/lib", ] diff --git a/examples/fabric-bridge-app/linux/Dockerfile b/examples/fabric-bridge-app/linux/Dockerfile deleted file mode 100644 index 5194431decc644..00000000000000 --- a/examples/fabric-bridge-app/linux/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -ARG VERSION=1 -FROM ghcr.io/project-chip/chip-cirque-device-base:${VERSION} -LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip - -COPY out/debug/chip-bridge-app /usr/bin/ -COPY entrypoint.sh / - -ENTRYPOINT ["/entrypoint.sh", "server"] diff --git a/examples/fabric-bridge-app/linux/RpcClient.cpp b/examples/fabric-bridge-app/linux/RpcClient.cpp index 815250f12bc328..02916b87aaa06a 100644 --- a/examples/fabric-bridge-app/linux/RpcClient.cpp +++ b/examples/fabric-bridge-app/linux/RpcClient.cpp @@ -19,9 +19,11 @@ #include "RpcClient.h" #include "RpcClientProcessor.h" +#include +#include +#include #include #include -#include #include "fabric_admin_service/fabric_admin_service.rpc.pb.h" #include "pw_assert/check.h" @@ -36,15 +38,45 @@ using namespace chip; namespace { // Constants +constexpr uint32_t kRpcTimeoutMs = 1000; constexpr uint32_t kDefaultChannelId = 1; // Fabric Admin Client rpc::pw_rpc::nanopb::FabricAdmin::Client fabricAdminClient(rpc::client::GetDefaultRpcClient(), kDefaultChannelId); -pw::rpc::NanopbUnaryReceiver<::chip_rpc_OperationStatus> openCommissioningWindowCall; + +std::mutex responseMutex; +std::condition_variable responseCv; +bool responseReceived = false; +CHIP_ERROR responseError = CHIP_NO_ERROR; + +// By passing the `call` parameter into WaitForResponse we are explicitly trying to insure the caller takes into consideration that +// the lifetime of the `call` object when calling WaitForResponse +template +CHIP_ERROR WaitForResponse(CallType & call) +{ + std::unique_lock lock(responseMutex); + responseReceived = false; + responseError = CHIP_NO_ERROR; + + if (responseCv.wait_for(lock, std::chrono::milliseconds(kRpcTimeoutMs), [] { return responseReceived; })) + { + return responseError; + } + else + { + ChipLogError(NotSpecified, "RPC Response timed out!"); + return CHIP_ERROR_TIMEOUT; + } +} // Callback function to be called when the RPC response is received void OnOpenCommissioningWindowCompleted(const chip_rpc_OperationStatus & response, pw::Status status) { + std::lock_guard lock(responseMutex); + responseReceived = true; + responseError = status.ok() ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + responseCv.notify_one(); + if (status.ok()) { ChipLogProgress(NotSpecified, "OpenCommissioningWindow received operation status: %d", response.success); @@ -67,22 +99,18 @@ CHIP_ERROR OpenCommissioningWindow(NodeId nodeId) { ChipLogProgress(NotSpecified, "OpenCommissioningWindow with Node Id 0x:" ChipLogFormatX64, ChipLogValueX64(nodeId)); - if (openCommissioningWindowCall.active()) - { - ChipLogError(NotSpecified, "OpenCommissioningWindow is in progress\n"); - return CHIP_ERROR_BUSY; - } - chip_rpc_DeviceInfo device; device.node_id = nodeId; - // The RPC will remain active as long as `openCommissioningWindowCall` is alive. - openCommissioningWindowCall = fabricAdminClient.OpenCommissioningWindow(device, OnOpenCommissioningWindowCompleted); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricAdminClient.OpenCommissioningWindow(device, OnOpenCommissioningWindowCompleted); - if (!openCommissioningWindowCall.active()) + if (!call.active()) { + // The RPC call was not sent. This could occur due to, for example, an invalid channel ID. Handle if necessary. return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; + return WaitForResponse(call); } diff --git a/examples/fabric-bridge-app/linux/include/RpcClient.h b/examples/fabric-bridge-app/linux/include/RpcClient.h index bd424e9d275910..34fa5c19de9349 100644 --- a/examples/fabric-bridge-app/linux/include/RpcClient.h +++ b/examples/fabric-bridge-app/linux/include/RpcClient.h @@ -37,7 +37,7 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort); * * @param nodeId The identifier of the node for which the commissioning window should be opened. * @return CHIP_ERROR An error code indicating the success or failure of the operation. - * - CHIP_NO_ERROR: The RPC command was successfully sent. + * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another commissioning window is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred. */ diff --git a/examples/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index 2047e15877ee4c..0aa22b8445ee56 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -23,7 +23,6 @@ #include "DeviceManager.h" #include -#include #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE #include "RpcClient.h" @@ -40,10 +39,6 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::AdministratorCommissioning; -#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) -#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION (2u) -#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP (0u) - namespace { constexpr uint16_t kPollIntervalMs = 100; @@ -158,6 +153,8 @@ AdministratorCommissioningCommandHandler gAdministratorCommissioningCommandHandl void ApplicationInit() { + ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationInit()"); + InteractionModelEngine::GetInstance()->RegisterCommandHandler(&gAdministratorCommissioningCommandHandler); #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE @@ -172,7 +169,10 @@ void ApplicationInit() DeviceMgr().Init(); } -void ApplicationShutdown() {} +void ApplicationShutdown() +{ + ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationShutdown()"); +} int main(int argc, char * argv[]) { @@ -185,65 +185,3 @@ int main(int argc, char * argv[]) return 0; } - -// External attribute read callback function -Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer, uint16_t maxReadLength) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - AttributeId attributeId = attributeMetadata->attributeId; - - Device * dev = DeviceMgr().GetDevice(endpointIndex); - if (dev != nullptr && clusterId == app::Clusters::BridgedDeviceBasicInformation::Id) - { - using namespace app::Clusters::BridgedDeviceBasicInformation::Attributes; - ChipLogProgress(NotSpecified, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, - maxReadLength); - - if ((attributeId == Reachable::Id) && (maxReadLength == 1)) - { - *buffer = dev->IsReachable() ? 1 : 0; - } - else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) - { - MutableByteSpan zclNameSpan(buffer, maxReadLength); - MakeZclCharString(zclNameSpan, dev->GetName()); - } - else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) - { - uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; - memcpy(buffer, &rev, sizeof(rev)); - } - else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) - { - uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; - memcpy(buffer, &featureMap, sizeof(featureMap)); - } - else - { - return Protocols::InteractionModel::Status::Failure; - } - return Protocols::InteractionModel::Status::Success; - } - - return Protocols::InteractionModel::Status::Failure; -} - -// External attribute write callback function -Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; - - Device * dev = DeviceMgr().GetDevice(endpointIndex); - if (dev != nullptr && dev->IsReachable()) - { - ChipLogProgress(NotSpecified, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); - ret = Protocols::InteractionModel::Status::Success; - } - - return ret; -} diff --git a/examples/laundry-washer-app/nxp/zephyr/.gitignore b/examples/laundry-washer-app/nxp/zephyr/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/laundry-washer-app/nxp/zephyr/CMakeLists.txt b/examples/laundry-washer-app/nxp/zephyr/CMakeLists.txt new file mode 100644 index 00000000000000..f7b32881ada959 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/CMakeLists.txt @@ -0,0 +1,116 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(LAUNDRY_WASHER_NXP_COMMON_DIR ${CHIP_ROOT}/examples/laundry-washer-app/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_COMMON_DIR ${CHIP_ROOT}/examples/platform/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR ${CHIP_ROOT}/examples/platform/nxp/zephyr REALPATH) + +# Perform common operations like detecting extra overlays in the platform folder for the target board +# This must be called before find_package(Zephyr) +include(${CHIP_ROOT}/config/nxp/app/pre-zephyr.cmake) + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nxp/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) +target_compile_options(app PRIVATE -Werror PRIVATE -Wno-error=format) + +project(chip-nxp-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nxp/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app + PRIVATE + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/include + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/Zephyr/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include +) + +target_sources(app + PRIVATE + main/main.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/AppTask.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/source/CHIPDeviceManager.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/DeviceCallbacks.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/source/CommonDeviceCallbacks.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/ZclCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskZephyr.cpp + ${EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR}/factory_data/source/AppFactoryDataExample.cpp +) + +target_compile_definitions(app PUBLIC + "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\"" +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorZephyr.cpp + ) + target_include_directories(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/include/ + ) +endif() + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/../../laundry-washer-app/nxp/zap/laundry-washer-app.zap +) + +if(CONFIG_CHIP_LIB_SHELL) + target_compile_definitions(app PRIVATE ENABLE_CHIP_SHELL) + target_include_directories(app PRIVATE + ${CHIP_ROOT}/examples/shell/shell_common/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/include + ) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIZephyr.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_misc.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_otcli.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_server.cpp + ) +endif() + +target_sources(app + PRIVATE + ${ALL_CLUSTERS_COMMON_DIR}/src/smco-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/laundry-washer-mode.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/laundry-washer-controls-delegate-impl.cpp + ${LAUNDRY_WASHER_NXP_COMMON_DIR}/main/operational-state-delegate-impl.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/source/ICDUtil.cpp +) diff --git a/examples/laundry-washer-app/nxp/zephyr/Kconfig b/examples/laundry-washer-app/nxp/zephyr/Kconfig new file mode 100644 index 00000000000000..1d8b3f96581e51 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/Kconfig @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +mainmenu "Matter NXP Laundry Washer Example Application" + +rsource "../../../../config/nxp/chip-module/Kconfig.features" +rsource "../../../../config/nxp/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/laundry-washer-app/nxp/zephyr/README.md b/examples/laundry-washer-app/nxp/zephyr/README.md new file mode 100644 index 00000000000000..406ee3b7796ede --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/README.md @@ -0,0 +1,4 @@ +# CHIP NXP Zephyr Laundry Washer Application + +All instructions describing how to use a Matter application on NXP Zephyr can be +found in [README.md](../../../all-clusters-app/nxp/zephyr/README.md) root readme diff --git a/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga.overlay b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga.overlay new file mode 100644 index 00000000000000..86bb20739527cd --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: //www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm3; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; diff --git a/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf new file mode 100644 index 00000000000000..73d139c3948d95 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/boards/rd_rw612_bga_fdata.conf @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +CONFIG_SETTINGS_NVS_SECTOR_COUNT=16 + +# 0xA226 +CONFIG_CHIP_DEVICE_PRODUCT_ID=41510 +CONFIG_CHIP_DEVICE_PRODUCT_URL="https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radio-1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612" +CONFIG_CHIP_DEVICE_PRODUCT_LABEL="RW612" +CONFIG_CHIP_DEVICE_PART_NUMBER="RW612" diff --git a/examples/laundry-washer-app/nxp/zephyr/main/include/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/zephyr/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..84c57df1ea140d --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/main/include/CHIPProjectConfig.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR CONFIG_CHIP_DEVICE_DISCRIMINATOR + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 diff --git a/examples/laundry-washer-app/nxp/zephyr/main/main.cpp b/examples/laundry-washer-app/nxp/zephyr/main/main.cpp new file mode 100644 index 00000000000000..9be47dfe0a95d8 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/main/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (err == CHIP_NO_ERROR) + { + err = chip::NXP::App::GetAppTask().Start(); + } + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/laundry-washer-app/nxp/zephyr/prj.conf b/examples/laundry-washer-app/nxp/zephyr/prj.conf new file mode 100644 index 00000000000000..ed59218a7da0e9 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/prj.conf @@ -0,0 +1,59 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Laundry Washer" +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0x800 + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="LaundryWasher" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +# enable NET commands if desired +#CONFIG_NET_SHELL=y +CONFIG_CHIP_STATISTICS=y diff --git a/examples/laundry-washer-app/nxp/zephyr/prj_fdata.conf b/examples/laundry-washer-app/nxp/zephyr/prj_fdata.conf new file mode 100644 index 00000000000000..986fc877aec5df --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/prj_fdata.conf @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="LaundryWasher" + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +CONFIG_CHIP_STATISTICS=y + +# Factory data configuration +CONFIG_CHIP_DEVICE_VENDOR_ID=4151 +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xA00 +CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE=14014 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Laundry Washer" +CONFIG_CHIP_DEVICE_TYPE=115 +CONFIG_CHIP_DEVICE_MANUFACTURING_DATE="2023-01-01" +CONFIG_CHIP_DEVICE_SERIAL_NUMBER="12345678" +CONFIG_CHIP_DEVICE_PRODUCT_COLOR="Green" +CONFIG_CHIP_DEVICE_PRODUCT_FINISH="Matte" + +# Use factory data provider for device info +CONFIG_CHIP_FACTORY_DATA=y +# Generate factor data raw binary during the build process +# CONFIG_CHIP_FACTORY_DATA_BUILD=y +# Generate test certificates for factory data during the build process +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y +# Spake2p verifier will be generated during factory data generation +# CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=y + +# Example of using pre-generated certificates +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT="/Chip-Test-CD-1037-A226.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT="/Chip-DAC-NXP-1037-A226-Cert.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY="/Chip-DAC-NXP-1037-A226-Key.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT="/Chip-PAI-NXP-1037-A226-Cert.der" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y diff --git a/examples/laundry-washer-app/nxp/zephyr/prj_ota.conf b/examples/laundry-washer-app/nxp/zephyr/prj_ota.conf new file mode 100644 index 00000000000000..bdc65e94fabf70 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/prj_ota.conf @@ -0,0 +1,31 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Options needed for OTA are located on this file +# This file should contain only options specific for this sample +# or overrides the default ones. + +CONFIG_CHIP_OTA_REQUESTOR=y + +# To generate an OTA image based on the application +CONFIG_CHIP_OTA_IMAGE_BUILD=y + +# By default, MCUBOOT bootloader uses a signature key provided in their repository. +# Change the key to the appropriate one. +# Note: You need to use the same signature key used by MCUBOOT, i.e BOOT_SIGNATURE_KEY_FILE. +# Default CONFIG_BOOT_SIGNATURE_KEY_FILE is defined in config/nxp/app/bootloader.conf +CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" diff --git a/examples/laundry-washer-app/nxp/zephyr/third_party/connectedhomeip b/examples/laundry-washer-app/nxp/zephyr/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/laundry-washer-app/nxp/zephyr/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/light-switch-app/infineon/cyw30739/README.md b/examples/light-switch-app/infineon/cyw30739/README.md index 70d650cfef97a3..0343563087a154 100644 --- a/examples/light-switch-app/infineon/cyw30739/README.md +++ b/examples/light-switch-app/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/lighting-app/infineon/cyw30739/README.md b/examples/lighting-app/infineon/cyw30739/README.md index b1ff7aa5304902..a69ddb0957c8fa 100644 --- a/examples/lighting-app/infineon/cyw30739/README.md +++ b/examples/lighting-app/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/lock-app/infineon/cyw30739/README.md b/examples/lock-app/infineon/cyw30739/README.md index 2b7bd2094154df..0c9b769b665c2a 100644 --- a/examples/lock-app/infineon/cyw30739/README.md +++ b/examples/lock-app/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/lock-app/lock-common/include/LockEndpoint.h b/examples/lock-app/lock-common/include/LockEndpoint.h index bd193d388db02b..aa67a69481f23d 100644 --- a/examples/lock-app/lock-common/include/LockEndpoint.h +++ b/examples/lock-app/lock-common/include/LockEndpoint.h @@ -18,7 +18,9 @@ #pragma once +#include #include +#include #include struct LockUserInfo @@ -38,10 +40,10 @@ struct WeekDaysScheduleInfo; struct YearDayScheduleInfo; struct HolidayScheduleInfo; -static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20; -static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 6; +static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 65; +static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 9; -class LockEndpoint +class LockEndpoint : public chip::app::Clusters::DoorLock::Delegate { public: LockEndpoint(chip::EndpointId endpointId, uint16_t numberOfLockUsersSupported, uint16_t numberOfCredentialsSupported, @@ -60,6 +62,7 @@ class LockEndpoint } DoorLockServer::Instance().SetDoorState(endpointId, mDoorState); DoorLockServer::Instance().SetLockState(endpointId, mLockState); + chip::Crypto::DRBG_get_bytes(mAliroReaderGroupSubIdentifier, sizeof(mAliroReaderGroupSubIdentifier)); } inline chip::EndpointId GetEndpointId() const { return mEndpointId; } @@ -100,6 +103,22 @@ class LockEndpoint DlStatus SetSchedule(uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode); + // DoorLock::Delegate API. + CHIP_ERROR GetAliroReaderVerificationKey(chip::MutableByteSpan & verificationKey) override; + CHIP_ERROR GetAliroReaderGroupIdentifier(chip::MutableByteSpan & groupIdentifier) override; + CHIP_ERROR GetAliroReaderGroupSubIdentifier(chip::MutableByteSpan & groupSubIdentifier) override; + CHIP_ERROR GetAliroExpeditedTransactionSupportedProtocolVersionAtIndex(size_t index, + chip::MutableByteSpan & protocolVersion) override; + CHIP_ERROR GetAliroGroupResolvingKey(chip::MutableByteSpan & groupResolvingKey) override; + CHIP_ERROR GetAliroSupportedBLEUWBProtocolVersionAtIndex(size_t index, chip::MutableByteSpan & protocolVersion) override; + uint8_t GetAliroBLEAdvertisingVersion() override; + uint16_t GetNumberOfAliroCredentialIssuerKeysSupported() override; + uint16_t GetNumberOfAliroEndpointKeysSupported() override; + CHIP_ERROR SetAliroReaderConfig(const chip::ByteSpan & signingKey, const chip::ByteSpan & verificationKey, + const chip::ByteSpan & groupIdentifier, + const chip::Optional & groupResolvingKey) override; + CHIP_ERROR ClearAliroReaderConfig() override; + private: bool setLockState(const Nullable & fabricIdx, const Nullable & nodeId, DlLockState lockState, const Optional & pin, OperationErrorEnum & err, @@ -130,6 +149,14 @@ class LockEndpoint std::vector> mWeekDaySchedules; std::vector> mYearDaySchedules; std::vector mHolidaySchedules; + + // Actual Aliro state would presumably be stored somewhere else, and persistently; this + // example just stores it in memory for illustration purposes. + uint8_t mAliroReaderVerificationKey[chip::app::Clusters::DoorLock::kAliroReaderVerificationKeySize]; + uint8_t mAliroReaderGroupIdentifier[chip::app::Clusters::DoorLock::kAliroReaderGroupIdentifierSize]; + uint8_t mAliroReaderGroupSubIdentifier[chip::app::Clusters::DoorLock::kAliroReaderGroupSubIdentifierSize]; + uint8_t mAliroGroupResolvingKey[chip::app::Clusters::DoorLock::kAliroGroupResolvingKeySize]; + bool mAliroStateInitialized = false; }; struct LockCredentialInfo diff --git a/examples/lock-app/lock-common/include/LockManager.h b/examples/lock-app/lock-common/include/LockManager.h index 71dcf6f02dc072..fb4299a534622c 100644 --- a/examples/lock-app/lock-common/include/LockManager.h +++ b/examples/lock-app/lock-common/include/LockManager.h @@ -70,7 +70,12 @@ class LockManager private: LockEndpoint * getEndpoint(chip::EndpointId endpointId); - std::vector mEndpoints; + /** + * We store the LockEndpoint instances by pointer, not value, so + * LockEndpoint can have a stable location in memory, which lets it + * implement DoorLock::Delegate. + */ + std::vector> mEndpoints; static LockManager instance; }; diff --git a/examples/lock-app/lock-common/src/LockEndpoint.cpp b/examples/lock-app/lock-common/src/LockEndpoint.cpp index bda27f18ba2c8c..5481d01471cfd0 100644 --- a/examples/lock-app/lock-common/src/LockEndpoint.cpp +++ b/examples/lock-app/lock-common/src/LockEndpoint.cpp @@ -17,10 +17,15 @@ */ #include "LockEndpoint.h" #include +#include #include +#include #include #include +using chip::ByteSpan; +using chip::MutableByteSpan; +using chip::Optional; using chip::to_underlying; using chip::app::DataModel::MakeNullable; @@ -204,7 +209,8 @@ bool LockEndpoint::GetCredential(uint16_t credentialIndex, CredentialTypeEnum cr if (credentialIndex >= mLockCredentials.at(to_underlying(credentialType)).size() || (0 == credentialIndex && CredentialTypeEnum::kProgrammingPIN != credentialType)) { - ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex); + ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]: %d", mEndpointId, credentialIndex, + static_cast(mLockCredentials.at(to_underlying(credentialType)).size())); return false; } @@ -407,6 +413,149 @@ DlStatus LockEndpoint::SetSchedule(uint8_t holidayIndex, DlScheduleStatus status return DlStatus::kSuccess; } +CHIP_ERROR LockEndpoint::GetAliroReaderVerificationKey(MutableByteSpan & verificationKey) +{ + if (!mAliroStateInitialized) + { + verificationKey.reduce_size(0); + return CHIP_NO_ERROR; + } + + return chip::CopySpanToMutableSpan(ByteSpan(mAliroReaderVerificationKey), verificationKey); +} + +CHIP_ERROR LockEndpoint::GetAliroReaderGroupIdentifier(MutableByteSpan & groupIdentifier) +{ + if (!mAliroStateInitialized) + { + groupIdentifier.reduce_size(0); + return CHIP_NO_ERROR; + } + + return CopySpanToMutableSpan(ByteSpan(mAliroReaderGroupIdentifier), groupIdentifier); +} + +CHIP_ERROR LockEndpoint::GetAliroReaderGroupSubIdentifier(MutableByteSpan & groupSubIdentifier) +{ + return CopySpanToMutableSpan(ByteSpan(mAliroReaderGroupSubIdentifier), groupSubIdentifier); +} + +namespace { + +CHIP_ERROR CopyProtocolVersionIntoSpan(uint16_t protocolVersionValue, MutableByteSpan & protocolVersion) +{ + using namespace chip::app::Clusters::DoorLock; + + static_assert(sizeof(protocolVersionValue) == kAliroProtocolVersionSize); + + if (protocolVersion.size() < kAliroProtocolVersionSize) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Per Aliro spec, protocol version encoding is big-endian + chip::Encoding::BigEndian::Put16(protocolVersion.data(), protocolVersionValue); + protocolVersion.reduce_size(kAliroProtocolVersionSize); + return CHIP_NO_ERROR; +} + +} // anonymous namespace + +CHIP_ERROR LockEndpoint::GetAliroExpeditedTransactionSupportedProtocolVersionAtIndex(size_t index, + MutableByteSpan & protocolVersion) +{ + // Only claim support for the one known protocol version for now: 0x0100. + constexpr uint16_t knownProtocolVersion = 0x0100; + + if (index > 0) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + return CopyProtocolVersionIntoSpan(knownProtocolVersion, protocolVersion); +} + +CHIP_ERROR LockEndpoint::GetAliroGroupResolvingKey(MutableByteSpan & groupResolvingKey) +{ + if (!mAliroStateInitialized) + { + groupResolvingKey.reduce_size(0); + return CHIP_NO_ERROR; + } + + return CopySpanToMutableSpan(ByteSpan(mAliroGroupResolvingKey), groupResolvingKey); +} + +CHIP_ERROR LockEndpoint::GetAliroSupportedBLEUWBProtocolVersionAtIndex(size_t index, MutableByteSpan & protocolVersion) +{ + // Only claim support for the one known protocol version for now: 0x0100. + constexpr uint16_t knownProtocolVersion = 0x0100; + + if (index > 0) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + return CopyProtocolVersionIntoSpan(knownProtocolVersion, protocolVersion); +} + +uint8_t LockEndpoint::GetAliroBLEAdvertisingVersion() +{ + // For now the only define value of the BLE advertising version for Aliro is 0. + return 0; +} + +uint16_t LockEndpoint::GetNumberOfAliroCredentialIssuerKeysSupported() +{ + using namespace chip::app::Clusters::DoorLock; + + // Our vector has an extra entry at index 0 that is not a valid entry, so + // the actual number of credentials supported is one length than the length. + return static_cast(mLockCredentials.at(to_underlying(CredentialTypeEnum::kAliroCredentialIssuerKey)).size() - 1); +} + +uint16_t LockEndpoint::GetNumberOfAliroEndpointKeysSupported() +{ + using namespace chip::app::Clusters::DoorLock; + + // Our vector has an extra entry at index 0 that is not a valid entry, so + // the actual number of credentials supported is one length than the length. + // + // Also, our arrays are the same size, so we just return the size of one of + // the arrays: that is the cap on the total number of endpoint keys + // supported, which can be of either type. + return static_cast(mLockCredentials.at(to_underlying(CredentialTypeEnum::kAliroEvictableEndpointKey)).size() - 1); +} + +CHIP_ERROR LockEndpoint::SetAliroReaderConfig(const ByteSpan & signingKey, const ByteSpan & verificationKey, + const ByteSpan & groupIdentifier, const Optional & groupResolvingKey) +{ + // We ignore the signing key, since we never do anything with it. + + VerifyOrReturnError(verificationKey.size() == sizeof(mAliroReaderVerificationKey), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mAliroReaderVerificationKey, verificationKey.data(), sizeof(mAliroReaderVerificationKey)); + + VerifyOrReturnError(groupIdentifier.size() == sizeof(mAliroReaderGroupIdentifier), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mAliroReaderGroupIdentifier, groupIdentifier.data(), sizeof(mAliroReaderGroupIdentifier)); + + if (groupResolvingKey.HasValue()) + { + VerifyOrReturnError(groupResolvingKey.Value().size() == sizeof(mAliroGroupResolvingKey), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mAliroGroupResolvingKey, groupResolvingKey.Value().data(), sizeof(mAliroGroupResolvingKey)); + } + + mAliroStateInitialized = true; + return CHIP_NO_ERROR; +} + +CHIP_ERROR LockEndpoint::ClearAliroReaderConfig() +{ + // A real implementation would clear out key data from the other parts of + // the application that might use it. + mAliroStateInitialized = false; + return CHIP_NO_ERROR; +} + bool LockEndpoint::setLockState(const Nullable & fabricIdx, const Nullable & nodeId, DlLockState lockState, const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) diff --git a/examples/lock-app/lock-common/src/LockManager.cpp b/examples/lock-app/lock-common/src/LockManager.cpp index 8fd1ef5441b139..8af66051883aa4 100644 --- a/examples/lock-app/lock-common/src/LockManager.cpp +++ b/examples/lock-app/lock-common/src/LockManager.cpp @@ -20,6 +20,7 @@ #include #include +#include using chip::to_underlying; @@ -98,8 +99,9 @@ bool LockManager::InitEndpoint(chip::EndpointId endpointId) numberOfHolidaySchedules = 10; } - mEndpoints.emplace_back(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser, - numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules); + mEndpoints.emplace_back(std::make_unique(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, + numberOfWeekDaySchedulesPerUser, numberOfYearDaySchedulesPerUser, + numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules)); ChipLogProgress(Zcl, "Initialized new lock door endpoint " @@ -107,6 +109,7 @@ bool LockManager::InitEndpoint(chip::EndpointId endpointId) "numberOfCredentialsSupportedPerUser=%d,holidaySchedules=%d]", endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser, numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules); + DoorLockServer::Instance().SetDelegate(endpointId, mEndpoints.back().get()); return true; } @@ -303,11 +306,11 @@ DlStatus LockManager::SetSchedule(chip::EndpointId endpointId, uint8_t holidayIn LockEndpoint * LockManager::getEndpoint(chip::EndpointId endpointId) { - for (auto & mEndpoint : mEndpoints) + for (auto & endpoint : mEndpoints) { - if (mEndpoint.GetEndpointId() == endpointId) + if (endpoint->GetEndpointId() == endpointId) { - return &mEndpoint; + return endpoint.get(); } } return nullptr; diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index f3eadf7c9db5d2..a0ae180bbc1307 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -1293,6 +1293,7 @@ cluster UserLabel = 65 { endpoint 0 { device type ma_rootdevice = 22, version 1; + device type ma_otarequestor = 18, version 1; binding cluster OtaSoftwareUpdateProvider; @@ -1301,6 +1302,10 @@ endpoint 0 { callback attribute serverList; callback attribute clientList; callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; } @@ -1313,6 +1318,9 @@ endpoint 0 { callback attribute subjectsPerAccessControlEntry; callback attribute targetsPerAccessControlEntry; callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1343,6 +1351,10 @@ endpoint 0 { callback attribute capabilityMinima; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; } @@ -1355,6 +1367,10 @@ endpoint 0 { ram attribute updatePossible default = 1; ram attribute updateState default = 0; ram attribute updateStateProgress default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1364,6 +1380,10 @@ endpoint 0 { server cluster LocalizationConfiguration { persist attribute activeLocale default = "en-US"; callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } @@ -1382,6 +1402,10 @@ endpoint 0 { callback attribute regulatoryConfig; callback attribute locationCapability; callback attribute supportsConcurrentConnection; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1402,6 +1426,10 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -1427,6 +1455,10 @@ endpoint 0 { callback attribute activeRadioFaults; callback attribute activeNetworkFaults; callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1439,6 +1471,10 @@ endpoint 0 { callback attribute windowStatus; callback attribute adminFabricIndex; callback attribute adminVendorId; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1454,6 +1490,10 @@ endpoint 0 { callback attribute commissionedFabrics; callback attribute trustedRootCertificates; callback attribute currentFabricIndex; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1476,6 +1516,10 @@ endpoint 0 { callback attribute groupTable; callback attribute maxGroupsPerFabric; callback attribute maxGroupKeysPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap index 5291880efb89f0..75b4eb0a223b9e 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap @@ -38,12 +38,18 @@ "id": 1, "name": "MA-rootdevice", "deviceTypeRef": { - "code": 22, + "code": 18, "profileId": 259, - "label": "MA-rootdevice", - "name": "MA-rootdevice" + "label": "MA-otarequestor", + "name": "MA-otarequestor" }, "deviceTypes": [ + { + "code": 18, + "profileId": 259, + "label": "MA-otarequestor", + "name": "MA-otarequestor" + }, { "code": 22, "profileId": 259, @@ -52,13 +58,15 @@ } ], "deviceVersions": [ + 1, 1 ], "deviceIdentifiers": [ + 18, 22 ], - "deviceTypeName": "MA-rootdevice", - "deviceTypeCode": 22, + "deviceTypeName": "MA-otarequestor", + "deviceTypeCode": 18, "deviceTypeProfileId": 259, "clusters": [ { @@ -96,7 +104,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65534, "reportableChange": 0 @@ -112,7 +120,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65534, "reportableChange": 0 @@ -128,11 +136,75 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -186,7 +258,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -202,7 +274,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -255,6 +327,54 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, @@ -340,7 +460,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -356,7 +476,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -372,7 +492,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -388,7 +508,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -404,7 +524,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -420,7 +540,7 @@ "singleton": 1, "bounded": 0, "defaultValue": "", - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -436,7 +556,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -452,7 +572,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -468,7 +588,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -484,7 +604,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -500,7 +620,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -665,6 +785,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -772,6 +956,22 @@ } ], "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, @@ -873,53 +1073,117 @@ "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 - } - ], - "events": [ + }, { - "name": "StateTransition", - "code": 0, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", - "included": 1 + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 }, { - "name": "VersionApplied", - "code": 1, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "included": 1 - }, + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "VersionApplied", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, { "name": "DownloadError", "code": 2, @@ -948,7 +1212,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "en-US", - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -964,6 +1228,70 @@ "singleton": 0, "bounded": 0, "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1022,7 +1350,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -1231,6 +1559,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1475,6 +1867,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1586,7 +2042,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -1687,6 +2143,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1812,6 +2332,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -2048,6 +2632,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -2204,6 +2852,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp new file mode 100644 index 00000000000000..d06a8b8b7dc809 --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp @@ -0,0 +1,223 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "static-supported-modes-manager.h" +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::DeviceLayer::Internal; +using namespace chip::app::Clusters::ModeSelect; +using chip::Protocols::InteractionModel::Status; + +using ModeOptionStructType = Structs::ModeOptionStruct::Type; +using SemanticTag = Structs::SemanticTagStruct::Type; + +template +using List = app::DataModel::List; + +SupportedModesManager::ModeOptionsProvider * StaticSupportedModesManager::epModeOptionsProviderList = nullptr; + +const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager(); + +int StaticSupportedModesManager::mSize = 0; + +CHIP_ERROR StaticSupportedModesManager::InitEndpointArray(int size) +{ + if (epModeOptionsProviderList != nullptr) + { + ChipLogError(Zcl, "Cannot allocate epModeOptionsProviderList"); + return CHIP_ERROR_INCORRECT_STATE; + } + mSize = size; + epModeOptionsProviderList = new SupportedModesManager::ModeOptionsProvider[mSize]; + if (epModeOptionsProviderList == nullptr) + { + ChipLogError(Zcl, "Failed to allocate memory to epModeOptionsProviderList"); + return CHIP_ERROR_NO_MEMORY; + } + for (int i = 0; i < mSize; i++) + { + epModeOptionsProviderList[i] = ModeOptionsProvider(); + } + return CHIP_NO_ERROR; +} + +SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr && epModeOptionsProviderList[endpointId].end() != nullptr) + { + return ModeOptionsProvider(epModeOptionsProviderList[endpointId].begin(), epModeOptionsProviderList[endpointId].end()); + } + + ModeOptionStructType * modeOptionStructList = nullptr; + SemanticTag * semanticTags = nullptr; + + char keyBuf[ESP32Config::kMaxConfigKeyNameLength]; + uint32_t supportedModeCount = 0; + + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesCount(keyBuf, sizeof(keyBuf), endpointId) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + ESP32Config::Key countKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(countKey, supportedModeCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + + modeOptionStructList = new ModeOptionStructType[supportedModeCount]; + if (modeOptionStructList == nullptr) + { + return ModeOptionsProvider(nullptr, nullptr); + } + + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); + + for (int index = 0; index < supportedModeCount; index++) + { + Structs::ModeOptionStruct::Type option; + uint32_t supportedModeMode = 0; + uint32_t semanticTagCount = 0; + size_t outLen = 0; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesLabel(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key labelKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, nullptr, 0, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + char * modeLabel = new char[outLen + 1]; + if (modeLabel == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, modeLabel, outLen + 1, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesValue(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key modeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(labelKey, supportedModeMode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagsCount(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stCountKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stCountKey, semanticTagCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + semanticTags = new SemanticTag[semanticTagCount]; + if (semanticTags == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + for (auto stIndex = 0; stIndex < semanticTagCount; stIndex++) + { + + uint32_t semanticTagValue = 0; + uint32_t semanticTagMfgCode = 0; + SemanticTag tag; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagValue(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stValueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stValueKey, semanticTagValue) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagMfgCode(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stMfgCodeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stMfgCodeKey, semanticTagMfgCode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + tag.value = static_cast(semanticTagValue); + tag.mfgCode = static_cast(semanticTagMfgCode); + semanticTags[stIndex] = tag; + } + + option.label = chip::CharSpan::fromCharString(modeLabel); + option.mode = static_cast(supportedModeMode); + option.semanticTags = DataModel::List(semanticTags, semanticTagCount); + + modeOptionStructList[index] = option; + } + + return ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); +} + +Status StaticSupportedModesManager::getModeOptionByMode(unsigned short endpointId, unsigned char mode, + const ModeOptionStructType ** dataPtr) const +{ + auto modeOptionsProvider = this->getModeOptionsProvider(endpointId); + if (modeOptionsProvider.begin() == nullptr) + { + return Status::UnsupportedCluster; + } + auto * begin = modeOptionsProvider.begin(); + auto * end = modeOptionsProvider.end(); + + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + if (modeOption.mode == mode) + { + *dataPtr = &modeOption; + return Status::Success; + } + } + ChipLogProgress(Zcl, "Cannot find the mode %u", mode); + return Status::InvalidCommand; +} + +const ModeSelect::SupportedModesManager * ModeSelect::getSupportedModesManager() +{ + return &StaticSupportedModesManager::getStaticSupportedModesManagerInstance(); +} + +void StaticSupportedModesManager::FreeSupportedModes(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr) + { + auto * begin = epModeOptionsProviderList[endpointId].begin(); + auto * end = epModeOptionsProviderList[endpointId].end(); + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + delete[] modeOption.label.data(); + delete[] modeOption.semanticTags.data(); + } + delete[] begin; + } + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(); +} + +void StaticSupportedModesManager::CleanUp(EndpointId endpointId) const +{ + ChipLogError(Zcl, "Supported mode data is in incorrect format"); + FreeSupportedModes(endpointId); +} diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.h b/examples/platform/esp32/mode-support/static-supported-modes-manager.h new file mode 100644 index 00000000000000..8d6bb3c665ff0c --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeSelect { + +class StaticSupportedModesManager : public chip::app::Clusters::ModeSelect::SupportedModesManager +{ +private: + using ModeOptionStructType = Structs::ModeOptionStruct::Type; + using SemanticTag = Structs::SemanticTagStruct::Type; + static int mSize; + + static ModeOptionsProvider * epModeOptionsProviderList; + + void FreeSupportedModes(EndpointId endpointId) const; + + static const StaticSupportedModesManager instance; + +public: + // InitEndpointArray should be called only once in the application. Memory allocated to the + // epModeOptionsProviderList will be needed for the lifetime of the program, so it's never deallocated. + static CHIP_ERROR InitEndpointArray(int size); + + // DeInitEndpointArray should be called only when application need to reallocate memory of + // epModeOptionsProviderList ( Eg. Bridges ). + static void DeInitEndpointArray() + { + delete[] epModeOptionsProviderList; + epModeOptionsProviderList = nullptr; + mSize = 0; + } + + SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override; + + Protocols::InteractionModel::Status getModeOptionByMode(EndpointId endpointId, uint8_t mode, + const ModeOptionStructType ** dataPtr) const override; + + void CleanUp(EndpointId endpointId) const; + + StaticSupportedModesManager() {} + + ~StaticSupportedModesManager() + { + for (int i = 0; i < mSize; i++) + { + FreeSupportedModes(i); + } + } + + static inline const StaticSupportedModesManager & getStaticSupportedModesManagerInstance() { return instance; } +}; + +const SupportedModesManager * getSupportedModesManager(); + +} // namespace ModeSelect +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp index c9b4a3ab7281f1..dc99728ccf90d5 100644 --- a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp +++ b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp @@ -78,7 +78,10 @@ CHIP_ERROR AppTask::Init() } // Register Smoke & Co Test Event Trigger - Server::GetInstance().GetTestEventTriggerDelegate()->AddHandler(&AlarmMgr()); + if (Server::GetInstance().GetTestEventTriggerDelegate() != nullptr) + { + Server::GetInstance().GetTestEventTriggerDelegate()->AddHandler(&AlarmMgr()); + } sAlarmLED.Init(LIGHT_LED); sAlarmLED.Set(false); diff --git a/examples/thermostat/infineon/cyw30739/README.md b/examples/thermostat/infineon/cyw30739/README.md index 6d37d24eb920ef..0b94884fe134a4 100644 --- a/examples/thermostat/infineon/cyw30739/README.md +++ b/examples/thermostat/infineon/cyw30739/README.md @@ -12,7 +12,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) - [ModusToolbox™ tools package](#modustoolbox-tools-package) - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) - - [Checkout Submodules](#checkout-submodules) + - [Checkout Submodules and Bootstrap](#checkout-submodules-and-bootstrap) - [Building](#building) - [Factory Data](#factory-data) - [Commissionable Data](#commissionable-data) @@ -65,7 +65,7 @@ If you are using WSL, please ensure you have installed the ModusToolbox™ Software for Linux. Running Windows tools directly from the WSL command line would cause path resolution failure in the build process. -### Checkout Submodules +### Checkout Submodules and Bootstrap Before building the example, check out the Matter repository and sync submodules using the following command: @@ -73,6 +73,7 @@ using the following command: ```bash $ cd ~/connectedhomeip $ scripts/checkout_submodules.py --platform infineon +$ bash scripts/bootstrap.sh -p all,infineon ``` ## Building diff --git a/examples/thermostat/nxp/zephyr/.gitignore b/examples/thermostat/nxp/zephyr/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/thermostat/nxp/zephyr/CMakeLists.txt b/examples/thermostat/nxp/zephyr/CMakeLists.txt new file mode 100644 index 00000000000000..2b0fb87a55e7f9 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/CMakeLists.txt @@ -0,0 +1,104 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(THERMOSTAT_NXP_COMMON_DIR ${CHIP_ROOT}/examples/thermostat/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_COMMON_DIR ${CHIP_ROOT}/examples/platform/nxp/common REALPATH) +get_filename_component(EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR ${CHIP_ROOT}/examples/platform/nxp/zephyr REALPATH) + +# Perform common operations like detecting extra overlays in the platform folder for the target board +# This must be called before find_package(Zephyr) +include(${CHIP_ROOT}/config/nxp/app/pre-zephyr.cmake) + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nxp/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) +target_compile_options(app PRIVATE -Werror PRIVATE -Wno-error=format) + +project(chip-nxp-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nxp/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app + PRIVATE + ${THERMOSTAT_NXP_COMMON_DIR}/main/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include +) + +target_sources(app + PRIVATE + main/main.cpp + ${THERMOSTAT_NXP_COMMON_DIR}/main/AppTask.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_manager/source/CHIPDeviceManager.cpp + ${THERMOSTAT_NXP_COMMON_DIR}/main/DeviceCallbacks.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/source/CommonDeviceCallbacks.cpp + ${THERMOSTAT_NXP_COMMON_DIR}/main/ZclCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/source/AppTaskZephyr.cpp + ${EXAMPLE_PLATFORM_NXP_ZEPHYR_DIR}/factory_data/source/AppFactoryDataExample.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/icd/source/ICDUtil.cpp +) + +target_compile_definitions(app PUBLIC + "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\"" +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorZephyr.cpp + ) + target_include_directories(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/include/ + ) +endif() + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/../../thermostat/nxp/zap/thermostat_matter_wifi.zap +) + +if(CONFIG_CHIP_LIB_SHELL) + target_compile_definitions(app PRIVATE ENABLE_CHIP_SHELL) + target_include_directories(app PRIVATE + ${CHIP_ROOT}/examples/shell/shell_common/include + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/include + ) + target_sources(app PRIVATE + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIBase.cpp + ${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/matter_cli/source/AppCLIZephyr.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_misc.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_otcli.cpp + ${CHIP_ROOT}/examples/shell/shell_common/cmd_server.cpp + ) +endif() diff --git a/examples/thermostat/nxp/zephyr/Kconfig b/examples/thermostat/nxp/zephyr/Kconfig new file mode 100644 index 00000000000000..72e90f047d1e38 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/Kconfig @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +mainmenu "Matter NXP Thermostat Example Application" + +rsource "../../../../config/nxp/chip-module/Kconfig.features" +rsource "../../../../config/nxp/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/thermostat/nxp/zephyr/README.md b/examples/thermostat/nxp/zephyr/README.md new file mode 100644 index 00000000000000..84d3fb9e59cf01 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/README.md @@ -0,0 +1,4 @@ +# CHIP NXP Zephyr Thermostat Application + +All instructions describing how to use a Matter application on NXP Zephyr can be +found in [README.md](../../../all-clusters-app/nxp/zephyr/README.md) root readme diff --git a/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga.overlay b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga.overlay new file mode 100644 index 00000000000000..86bb20739527cd --- /dev/null +++ b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http: //www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm3; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; diff --git a/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga_fdata.conf b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga_fdata.conf new file mode 100644 index 00000000000000..73d139c3948d95 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/boards/rd_rw612_bga_fdata.conf @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +CONFIG_SETTINGS_NVS_SECTOR_COUNT=16 + +# 0xA226 +CONFIG_CHIP_DEVICE_PRODUCT_ID=41510 +CONFIG_CHIP_DEVICE_PRODUCT_URL="https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radio-1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612" +CONFIG_CHIP_DEVICE_PRODUCT_LABEL="RW612" +CONFIG_CHIP_DEVICE_PART_NUMBER="RW612" diff --git a/examples/thermostat/nxp/zephyr/main/include/CHIPProjectConfig.h b/examples/thermostat/nxp/zephyr/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..84c57df1ea140d --- /dev/null +++ b/examples/thermostat/nxp/zephyr/main/include/CHIPProjectConfig.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR CONFIG_CHIP_DEVICE_DISCRIMINATOR + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 diff --git a/examples/thermostat/nxp/zephyr/main/main.cpp b/examples/thermostat/nxp/zephyr/main/main.cpp new file mode 100644 index 00000000000000..9be47dfe0a95d8 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/main/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (err == CHIP_NO_ERROR) + { + err = chip::NXP::App::GetAppTask().Start(); + } + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/thermostat/nxp/zephyr/prj.conf b/examples/thermostat/nxp/zephyr/prj.conf new file mode 100644 index 00000000000000..8bb5bd9f275756 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/prj.conf @@ -0,0 +1,59 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Thermostat" +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0x800 + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="Thermostat" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +# enable NET commands if desired +#CONFIG_NET_SHELL=y +CONFIG_CHIP_STATISTICS=y diff --git a/examples/thermostat/nxp/zephyr/prj_fdata.conf b/examples/thermostat/nxp/zephyr/prj_fdata.conf new file mode 100644 index 00000000000000..ee559b42ed9a71 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/prj_fdata.conf @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_STD_CPP17=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable MbedTLS PSA - heavily experimental, not thread safe yet +# CONFIG_CHIP_CRYPTO_PSA=y + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="Thermostat" + +# enable Matter CLI +CONFIG_CHIP_LIB_SHELL=y +CONFIG_CHIP_STATISTICS=y + +# Factory data configuration +CONFIG_CHIP_DEVICE_VENDOR_ID=4151 +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xA00 +CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE=14014 +CONFIG_CHIP_DEVICE_PRODUCT_NAME="Thermostat" +CONFIG_CHIP_DEVICE_TYPE=769 +CONFIG_CHIP_DEVICE_MANUFACTURING_DATE="2023-01-01" +CONFIG_CHIP_DEVICE_SERIAL_NUMBER="12345678" +CONFIG_CHIP_DEVICE_PRODUCT_COLOR="Green" +CONFIG_CHIP_DEVICE_PRODUCT_FINISH="Matte" + +# Use factory data provider for device info +CONFIG_CHIP_FACTORY_DATA=y +# Generate factor data raw binary during the build process +# CONFIG_CHIP_FACTORY_DATA_BUILD=y +# Generate test certificates for factory data during the build process +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y +# Spake2p verifier will be generated during factory data generation +# CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=y + +# Example of using pre-generated certificates +# CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT="/Chip-Test-CD-1037-A226.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT="/Chip-DAC-NXP-1037-A226-Cert.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY="/Chip-DAC-NXP-1037-A226-Key.der" +# CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT="/Chip-PAI-NXP-1037-A226-Cert.der" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_THREAD_INFO=y +# use this config if stepping during debug session is not consistent +# CONFIG_NO_OPTIMIZATIONS=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_ASSERT=y +# by default west will generate the full assembly output, which can take several minutes when binaries are large +CONFIG_OUTPUT_DISASSEMBLY=n +# embedded thread analyzer with thread statistics (stack usage, cpu usage...) +# CONFIG_THREAD_ANALYZER=y +# CONFIG_THREAD_ANALYZER_USE_PRINTK=y +# CONFIG_THREAD_ANALYZER_AUTO=y diff --git a/examples/thermostat/nxp/zephyr/prj_ota.conf b/examples/thermostat/nxp/zephyr/prj_ota.conf new file mode 100644 index 00000000000000..bdc65e94fabf70 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/prj_ota.conf @@ -0,0 +1,31 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Options needed for OTA are located on this file +# This file should contain only options specific for this sample +# or overrides the default ones. + +CONFIG_CHIP_OTA_REQUESTOR=y + +# To generate an OTA image based on the application +CONFIG_CHIP_OTA_IMAGE_BUILD=y + +# By default, MCUBOOT bootloader uses a signature key provided in their repository. +# Change the key to the appropriate one. +# Note: You need to use the same signature key used by MCUBOOT, i.e BOOT_SIGNATURE_KEY_FILE. +# Default CONFIG_BOOT_SIGNATURE_KEY_FILE is defined in config/nxp/app/bootloader.conf +CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" diff --git a/examples/thermostat/nxp/zephyr/third_party/connectedhomeip b/examples/thermostat/nxp/zephyr/third_party/connectedhomeip new file mode 120000 index 00000000000000..3efed95be5dbe9 --- /dev/null +++ b/examples/thermostat/nxp/zephyr/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../ \ No newline at end of file diff --git a/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml b/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml index 61d036e0a90ef4..fff52c4b59db7e 100644 --- a/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml +++ b/examples/tv-app/android/App/content-app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ - + diff --git a/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml b/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml index b6e00cd75d0365..476faa2030c7a2 100644 --- a/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml +++ b/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml @@ -26,6 +26,9 @@ tools:ignore="QueryAllPackagesPermission" /> + + + tasks = activityManager.getRunningTasks(1); + if (tasks != null && !tasks.isEmpty()) { + ActivityManager.RunningTaskInfo taskInfo = tasks.get(0); + String packageName = + taskInfo.topActivity != null ? taskInfo.topActivity.getPackageName() : ""; + return packageName.equals(contentAppPackageName); + } + return false; + } + public String sendCommand(int endpointId, long clusterId, long commandId, String commandPayload) { Log.d(TAG, "Received a command for endpointId " + endpointId + ". Message " + commandPayload); @@ -26,6 +55,17 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values(), endpointId); if (discoveredApp != null) { + // Intercept NavigateTarget and LaunchContent commands and launch content app if necessary + if (isForegroundCommand(clusterId, commandId)) { + // Check if contentapp main/launch activity is already in foreground before launching. + if (!isAppInForeground(discoveredApp.getAppName())) { + Intent launchIntent = + context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); + if (launchIntent != null) { + context.startActivity(launchIntent); + } + } + } Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload); return ContentAppAgentService.sendCommand( context, discoveredApp.getAppName(), clusterId, commandId, commandPayload); diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java index e30a75a00d98b2..0cd12b404d6fcf 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java @@ -25,6 +25,7 @@ public ContentApp( this.vendorId = vendorId; this.productId = productId; this.version = version; + this.supportedClusters = Collections.EMPTY_SET; } public ContentApp( @@ -67,9 +68,7 @@ public void setEndpointId(int endpoint) { } public Set getSupportedClusters() { - return supportedClusters != null - ? Collections.unmodifiableSet(supportedClusters) - : Collections.EMPTY_SET; + return Collections.unmodifiableSet(supportedClusters); } public String getVersion() { diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java index f587905fb09145..227ea9326be538 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java @@ -4,13 +4,18 @@ import android.content.SharedPreferences; import android.util.JsonReader; import android.util.JsonWriter; +import com.matter.tv.app.api.SupportedCluster; import com.matter.tv.server.model.ContentApp; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; public class EndpointsDataStore { @@ -21,6 +26,11 @@ public class EndpointsDataStore { private static final String KEY_PRODUCTID = "PID"; private static final String KEY_VERSION = "VER"; private static final String KEY_ENDPOINTID = "EPID"; + private static final String KEY_SUPPORTED_CLUSTERS = "supportedClusters"; + private static final String KEY_CLUSTER_IDENTIFIER = "clusterIdentifier"; + private static final String KEY_FEATURES = "features"; + private static final String KEY_OPTIONAL_COMMAND_IDENTIFIERS = "optionalCommandIdentifiers"; + private static final String KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS = "optionalAttributesIdentifiers"; private static EndpointsDataStore instance; private final SharedPreferences discoveredEndpoints; Map persistedContentApps = new HashMap<>(); @@ -57,19 +67,20 @@ private String serializeContentApp(ContentApp app) { StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter); try { - jsonWriter - .beginObject() - .name(KEY_VENDORID) - .value(app.getVendorId()) - .name(KEY_VENDORNAME) - .value(app.getVendorName()) - .name(KEY_PRODUCTID) - .value(app.getProductId()) - .name(KEY_VERSION) - .value(app.getVersion()) - .name(KEY_ENDPOINTID) - .value(app.getEndpointId()) - .endObject(); + jsonWriter.beginObject(); + jsonWriter.name(KEY_VENDORID); + jsonWriter.value(app.getVendorId()); + jsonWriter.name(KEY_VENDORNAME); + jsonWriter.value(app.getVendorName()); + jsonWriter.name(KEY_PRODUCTID); + jsonWriter.value(app.getProductId()); + jsonWriter.name(KEY_VERSION); + jsonWriter.value(app.getVersion()); + jsonWriter.name(KEY_ENDPOINTID); + jsonWriter.value(app.getEndpointId()); + jsonWriter.name(KEY_SUPPORTED_CLUSTERS); + serializeSupportedClusters(jsonWriter, app.getSupportedClusters()); + jsonWriter.endObject(); jsonWriter.flush(); jsonWriter.close(); } catch (IOException e) { @@ -88,6 +99,7 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) { int vendorId = 0; int productId = 0; int endpoint = ContentApp.INVALID_ENDPOINTID; + Set supportedClusters = new HashSet<>(); while (jsonReader.hasNext()) { String name = jsonReader.nextName(); switch (name) { @@ -106,9 +118,12 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) { case KEY_ENDPOINTID: endpoint = jsonReader.nextInt(); break; + case KEY_SUPPORTED_CLUSTERS: + supportedClusters = deserializeSupportedClusters(jsonReader); + break; } } - app = new ContentApp(appName, vendorName, vendorId, productId, version); + app = new ContentApp(appName, vendorName, vendorId, productId, version, supportedClusters); jsonReader.endObject(); jsonReader.close(); } catch (IOException e) { @@ -116,4 +131,86 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) { } return app; } + + private void serializeSupportedClusters( + JsonWriter jsonWriter, Set supportedClusters) throws IOException { + if (supportedClusters != null) { + jsonWriter.beginArray(); + for (SupportedCluster supportedCluster : supportedClusters) { + if (supportedCluster != null) { + serializeSupportedCluster(jsonWriter, supportedCluster); + } + } + jsonWriter.endArray(); + } + } + + private Set deserializeSupportedClusters(JsonReader jsonReader) + throws IOException { + Set supportedClusters = new HashSet<>(); + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + supportedClusters.add(deserializeSupportedCluster(jsonReader)); + } + jsonReader.endArray(); + return supportedClusters; + } + + private void serializeSupportedCluster(JsonWriter jsonWriter, SupportedCluster supportedCluster) + throws IOException { + jsonWriter.beginObject(); + jsonWriter.name(KEY_CLUSTER_IDENTIFIER); + jsonWriter.value(supportedCluster.clusterIdentifier); + jsonWriter.name(KEY_FEATURES); + jsonWriter.value(supportedCluster.features); + jsonWriter.name(KEY_OPTIONAL_COMMAND_IDENTIFIERS); + serializeIntArray(jsonWriter, supportedCluster.optionalCommandIdentifiers); + jsonWriter.name(KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS); + serializeIntArray(jsonWriter, supportedCluster.optionalAttributesIdentifiers); + jsonWriter.endObject(); + } + + private SupportedCluster deserializeSupportedCluster(JsonReader jsonReader) throws IOException { + SupportedCluster supportedCluster = new SupportedCluster(); + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + String name = jsonReader.nextName(); + switch (name) { + case KEY_CLUSTER_IDENTIFIER: + supportedCluster.clusterIdentifier = jsonReader.nextInt(); + break; + case KEY_FEATURES: + supportedCluster.features = jsonReader.nextInt(); + break; + case KEY_OPTIONAL_COMMAND_IDENTIFIERS: + supportedCluster.optionalCommandIdentifiers = deserializeIntArray(jsonReader); + break; + case KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS: + supportedCluster.optionalAttributesIdentifiers = deserializeIntArray(jsonReader); + break; + } + } + jsonReader.endObject(); + return supportedCluster; + } + + private void serializeIntArray(JsonWriter jsonWriter, int[] array) throws IOException { + jsonWriter.beginArray(); + if (array != null) { + for (int value : array) { + jsonWriter.value(value); + } + } + jsonWriter.endArray(); + } + + private int[] deserializeIntArray(JsonReader jsonReader) throws IOException { + List dynamicArray = new ArrayList<>(); + jsonReader.beginArray(); + while (jsonReader.hasNext()) { + dynamicArray.add(jsonReader.nextInt()); + } + jsonReader.endArray(); + return dynamicArray.stream().mapToInt(Integer::intValue).toArray(); + } } diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index 4dfabd03f12ec6..c24e7e537dbb23 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -355,6 +355,87 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend return nullptr; } +class DevicePairedCommand : public Controller::DevicePairingDelegate +{ +public: + struct CallbackContext + { + uint16_t vendorId; + uint16_t productId; + chip::NodeId nodeId; + + CallbackContext(uint16_t vId, uint16_t pId, chip::NodeId nId) : vendorId(vId), productId(pId), nodeId(nId) {} + }; + DevicePairedCommand(uint16_t vendorId, uint16_t productId, chip::NodeId nodeId) : + mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + { + mContext = std::make_shared(vendorId, productId, nodeId); + } + + static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectedFn - Updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + + GetCommissionerDiscoveryController()->CommissioningSucceeded(cbContext->vendorId, cbContext->productId, + cbContext->nodeId, exchangeMgr, sessionHandle); + } + } + + static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectionFailureFn - Not updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + // TODO: Remove Node Id + } + } + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + std::shared_ptr mContext; +}; + +void refreshConnectedClientsAcl(uint16_t vendorId, uint16_t productId, ContentAppImpl * app) +{ + + std::set nodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForContentApp(vendorId, productId); + + for (const auto & allowedVendor : app->GetApplicationBasicDelegate()->GetAllowedVendorList()) + { + std::set tempNodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForAllowVendorId(allowedVendor); + + nodeIds.insert(tempNodeIds.begin(), tempNodeIds.end()); + } + + for (const auto & nodeId : nodeIds) + { + + ChipLogProgress(DeviceLayer, + "Creating Pairing Command with node id: " ChipLogFormatX64 " and vendor id: %d and product id: %d", + ChipLogValueX64(nodeId), vendorId, productId); + + std::shared_ptr pairingCommand = std::make_shared(vendorId, productId, nodeId); + + GetDeviceCommissioner()->GetConnectedDevice(nodeId, &pairingCommand->mOnDeviceConnectedCallback, + &pairingCommand->mOnDeviceConnectionFailureCallback); + } +} + EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId, const char * szApplicationVersion, std::vector supportedClusters, jobject manager) @@ -369,6 +450,9 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1 app->GetEndpointId()); mContentApps.push_back(app); mDataVersions.push_back(dataVersionBuf); + + refreshConnectedClientsAcl(vendorId, productId, app); + return epId; } @@ -387,6 +471,9 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1 app->GetEndpointId()); mContentApps.push_back(app); mDataVersions.push_back(dataVersionBuf); + + refreshConnectedClientsAcl(vendorId, productId, app); + return epId; } diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp index 04b5f4199edcaa..65a0a4409e9b8f 100644 --- a/examples/tv-app/android/java/TVApp-JNI.cpp +++ b/examples/tv-app/android/java/TVApp-JNI.cpp @@ -258,6 +258,8 @@ class MyPostCommissioningListener : public PostCommissioningListener // read current binding list chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId); + ContentAppPlatform::GetInstance().StoreNodeIdForContentApp(vendorId, productId, nodeId); + cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle); CHIP_ERROR err = diff --git a/examples/tv-app/linux/main.cpp b/examples/tv-app/linux/main.cpp index 29fdd69cb36792..c2055e0abd03f3 100644 --- a/examples/tv-app/linux/main.cpp +++ b/examples/tv-app/linux/main.cpp @@ -45,6 +45,31 @@ void ApplicationInit() ChipLogDetail(DeviceLayer, "TV Linux App: Warning - Fixed Content App Endpoint Not Disabled"); // Can't disable this without breaking CI unit tests that act upon account login cluster (only available on ep3) // emberAfEndpointEnableDisable(3, false); + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // Install Content Apps + ContentAppFactoryImpl * factory = GetContentAppFactoryImpl(); + + // Content App 1 + constexpr uint16_t kApp1VendorId = 65521; + constexpr uint16_t kApp1ProductId = 32769; + factory->InstallContentApp(kApp1VendorId, kApp1ProductId); + + // Content App 2 + constexpr uint16_t kApp2VendorId = 1; + constexpr uint16_t kApp2ProductId = 11; + factory->InstallContentApp(kApp2VendorId, kApp2ProductId); + + // Content App 3 + constexpr uint16_t kApp3VendorId = 9050; + constexpr uint16_t kApp3ProductId = 22; + factory->InstallContentApp(kApp3VendorId, kApp3ProductId); + + // Content App 4 + constexpr uint16_t kApp4VendorId = 1111; + constexpr uint16_t kApp4ProductId = 22; + factory->InstallContentApp(kApp4VendorId, kApp4ProductId); +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED } void ApplicationShutdown() {} diff --git a/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp b/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp index b39e84ad40f89a..5125ebbbbd7ecd 100644 --- a/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp +++ b/examples/tv-app/tv-common/shell/AppTvShellCommands.cpp @@ -209,6 +209,10 @@ static CHIP_ERROR PrintAllCommands() #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE streamer_printf(sout, " print-app-access Print all ACLs for app platform fabric. Usage: app print-app-access\r\n"); streamer_printf(sout, " remove-app-access Remove all ACLs for app platform fabric. Usage: app remove-app-access\r\n"); + streamer_printf( + sout, + " print-installed-apps Print all installed content apps with their endpoints. Usage: app print-installed-apps\r\n"); + streamer_printf(sout, " commission Commission given udc-entry using given pincode from corresponding app. Usage: " "app commission 0\r\n"); @@ -436,6 +440,13 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv) Access::GetAccessControl().DeleteAllEntriesForFabric(GetDeviceCommissioner()->GetFabricIndex()); return CHIP_NO_ERROR; } + else if (strcmp(argv[0], "print-installed-apps") == 0) + { + ContentAppFactoryImpl * factory = GetContentAppFactoryImpl(); + factory->LogInstalledApps(); + + return CHIP_NO_ERROR; + } else if (strcmp(argv[0], "commission") == 0) { if (argc < 2) diff --git a/examples/tv-app/tv-common/src/AppTv.cpp b/examples/tv-app/tv-common/src/AppTv.cpp index 03422c3fa462e7..8d81d9cf6c2c5c 100644 --- a/examples/tv-app/tv-common/src/AppTv.cpp +++ b/examples/tv-app/tv-common/src/AppTv.cpp @@ -164,6 +164,8 @@ class MyPostCommissioningListener : public PostCommissioningListener // read current binding list chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId); + ContentAppPlatform::GetInstance().StoreNodeIdForContentApp(vendorId, productId, nodeId); + cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle); CHIP_ERROR err = @@ -565,6 +567,63 @@ void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId) mAdminVendorIds.push_back(vendorId); } +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE +class DevicePairedCommand : public Controller::DevicePairingDelegate +{ +public: + struct CallbackContext + { + uint16_t vendorId; + uint16_t productId; + chip::NodeId nodeId; + + CallbackContext(uint16_t vId, uint16_t pId, chip::NodeId nId) : vendorId(vId), productId(pId), nodeId(nId) {} + }; + DevicePairedCommand(uint16_t vendorId, uint16_t productId, chip::NodeId nodeId) : + mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + { + mContext = std::make_shared(vendorId, productId, nodeId); + } + + static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectedFn - Updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + + GetCommissionerDiscoveryController()->CommissioningSucceeded(cbContext->vendorId, cbContext->productId, + cbContext->nodeId, exchangeMgr, sessionHandle); + } + } + + static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) + { + auto * pairingCommand = static_cast(context); + auto cbContext = pairingCommand->mContext; + + if (pairingCommand) + { + ChipLogProgress(DeviceLayer, + "OnDeviceConnectionFailureFn - Not updating ACL for node id: " ChipLogFormatX64 + " and vendor id: %d and product id: %d", + ChipLogValueX64(cbContext->nodeId), cbContext->vendorId, cbContext->productId); + // TODO: Remove Node Id + } + } + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + std::shared_ptr mContext; +}; +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t productId) { auto make_default_supported_clusters = []() { @@ -605,6 +664,46 @@ void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t produc make_default_supported_clusters()); mContentApps.emplace_back(std::move(ptr)); } + +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + // Get the list of node ids + std::set nodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForContentApp(vendorId, productId); + + // update ACLs + for (auto & contentApp : mContentApps) + { + auto app = contentApp.get(); + + if (app->MatchesPidVid(productId, vendorId)) + { + CatalogVendorApp vendorApp = app->GetApplicationBasicDelegate()->GetCatalogVendorApp(); + + GetContentAppFactoryImpl()->LoadContentApp(vendorApp); + } + + // update the list of node ids with content apps allowed vendor list + for (const auto & allowedVendor : app->GetApplicationBasicDelegate()->GetAllowedVendorList()) + { + std::set tempNodeIds = ContentAppPlatform::GetInstance().GetNodeIdsForAllowVendorId(allowedVendor); + + nodeIds.insert(tempNodeIds.begin(), tempNodeIds.end()); + } + } + + // refresh ACLs + for (const auto & nodeId : nodeIds) + { + + ChipLogProgress(DeviceLayer, + "Creating Pairing Command with node id: " ChipLogFormatX64 " and vendor id: %d and product id: %d", + ChipLogValueX64(nodeId), vendorId, productId); + + std::shared_ptr pairingCommand = std::make_shared(vendorId, productId, nodeId); + + GetDeviceCommissioner()->GetConnectedDevice(nodeId, &pairingCommand->mOnDeviceConnectedCallback, + &pairingCommand->mOnDeviceConnectionFailureCallback); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE } bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t productId) @@ -625,8 +724,9 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod ChipLogProgress(DeviceLayer, "Found an app vid=%d pid=%d. Uninstalling it.", app->GetApplicationBasicDelegate()->HandleGetVendorId(), app->GetApplicationBasicDelegate()->HandleGetProductId()); + EndpointId removedEndpointID = ContentAppPlatform::GetInstance().RemoveContentApp(app); + ChipLogProgress(DeviceLayer, "Removed content app at endpoint id: %d", removedEndpointID); mContentApps.erase(mContentApps.begin() + index); - // TODO: call ContentAppPlatform->RemoveContentApp(ids...) return true; } @@ -701,22 +801,8 @@ std::list ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoi CHIP_ERROR AppTvInit() { #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - // test data for apps - constexpr uint16_t kApp1VendorId = 1; - constexpr uint16_t kApp1ProductId = 11; - constexpr uint16_t kApp2VendorId = 65521; - constexpr uint16_t kApp2ProductId = 32769; - constexpr uint16_t kApp3VendorId = 9050; - constexpr uint16_t kApp3ProductId = 22; - constexpr uint16_t kApp4VendorId = 1111; - constexpr uint16_t kApp4ProductId = 22; - ContentAppPlatform::GetInstance().SetupAppPlatform(); ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory); - gFactory.InstallContentApp(kApp1VendorId, kApp1ProductId); - gFactory.InstallContentApp(kApp2VendorId, kApp2ProductId); - gFactory.InstallContentApp(kApp3VendorId, kApp3ProductId); - gFactory.InstallContentApp(kApp4VendorId, kApp4ProductId); uint16_t value; if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR) { diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 0a72b3733a96d1..97f8e90af507d5 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -28,7 +28,7 @@ from builders.mw320 import MW320App, MW320Builder from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder from builders.nuttx import NuttXApp, NuttXBoard, NuttXBuilder -from builders.nxp import NxpApp, NxpBoard, NxpBuilder +from builders.nxp import NxpApp, NxpBoard, NxpBuilder, NxpOsUsed from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend from builders.qpg import QpgApp, QpgBoard, QpgBuilder from builders.rw61x import RW61XApp, RW61XBuilder @@ -499,13 +499,23 @@ def BuildNxpTarget(): # boards target.AppendFixedTargets([ TargetPart('k32w0', board=NxpBoard.K32W0), - TargetPart('k32w1', board=NxpBoard.K32W1) + TargetPart('k32w1', board=NxpBoard.K32W1), + TargetPart('rw61x', board=NxpBoard.RW61X) + ]) + + # OS + target.AppendFixedTargets([ + TargetPart('zephyr', os_env=NxpOsUsed.ZEPHYR).OnlyIfRe('rw61x'), + TargetPart('freertos', os_env=NxpOsUsed.FREERTOS).ExceptIfRe('rw61x'), ]) # apps target.AppendFixedTargets([ TargetPart('lighting', app=NxpApp.LIGHTING).OnlyIfRe('(k32w0|k32w1)'), - TargetPart('contact-sensor', app=NxpApp.CONTACT).OnlyIfRe('(k32w0|k32w1)') + TargetPart('contact-sensor', app=NxpApp.CONTACT).OnlyIfRe('(k32w0|k32w1)'), + TargetPart('all-clusters', app=NxpApp.ALLCLUSTERS).OnlyIfRe('rw61x'), + TargetPart('laundry-washer', app=NxpApp.LAUNDRYWASHER).OnlyIfRe('rw61x'), + TargetPart('thermostat', app=NxpApp.THERMOSTAT).OnlyIfRe('rw61x') ]) target.AppendModifier(name="factory", enable_factory_data=True) @@ -513,8 +523,8 @@ def BuildNxpTarget(): target.AppendModifier(name="lit", enable_lit=True).OnlyIfRe('contact-sensor') target.AppendModifier(name="fro32k", use_fro32k=True).OnlyIfRe('k32w0') target.AppendModifier(name="smu2", smu2=True).OnlyIfRe('k32w1-lighting') - target.AppendModifier(name="dac-conversion", convert_dac_pk=True).OnlyIfRe('factory').ExceptIfRe('k32w0') - target.AppendModifier(name="rotating-id", enable_rotating_id=True) + target.AppendModifier(name="dac-conversion", convert_dac_pk=True).OnlyIfRe('factory').ExceptIfRe('(k32w0|rw61x)') + target.AppendModifier(name="rotating-id", enable_rotating_id=True).ExceptIfRe('rw61x') target.AppendModifier(name="sw-v2", has_sw_version_2=True) return target diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 4bd4f0ae451875..74f40eaa0a36aa 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Project CHIP Authors +# Copyright (c) 2021-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging import os from enum import Enum, auto @@ -19,15 +20,31 @@ from .gn import GnBuilder +class NxpOsUsed(Enum): + FREERTOS = auto() + ZEPHYR = auto() + + def OsEnv(self): + if self == NxpOsUsed.ZEPHYR: + return 'zephyr' + elif self == NxpOsUsed.FREERTOS: + return 'freertos' + else: + raise Exception('Unknown OS type: %r' % self) + + class NxpBoard(Enum): K32W0 = auto() K32W1 = auto() + RW61X = auto() def Name(self): if self == NxpBoard.K32W0: return 'k32w0x' elif self == NxpBoard.K32W1: return 'k32w1' + elif self == NxpBoard.RW61X: + return 'rd_rw612_bga' else: raise Exception('Unknown board type: %r' % self) @@ -36,6 +53,8 @@ def FolderName(self): return 'k32w/k32w0' elif self == NxpBoard.K32W1: return 'k32w/k32w1' + elif self == NxpBoard.RW61X: + return 'zephyr' else: raise Exception('Unknown board type: %r' % self) @@ -43,12 +62,21 @@ def FolderName(self): class NxpApp(Enum): LIGHTING = auto() CONTACT = auto() + ALLCLUSTERS = auto() + LAUNDRYWASHER = auto() + THERMOSTAT = auto() def ExampleName(self): if self == NxpApp.LIGHTING: return 'lighting-app' elif self == NxpApp.CONTACT: return "contact-sensor-app" + elif self == NxpApp.ALLCLUSTERS: + return "all-clusters-app" + elif self == NxpApp.LAUNDRYWASHER: + return "laundry-washer-app" + elif self == NxpApp.THERMOSTAT: + return "thermostat" else: raise Exception('Unknown app type: %r' % self) @@ -57,6 +85,12 @@ def NameSuffix(self): return 'light-example' elif self == NxpApp.CONTACT: return 'contact-example' + elif self == NxpApp.ALLCLUSTERS: + return "all-cluster-example" + elif self == NxpApp.LAUNDRYWASHER: + return "laundry-washer-example" + elif self == NxpApp.THERMOSTAT: + return "thermostat-example" else: raise Exception('Unknown app type: %r' % self) @@ -71,6 +105,7 @@ def __init__(self, runner, app: NxpApp = NxpApp.LIGHTING, board: NxpBoard = NxpBoard.K32W0, + os_env: NxpOsUsed = NxpOsUsed.FREERTOS, low_power: bool = False, smu2: bool = False, enable_factory_data: bool = False, @@ -85,6 +120,7 @@ def __init__(self, self.code_root = root self.app = app self.board = board + self.os_env = os_env self.low_power = low_power self.smu2 = smu2 self.enable_factory_data = enable_factory_data @@ -125,15 +161,54 @@ def GnBuildArgs(self): return args + def WestBuildArgs(self): + args = [] + if self.enable_factory_data: + args.append('-DFILE_SUFFIX=fdata') + + if self.has_sw_version_2: + args.append('-DCONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2') + + build_args = " -- " + " ".join(args) if len(args) > 0 else "" + return build_args + def generate(self): - super(NxpBuilder, self).generate() + if self.os_env == NxpOsUsed.ZEPHYR: + if 'ZEPHYR_NXP_SDK_INSTALL_DIR' in os.environ: + cmd = 'export ZEPHYR_SDK_INSTALL_DIR="$ZEPHYR_NXP_SDK_INSTALL_DIR"\n' + else: + raise Exception("ZEPHYR_SDK_INSTALL_DIR need to be set") + if 'ZEPHYR_NXP_BASE' in os.environ: + cmd += 'export ZEPHYR_BASE="$ZEPHYR_NXP_BASE"\n' + else: + raise Exception("ZEPHYR_NXP_BASE need to be set") + build_args = self.WestBuildArgs() + cmd += ''' + west build -p --cmake-only -b {board_name} -d {out_folder} {example_folder} {build_args} + '''.format( + board_name=self.board.Name(), + out_folder=self.output_dir, + example_folder=self.app.BuildRoot(self.code_root, self.board), + build_args=build_args).strip() + self._Execute(['bash', '-c', cmd], title='Generating ' + self.identifier) + else: + super(NxpBuilder, self).generate() def build_outputs(self): name = 'chip-%s-%s' % (self.board.Name(), self.app.NameSuffix()) - yield BuilderOutput( - os.path.join(self.output_dir, name), - f'{name}.elf') - if self.options.enable_link_map_file: + if self.os_env == NxpOsUsed.ZEPHYR: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + f'{name}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + f'{name}.map') + else: yield BuilderOutput( - os.path.join(self.output_dir, f'{name}.map'), - f'{name}.map') + os.path.join(self.output_dir, name), + f'{name}.elf') + if self.options.enable_link_map_file: + yield BuilderOutput( + os.path.join(self.output_dir, f'{name}.map'), + f'{name}.map') diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 7714bddaae42e3..2d9fee76e68ac0 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -14,7 +14,7 @@ linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] rw61x-{all-clusters-app,thermostat,laundry-washer}[-ota][-wifi][-thread][-factory-data][-matter-shell] -nxp-{k32w0,k32w1}-{lighting,contact-sensor}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2] +nxp-{k32w0,k32w1,rw61x}-{zephyr,freertos}-{lighting,contact-sensor,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,ota-requestor,shell}[-release][-develop][-debug] mw320-all-clusters-app nrf-{nrf5340dk,nrf52840dk,nrf52840dongle}-{all-clusters,all-clusters-minimal,lock,light,light-switch,shell,pump,pump-controller,window-covering}[-rpc] diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index ecfd8a99fe3d6f..eff738deb58d8e 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -19,6 +19,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/chip-ota.xml"; load "../src/app/zap-templates/zcl/data-model/chip/chip-types.xml"; load "../src/app/zap-templates/zcl/data-model/chip/clusters-extensions.xml"; load "../src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml"; diff --git a/scripts/setup/requirements.infineon.txt b/scripts/setup/requirements.infineon.txt index 0a79ce1f3bfa63..97b60983b72f32 100644 --- a/scripts/setup/requirements.infineon.txt +++ b/scripts/setup/requirements.infineon.txt @@ -1,2 +1,4 @@ +ecdsa +intelhex leb128 zcbor diff --git a/scripts/setup/zap.json b/scripts/setup/zap.json index c3e65c8bab9752..636da03eeb2e8f 100644 --- a/scripts/setup/zap.json +++ b/scripts/setup/zap.json @@ -8,13 +8,13 @@ "mac-amd64", "windows-amd64" ], - "tags": ["version:2@v2024.06.10-nightly.1"] + "tags": ["version:2@v2024.07.10-nightly.1"] }, { "_comment": "Always get the amd64 version on mac until usable arm64 zap build is available", "path": "fuchsia/third_party/zap/mac-amd64", "platforms": ["mac-arm64"], - "tags": ["version:2@v2024.06.10-nightly.1"] + "tags": ["version:2@v2024.07.10-nightly.1"] } ] } diff --git a/scripts/setup/zap.version b/scripts/setup/zap.version index 8b3c20afc891f6..4414b06f961e8b 100644 --- a/scripts/setup/zap.version +++ b/scripts/setup/zap.version @@ -1 +1 @@ -v2024.06.10-nightly +v2024.07.10-nightly diff --git a/scripts/tests/py/metadata.py b/scripts/tests/py/metadata.py index 46ac1fe9ec8ab8..050f20f9920d6b 100644 --- a/scripts/tests/py/metadata.py +++ b/scripts/tests/py/metadata.py @@ -14,12 +14,18 @@ # limitations under the License. import re +import sys from dataclasses import dataclass from typing import Any, Dict, List import yaml +def bool_from_str(value: str) -> bool: + """Convert True/true/False/false strings to bool.""" + return value.strip().lower() == "true" + + @dataclass class Metadata: py_script_path: str @@ -58,16 +64,59 @@ def copy_from_dict(self, attr_dict: Dict[str, Any]) -> None: self.py_script_path = attr_dict["py_script_path"] if "factoryreset" in attr_dict: - self.factoryreset = bool(attr_dict["factoryreset"]) + self.factoryreset = bool_from_str(attr_dict["factoryreset"]) if "factoryreset_app_only" in attr_dict: - self.factoryreset_app_only = bool(attr_dict["factoryreset_app_only"]) + self.factoryreset_app_only = bool_from_str(attr_dict["factoryreset_app_only"]) if "script_gdb" in attr_dict: - self.script_gdb = bool(attr_dict["script_gdb"]) + self.script_gdb = bool_from_str(attr_dict["script_gdb"]) if "quiet" in attr_dict: - self.quiet = bool(attr_dict["quiet"]) + self.quiet = bool_from_str(attr_dict["quiet"]) + + +def extract_runs_arg_lines(py_script_path: str) -> Dict[str, Dict[str, str]]: + """Extract the run arguments from the CI test arguments blocks.""" + + found_ci_args_section = False + done_ci_args_section = False + + runs_def_ptrn = re.compile(r'^\s*#\s*test-runner-runs:\s*(?P.*)$') + arg_def_ptrn = re.compile( + r'^\s*#\s*test-runner-run/(?P[a-zA-Z0-9_]+)/(?P[a-zA-Z0-9_\-]+):\s*(?P.*)$') + + runs_arg_lines: Dict[str, Dict[str, str]] = {} + + with open(py_script_path, 'r', encoding='utf8') as py_script: + for line_idx, line in enumerate(py_script.readlines()): + line = line.strip() + line_num = line_idx + 1 + + # Detect the single CI args section, to skip the lines otherwise. + if not done_ci_args_section and line.startswith("# === BEGIN CI TEST ARGUMENTS ==="): + found_ci_args_section = True + elif found_ci_args_section and line.startswith("# === END CI TEST ARGUMENTS ==="): + done_ci_args_section = True + found_ci_args_section = False + + runs_match = runs_def_ptrn.match(line) + args_match = arg_def_ptrn.match(line) + + if not found_ci_args_section and (runs_match or args_match): + print(f"WARNING: {py_script_path}:{line_num}: Found CI args outside of CI TEST ARGUMENTS block!", file=sys.stderr) + continue + + if runs_match: + for run in runs_match.group("run_id").strip().split(): + runs_arg_lines[run] = {} + runs_arg_lines[run]['run'] = run + runs_arg_lines[run]['py_script_path'] = py_script_path + + elif args_match: + runs_arg_lines[args_match.group("run_id")][args_match.group("arg_name")] = args_match.group("arg_val") + + return runs_arg_lines class MetadataReader: @@ -126,33 +175,15 @@ def parse_script(self, py_script_path: str) -> List[Metadata]: the run arguments associated with a particular run defined in the script file. """ - - runs_def_ptrn = re.compile(r'^\s*#\s*test-runner-runs:\s*(.*)$') - arg_def_ptrn = re.compile(r'^\s*#\s*test-runner-run/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\-]+):\s*(.*)$') - - runs_arg_lines: Dict[str, Dict[str, str]] = {} runs_metadata: List[Metadata] = [] - - with open(py_script_path, 'r', encoding='utf8') as py_script: - for line in py_script.readlines(): - runs_match = runs_def_ptrn.match(line.strip()) - args_match = arg_def_ptrn.match(line.strip()) - - if runs_match: - for run in runs_match.group(1).strip().split(): - runs_arg_lines[run] = {} - runs_arg_lines[run]['run'] = run - runs_arg_lines[run]['py_script_path'] = py_script_path - - elif args_match: - runs_arg_lines[args_match.group(1)][args_match.group(2)] = args_match.group(3) + runs_arg_lines = extract_runs_arg_lines(py_script_path) for run, attr in runs_arg_lines.items(): self.__resolve_env_vals__(attr) metadata = Metadata( py_script_path=attr.get("py_script_path", ""), - run=attr.get("run", ""), + run=run, app=attr.get("app", ""), app_args=attr.get("app_args", ""), script_args=attr.get("script_args", ""), diff --git a/scripts/tests/py/test_metadata.py b/scripts/tests/py/test_metadata.py index a0c12a0ab0ed5a..863add965c315e 100644 --- a/scripts/tests/py/test_metadata.py +++ b/scripts/tests/py/test_metadata.py @@ -21,13 +21,17 @@ class TestMetadataReader(unittest.TestCase): - test_file_content = ''' - # test-runner-runs: run1 + test_file_content = ''' + # === BEGIN CI TEST ARGUMENTS === + # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/app-args: --discriminator 1234 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --commissioning-method on-network --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True + # === END CI TEST ARGUMENTS === + + # test-runner-run/run1/quiet: False ''' env_file_content = ''' diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index b641ef05b6cd88..eab2ec6b43c229 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -159,6 +159,39 @@ def ishex(s): except ValueError: return False +# get_supported_modes_dict() converts the list of strings to per endpoint dictionaries. +# example with semantic tags +# input : ['0/label1/1/"1\0x8000, 2\0x8000" 1/label2/1/"1\0x8000, 2\0x8000"'] +# output : {'1': [{'Label': 'label1', 'Mode': 0, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}, {'Label': 'label2', 'Mode': 1, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}]} + +# example without semantic tags +# input : ['0/label1/1 1/label2/1'] +# output : {'1': [{'Label': 'label1', 'Mode': 0, 'Semantic_Tag': []}, {'Label': 'label2', 'Mode': 1, 'Semantic_Tag': []}]} + + +def get_supported_modes_dict(supported_modes): + output_dict = {} + + for mode_str in supported_modes: + mode_label_strs = mode_str.split('/') + mode = mode_label_strs[0] + label = mode_label_strs[1] + ep = mode_label_strs[2] + + semantic_tags = '' + if (len(mode_label_strs) == 4): + semantic_tag_strs = mode_label_strs[3].split(', ') + semantic_tags = [{"value": int(v.split('\\')[0]), "mfgCode": int(v.split('\\')[1], 16)} for v in semantic_tag_strs] + + mode_dict = {"Label": label, "Mode": int(mode), "Semantic_Tag": semantic_tags} + + if ep in output_dict: + output_dict[ep].append(mode_dict) + else: + output_dict[ep] = [mode_dict] + + return output_dict + def check_str_range(s, min_len, max_len, name): if s and ((len(s) < min_len) or (len(s) > max_len)): @@ -269,6 +302,60 @@ def populate_factory_data(args, spake2p_params): if args.hw_ver_str: FACTORY_DATA['hw-ver-str']['value'] = args.hw_ver_str + # SupportedModes are stored as multiple entries + # - sm-sz/ : number of supported modes for the endpoint + # - sm-label// : supported modes label key for the endpoint and index + # - sm-mode// : supported modes mode key for the endpoint and index + # - sm-st-sz// : supported modes SemanticTag key for the endpoint and index + # - st-v/// : semantic tag value key for the endpoint and index and ind + # - st-mfg/// : semantic tag mfg code key for the endpoint and index and ind + if (args.supported_modes is not None): + dictionary = get_supported_modes_dict(args.supported_modes) + for ep in dictionary.keys(): + _sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(dictionary[ep]) + } + FACTORY_DATA.update({'sm-sz/{:x}'.format(int(ep)): _sz}) + for i in range(len(dictionary[ep])): + item = dictionary[ep][i] + _label = { + 'type': 'data', + 'encoding': 'string', + 'value': item["Label"] + } + _mode = { + 'type': 'data', + 'encoding': 'u32', + 'value': item["Mode"] + } + _st_sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(item["Semantic_Tag"]) + } + FACTORY_DATA.update({'sm-label/{:x}/{:x}'.format(int(ep), i): _label}) + FACTORY_DATA.update({'sm-mode/{:x}/{:x}'.format(int(ep), i): _mode}) + FACTORY_DATA.update({'sm-st-sz/{:x}/{:x}'.format(int(ep), i): _st_sz}) + + for j in range(len(item["Semantic_Tag"])): + entry = item["Semantic_Tag"][j] + + _value = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["value"] + } + _mfg_code = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["mfgCode"] + } + + FACTORY_DATA.update({'st-v/{:x}/{:x}/{:x}'.format(int(ep), i, j): _value}) + FACTORY_DATA.update({'st-mfg/{:x}/{:x}/{:x}'.format(int(ep), i, j): _mfg_code}) + def gen_raw_ec_keypair_from_der(key_file, pubkey_raw_file, privkey_raw_file): with open(key_file, 'rb') as f: @@ -381,6 +468,9 @@ def any_base_int(s): return int(s, 0) help=('128-bit unique identifier for generating rotating device identifier, ' 'provide 32-byte hex string, e.g. "1234567890abcdef1234567890abcdef"')) + parser.add_argument('--supported-modes', type=str, nargs='+', required=False, + help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"') + parser.add_argument('-s', '--size', type=any_base_int, default=0x6000, help='The size of the partition.bin, default: 0x6000') parser.add_argument('--target', default='esp32', @@ -419,8 +509,7 @@ def set_up_factory_data(args): def generate_factory_partiton_binary(args): generate_nvs_csv(args.output_dir, FACTORY_PARTITION_CSV) if args.generate_bin: - csv_file = os.path.join(args.output_dir, FACTORY_PARTITION_CSV) - generate_nvs_bin(args.encrypt, args.size, csv_file, FACTORY_PARTITION_BIN, args.output_dir) + generate_nvs_bin(args.encrypt, args.size, FACTORY_PARTITION_CSV, FACTORY_PARTITION_BIN, args.output_dir) print_flashing_help(args.encrypt, args.output_dir, FACTORY_PARTITION_BIN) clean_up() diff --git a/scripts/tools/zap/zap_execution.py b/scripts/tools/zap/zap_execution.py index 80def9602dce77..d027079ac70070 100644 --- a/scripts/tools/zap/zap_execution.py +++ b/scripts/tools/zap/zap_execution.py @@ -23,7 +23,7 @@ # Use scripts/tools/zap/version_update.py to manage ZAP versioning as many # files may need updating for versions # -MIN_ZAP_VERSION = '2024.6.6' +MIN_ZAP_VERSION = '2024.7.10' class ZapTool: diff --git a/scripts/tools/zap_regen_all.py b/scripts/tools/zap_regen_all.py index dce4f719a19829..afe931fd8609a6 100755 --- a/scripts/tools/zap_regen_all.py +++ b/scripts/tools/zap_regen_all.py @@ -350,7 +350,8 @@ def setupArgumentsParser(): parser.add_argument('--parallel', action='store_true') parser.add_argument('--no-parallel', action='store_false', dest='parallel') - parser.set_defaults(parallel=True) + parser.add_argument('--no-rerun-in-env', action='store_false', dest='rerun_in_env') + parser.set_defaults(parallel=True, rerun_in_env=True) args = parser.parse_args() @@ -495,6 +496,26 @@ def main(): level=logging.INFO, format='%(asctime)s %(name)s %(levelname)-7s %(message)s' ) + + # The scripts executed by this generally MUST be within a bootstrapped environment because + # we need: + # - zap-cli in PATH + # - scripts/codegen.py uses click (can be in current pyenv, but guaranteed in bootstrap) + # - formatting is using bootstrapped clang-format + # Figure out if bootstrapped. For now assume `PW_ROOT` is such a marker in the environment + if "PW_ROOT" not in os.environ: + logging.error("Script MUST be run in a bootstrapped environment.") + + # using the `--no-rerun-in-env` to avoid recursive infinite calls + if '--no-rerun-in-env' not in sys.argv: + import shlex + logging.info("Will re-try running in a build environment....") + + what_to_run = sys.argv + ['--no-rerun-in-env'] + launcher = os.path.join(CHIP_ROOT_DIR, 'scripts', 'run_in_build_env.sh') + os.execv(launcher, [launcher, shlex.join(what_to_run)]) + sys.exit(1) + checkPythonVersion() os.chdir(CHIP_ROOT_DIR) args = setupArgumentsParser() diff --git a/src/BUILD.gn b/src/BUILD.gn index 3f4421d2f3f584..7e5fedcc0d539b 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -51,6 +51,7 @@ if (chip_build_tests) { deps = [] tests = [ "${chip_root}/src/app/data-model/tests", + "${chip_root}/src/app/cluster-building-blocks/tests", "${chip_root}/src/app/data-model-interface/tests", "${chip_root}/src/access/tests", "${chip_root}/src/crypto/tests", diff --git a/src/access/tests/BUILD.gn b/src/access/tests/BUILD.gn index 702aade7f8c5e2..d8b43e6a17a01d 100644 --- a/src/access/tests/BUILD.gn +++ b/src/access/tests/BUILD.gn @@ -25,6 +25,7 @@ chip_test_suite("tests") { cflags = [ "-Wconversion" ] public_deps = [ "${chip_root}/src/access", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:test_utils", "${dir_pw_unit_test}", ] diff --git a/src/access/tests/TestAccessControl.cpp b/src/access/tests/TestAccessControl.cpp index 16f30284fbc4d1..400ea04b76e535 100644 --- a/src/access/tests/TestAccessControl.cpp +++ b/src/access/tests/TestAccessControl.cpp @@ -19,9 +19,10 @@ #include "access/AccessControl.h" #include "access/examples/ExampleAccessControlDelegate.h" -#include +#include -#include +#include +#include namespace chip { namespace Access { diff --git a/src/app/AttributeAccessInterfaceCache.h b/src/app/AttributeAccessInterfaceCache.h index 21e29410f9a367..9268a7096ea9d5 100644 --- a/src/app/AttributeAccessInterfaceCache.h +++ b/src/app/AttributeAccessInterfaceCache.h @@ -48,7 +48,7 @@ class AttributeAccessInterfaceCache kDefinitelyUsed }; - constexpr AttributeAccessInterfaceCache() = default; + AttributeAccessInterfaceCache() { Invalidate(); } /** * @brief Invalidate the whole cache. Must be called every time list of AAI registrations changes. @@ -106,8 +106,6 @@ class AttributeAccessInterfaceCache private: struct AttributeAccessCacheEntry { - constexpr AttributeAccessCacheEntry() = default; - EndpointId endpointId = kInvalidEndpointId; ClusterId clusterId = kInvalidClusterId; AttributeAccessInterface * accessor = nullptr; @@ -139,8 +137,8 @@ class AttributeAccessInterfaceCache return &mCacheSlots[0]; } - AttributeAccessCacheEntry mCacheSlots[1] = {}; - AttributeAccessCacheEntry mLastUnusedEntry{}; + AttributeAccessCacheEntry mCacheSlots[1]; + AttributeAccessCacheEntry mLastUnusedEntry; }; } // namespace app diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 55bc5f305ddd99..666c452b09dc3a 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -207,7 +207,7 @@ static_library("interaction-model") { public_deps = [ ":app_config", - ":command-handler", + ":command-handler-impl", ":constants", ":paths", ":subscription-info-provider", @@ -333,16 +333,32 @@ source_set("status-response") { ] } -source_set("command-handler") { +source_set("command-handler-interface") { sources = [ "CommandHandler.cpp", "CommandHandler.h", "CommandHandlerExchangeInterface.h", + ] + + public_deps = [ + ":paths", + "${chip_root}/src/access:types", + "${chip_root}/src/app/data-model", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/messaging", + "${chip_root}/src/protocols/interaction_model", + ] +} + +source_set("command-handler-impl") { + sources = [ "CommandHandlerImpl.cpp", "CommandHandlerImpl.h", ] public_deps = [ + ":command-handler-interface", ":paths", ":required-privileges", ":status-response", diff --git a/src/app/DefaultAttributePersistenceProvider.cpp b/src/app/DefaultAttributePersistenceProvider.cpp index 5bef4c11fb8c1a..6e7120999fe519 100644 --- a/src/app/DefaultAttributePersistenceProvider.cpp +++ b/src/app/DefaultAttributePersistenceProvider.cpp @@ -37,34 +37,40 @@ CHIP_ERROR DefaultAttributePersistenceProvider::InternalWriteValue(const Storage return mStorage->SyncSetKeyValue(aKey.KeyName(), aValue.data(), static_cast(aValue.size())); } -CHIP_ERROR DefaultAttributePersistenceProvider::InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, - size_t aSize, MutableByteSpan & aValue) +CHIP_ERROR DefaultAttributePersistenceProvider::InternalReadValue(const StorageKeyName & aKey, MutableByteSpan & aValue) { VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); uint16_t size = static_cast(min(aValue.size(), static_cast(UINT16_MAX))); ReturnErrorOnFailure(mStorage->SyncGetKeyValue(aKey.KeyName(), aValue.data(), size)); - EmberAfAttributeType type = aType; - if (emberAfIsStringAttributeType(type)) + aValue.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DefaultAttributePersistenceProvider::InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, + size_t aExpectedSize, MutableByteSpan & aValue) +{ + ReturnErrorOnFailure(InternalReadValue(aKey, aValue)); + size_t size = aValue.size(); + if (emberAfIsStringAttributeType(aType)) { // Ensure that we've read enough bytes that we are not ending up with // un-initialized memory. Should have read length + 1 (for the length // byte). - VerifyOrReturnError(size >= emberAfStringLength(aValue.data()) + 1, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(size >= 1 && size - 1 >= emberAfStringLength(aValue.data()), CHIP_ERROR_INCORRECT_STATE); } - else if (emberAfIsLongStringAttributeType(type)) + else if (emberAfIsLongStringAttributeType(aType)) { // Ensure that we've read enough bytes that we are not ending up with // un-initialized memory. Should have read length + 2 (for the length // bytes). - VerifyOrReturnError(size >= emberAfLongStringLength(aValue.data()) + 2, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(size >= 2 && size - 2 >= emberAfLongStringLength(aValue.data()), CHIP_ERROR_INCORRECT_STATE); } else { // Ensure we got the expected number of bytes for all other types. - VerifyOrReturnError(size == aSize, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(size == aExpectedSize, CHIP_ERROR_INVALID_ARGUMENT); } - aValue.reduce_size(size); return CHIP_NO_ERROR; } @@ -90,8 +96,7 @@ CHIP_ERROR DefaultAttributePersistenceProvider::SafeWriteValue(const ConcreteAtt CHIP_ERROR DefaultAttributePersistenceProvider::SafeReadValue(const ConcreteAttributePath & aPath, MutableByteSpan & aValue) { return InternalReadValue( - DefaultStorageKeyAllocator::SafeAttributeValue(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId), 0x20, - aValue.size(), aValue); + DefaultStorageKeyAllocator::SafeAttributeValue(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId), aValue); } namespace { diff --git a/src/app/DefaultAttributePersistenceProvider.h b/src/app/DefaultAttributePersistenceProvider.h index 4db77e8919222c..3e18808f366d37 100644 --- a/src/app/DefaultAttributePersistenceProvider.h +++ b/src/app/DefaultAttributePersistenceProvider.h @@ -63,7 +63,9 @@ class DefaultAttributePersistenceProvider : public AttributePersistenceProvider, private: CHIP_ERROR InternalWriteValue(const StorageKeyName & aKey, const ByteSpan & aValue); - CHIP_ERROR InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, size_t aSize, MutableByteSpan & aValue); + CHIP_ERROR InternalReadValue(const StorageKeyName & aKey, MutableByteSpan & aValue); + CHIP_ERROR InternalReadValue(const StorageKeyName & aKey, EmberAfAttributeType aType, size_t aExpectedSize, + MutableByteSpan & aValue); }; } // namespace app diff --git a/src/app/EventLoggingTypes.h b/src/app/EventLoggingTypes.h index 666cb3886331fe..04a843ebcfbd60 100644 --- a/src/app/EventLoggingTypes.h +++ b/src/app/EventLoggingTypes.h @@ -100,7 +100,7 @@ struct Timestamp kSystem = 0, kEpoch }; - constexpr Timestamp() = default; + Timestamp() {} Timestamp(Type aType, uint64_t aValue) : mType(aType), mValue(aValue) {} Timestamp(System::Clock::Timestamp aValue) : mType(Type::kSystem), mValue(aValue.count()) {} static Timestamp Epoch(System::Clock::Timestamp aValue) diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp index 7b210064898b6e..8e6d53c24c9636 100644 --- a/src/app/EventManagement.cpp +++ b/src/app/EventManagement.cpp @@ -32,7 +32,7 @@ using namespace chip::TLV; namespace chip { namespace app { -EventManagement EventManagement::sInstance; +static EventManagement sInstance; /** * @brief diff --git a/src/app/EventManagement.h b/src/app/EventManagement.h index 16e2271d3448b5..ce5a34039ea0fe 100644 --- a/src/app/EventManagement.h +++ b/src/app/EventManagement.h @@ -73,7 +73,7 @@ namespace app { inline constexpr const uint32_t kEventManagementProfile = 0x1; inline constexpr const uint32_t kFabricIndexTag = 0x1; inline constexpr size_t kMaxEventSizeReserve = 512; -inline constexpr uint16_t kRequiredEventField = +constexpr uint16_t kRequiredEventField = (1 << to_underlying(EventDataIB::Tag::kPriority)) | (1 << to_underlying(EventDataIB::Tag::kPath)); /** @@ -388,9 +388,6 @@ class EventManagement void SetScheduledEventInfo(EventNumber & aEventNumber, uint32_t & aInitialWrittenEventBytes) const; private: - constexpr EventManagement() = default; - static EventManagement sInstance; - /** * @brief * Internal structure for traversing events. @@ -558,9 +555,9 @@ class EventManagement MonotonicallyIncreasingCounter * mpEventNumberCounter = nullptr; EventNumber mLastEventNumber = 0; ///< Last event Number vended - Timestamp mLastEventTimestamp{}; ///< The timestamp of the last event in this buffer + Timestamp mLastEventTimestamp; ///< The timestamp of the last event in this buffer - System::Clock::Milliseconds64 mMonotonicStartupTime{}; + System::Clock::Milliseconds64 mMonotonicStartupTime; }; } // namespace app } // namespace chip diff --git a/src/app/SafeAttributePersistenceProvider.h b/src/app/SafeAttributePersistenceProvider.h index ed02d6039043ad..8d11d95d47b02d 100644 --- a/src/app/SafeAttributePersistenceProvider.h +++ b/src/app/SafeAttributePersistenceProvider.h @@ -40,8 +40,8 @@ class SafeAttributePersistenceProvider // The following API provides helper functions to simplify the access of commonly used types. // The API may not be complete. - // Currently implemented write and read types are: uint8_t, uint16_t, uint32_t, unit64_t and - // their nullable varieties, and bool. + // Currently implemented write and read types are: bool, uint8_t, uint16_t, uint32_t, unit64_t and + // their nullable varieties, as well as ByteSpans. /** * Write an attribute value of type intX, uintX or bool to non-volatile memory. @@ -50,7 +50,7 @@ class SafeAttributePersistenceProvider * @param [in] aValue the data to write. */ template ::value, bool> = true> - CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, T & aValue) + CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, T aValue) { uint8_t value[sizeof(T)]; auto w = Encoding::LittleEndian::BufferWriter(value, sizeof(T)); @@ -71,18 +71,16 @@ class SafeAttributePersistenceProvider * * @param [in] aPath the attribute path for the data being persisted. * @param [in,out] aValue where to place the data. + * + * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute */ template ::value, bool> = true> CHIP_ERROR ReadScalarValue(const ConcreteAttributePath & aPath, T & aValue) { uint8_t attrData[sizeof(T)]; MutableByteSpan tempVal(attrData); - auto err = SafeReadValue(aPath, tempVal); - if (err != CHIP_NO_ERROR) - { - return err; - } - + ReturnErrorOnFailure(SafeReadValue(aPath, tempVal)); + VerifyOrReturnError(tempVal.size() == sizeof(T), CHIP_ERROR_INCORRECT_STATE); Encoding::LittleEndian::Reader r(tempVal.data(), tempVal.size()); r.RawReadLowLevelBeCareful(&aValue); return r.StatusCode(); @@ -95,7 +93,7 @@ class SafeAttributePersistenceProvider * @param [in] aValue the data to write. */ template ::value, bool> = true> - CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, DataModel::Nullable & aValue) + CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, const DataModel::Nullable & aValue) { typename NumericAttributeTraits::StorageType storageValue; if (aValue.IsNull()) @@ -114,16 +112,14 @@ class SafeAttributePersistenceProvider * * @param [in] aPath the attribute path for the data being persisted. * @param [in,out] aValue where to place the data. + * + * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute */ template ::value, bool> = true> CHIP_ERROR ReadScalarValue(const ConcreteAttributePath & aPath, DataModel::Nullable & aValue) { typename NumericAttributeTraits::StorageType storageValue; - CHIP_ERROR err = ReadScalarValue(aPath, storageValue); - if (err != CHIP_NO_ERROR) - { - return err; - } + ReturnErrorOnFailure(ReadScalarValue(aPath, storageValue)); if (NumericAttributeTraits::IsNullValue(storageValue)) { @@ -137,25 +133,25 @@ class SafeAttributePersistenceProvider return CHIP_NO_ERROR; } -protected: /** * Write an attribute value from the attribute store (i.e. not a struct or * list) to non-volatile memory. * * @param [in] aPath the attribute path for the data being written. - * @param [in] aValue the data to write. The value should be stored as-is. + * @param [in] aValue the data to write. The value will be stored as-is. */ virtual CHIP_ERROR SafeWriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue) = 0; /** - * Read an attribute value from non-volatile memory. - * It can be assumed that this method will never be called upon to read - * an attribute of type string or long-string. + * Read an attribute value as a raw sequence of bytes from non-volatile memory. * * @param [in] aPath the attribute path for the data being persisted. * @param [in,out] aValue where to place the data. The size of the buffer - * will be equal to `aValue.size()`. The callee is expected to adjust - * aValue's size to the actual number of bytes read. + * will be equal to `aValue.size()`. On success aValue.size() + * will be the actual number of bytes read. + * + * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute + * @retval CHIP_ERROR_BUFFER_TOO_SMALL aValue.size() is too small to hold the value. */ virtual CHIP_ERROR SafeReadValue(const ConcreteAttributePath & aPath, MutableByteSpan & aValue) = 0; }; diff --git a/src/app/WriteClient.h b/src/app/WriteClient.h index b67bf4ea0b8c84..b4d803981be3d8 100644 --- a/src/app/WriteClient.h +++ b/src/app/WriteClient.h @@ -178,7 +178,7 @@ class WriteClient : public Messaging::ExchangeDelegate ReturnErrorOnFailure(EncodeSingleAttributeDataIB(path, DataModel::List())); path.mListOp = ConcreteDataAttributePath::ListOperation::AppendItem; - for (ListIndex i = 0; i < value.size(); i++) + for (size_t i = 0; i < value.size(); i++) { ReturnErrorOnFailure(EncodeSingleAttributeDataIB(path, value.data()[i])); } diff --git a/src/app/app-platform/ContentAppPlatform.cpp b/src/app/app-platform/ContentAppPlatform.cpp index fb2d6ab39a1b5f..214af261e26e54 100644 --- a/src/app/app-platform/ContentAppPlatform.cpp +++ b/src/app/app-platform/ContentAppPlatform.cpp @@ -387,6 +387,57 @@ ContentApp * ContentAppPlatform::GetContentApp(EndpointId id) return nullptr; } +// create a string key from vendorId and productId +std::string createKey(uint16_t vendorId, uint16_t productId) +{ + return std::to_string(vendorId) + ":" + std::to_string(productId); +} + +void ContentAppPlatform::StoreNodeIdForContentApp(uint16_t vendorId, uint16_t productId, NodeId nodeId) +{ + std::string key = createKey(vendorId, productId); + + ChipLogProgress(DeviceLayer, "Stored node id: " ChipLogFormatX64 " for key: %s", ChipLogValueX64(nodeId), key.c_str()); + + mConnectedContentAppNodeIds[key].insert(nodeId); +} + +std::set ContentAppPlatform::GetNodeIdsForContentApp(uint16_t vendorId, uint16_t productId) +{ + std::string key = createKey(vendorId, productId); + + ChipLogProgress(DeviceLayer, "Retrieving node id for key: %s", key.c_str()); + + auto it = mConnectedContentAppNodeIds.find(key); + if (it != mConnectedContentAppNodeIds.end()) + { + ChipLogProgress(DeviceLayer, "Found node id"); + return it->second; + } + + ChipLogProgress(DeviceLayer, "Didn't find node id"); + // If key not found, return an empty set + return {}; +} + +std::set ContentAppPlatform::GetNodeIdsForAllowVendorId(uint16_t vendorId) +{ + std::set result; + std::string vendorPrefix = std::to_string(vendorId) + ":"; + + for (const auto & pair : mConnectedContentAppNodeIds) + { + const std::string & key = pair.first; + if (key.find(vendorPrefix) == 0) + { // Check if the key starts with the vendor prefix + const std::set & nodeIds = pair.second; + result.insert(nodeIds.begin(), nodeIds.end()); + } + } + + return result; +} + void ContentAppPlatform::SetCurrentApp(ContentApp * app) { if (!HasCurrentApp()) diff --git a/src/app/app-platform/ContentAppPlatform.h b/src/app/app-platform/ContentAppPlatform.h index 16a47c26a3b991..45615d09ed8ddf 100644 --- a/src/app/app-platform/ContentAppPlatform.h +++ b/src/app/app-platform/ContentAppPlatform.h @@ -161,6 +161,18 @@ class DLL_EXPORT ContentAppPlatform bool HasTargetContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId, Protocols::UserDirectedCommissioning::TargetAppInfo & info, uint32_t & passcode); + // returns set of connected nodes for a given content app + std::set GetNodeIdsForContentApp(uint16_t vendorId, uint16_t productId); + + // returns set of connected nodes for a given allowed vendor id + std::set GetNodeIdsForAllowVendorId(uint16_t vendorId); + + // store node id for content app after commissioning + // node id can be used later on to update ACL + // in case app is not installed + // Note: This is in memory storing, the values are deleted after reboot + void StoreNodeIdForContentApp(uint16_t vendorId, uint16_t productId, NodeId nodeId); + /** * @brief * Add ACLs on this device for the given client, @@ -201,6 +213,8 @@ class DLL_EXPORT ContentAppPlatform EndpointId mCurrentEndpointId; EndpointId mFirstDynamicEndpointId; ContentApp * mContentApps[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; + // key is string -> vendorId:producTid + std::map> mConnectedContentAppNodeIds; private: void IncrementCurrentEndpointID(); diff --git a/src/app/cluster-building-blocks/BUILD.gn b/src/app/cluster-building-blocks/BUILD.gn new file mode 100644 index 00000000000000..dedce36ea43e6b --- /dev/null +++ b/src/app/cluster-building-blocks/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build_overrides/chip.gni") + +source_set("cluster-building-blocks") { + sources = [ "QuieterReporting.h" ] + + public_deps = [ + "${chip_root}/src/app/data-model:nullable", + "${chip_root}/src/lib/support:support", + "${chip_root}/src/system", + ] +} diff --git a/src/app/cluster-building-blocks/QuieterReporting.h b/src/app/cluster-building-blocks/QuieterReporting.h new file mode 100644 index 00000000000000..d44f12b0f2b0bf --- /dev/null +++ b/src/app/cluster-building-blocks/QuieterReporting.h @@ -0,0 +1,241 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace chip { +namespace app { + +enum class QuieterReportingPolicyEnum +{ + kMarkDirtyOnChangeToFromZero = (1u << 0), + kMarkDirtyOnDecrement = (1u << 1), + kMarkDirtyOnIncrement = (1u << 2), +}; + +enum class AttributeDirtyState +{ + kNoReportNeeded = 0, + kMustReport = 1, +}; + +using QuieterReportingPolicyFlags = BitFlags; + +namespace detail { + +using Timestamp = System::Clock::Milliseconds64; +template +using Nullable = DataModel::Nullable; + +/** + * This class helps track reporting state of an attribute to properly keep track of whether + * it needs to be marked as dirty or not for purposes of reporting using + * "7.7.9 Quieter Reporting Quality" (Q quality) + * + * The class can be configured via `policy()` to have some/all of the common reasons + * for reporting (e.g. increment only, decrement only, change to/from zero). + * + * Changes of null to non-null or non-null to null are always considered dirty. + * + * It is possible to force mark the attribute as dirty (see `ForceDirty()`) such as + * for conditions like "When there is any increase or decrease in the estimated time + * remaining that was due to progressing insight of the server's control logic". + * + * Class maintains a `current value` and a timestamped `dirty` state. The `SetValue()` + * method must be used to update the `current value` and will return AttributeDirtyState::kMustReport + * if the attribute should be marked dirty/ + * + * - `SetValue()` has internal rules for null/non-null changes and policy-based rules + * - `SetValue()` with a `SufficientChangePredicate` uses the internal rules in addition to + * the predicate to determine dirty state + * + * See [QuieterReportingPolicyEnum] for policy flags on when a value is considered dirty + * beyond non/non-null changes. + * + * Common quieter reporting usecases that can be supported by this class are: + * - If attribute has changed due to a change in the X or Y attributes + * - Use SufficientChangePredicate version + * - When it changes from 0 to any other value and vice versa + * - Use `kMarkDirtyOnChangeToFromZero` internal policy. + * - When it changes from null to any other value and vice versa + * - Built-in rule. + * - When it increases + * - Use `kMarkDirtyOnIncrement` internal policy. + * - When it decreases + * - Use `kMarkDirtyOnDecrement` internal policy. + * - When there is any increase or decrease in the estimated time remaining that was + * due to progressing insight of the server's control logic + * - Use SufficientChangePredicate version with an always-true predicate. + * - When it changes at a rate significantly different from one unit per second. + * - Use SufficientChangePredicate version. + * Example usage in-situ: + * + * Class has: + * QuieterReportingAttribute mAttrib; + * + * Code at time of setting new value has: + * + * uint8_t newValue = driver.GetNewValue(); + * auto now = SystemClock().GetMonotonicTimestamp(); + * if (mAttrib.SetValue(newValue, now) == AttributeDirtyState::kMustReport) + * { + * MatterReportingAttributeChangeCallback(path_for_attribute); + * } + * + * @tparam T - the type of underlying numerical value that will be held by the class. + */ +template ::value, bool> = true> +class QuieterReportingAttribute +{ +public: + explicit QuieterReportingAttribute(const Nullable & initialValue) : mValue(initialValue), mLastDirtyValue(initialValue) {} + + struct SufficientChangePredicateCandidate + { + // Timestamp of last time attribute was marked dirty. + Timestamp lastDirtyTimestamp; + // New (`now`) timestamp passed in `SetValue()`. + Timestamp nowTimestamp; + // Value last marked as dirty. + const Nullable & lastDirtyValue; + // New value passed in `SetValue()`, to compare against lastDirtyValue for sufficient change if needed. + const Nullable & newValue; + }; + + using SufficientChangePredicate = std::function; + + /** + * @brief Factory to generate a functor for "attribute was last reported" at least `minimumDurationMillis` ago. + * + * @param minimumDurationMillis - number of millis needed since last marked as dirty before we mark dirty again. + * @return a functor usable for the `changedPredicate` arg of `SetValue()` + */ + static SufficientChangePredicate + GetPredicateForSufficientTimeSinceLastDirty(System::Clock::Milliseconds64 minimumDurationMillis) + { + return [minimumDurationMillis](const SufficientChangePredicateCandidate & candidate) -> bool { + return (candidate.lastDirtyValue != candidate.newValue) && + ((candidate.nowTimestamp - candidate.lastDirtyTimestamp) >= minimumDurationMillis); + }; + } + + /** + * @brief Factory to generate a functor that forces reportable now. + * @return a functor usable for the `changedPredicate` arg of `SetValue()` + */ + static SufficientChangePredicate GetForceReportablePredicate() + { + return [](const SufficientChangePredicateCandidate & candidate) -> bool { return true; }; + } + + Nullable value() const { return mValue; } + QuieterReportingPolicyFlags & policy() { return mPolicyFlags; } + const QuieterReportingPolicyFlags & policy() const { return mPolicyFlags; } + + /** + * Set the updated value of the attribute, computing whether it needs to be reported according to `changedPredicate` and + * policies. + * + * - Any change of nullability between `newValue` and the old value will be considered dirty. + * - The policies from `QuieterReportingPolicyEnum` and set via `SetPolicy()` are self-explanatory by name. + * - The changedPredicate will be called with last dirty and new and may override + * the dirty state altogether when it returns true. Use sparingly and default to a functor returning false. + * + * Internal recording will be done about last dirty value and last dirty timestamp based on the policies having applied. + * + * @param newValue - new value to set for the attribute + * @param now - system monotonic timestamp at the time of the call + * @param changedPredicate - functor to possibly override dirty state + * @return AttributeDirtyState::kMustReport if attribute must be marked dirty right away, or + * AttributeDirtyState::kNoReportNeeded otherwise. + */ + AttributeDirtyState SetValue(const chip::app::DataModel::Nullable & newValue, Timestamp now, + SufficientChangePredicate changedPredicate) + { + bool isChangeOfNull = newValue.IsNull() ^ mValue.IsNull(); + bool areBothValuesNonNull = !newValue.IsNull() && !mValue.IsNull(); + + bool changeToFromZero = areBothValuesNonNull && (newValue.Value() == 0 || mValue.Value() == 0); + bool isIncrement = areBothValuesNonNull && (newValue.Value() > mValue.Value()); + bool isDecrement = areBothValuesNonNull && (newValue.Value() < mValue.Value()); + + bool isNewlyDirty = isChangeOfNull; + isNewlyDirty = + isNewlyDirty || (mPolicyFlags.Has(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero) && changeToFromZero); + isNewlyDirty = isNewlyDirty || (mPolicyFlags.Has(QuieterReportingPolicyEnum::kMarkDirtyOnDecrement) && isDecrement); + isNewlyDirty = isNewlyDirty || (mPolicyFlags.Has(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) && isIncrement); + + SufficientChangePredicateCandidate candidate{ + mLastDirtyTimestampMillis, // lastDirtyTimestamp + now, // nowTimestamp + mLastDirtyValue, // lastDirtyValue + newValue // newValue + }; + isNewlyDirty = isNewlyDirty || changedPredicate(candidate); + + mValue = newValue; + + if (isNewlyDirty) + { + mLastDirtyValue = newValue; + mLastDirtyTimestampMillis = now; + } + + return isNewlyDirty ? AttributeDirtyState::kMustReport : AttributeDirtyState::kNoReportNeeded; + } + + /** + * Same as the other `SetValue`, but assumes a changedPredicate that never overrides to dirty. + * + * This is the easy/common case. + * + * @param newValue - new value to set for the attribute + * @param now - system monotonic timestamp at the time of the call + * @return AttributeDirtyState::kMustReport if attribute must be marked dirty right away, or + * AttributeDirtyState::kNoReportNeeded otherwise. + */ + AttributeDirtyState SetValue(const chip::app::DataModel::Nullable & newValue, Timestamp now) + { + return SetValue(newValue, now, [](const SufficientChangePredicateCandidate &) -> bool { return false; }); + } + +protected: + // Current value of the attribute. + chip::app::DataModel::Nullable mValue; + // Last value that was marked as dirty (to use in comparisons for change, e.g. by SufficientChangePredicate). + chip::app::DataModel::Nullable mLastDirtyValue; + // Enabled internal change detection policies. + QuieterReportingPolicyFlags mPolicyFlags{ 0 }; + // Timestamp associated with the last time the attribute was marked dirty (to use in comparisons for change). + chip::System::Clock::Milliseconds64 mLastDirtyTimestampMillis{}; +}; + +} // namespace detail + +using detail::QuieterReportingAttribute; + +} // namespace app +} // namespace chip diff --git a/src/app/cluster-building-blocks/tests/BUILD.gn b/src/app/cluster-building-blocks/tests/BUILD.gn new file mode 100644 index 00000000000000..3ac4e07f234ba3 --- /dev/null +++ b/src/app/cluster-building-blocks/tests/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/build/chip/chip_test_suite.gni") + +chip_test_suite("tests") { + output_name = "libAppClusterBuildingBlockTests" + + test_sources = [ "TestQuieterReporting.cpp" ] + + public_deps = [ + "${chip_root}/src/app/cluster-building-blocks", + "${chip_root}/src/app/data-model:nullable", + "${chip_root}/src/lib/core:error", + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/support/tests:pw-test-macros", + "${chip_root}/src/system", + ] +} diff --git a/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp b/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp new file mode 100644 index 00000000000000..a7750380285438 --- /dev/null +++ b/src/app/cluster-building-blocks/tests/TestQuieterReporting.cpp @@ -0,0 +1,263 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include +#include +#include +#include + +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::System::Clock; +using namespace chip::System::Clock::Literals; + +class FakeClock +{ +public: + FakeClock() = default; + + Timestamp Advance(Milliseconds64 numMillis) + { + mCurrentTimestamp += numMillis; + return mCurrentTimestamp; + } + + void SetMonotonic(Timestamp now) { mCurrentTimestamp = now; } + + Timestamp now() const { return mCurrentTimestamp; } + +private: + Timestamp mCurrentTimestamp{}; +}; + +TEST(TestQuieterReporting, ChangeToFromZeroPolicyWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(10) }; + EXPECT_FALSE(attribute.value().IsNull()); + EXPECT_EQ(attribute.policy(), QuieterReportingPolicyFlags{}); + + auto now = fakeClock.now(); + + attribute.policy().Set(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); + EXPECT_TRUE(attribute.policy().HasOnly(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero)); + + // 10 --> 11, expect not marked dirty yet. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> 0, expect marked dirty. + EXPECT_EQ(attribute.SetValue(0, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 0); + + // 0 --> 11, expect marked dirty. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> 12, expect not marked dirty. + EXPECT_EQ(attribute.SetValue(12, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 12); + + // Reset policy, expect 12 --> 0 does not mark dirty due to no longer having the policy that causes it. + attribute.policy().ClearAll(); + EXPECT_FALSE(attribute.policy().HasAny()); + + EXPECT_EQ(attribute.SetValue(0, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 0); +} + +TEST(TestQuieterReporting, ChangeOnIncrementPolicyWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(10) }; + + // Always start not dirty (because first sub priming always just read value anyway). + ASSERT_EQ(attribute.value().Value(), 10); + + auto now = fakeClock.now(); + + attribute.policy().Set(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement); + EXPECT_TRUE(attribute.policy().HasOnly(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement)); + + // 10 --> 9, expect not marked dirty yet. + EXPECT_EQ(attribute.SetValue(9, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 9); + + // 9 --> 10, expect marked dirty. + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); + + // 10 --> 11, expect marked dirty. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> 11, expect marked not dirty. + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // 11 --> null, expect marked dirty (null change always marks dirty) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kMustReport); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> null, not dirty (no change) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> 11, expect marked dirty (null change always marks dirty). + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Reset policy, expect 11 --> 12 does not mark dirty due to no longer having the policy that causes it. + attribute.policy().ClearAll(); + EXPECT_FALSE(attribute.policy().HasAny()); + + EXPECT_EQ(attribute.SetValue(12, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 12); +} + +TEST(TestQuieterReporting, ChangeOnDecrementPolicyWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(9) }; + + // Always start not dirty (because first sub priming always just read value anyway). + ASSERT_EQ(attribute.value().Value(), 9); + + auto now = fakeClock.now(); + + attribute.policy().Set(QuieterReportingPolicyEnum::kMarkDirtyOnDecrement); + EXPECT_TRUE(attribute.policy().HasOnly(QuieterReportingPolicyEnum::kMarkDirtyOnDecrement)); + + // 9 --> 10, expect not marked dirty yet. + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); + + // 10 --> 9, expect marked dirty. + EXPECT_EQ(attribute.SetValue(9, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 9); + + // 9 --> 8, expect marked dirty. + EXPECT_EQ(attribute.SetValue(8, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 8); + + // Second call in a row always false. + + // 8 --> 8, expect not marked dirty. + EXPECT_EQ(attribute.SetValue(8, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 8); + + // 8 --> null, expect marked dirty (null change always marks dirty) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kMustReport); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> null, not dirty (no change) + EXPECT_EQ(attribute.SetValue(NullNullable, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_TRUE(attribute.value().IsNull()); + + // null --> 11, expect marked dirty (null change always marks dirty). + EXPECT_EQ(attribute.SetValue(11, now), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Reset policy, expect 11 --> 10 does not mark dirty due to no longer having the policy that causes it. + attribute.policy().ClearAll(); + EXPECT_FALSE(attribute.policy().HasAny()); + + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); +} + +TEST(TestQuieterReporting, SufficientChangePredicateWorks) +{ + FakeClock fakeClock; + fakeClock.SetMonotonic(100_ms); + + QuieterReportingAttribute attribute{ MakeNullable(9) }; + + // Always start not dirty (because first sub priming always just read value anyway). + ASSERT_EQ(attribute.value().Value(), 9); + + auto now = fakeClock.now(); + + EXPECT_EQ(attribute.SetValue(10, now), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 10); + + // Forcing dirty can be done with a force-true predicate + EXPECT_EQ(attribute.SetValue(10, now, attribute.GetForceReportablePredicate()), AttributeDirtyState::kMustReport); + + auto predicate = attribute.GetPredicateForSufficientTimeSinceLastDirty(1000_ms); + + now = fakeClock.Advance(100_ms); + + // Last dirty value is 10. This won't mark dirty again due to predicate mismatch. + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + now = fakeClock.Advance(900_ms); + // Last dirty value is 10 still. This will mark dirty because both enough time has passed + // and value is different from the last dirty value. + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Last dirty value is 11. Since there has not been a value change, no amount of time will + // mark dirty. + now = fakeClock.Advance(1000_ms); + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + now = fakeClock.Advance(1000_ms); + EXPECT_EQ(attribute.SetValue(11, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 11); + + // Change the value to a value that marks dirty. + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(12, now, predicate), AttributeDirtyState::kMustReport); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 12); + + // Wait a small delay and change again. Will not mark dirty due to too little time. + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(13, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 13); + + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(14, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_EQ(attribute.value().ValueOr(INT_MAX), 14); + + // Change to a value that marks dirty no matter what (e.g. null). Should be dirty even + // before delay. + now = fakeClock.Advance(1_ms); + EXPECT_EQ(attribute.SetValue(NullNullable, now, predicate), AttributeDirtyState::kMustReport); + EXPECT_TRUE(attribute.value().IsNull()); + + // Null --> Null should not lead to dirty. + now = fakeClock.Advance(1000_ms); + EXPECT_EQ(attribute.SetValue(NullNullable, now, predicate), AttributeDirtyState::kNoReportNeeded); + EXPECT_TRUE(attribute.value().IsNull()); +} diff --git a/src/app/clusters/descriptor/descriptor.cpp b/src/app/clusters/descriptor/descriptor.cpp index 4eb68621c5767e..514051226fdcf5 100644 --- a/src/app/clusters/descriptor/descriptor.cpp +++ b/src/app/clusters/descriptor/descriptor.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -206,9 +205,7 @@ CHIP_ERROR DescriptorAttrAccess::ReadClusterRevision(EndpointId endpoint, Attrib return aEncoder.Encode(kClusterRevision); } -namespace { -Global gAttrAccess; -} +DescriptorAttrAccess gAttrAccess; CHIP_ERROR DescriptorAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) { @@ -247,5 +244,5 @@ CHIP_ERROR DescriptorAttrAccess::Read(const ConcreteReadAttributePath & aPath, A void MatterDescriptorPluginServerInitCallback() { - registerAttributeAccessOverride(&gAttrAccess.get()); + registerAttributeAccessOverride(&gAttrAccess); } diff --git a/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp index ca0fc231d6cc94..b3c9b8edbccf34 100644 --- a/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp +++ b/src/app/clusters/dishwasher-alarm-server/dishwasher-alarm-server.cpp @@ -129,12 +129,13 @@ Status DishwasherAlarmServer::GetSupportedValue(EndpointId endpoint, BitMask supported) { Status status = Status::Success; - ; + if ((status = Attributes::Supported::Set(endpoint, supported)) != Status::Success) { ChipLogProgress(Zcl, "Dishwasher Alarm: ERR: writing supported, err:0x%x", to_underlying(status)); return status; } + // Whenever there is change in Supported attribute, Latch should change accordingly (if possible). BitMask latch; if (GetLatchValue(endpoint, &latch) == Status::Success && !supported.HasAll(latch)) diff --git a/src/app/clusters/door-lock-server/door-lock-server.cpp b/src/app/clusters/door-lock-server/door-lock-server.cpp index 481587322216eb..68e5f398b5bc84 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server.cpp @@ -51,39 +51,6 @@ static constexpr uint8_t DOOR_LOCK_ALIRO_CREDENTIAL_SIZE = 65; static constexpr uint32_t DOOR_LOCK_MAX_LOCK_TIMEOUT_SEC = MAX_INT32U_VALUE / MILLISECOND_TICKS_PER_SECOND; -static constexpr size_t kDoorLockDelegateTableSize = - MATTER_DM_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; - -static_assert(kDoorLockDelegateTableSize <= kEmberInvalidEndpointIndex, "Door Lock Delegate table size error"); - -namespace chip { -namespace app { -namespace Clusters { -namespace DoorLock { - -Delegate * gDelegateTable[kDoorLockDelegateTableSize] = { nullptr }; - -Delegate * GetDelegate(EndpointId endpoint) -{ - uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, DoorLock::Id, MATTER_DM_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT); - return (ep >= kDoorLockDelegateTableSize ? nullptr : gDelegateTable[ep]); -} - -void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) -{ - uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, DoorLock::Id, MATTER_DM_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT); - // if endpoint is found - if (ep < ArraySize(gDelegateTable)) - { - gDelegateTable[ep] = delegate; - } -} - -} // namespace DoorLock -} // namespace Clusters -} // namespace app -} // namespace chip - DoorLockServer DoorLockServer::instance; class DoorLockClusterFabricDelegate : public chip::FabricTable::Delegate @@ -117,7 +84,18 @@ DoorLockServer & DoorLockServer::Instance() * * @param endpointId */ -void DoorLockServer::InitServer(chip::EndpointId endpointId) +void DoorLockServer::InitServer(EndpointId endpointId) +{ + CHIP_ERROR err = InitEndpoint(endpointId); + + // We have no way to communicate this error, so just log it. + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Door Lock cluster initialization on endpoint %d failed: %" CHIP_ERROR_FORMAT, endpointId, err.Format()); + } +} + +CHIP_ERROR DoorLockServer::InitEndpoint(EndpointId endpointId, Delegate * delegate) { ChipLogProgress(Zcl, "Door Lock cluster initialized at endpoint #%u", endpointId); @@ -128,11 +106,48 @@ void DoorLockServer::InitServer(chip::EndpointId endpointId) } SetActuatorEnabled(endpointId, true); - for (auto & ep : mEndpointCtx) + auto * endpointContext = getContext(endpointId); + if (!endpointContext) + { + ChipLogError(Zcl, "Invalid endpoint %d for initializing lock server: no endpoint context available", endpointId); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + endpointContext->lockoutEndTimestamp = endpointContext->lockoutEndTimestamp.zero(); + endpointContext->wrongCodeEntryAttempts = 0; + endpointContext->delegate = delegate; + return CHIP_NO_ERROR; +} + +void DoorLockServer::ShutdownEndpoint(EndpointId endpointId) +{ + auto * endpointContext = getContext(endpointId); + if (!endpointContext) + { + ChipLogError(Zcl, "Invalid endpoint %d for shutting down lock server: no endpoint context available", endpointId); + return; + } + + endpointContext->delegate = nullptr; +} + +CHIP_ERROR DoorLockServer::SetDelegate(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::Delegate * delegate) +{ + if (!delegate) + { + ChipLogError(Zcl, "Trying to set a null DoorLock::Delegate on endpoint %d", endpointId); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + auto * endpointContext = getContext(endpointId); + if (!endpointContext) { - ep.lockoutEndTimestamp = ep.lockoutEndTimestamp.zero(); - ep.wrongCodeEntryAttempts = 0; + ChipLogError(Zcl, "Invalid endpoint %d for setting a delegate: no endpoint context available", endpointId); + return CHIP_ERROR_INVALID_ARGUMENT; } + + endpointContext->delegate = delegate; + return CHIP_NO_ERROR; } bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLockState) @@ -942,7 +957,18 @@ void DoorLockServer::clearCredentialCommandHandler( } // Remove all the credentials of the particular type. - auto credentialType = credential.Value().credentialType; + auto credentialType = credential.Value().credentialType; + + if (!credentialTypeSupported(commandPath.mEndpointId, credentialType)) + { + ChipLogProgress(Zcl, + "[ClearCredential] Credential type is not supported [endpointId=%d,credentialType=%u" + "]", + commandPath.mEndpointId, to_underlying(credentialType)); + commandObj->AddStatus(commandPath, Status::InvalidCommand); + return; + } + auto credentialIndex = credential.Value().credentialIndex; if (0xFFFE == credentialIndex) { @@ -2395,6 +2421,42 @@ DlStatus DoorLockServer::createCredential(chip::EndpointId endpointId, chip::Fab return DlStatus::kInvalidField; } + // For Aliro endpoint keys, there is a single shared count for the total + // count of evictable and non-evictable keys that can be stored. This needs + // to be enforced specially, because none of the other logic we have handles that. + if (credentialType == CredentialTypeEnum::kAliroEvictableEndpointKey || + credentialType == CredentialTypeEnum::kAliroNonEvictableEndpointKey) + { + Delegate * delegate = GetDelegate(endpointId); + if (delegate == nullptr) + { + ChipLogError(Zcl, "Door lock delegate is null, can't handle Aliro credentials"); + return DlStatus::kFailure; + } + + size_t maxEndpointKeys = delegate->GetNumberOfAliroEndpointKeysSupported(); + size_t evictableEndpointKeys, nonEvictableEndpointKeys; + + if (!countOccupiedCredentials(endpointId, CredentialTypeEnum::kAliroEvictableEndpointKey, evictableEndpointKeys)) + { + ChipLogError(Zcl, "Unable to count Aliro evictable endpoint keys."); + return DlStatus::kFailure; + } + + if (!countOccupiedCredentials(endpointId, CredentialTypeEnum::kAliroNonEvictableEndpointKey, nonEvictableEndpointKeys)) + { + ChipLogError(Zcl, "Unable to count Aliro non-evictable endpoint keys."); + return DlStatus::kFailure; + } + + if (evictableEndpointKeys + nonEvictableEndpointKeys >= maxEndpointKeys) + { + // We have no space for another credential here. + ChipLogError(Zcl, "Unable to create Aliro endpoint key credential; too many exist already [endpointId=%d]", endpointId); + return DlStatus::kResourceExhausted; + } + } + CredentialStruct credential{ credentialType, credentialIndex }; // appclusters, 5.2.4.40: if userIndex is not provided we should create new user DlStatus status = DlStatus::kSuccess; @@ -2432,6 +2494,42 @@ DlStatus DoorLockServer::createCredential(chip::EndpointId endpointId, chip::Fab return status; } +bool DoorLockServer::countOccupiedCredentials(chip::EndpointId endpointId, CredentialTypeEnum credentialType, + size_t & occupiedCount) +{ + uint16_t maxCredentialCount; + + if (!getMaxNumberOfCredentials(endpointId, credentialType, maxCredentialCount)) + { + return false; + } + + uint16_t startIndex = 1; + // Programming PIN is a special case -- it is unique and its index assumed to be 0. + if (CredentialTypeEnum::kProgrammingPIN == credentialType) + { + startIndex = 0; + maxCredentialCount--; + } + + occupiedCount = 0; + for (uint16_t credentialIndex = startIndex; credentialIndex <= maxCredentialCount; ++credentialIndex) + { + EmberAfPluginDoorLockCredentialInfo credential; + if (!emberAfPluginDoorLockGetCredential(endpointId, credentialIndex, credentialType, credential)) + { + return false; + } + + if (credential.status == DlCredentialStatus::kOccupied) + { + ++occupiedCount; + } + } + + return true; +} + DlStatus DoorLockServer::modifyProgrammingPIN(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId, uint16_t credentialIndex, CredentialTypeEnum credentialType, @@ -2908,28 +3006,6 @@ Status DoorLockServer::clearCredential(chip::EndpointId endpointId, chip::Fabric return Status::Failure; } - uint8_t maxCredentialsPerUser; - if (!GetNumberOfCredentialsSupportedPerUser(endpointId, maxCredentialsPerUser)) - { - ChipLogError(Zcl, - "[clearCredential] Unable to get the number of available credentials per user: internal error " - "[endpointId=%d,credentialType=%d,credentialIndex=%d]", - endpointId, to_underlying(credentialType), credentialIndex); - return Status::Failure; - } - - // Should never happen, only possible if the implementation of application is incorrect - if (relatedUser.credentials.size() > maxCredentialsPerUser) - { - ChipLogError(Zcl, - "[clearCredential] Unable to clear credential for related user - user has too many credentials associated" - "[endpointId=%d,credentialType=%u,credentialIndex=%d,modifier=%d,userIndex=%d,credentialsCount=%u]", - endpointId, to_underlying(credentialType), credentialIndex, modifier, relatedUserIndex, - static_cast(relatedUser.credentials.size())); - - return Status::Failure; - } - chip::Platform::ScopedMemoryBuffer newCredentials; if (!newCredentials.Alloc(relatedUser.credentials.size())) { @@ -3445,6 +3521,17 @@ EmberAfDoorLockEndpointContext * DoorLockServer::getContext(chip::EndpointId end return nullptr; } +Delegate * DoorLockServer::GetDelegate(EndpointId endpointId) +{ + auto * endpointContext = getContext(endpointId); + if (!endpointContext) + { + return nullptr; + } + + return endpointContext->delegate; +} + bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, LockOperationTypeEnum opType, RemoteLockOpHandler opHandler, const Optional & pinCode) diff --git a/src/app/clusters/door-lock-server/door-lock-server.h b/src/app/clusters/door-lock-server/door-lock-server.h index bf2798115c985c..81b18c60e687e8 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.h +++ b/src/app/clusters/door-lock-server/door-lock-server.h @@ -86,20 +86,9 @@ struct EmberAfDoorLockEndpointContext { chip::System::Clock::Timestamp lockoutEndTimestamp; int wrongCodeEntryAttempts; + chip::app::Clusters::DoorLock::Delegate * delegate = nullptr; }; -namespace chip { -namespace app { -namespace Clusters { -namespace DoorLock { - -void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); - -} // namespace DoorLock -} // namespace Clusters -} // namespace app -} // namespace chip - /** * @brief Door Lock Server Plugin class. */ @@ -112,7 +101,28 @@ class DoorLockServer : public chip::app::AttributeAccessInterface using Feature = chip::app::Clusters::DoorLock::Feature; using OnFabricRemovedCustomCallback = void (*)(chip::EndpointId endpointId, chip::FabricIndex fabricIndex); - void InitServer(chip::EndpointId endpointId); + /** + * Multiple InitEndpoint calls can happen for different endpoints. Calling + * InitEndpoint twice for the same endpoint requires a ShutdownEndpoint call + * for that endpoint in between. + * + * A DoorLock::Delegate is optional, but needs to be provided in either + * InitEndpoint or in a separate SetDelegate call for Aliro features, and + * possibly other new features, to work. + */ + CHIP_ERROR InitEndpoint(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::Delegate * delegate = nullptr); + + void ShutdownEndpoint(chip::EndpointId endpointId); + + // InitServer is a deprecated alias for InitEndpoint with no delegate. + void InitServer(chip::EndpointId endpointid); + + /** + * Delegate is not supposed to be null. Removing a delegate + * should only happen when shutting down the door lock cluster on the + * endpoint, via ShutdownEndpoint. + */ + CHIP_ERROR SetDelegate(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::Delegate * delegate); /** * Updates the LockState attribute with new value and sends LockOperation event. @@ -350,6 +360,12 @@ class DoorLockServer : public chip::app::AttributeAccessInterface const EmberAfPluginDoorLockCredentialInfo & existingCredential, const chip::ByteSpan & credentialData, Nullable userIndex, const Nullable & userStatus, Nullable userType, uint16_t & createdUserIndex); + /** + * countOccupiedCredentials counts the number of occupied credentials of the + * given type. Returns false on application-side errors (i.e. if the count + * cannot be determined). + */ + bool countOccupiedCredentials(chip::EndpointId endpointId, CredentialTypeEnum credentialType, size_t & occupiedCount); DlStatus modifyProgrammingPIN(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId, uint16_t credentialIndex, CredentialTypeEnum credentialType, const EmberAfPluginDoorLockCredentialInfo & existingCredential, @@ -488,6 +504,13 @@ class DoorLockServer : public chip::app::AttributeAccessInterface static void sendClusterResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, chip::Protocols::InteractionModel::ClusterStatusCode status); + /** + * Get the DoorLock::Delegate for the given endpoint, if any. Will return + * null if there is no door lock server initialized on that endpoint or if + * there is no delegate associated with the initialized server. + */ + chip::app::Clusters::DoorLock::Delegate * GetDelegate(chip::EndpointId endpointId); + /** * @brief Common handler for LockDoor, UnlockDoor, UnlockWithTimeout commands * diff --git a/src/app/clusters/time-synchronization-server/time-synchronization-server.h b/src/app/clusters/time-synchronization-server/time-synchronization-server.h index 2581c9712e7862..ecc9a68cc3fc12 100644 --- a/src/app/clusters/time-synchronization-server/time-synchronization-server.h +++ b/src/app/clusters/time-synchronization-server/time-synchronization-server.h @@ -124,9 +124,10 @@ class TimeSynchronizationServer : public FabricTable::Delegate void OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus) override; void OnDone(ReadClient * apReadClient) override; - CHIP_ERROR AttemptToGetTimeFromTrustedNode(); #endif + CHIP_ERROR AttemptToGetTimeFromTrustedNode(); + // Platform event handler functions void OnPlatformEventFn(const DeviceLayer::ChipDeviceEvent & event); diff --git a/src/app/codegen-data-model/CodegenDataModel.cpp b/src/app/codegen-data-model/CodegenDataModel.cpp index 0cc9b42aaa64f7..851f7c341ab127 100644 --- a/src/app/codegen-data-model/CodegenDataModel.cpp +++ b/src/app/codegen-data-model/CodegenDataModel.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -232,10 +233,19 @@ bool CodegenDataModel::EmberCommandListIterator::Exists(const CommandId * list, } CHIP_ERROR CodegenDataModel::Invoke(const InteractionModel::InvokeRequest & request, TLV::TLVReader & input_arguments, - InteractionModel::InvokeReply & reply) + CommandHandler * handler) { - // TODO: this needs an implementation - return CHIP_ERROR_NOT_IMPLEMENTED; + // TODO: CommandHandlerInterface support is currently + // residing in InteractionModelEngine itself. We may want to separate this out + // into its own registry, similar to attributes, so that IM is decoupled from actual storage of things. + // + // Open issue at https://github.com/project-chip/connectedhomeip/issues/34258 + + // Ember dispatching automatically uses `handler` to set an appropriate result or status + // This never fails (as handler error is encoded as needed). + DispatchSingleClusterCommand(request.path, input_arguments, handler); + + return CHIP_NO_ERROR; } EndpointId CodegenDataModel::FirstEndpoint() diff --git a/src/app/codegen-data-model/CodegenDataModel.h b/src/app/codegen-data-model/CodegenDataModel.h index b65f38b9155e73..123dcd72382291 100644 --- a/src/app/codegen-data-model/CodegenDataModel.h +++ b/src/app/codegen-data-model/CodegenDataModel.h @@ -71,7 +71,7 @@ class CodegenDataModel : public chip::app::InteractionModel::DataModel CHIP_ERROR ReadAttribute(const InteractionModel::ReadAttributeRequest & request, AttributeValueEncoder & encoder) override; CHIP_ERROR WriteAttribute(const InteractionModel::WriteAttributeRequest & request, AttributeValueDecoder & decoder) override; CHIP_ERROR Invoke(const InteractionModel::InvokeRequest & request, chip::TLV::TLVReader & input_arguments, - InteractionModel::InvokeReply & reply) override; + CommandHandler * handler) override; /// attribute tree iteration EndpointId FirstEndpoint() override; diff --git a/src/app/codegen-data-model/CodegenDataModel_Write.cpp b/src/app/codegen-data-model/CodegenDataModel_Write.cpp index 0805bfec6cbd18..999f35ea7836cf 100644 --- a/src/app/codegen-data-model/CodegenDataModel_Write.cpp +++ b/src/app/codegen-data-model/CodegenDataModel_Write.cpp @@ -166,8 +166,8 @@ CHIP_ERROR DecodeIntoEmberBuffer(AttributeValueDecoder & decoder, bool isNullabl // Nullable(0xFF) is not representable because 0xFF is the encoding of NULL in ember // as well as odd-sized integers (e.g. full 32-bit value like 0x11223344 cannot be written // to a 3-byte odd-sized integger). - VerifyOrReturnError(Traits::CanRepresentValue(isNullable, *workingValue), CHIP_ERROR_INVALID_ARGUMENT); - Traits::WorkingToStorage(*workingValue, storageValue); + VerifyOrReturnError(Traits::CanRepresentValue(isNullable, workingValue.Value()), CHIP_ERROR_INVALID_ARGUMENT); + Traits::WorkingToStorage(workingValue.Value(), storageValue); } VerifyOrReturnError(out.size() >= sizeof(storageValue), CHIP_ERROR_INVALID_ARGUMENT); diff --git a/src/app/codegen-data-model/tests/BUILD.gn b/src/app/codegen-data-model/tests/BUILD.gn index 3d265a96a66b29..3f88ac61c41766 100644 --- a/src/app/codegen-data-model/tests/BUILD.gn +++ b/src/app/codegen-data-model/tests/BUILD.gn @@ -24,6 +24,8 @@ source_set("ember_extra_files") { "${chip_root}/src/app/util/ember-io-storage.cpp", "AttributeReportIBEncodeDecode.cpp", "AttributeReportIBEncodeDecode.h", + "EmberInvokeOverride.cpp", + "EmberInvokeOverride.h", "EmberReadWriteOverride.cpp", "EmberReadWriteOverride.h", "InteractionModelTemporaryOverrides.cpp", diff --git a/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp b/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp new file mode 100644 index 00000000000000..552e0be3d966ff --- /dev/null +++ b/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "EmberInvokeOverride.h" + +#include + +namespace { + +chip::app::ConcreteCommandPath gLastDispatchPath; +uint32_t gDispatchCount = 0; + +} // namespace + +namespace chip { +namespace Test { + +app::ConcreteCommandPath GetLastDispatchPath() +{ + return gLastDispatchPath; +} + +uint32_t DispatchCount() +{ + return gDispatchCount; +} + +} // namespace Test +} // namespace chip + +namespace chip { +namespace app { + +void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, + CommandHandler * apCommandObj) +{ + gLastDispatchPath = aRequestCommandPath; + gDispatchCount++; +} + +} // namespace app +} // namespace chip diff --git a/src/app/codegen-data-model/tests/EmberInvokeOverride.h b/src/app/codegen-data-model/tests/EmberInvokeOverride.h new file mode 100644 index 00000000000000..d2f7b5c32fb1f8 --- /dev/null +++ b/src/app/codegen-data-model/tests/EmberInvokeOverride.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +namespace chip { +namespace Test { + +/// what was the last path on which DispatchSingleClusterCommand was called +app::ConcreteCommandPath GetLastDispatchPath(); + +/// How many times was DispatchSingleClusterCommand called +uint32_t DispatchCount(); + +} // namespace Test +} // namespace chip diff --git a/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp b/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp index a595acc81f3b5c..e771827adf18f6 100644 --- a/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp +++ b/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp @@ -74,12 +74,6 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr return CHIP_ERROR_NOT_IMPLEMENTED; } -void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, - CommandHandler * apCommandObj) -{ - // TODO: total hardcoded noop -} - } // namespace app } // namespace chip diff --git a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp b/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp index 2bf88a02bae6ef..796c845ebe7787 100644 --- a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp +++ b/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp @@ -14,9 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include + +#include "app/ConcreteCommandPath.h" #include #include +#include #include #include @@ -52,9 +59,6 @@ #include #include -#include -#include - using namespace chip; using namespace chip::Test; using namespace chip::app; @@ -69,6 +73,9 @@ constexpr NodeId kTestNodeId = 0xFFFF'1234'ABCD'4321; constexpr AttributeId kAttributeIdReadOnly = 0x3001; constexpr AttributeId kAttributeIdTimedWrite = 0x3002; +constexpr CommandId kMockCommandId1 = 0x1234; +constexpr CommandId kMockCommandId2 = 0x1122; + constexpr EndpointId kEndpointIdThatIsMissing = kMockEndpointMin - 1; constexpr AttributeId kReadOnlyAttributeId = 0x5001; @@ -2430,6 +2437,47 @@ TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceTest) TestEmberScalarNullWrite(); } +TEST(TestCodegenModelViaMocks, EmberInvokeTest) +{ + // Ember invoke is fully code-generated - there is a single function for Dispatch + // that will do a `switch` on the path elements and invoke a corresponding `emberAf*` + // callback. + // + // The only thing that can be validated is that this `DispatchSingleClusterCommand` + // is actually invoked. + + UseMockNodeConfig config(gTestNodeConfig); + chip::app::CodegenDataModel model; + + { + const ConcreteCommandPath kCommandPath(kMockEndpoint1, MockClusterId(1), kMockCommandId1); + const InvokeRequest kInvokeRequest{ .path = kCommandPath }; + chip::TLV::TLVReader tlvReader; + + const uint32_t kDispatchCountPre = chip::Test::DispatchCount(); + + // Using a handler set to nullptr as it is not used by the impl + ASSERT_EQ(model.Invoke(kInvokeRequest, tlvReader, /* handler = */ nullptr), CHIP_NO_ERROR); + + EXPECT_EQ(chip::Test::DispatchCount(), kDispatchCountPre + 1); // single dispatch + EXPECT_EQ(chip::Test::GetLastDispatchPath(), kCommandPath); // for the right path + } + + { + const ConcreteCommandPath kCommandPath(kMockEndpoint1, MockClusterId(1), kMockCommandId2); + const InvokeRequest kInvokeRequest{ .path = kCommandPath }; + chip::TLV::TLVReader tlvReader; + + const uint32_t kDispatchCountPre = chip::Test::DispatchCount(); + + // Using a handler set to nullpotr as it is not used by the impl + ASSERT_EQ(model.Invoke(kInvokeRequest, tlvReader, /* handler = */ nullptr), CHIP_NO_ERROR); + + EXPECT_EQ(chip::Test::DispatchCount(), kDispatchCountPre + 1); // single dispatch + EXPECT_EQ(chip::Test::GetLastDispatchPath(), kCommandPath); // for the right path + } +} + TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceReturningError) { UseMockNodeConfig config(gTestNodeConfig); diff --git a/src/app/data-model-interface/BUILD.gn b/src/app/data-model-interface/BUILD.gn index 65cde75612e2ba..abe66a68f342bd 100644 --- a/src/app/data-model-interface/BUILD.gn +++ b/src/app/data-model-interface/BUILD.gn @@ -20,7 +20,6 @@ source_set("data-model-interface") { "DataModel.h", "DataModelChangeListener.h", "EventsGenerator.h", - "InvokeResponder.h", "MetadataTypes.cpp", "MetadataTypes.h", "OperationTypes.h", @@ -29,6 +28,7 @@ source_set("data-model-interface") { public_deps = [ "${chip_root}/src/access:types", "${chip_root}/src/app:attribute-access", + "${chip_root}/src/app:command-handler-interface", "${chip_root}/src/app:events", "${chip_root}/src/app:paths", "${chip_root}/src/app/MessageDef", diff --git a/src/app/data-model-interface/DataModel.h b/src/app/data-model-interface/DataModel.h index d673b79aac72a9..bcf24c1aa9e7b2 100644 --- a/src/app/data-model-interface/DataModel.h +++ b/src/app/data-model-interface/DataModel.h @@ -21,9 +21,9 @@ #include #include +#include #include -#include #include #include @@ -99,25 +99,9 @@ class DataModel : public DataModelMetadataTree /// - `NeedsTimedInteraction` for writes that are not timed however are required to be so virtual CHIP_ERROR WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0; - /// `reply` is used to send back the reply. - /// - calling Reply() or ReplyAsync() will let the application control the reply - /// - returning a CHIP_NO_ERROR without reply/reply_async implies a Status::Success reply without data + /// `handler` is used to send back the reply. /// - returning a value other than CHIP_NO_ERROR implies an error reply (error and data are mutually exclusive) - /// - /// See InvokeReply/AutoCompleteInvokeResponder for details on how to send back replies and expected - /// error handling. If you need to know weather a response was successfully sent, use the underlying - /// `reply` object instead of returning an error code from Invoke. - /// - /// Return codes - /// CHIP_IM_GLOBAL_STATUS(code): - /// - error codes that are translatable to specific IM codes - /// - in particular, the following codes are interesting/expected - /// - `UnsupportedEndpoint` for invalid endpoint - /// - `UnsupportedCluster` for no such cluster on the endpoint - /// - `UnsupportedCommand` for no such command in the cluster - /// - `UnsupportedAccess` for permission errors (ACL or fabric scoped with invalid fabric) - /// - `NeedsTimedInteraction` if the invoke requires timed interaction support - virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, InvokeReply & reply) = 0; + virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, CommandHandler * handler) = 0; private: InteractionModelContext mContext = { nullptr }; diff --git a/src/app/data-model-interface/InvokeResponder.h b/src/app/data-model-interface/InvokeResponder.h deleted file mode 100644 index 9890c3bb6f6d7e..00000000000000 --- a/src/app/data-model-interface/InvokeResponder.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2024 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include - -namespace chip { -namespace app { -namespace InteractionModel { - -/// Handles encoding of an invoke response for a specific invoke request. -/// -/// This class handles a single request (i.e. a CommandDataIB within the -/// matter protocol) and is responsible for constructing its corresponding -/// response (i.e. a InvokeResponseIB within the matter protocol) -/// -/// Invoke responses MUST contain exactly ONE of: -/// - response data (accessed via `ResponseEncoder`) -/// - A status, which may be success or failure, both of which may -/// contain a cluster-specific error code. -/// -/// To encode a response, `Complete` MUST be called. -/// -/// `Complete` requirements -/// - Complete with InteractionModel::Status::Success will respond with data -/// some response data was written. -/// - Any other case (including success with cluster specific codes) implies -/// no response data and a status will be encoded instead -/// - this includes the case when some response data was written already. -/// In that case, the response data will be rolled back and only the status -/// will be encoded. -/// -/// Creating a response MAY be retried at most once, if and only if `Complete` -/// returns CHIP_ERROR_BUFFER_TOO_SMALL. Retry attempts MUST not exceed 1: -/// - FlushPendingResponses MUST be called to make as much buffer space as possible -/// available for encoding -/// - The response encoding (including `ResponseEncoder` usage and calling Complete) -/// MUST be retried once more. If the final Complete returns an error, the result -/// of the invoke will be an error status. -/// -class InvokeResponder -{ -public: - virtual ~InvokeResponder() = default; - - // Copying not allowed since underlying requirement is that on deletion of this - // object, a reply will be sent. - InvokeResponder(const InvokeResponder &) = delete; - InvokeResponder & operator=(const InvokeResponder &) = delete; - - /// Flush any pending replies before encoding the current reply. - /// - /// MAY be called at most once. - /// - /// This function is intended to provided the ability to retry sending a reply - /// if a reply encoding fails due to insufficient buffer. - /// - /// Call this if `Complete(...)` returns CHIP_ERROR_BUFFER_TOO_SMALL and try - /// again. If reply data is needed, the complete ResponseEncoder + Complete - /// call chain MUST be re-run. - virtual CHIP_ERROR FlushPendingResponses() = 0; - - /// Reply with a data payload. - /// - /// MUST be called at most once per reply. - /// Can be called a 2nd time after a `FlushPendingResponses()` call - /// - /// - responseCommandId must correspond with the data encoded in the returned encoder - /// - Complete(CHIP_NO_ERROR) MUST be called to flush the reply - /// - /// If encoder returns CHIP_ERROR_BUFFER_TOO_SMALL, FlushPendingResponses should be - /// used to attempt to free up buffer space then encoding should be tried again. - virtual DataModel::WrappedStructEncoder & ResponseEncoder(CommandId responseCommandId) = 0; - - /// Signal completing of the reply. - /// - /// MUST be called exactly once to signal a response is to be recorded to be sent. - /// The error code (and the data encoded by ResponseEncoder) may be buffered for - /// sending among other batched responses. - /// - /// If this returns CHIP_ERROR_BUFFER_TOO_SMALL, this can be called a 2nd time after - /// a FlushPendingResponses. - /// - /// Argument behavior: - /// - Commands can only be replied with ONE of the following (spec 8.9.4.4): - /// - command data (i.e. ResponseEncoder contents) - /// - A status (including success/error/cluster-specific-success-or-error ) - /// - As a result there are two possible paths: - /// - IF a Status::Success is given (WITHOUT cluster specific status), then - /// the data in ResponseEncoder is sent as a reply. If no data was sent, - /// a invoke `Status::Success` with no cluster specific data is sent - /// - OTHERWISE any previously encoded data via ResponseEncoder is discarded - /// and the given reply (success with cluster status or failure) is sent - /// as a reply to the invoke. - /// - /// - /// Returns success/failure state. One error code MUST be handled in particular: - /// - /// - CHIP_ERROR_BUFFER_TOO_SMALL will return IF AND ONLY IF the responder was unable - /// to fully serialize the given reply/error data. - /// - /// If such an error is returned, the caller MUST retry by calling FlushPendingResponses - /// first and then re-encoding the reply content (use ResponseEncoder if applicable and - /// call Complete again) - /// - /// - Any other error (i.e. different from CHIP_NO_ERROR) mean that the invoke response - /// will contain an error and such an error is considered permanent. - /// - virtual CHIP_ERROR Complete(StatusIB error) = 0; -}; - -/// Enforces that once acquired, Complete will be called on the underlying writer -class AutoCompleteInvokeResponder -{ -public: - // non-copyable: once you have a handle, keep it - AutoCompleteInvokeResponder(const AutoCompleteInvokeResponder &) = delete; - AutoCompleteInvokeResponder & operator=(const AutoCompleteInvokeResponder &) = delete; - - AutoCompleteInvokeResponder(InvokeResponder * writer) : mWriter(writer) {} - ~AutoCompleteInvokeResponder() - { - if (mCompleteState != CompleteState::kComplete) - { - mWriter->Complete(StatusIB{ Protocols::InteractionModel::Status::Failure }); - } - } - - /// Direct access to reply encoding. - /// - /// Use this only in conjunction with the other Raw* calls - DataModel::WrappedStructEncoder & RawResponseEncoder(CommandId replyCommandId) - { - return mWriter->ResponseEncoder(replyCommandId); - } - - /// Direct access to flushing replies - /// - /// Use this only in conjunction with the other Raw* calls - CHIP_ERROR RawFlushPendingReplies() - { - // allow a flush if we never called it (this may not be reasonable, however - // we accept an early flush) or if flush is expected - VerifyOrReturnError((mCompleteState == CompleteState::kNeverCalled) || (mCompleteState == CompleteState::kFlushExpected), - CHIP_ERROR_INCORRECT_STATE); - mCompleteState = CompleteState::kFlushed; - return mWriter->FlushPendingResponses(); - } - - /// Call "Complete" without the automatic retries. - /// - /// Use this in conjunction with the other Raw* calls - CHIP_ERROR RawComplete(StatusIB status) - { - VerifyOrReturnError((mCompleteState == CompleteState::kNeverCalled) || (mCompleteState == CompleteState::kFlushed), - CHIP_ERROR_INCORRECT_STATE); - CHIP_ERROR err = mWriter->Complete(status); - if ((err == CHIP_ERROR_BUFFER_TOO_SMALL) && (mCompleteState == CompleteState::kNeverCalled)) - { - mCompleteState = CompleteState::kFlushExpected; - } - else - { - mCompleteState = CompleteState::kComplete; - } - return err; - } - - /// Complete the given command. - /// - /// Automatically handles retries for sending. - /// Cannot be called after Raw* methods are used. - /// - /// Any error returned by this are final and not retriable - /// as a retry for CHIP_ERROR_BUFFER_TOO_SMALL is already built in. - CHIP_ERROR Complete(StatusIB status) - { - VerifyOrReturnError(mCompleteState == CompleteState::kNeverCalled, CHIP_ERROR_INCORRECT_STATE); - // this is a final complete, including retry handling - mCompleteState = CompleteState::kComplete; - CHIP_ERROR err = mWriter->Complete(status); - - if (err != CHIP_ERROR_BUFFER_TOO_SMALL) - { - return err; - } - - // retry once. Failure to flush is permanent. - ReturnErrorOnFailure(mWriter->FlushPendingResponses()); - return mWriter->Complete(status); - } - - /// Sends the specified data structure as a response - /// - /// This version of the send has built-in RETRY and handles - /// Flush/Complete automatically. - /// Cannot be called after Raw* methods are used. - /// - /// Any error returned by this are final and not retriable - /// as a retry for CHIP_ERROR_BUFFER_TOO_SMALL is already built in. - template - CHIP_ERROR Send(const ReplyData & data) - { - VerifyOrReturnError(mCompleteState == CompleteState::kNeverCalled, CHIP_ERROR_INCORRECT_STATE); - // this is a final complete, including retry handling - mCompleteState = CompleteState::kComplete; - CHIP_ERROR err = data.Encode(ResponseEncoder(ReplyData::GetCommandId())); - if (err != CHIP_ERROR_BUFFER_TOO_SMALL) - { - LogErrorOnFailure(err); - err = mWriter->Complete(StatusIB(err)); - } - if (err != CHIP_ERROR_BUFFER_TOO_SMALL) - { - return err; - } - - // retry once. Failure to flush is permanent. - ReturnErrorOnFailure(mWriter->FlushPendingResponses()); - err = data.Encode(ResponseEncoder(ReplyData::GetCommandId())); - - // If encoding fails, we will end up sending an error back to the other side - // the caller - LogErrorOnFailure(err); - if (err == CHIP_NO_ERROR) - { - err = mWriter->Complete(StatusIB(err)); - } - else - { - // Error in "complete" is not something we can really forward anymore since - // we already got an error in Encode ... just log this. - LogErrorOnFailure(mWriter->Complete(StatusIB(err))); - } - - return err; - } - -private: - // Contract says that complete may only be called twice: - // - initial complete - // - again after a `Flush` - // The states here expect we are in: - // - // +----------------------------Flush---------| - // | v - // NEVER --Complete--> F_EXPECTED --Flush--> FLUSHED --Complete--> COMPLETE - // | ^ - // +-------------(success or permanent error)-----------| - enum class CompleteState - { - kNeverCalled, - kFlushExpected, - kFlushed, - kComplete, - }; - - InvokeResponder * mWriter; - CompleteState mCompleteState = CompleteState::kNeverCalled; -}; - -enum ReplyAsyncFlags -{ - // Some commands that are expensive to process (e.g. crypto). - // Implementations may choose to send an ack on the message right away to - // avoid MRP retransmits. - kSlowCommandHandling = 0x0001, -}; - -class InvokeReply -{ -public: - virtual ~InvokeReply() = default; - - // reply with no data - CHIP_ERROR Reply(StatusIB status) { return this->Reply().Complete(status); } - - // Enqueue the content of the reply at this point in time (rather than Async sending it). - // - // Implementations will often batch several replies into one packet for batch commands, - // so it will be implementation-specific on when the actual reply packet is - // sent. - virtual AutoCompleteInvokeResponder Reply() = 0; - - // Reply "later" to the command. This allows async processing. A reply will be forced - // when the returned InvokeReply is destroyed. - // - // NOTE: Each InvokeReply is associated with a separate `CommandDataIB` within batch - // commands. When replying asynchronously, each InvokeReply will set the response - // data for the given commandpath/ref only. - // - // IF empty pointer is returned, insufficient memory to reply async is available and - // this should be handled (e.g. by returning an error to the handler/replying with - // an errorcode synchronously). - virtual std::unique_ptr ReplyAsync(BitFlags flags) = 0; -}; - -} // namespace InteractionModel -} // namespace app -} // namespace chip diff --git a/src/app/data-model-interface/tests/BUILD.gn b/src/app/data-model-interface/tests/BUILD.gn index f366ee718fc3a3..94faf695f687af 100644 --- a/src/app/data-model-interface/tests/BUILD.gn +++ b/src/app/data-model-interface/tests/BUILD.gn @@ -21,5 +21,8 @@ chip_test_suite("tests") { cflags = [ "-Wconversion" ] - public_deps = [ "${chip_root}/src/app/data-model-interface" ] + public_deps = [ + "${chip_root}/src/app/data-model-interface", + "${chip_root}/src/lib/core:string-builder-adapters", + ] } diff --git a/src/app/data-model-interface/tests/TestEventEmitting.cpp b/src/app/data-model-interface/tests/TestEventEmitting.cpp index 81a89f1603a04b..fe4e37e57b7dd0 100644 --- a/src/app/data-model-interface/tests/TestEventEmitting.cpp +++ b/src/app/data-model-interface/tests/TestEventEmitting.cpp @@ -19,9 +19,10 @@ #include #include #include +#include #include -#include +#include namespace { diff --git a/src/app/data-model/Nullable.h b/src/app/data-model/Nullable.h index f56e67ced19113..660c889e789518 100644 --- a/src/app/data-model/Nullable.h +++ b/src/app/data-model/Nullable.h @@ -45,8 +45,11 @@ struct Nullable : protected std::optional // all constructors of the base class within this derived class. // using std::optional::optional; - using std::optional::operator*; - using std::optional::operator->; + + // Do NOT pull in optional::operator* or optional::operator->, because that + // leads people to write code that looks like it should work, and compiles, + // but does not do the right things with TLV encoding and decoding, when + // nullable data model objects are involved. Nullable(NullOptionalType) : std::optional(std::nullopt) {} diff --git a/src/app/icd/server/tests/BUILD.gn b/src/app/icd/server/tests/BUILD.gn index e96954a97dde58..95ece1d28ae4df 100644 --- a/src/app/icd/server/tests/BUILD.gn +++ b/src/app/icd/server/tests/BUILD.gn @@ -31,6 +31,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/app/icd/server:manager", "${chip_root}/src/app/icd/server:monitoring-table", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/lib/support:testing", "${chip_root}/src/messaging/tests:helpers", diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp index 83d3b1fd9951c1..3672955bdf4b26 100644 --- a/src/app/icd/server/tests/TestICDManager.cpp +++ b/src/app/icd/server/tests/TestICDManager.cpp @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/src/app/icd/server/tests/TestICDMonitoringTable.cpp b/src/app/icd/server/tests/TestICDMonitoringTable.cpp index 423bc1506b36fb..177f8caba507e1 100644 --- a/src/app/icd/server/tests/TestICDMonitoringTable.cpp +++ b/src/app/icd/server/tests/TestICDMonitoringTable.cpp @@ -15,12 +15,14 @@ * limitations under the License. */ +#include + #include #include #include -#include #include #include +#include #include #include diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index a71d797651b418..5be815f0864c95 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -182,6 +182,10 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) mReportScheduler = initParams.reportScheduler; mTestEventTriggerDelegate = initParams.testEventTriggerDelegate; + if (mTestEventTriggerDelegate == nullptr) + { + ChipLogProgress(AppServer, "WARNING: mTestEventTriggerDelegate is null"); + } deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider(); if (deviceInfoprovider) @@ -359,7 +363,10 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) chip::app::InteractionModelEngine::GetInstance()); // Register Test Event Trigger Handler - mTestEventTriggerDelegate->AddHandler(&mICDManager); + if (mTestEventTriggerDelegate != nullptr) + { + mTestEventTriggerDelegate->AddHandler(&mICDManager); + } #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -612,7 +619,10 @@ void Server::Shutdown() Credentials::SetGroupDataProvider(nullptr); #if CHIP_CONFIG_ENABLE_ICD_SERVER // Remove Test Event Trigger Handler - mTestEventTriggerDelegate->RemoveHandler(&mICDManager); + if (mTestEventTriggerDelegate != nullptr) + { + mTestEventTriggerDelegate->RemoveHandler(&mICDManager); + } mICDManager.Shutdown(); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER mAttributePersister.Shutdown(); diff --git a/src/app/tests/TestAclEvent.cpp b/src/app/tests/TestAclEvent.cpp index c216e8d1f9565d..bbded462985012 100644 --- a/src/app/tests/TestAclEvent.cpp +++ b/src/app/tests/TestAclEvent.cpp @@ -18,7 +18,6 @@ #include -#include #include #include @@ -27,11 +26,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/src/app/tests/TestAttributePersistenceProvider.cpp b/src/app/tests/TestAttributePersistenceProvider.cpp index 7ae40b52402fe0..1b8c7ee3d3872c 100644 --- a/src/app/tests/TestAttributePersistenceProvider.cpp +++ b/src/app/tests/TestAttributePersistenceProvider.cpp @@ -59,7 +59,13 @@ TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalByteSpans) MutableByteSpan valueReadBack(getArray); err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack); EXPECT_EQ(err, CHIP_NO_ERROR); - EXPECT_TRUE(std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end())); + EXPECT_TRUE(valueReadBack.data_equal(value)); + + uint8_t getArrayThatIsLongerThanNeeded[10]; + MutableByteSpan valueReadBack2(getArrayThatIsLongerThanNeeded); + err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack2); + EXPECT_EQ(err, CHIP_NO_ERROR); + EXPECT_TRUE(valueReadBack2.data_equal(value)); // Finishing persistenceProvider.Shutdown(); @@ -320,6 +326,7 @@ TEST_F(TestAttributePersistenceProvider, TestBufferTooSmallErrors) err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBackByteSpan8); EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL); + // TODO: ReadScalarValue() does not take a buffer, so expecting CHIP_ERROR_BUFFER_TOO_SMALL is bad API // Fail to get value as uint8_t uint8_t valueReadBack8; err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack8); diff --git a/src/app/tests/TestBufferedReadCallback.cpp b/src/app/tests/TestBufferedReadCallback.cpp index c16983c9c5605f..f3afeb7715cee3 100644 --- a/src/app/tests/TestBufferedReadCallback.cpp +++ b/src/app/tests/TestBufferedReadCallback.cpp @@ -235,11 +235,11 @@ void DataSeriesValidator::OnAttributeData(const ConcreteDataAttributePath & aPat auto iter = value.begin(); - uint8_t index = 0; + uint32_t index = 0; while (iter.Next() && index < expectedListLength) { auto & iterValue = iter.GetValue(); - EXPECT_EQ(iterValue, (index)); + EXPECT_EQ(iterValue, (index % 256)); index++; } diff --git a/src/app/tests/TestFailSafeContext.cpp b/src/app/tests/TestFailSafeContext.cpp index fa13990d4f7947..8d164fad2d42db 100644 --- a/src/app/tests/TestFailSafeContext.cpp +++ b/src/app/tests/TestFailSafeContext.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/src/app/tests/TestReportingEngine.cpp b/src/app/tests/TestReportingEngine.cpp index 341428fb7118d9..f0d3b0cc60d935 100644 --- a/src/app/tests/TestReportingEngine.cpp +++ b/src/app/tests/TestReportingEngine.cpp @@ -24,6 +24,8 @@ #include +#include + #include #include #include @@ -31,13 +33,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include 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 04fbb6fb6f309b..61d39b3b0173ea 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -18,6 +18,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml new file mode 100644 index 00000000000000..7228b8f47a20ab --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + General + Commissioner Control + 0x0751 + COMMISSIONER_CONTROL_CLUSTER + true + true + Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. + + + + + SupportedDeviceCategories + + + + + This command is sent by a client to request approval for a future CommissionNode call. + + + + + + + + + This command is sent by a client to request that the server begins commissioning a previously approved request. + + + + + + + + + + When received within the timeout specified by CommissionNode, the client SHALL open a commissioning window on to the node which the client called RequestCommissioningApproval to have commissioned. + + + + + + + + + This event SHALL be sent by the server following a RequestCommissioningApproval command which the server responded to with SUCCESS. + + + + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index a220de465f3686..c6b39c837a1e00 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -33,6 +33,7 @@ "channel-cluster.xml", "clusters-extensions.xml", "color-control-cluster.xml", + "commissioner-control-cluster.xml", "concentration-measurement-cluster.xml", "content-launch-cluster.xml", "content-app-observer-cluster.xml", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 7c8b05d39fd708..18afa7eacc2f8a 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -32,6 +32,7 @@ "channel-cluster.xml", "clusters-extensions.xml", "color-control-cluster.xml", + "commissioner-control-cluster.xml", "concentration-measurement-cluster.xml", "content-launch-cluster.xml", "content-app-observer-cluster.xml", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 4c7757224b1a7d..dc324968991adc 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -23,6 +23,7 @@ "CHANNEL_CLUSTER": [], "CLIENT_MONITORING_CLUSTER": [], "COLOR_CONTROL_CLUSTER": [], + "COMMISSIONER_CONTROL_CLUSTER": [], "COMMISSIONING_CLUSTER": [], "CONTENT_LAUNCHER_CLUSTER": [], "CONTENT_CONTROL_CLUSTER": [], @@ -168,6 +169,7 @@ ], "CHANNEL_CLUSTER": ["channel-server"], "COLOR_CONTROL_CLUSTER": ["color-control-server"], + "COMMISSIONER_CONTROL_CLUSTER": ["commissioner-control-server"], "COMMISSIONING_CLUSTER": [], "CONTENT_LAUNCHER_CLUSTER": ["content-launch-server"], "CONTENT_CONTROL_CLUSTER": ["content-control-server"], diff --git a/src/ble/tests/BUILD.gn b/src/ble/tests/BUILD.gn index ac897ab40a9c27..cfc5b5cb67be25 100644 --- a/src/ble/tests/BUILD.gn +++ b/src/ble/tests/BUILD.gn @@ -31,6 +31,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/ble", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", ] } diff --git a/src/ble/tests/TestBleErrorStr.cpp b/src/ble/tests/TestBleErrorStr.cpp index 6868532823d950..7e3f0f51d5bfc4 100644 --- a/src/ble/tests/TestBleErrorStr.cpp +++ b/src/ble/tests/TestBleErrorStr.cpp @@ -28,13 +28,13 @@ #include #include +#include + #include #define _CHIP_BLE_BLE_H #include -#include - using namespace chip; // Test input data. diff --git a/src/ble/tests/TestBleLayer.cpp b/src/ble/tests/TestBleLayer.cpp index 5377e4465f66c5..29c8c472198221 100644 --- a/src/ble/tests/TestBleLayer.cpp +++ b/src/ble/tests/TestBleLayer.cpp @@ -21,9 +21,10 @@ #include #include -#include +#include #include +#include #include #include #include diff --git a/src/ble/tests/TestBleUUID.cpp b/src/ble/tests/TestBleUUID.cpp index 445535594fae4b..e4284001f138dd 100644 --- a/src/ble/tests/TestBleUUID.cpp +++ b/src/ble/tests/TestBleUUID.cpp @@ -27,7 +27,7 @@ #define _CHIP_BLE_BLE_H #include -#include +#include using namespace chip; using namespace chip::Ble; diff --git a/src/ble/tests/TestBtpEngine.cpp b/src/ble/tests/TestBtpEngine.cpp index 2b8fb1ff84b562..e565ac2a30de91 100644 --- a/src/ble/tests/TestBtpEngine.cpp +++ b/src/ble/tests/TestBtpEngine.cpp @@ -20,6 +20,9 @@ #include #include +#include + +#include #include #include @@ -27,8 +30,6 @@ #include #include -#include - using namespace chip; using namespace chip::Ble; diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index bba383df6a93b6..8459f1887c746b 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9195,6 +9195,57 @@ provisional cluster ContentAppObserver = 1296 { command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; } +/** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ +provisional cluster CommissionerControl = 1873 { + revision 1; + + bitmap SupportedDeviceCategoryBitmap : bitmap32 { + kFabricSynchronization = 0x1; + } + + fabric_sensitive info event access(read: manage) CommissioningRequestResult = 0 { + int64u requestId = 0; + node_id clientNodeId = 1; + enum8 statusCode = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: manage) SupportedDeviceCategoryBitmap supportedDeviceCategories = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RequestCommissioningApprovalRequest { + int64u requestId = 0; + vendor_id vendorId = 1; + int16u productId = 2; + optional char_string<64> label = 3; + } + + request struct CommissionNodeRequest { + int64u requestId = 0; + int16u responseTimeoutSeconds = 1; + optional octet_string ipAddress = 2; + optional int16u port = 3; + } + + response struct ReverseOpenCommissioningWindow = 2 { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + /** This command is sent by a client to request approval for a future CommissionNode call. */ + command access(invoke: manage) RequestCommissioningApproval(RequestCommissioningApprovalRequest): DefaultSuccess = 0; + /** This command is sent by a client to request that the server begins commissioning a previously approved request. */ + command access(invoke: manage) CommissionNode(CommissionNodeRequest): ReverseOpenCommissioningWindow = 1; +} + /** Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster.. */ deprecated cluster ElectricalMeasurement = 2820 { revision 3; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 15ef0629b5daca..0e027a3c0c0647 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -60158,6 +60158,332 @@ public void onSuccess(byte[] tlv) { } } + public static class CommissionerControlCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1873L; + + private static final long SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID = 0L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + 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 CommissionerControlCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestId, Integer vendorId, Integer productId, Optional label) { + requestCommissioningApproval(callback, requestId, vendorId, productId, label, 0); + } + + public void requestCommissioningApproval(DefaultClusterCallback callback, Long requestId, Integer vendorId, Integer productId, Optional label, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long requestIdFieldID = 0L; + BaseTLVType requestIdtlvValue = new UIntType(requestId); + elements.add(new StructElement(requestIdFieldID, requestIdtlvValue)); + + final long vendorIdFieldID = 1L; + BaseTLVType vendorIdtlvValue = new UIntType(vendorId); + elements.add(new StructElement(vendorIdFieldID, vendorIdtlvValue)); + + final long productIdFieldID = 2L; + BaseTLVType productIdtlvValue = new UIntType(productId); + elements.add(new StructElement(productIdFieldID, productIdtlvValue)); + + final long labelFieldID = 3L; + BaseTLVType labeltlvValue = label.map((nonOptionallabel) -> new StringType(nonOptionallabel)).orElse(new EmptyType()); + elements.add(new StructElement(labelFieldID, labeltlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestId, Integer responseTimeoutSeconds, Optional ipAddress, Optional port) { + commissionNode(callback, requestId, responseTimeoutSeconds, ipAddress, port, 0); + } + + public void commissionNode(ReverseOpenCommissioningWindowCallback callback, Long requestId, Integer responseTimeoutSeconds, Optional ipAddress, Optional port, int timedInvokeTimeoutMs) { + final long commandId = 1L; + + ArrayList elements = new ArrayList<>(); + final long requestIdFieldID = 0L; + BaseTLVType requestIdtlvValue = new UIntType(requestId); + elements.add(new StructElement(requestIdFieldID, requestIdtlvValue)); + + final long responseTimeoutSecondsFieldID = 1L; + BaseTLVType responseTimeoutSecondstlvValue = new UIntType(responseTimeoutSeconds); + elements.add(new StructElement(responseTimeoutSecondsFieldID, responseTimeoutSecondstlvValue)); + + final long ipAddressFieldID = 2L; + BaseTLVType ipAddresstlvValue = ipAddress.map((nonOptionalipAddress) -> new ByteArrayType(nonOptionalipAddress)).orElse(new EmptyType()); + elements.add(new StructElement(ipAddressFieldID, ipAddresstlvValue)); + + final long portFieldID = 3L; + BaseTLVType porttlvValue = port.map((nonOptionalport) -> new UIntType(nonOptionalport)).orElse(new EmptyType()); + elements.add(new StructElement(portFieldID, porttlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long commissioningTimeoutFieldID = 0L; + Integer commissioningTimeout = null; + final long PAKEPasscodeVerifierFieldID = 1L; + byte[] PAKEPasscodeVerifier = null; + final long discriminatorFieldID = 2L; + Integer discriminator = null; + final long iterationsFieldID = 3L; + Long iterations = null; + final long saltFieldID = 4L; + byte[] salt = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == commissioningTimeoutFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + commissioningTimeout = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == PAKEPasscodeVerifierFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + PAKEPasscodeVerifier = castingValue.value(byte[].class); + } + } else if (element.contextTagNum() == discriminatorFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + discriminator = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == iterationsFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + iterations = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == saltFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { + ByteArrayType castingValue = element.value(ByteArrayType.class); + salt = castingValue.value(byte[].class); + } + } + } + callback.onSuccess(commissioningTimeout, PAKEPasscodeVerifier, discriminator, iterations, salt); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface ReverseOpenCommissioningWindowCallback extends BaseClusterCallback { + void onSuccess(Integer commissioningTimeout, byte[] PAKEPasscodeVerifier, Integer discriminator, Long iterations, byte[] salt); + } + + 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 readSupportedDeviceCategoriesAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID, true); + } + + public void subscribeSupportedDeviceCategoriesAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_DEVICE_CATEGORIES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + 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 ElectricalMeasurementCluster extends BaseChipCluster { public static final long CLUSTER_ID = 2820L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index 5cdcb6843ec864..d256c91c32d9ed 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -5976,6 +5976,97 @@ public String toString() { return output.toString(); } } +public static class CommissionerControlClusterCommissioningRequestResultEvent { + public Long requestId; + public Long clientNodeId; + public Integer statusCode; + public Integer fabricIndex; + private static final long REQUEST_ID_ID = 0L; + private static final long CLIENT_NODE_ID_ID = 1L; + private static final long STATUS_CODE_ID = 2L; + private static final long FABRIC_INDEX_ID = 254L; + + public CommissionerControlClusterCommissioningRequestResultEvent( + Long requestId, + Long clientNodeId, + Integer statusCode, + Integer fabricIndex + ) { + this.requestId = requestId; + this.clientNodeId = clientNodeId; + this.statusCode = statusCode; + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(REQUEST_ID_ID, new UIntType(requestId))); + values.add(new StructElement(CLIENT_NODE_ID_ID, new UIntType(clientNodeId))); + values.add(new StructElement(STATUS_CODE_ID, new UIntType(statusCode))); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static CommissionerControlClusterCommissioningRequestResultEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long requestId = null; + Long clientNodeId = null; + Integer statusCode = null; + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == REQUEST_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + requestId = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == CLIENT_NODE_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + clientNodeId = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == STATUS_CODE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + statusCode = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == FABRIC_INDEX_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + fabricIndex = castingValue.value(Integer.class); + } + } + } + return new CommissionerControlClusterCommissioningRequestResultEvent( + requestId, + clientNodeId, + statusCode, + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("CommissionerControlClusterCommissioningRequestResultEvent {\n"); + output.append("\trequestId: "); + output.append(requestId); + output.append("\n"); + output.append("\tclientNodeId: "); + output.append(clientNodeId); + output.append("\n"); + output.append("\tstatusCode: "); + output.append(statusCode); + output.append("\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class UnitTestingClusterTestEventEvent { public Integer arg1; public Integer arg2; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 596b91f1920db5..698ee556bb324b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -385,6 +385,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == ContentAppObserver.ID) { return new ContentAppObserver(); } + if (clusterId == CommissionerControl.ID) { + return new CommissionerControl(); + } if (clusterId == ElectricalMeasurement.ID) { return new ElectricalMeasurement(); } @@ -17038,6 +17041,144 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class CommissionerControl implements BaseCluster { + public static final long ID = 1873L; + public long getID() { + return ID; + } + + public enum Attribute { + SupportedDeviceCategories(0L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event { + CommissioningRequestResult(0L),; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + RequestCommissioningApproval(0L), + CommissionNode(1L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum RequestCommissioningApprovalCommandField {RequestId(0),VendorId(1),ProductId(2),Label(3),; + private final int id; + RequestCommissioningApprovalCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static RequestCommissioningApprovalCommandField value(int id) throws NoSuchFieldError { + for (RequestCommissioningApprovalCommandField field : RequestCommissioningApprovalCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum CommissionNodeCommandField {RequestId(0),ResponseTimeoutSeconds(1),IpAddress(2),Port(3),; + private final int id; + CommissionNodeCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static CommissionNodeCommandField value(int id) throws NoSuchFieldError { + for (CommissionNodeCommandField field : CommissionNodeCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class ElectricalMeasurement implements BaseCluster { public static final long ID = 2820L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index dfe72ba2f8a7d9..06b24ad59e09af 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -19939,6 +19939,120 @@ public void onError(Exception ex) { } } + + public static class DelegatedCommissionerControlClusterReverseOpenCommissioningWindowCallback implements ChipClusters.CommissionerControlCluster.ReverseOpenCommissioningWindowCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer commissioningTimeout, byte[] PAKEPasscodeVerifier, Integer discriminator, Long iterations, byte[] salt) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo commissioningTimeoutResponseValue = new CommandResponseInfo("commissioningTimeout", "Integer"); + responseValues.put(commissioningTimeoutResponseValue, commissioningTimeout); + CommandResponseInfo PAKEPasscodeVerifierResponseValue = new CommandResponseInfo("PAKEPasscodeVerifier", "byte[]"); + responseValues.put(PAKEPasscodeVerifierResponseValue, PAKEPasscodeVerifier); + CommandResponseInfo discriminatorResponseValue = new CommandResponseInfo("discriminator", "Integer"); + responseValues.put(discriminatorResponseValue, discriminator); + CommandResponseInfo iterationsResponseValue = new CommandResponseInfo("iterations", "Long"); + responseValues.put(iterationsResponseValue, iterations); + CommandResponseInfo saltResponseValue = new CommandResponseInfo("salt", "byte[]"); + responseValues.put(saltResponseValue, salt); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedCommissionerControlClusterGeneratedCommandListAttributeCallback implements ChipClusters.CommissionerControlCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedCommissionerControlClusterAcceptedCommandListAttributeCallback implements ChipClusters.CommissionerControlCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedCommissionerControlClusterEventListAttributeCallback implements ChipClusters.CommissionerControlCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedCommissionerControlClusterAttributeListAttributeCallback implements ChipClusters.CommissionerControlCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedElectricalMeasurementClusterGeneratedCommandListAttributeCallback implements ChipClusters.ElectricalMeasurementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -22040,6 +22154,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.ContentAppObserverCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("contentAppObserver", contentAppObserverClusterInfo); + ClusterInfo commissionerControlClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.CommissionerControlCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("commissionerControl", commissionerControlClusterInfo); + ClusterInfo electricalMeasurementClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.ElectricalMeasurementCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("electricalMeasurement", electricalMeasurementClusterInfo); @@ -22179,6 +22297,7 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("contentAppObserver", contentAppObserverClusterInteractionInfoMap); + Map commissionerControlClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map commissionerControlrequestCommissioningApprovalCommandParams = new LinkedHashMap(); + + CommandParameterInfo commissionerControlrequestCommissioningApprovalrequestIdCommandParameterInfo = new CommandParameterInfo("requestId", Long.class, Long.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("requestId",commissionerControlrequestCommissioningApprovalrequestIdCommandParameterInfo); + + CommandParameterInfo commissionerControlrequestCommissioningApprovalvendorIdCommandParameterInfo = new CommandParameterInfo("vendorId", Integer.class, Integer.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("vendorId",commissionerControlrequestCommissioningApprovalvendorIdCommandParameterInfo); + + CommandParameterInfo commissionerControlrequestCommissioningApprovalproductIdCommandParameterInfo = new CommandParameterInfo("productId", Integer.class, Integer.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("productId",commissionerControlrequestCommissioningApprovalproductIdCommandParameterInfo); + + CommandParameterInfo commissionerControlrequestCommissioningApprovallabelCommandParameterInfo = new CommandParameterInfo("label", Optional.class, String.class); + commissionerControlrequestCommissioningApprovalCommandParams.put("label",commissionerControlrequestCommissioningApprovallabelCommandParameterInfo); + InteractionInfo commissionerControlrequestCommissioningApprovalInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster) + .requestCommissioningApproval((DefaultClusterCallback) callback + , (Long) + commandArguments.get("requestId") + , (Integer) + commandArguments.get("vendorId") + , (Integer) + commandArguments.get("productId") + , (Optional) + commandArguments.get("label") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + commissionerControlrequestCommissioningApprovalCommandParams + ); + commissionerControlClusterInteractionInfoMap.put("requestCommissioningApproval", commissionerControlrequestCommissioningApprovalInteractionInfo); + + Map commissionerControlcommissionNodeCommandParams = new LinkedHashMap(); + + CommandParameterInfo commissionerControlcommissionNoderequestIdCommandParameterInfo = new CommandParameterInfo("requestId", Long.class, Long.class); + commissionerControlcommissionNodeCommandParams.put("requestId",commissionerControlcommissionNoderequestIdCommandParameterInfo); + + CommandParameterInfo commissionerControlcommissionNoderesponseTimeoutSecondsCommandParameterInfo = new CommandParameterInfo("responseTimeoutSeconds", Integer.class, Integer.class); + commissionerControlcommissionNodeCommandParams.put("responseTimeoutSeconds",commissionerControlcommissionNoderesponseTimeoutSecondsCommandParameterInfo); + + CommandParameterInfo commissionerControlcommissionNodeipAddressCommandParameterInfo = new CommandParameterInfo("ipAddress", Optional.class, byte[].class); + commissionerControlcommissionNodeCommandParams.put("ipAddress",commissionerControlcommissionNodeipAddressCommandParameterInfo); + + CommandParameterInfo commissionerControlcommissionNodeportCommandParameterInfo = new CommandParameterInfo("port", Optional.class, Integer.class); + commissionerControlcommissionNodeCommandParams.put("port",commissionerControlcommissionNodeportCommandParameterInfo); + InteractionInfo commissionerControlcommissionNodeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster) + .commissionNode((ChipClusters.CommissionerControlCluster.ReverseOpenCommissioningWindowCallback) callback + , (Long) + commandArguments.get("requestId") + + , (Integer) + commandArguments.get("responseTimeoutSeconds") + + , (Optional) + commandArguments.get("ipAddress") + + , (Optional) + commandArguments.get("port") + + ); + }, + () -> new DelegatedCommissionerControlClusterReverseOpenCommissioningWindowCallback(), + commissionerControlcommissionNodeCommandParams + ); + commissionerControlClusterInteractionInfoMap.put("commissionNode", commissionerControlcommissionNodeInteractionInfo); + + commandMap.put("commissionerControl", commissionerControlClusterInteractionInfoMap); + Map electricalMeasurementClusterInteractionInfoMap = new LinkedHashMap<>(); Map electricalMeasurementgetProfileInfoCommandCommandParams = new LinkedHashMap(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 25549f9f6a6b6a..a15dca9774da6b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -18475,6 +18475,87 @@ private static Map readContentAppObserverInteractionInf return result; } + private static Map readCommissionerControlInteractionInfo() { + Map result = new LinkedHashMap<>();Map readCommissionerControlSupportedDeviceCategoriesCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlSupportedDeviceCategoriesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readSupportedDeviceCategoriesAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readCommissionerControlSupportedDeviceCategoriesCommandParams + ); + result.put("readSupportedDeviceCategoriesAttribute", readCommissionerControlSupportedDeviceCategoriesAttributeInteractionInfo); + Map readCommissionerControlGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.CommissionerControlCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterGeneratedCommandListAttributeCallback(), + readCommissionerControlGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readCommissionerControlGeneratedCommandListAttributeInteractionInfo); + Map readCommissionerControlAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.CommissionerControlCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterAcceptedCommandListAttributeCallback(), + readCommissionerControlAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readCommissionerControlAcceptedCommandListAttributeInteractionInfo); + Map readCommissionerControlEventListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readEventListAttribute( + (ChipClusters.CommissionerControlCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterEventListAttributeCallback(), + readCommissionerControlEventListCommandParams + ); + result.put("readEventListAttribute", readCommissionerControlEventListAttributeInteractionInfo); + Map readCommissionerControlAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readAttributeListAttribute( + (ChipClusters.CommissionerControlCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedCommissionerControlClusterAttributeListAttributeCallback(), + readCommissionerControlAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readCommissionerControlAttributeListAttributeInteractionInfo); + Map readCommissionerControlFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readCommissionerControlFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readCommissionerControlFeatureMapAttributeInteractionInfo); + Map readCommissionerControlClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readCommissionerControlClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.CommissionerControlCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readCommissionerControlClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readCommissionerControlClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readElectricalMeasurementInteractionInfo() { Map result = new LinkedHashMap<>();Map readElectricalMeasurementMeasurementTypeCommandParams = new LinkedHashMap(); InteractionInfo readElectricalMeasurementMeasurementTypeAttributeInteractionInfo = new InteractionInfo( @@ -21188,6 +21269,7 @@ public Map> getReadAttributeMap() { put("accountLogin", readAccountLoginInteractionInfo()); put("contentControl", readContentControlInteractionInfo()); put("contentAppObserver", readContentAppObserverInteractionInfo()); + put("commissionerControl", readCommissionerControlInteractionInfo()); put("electricalMeasurement", readElectricalMeasurementInteractionInfo()); put("unitTesting", readUnitTestingInteractionInfo()); put("faultInjection", readFaultInjectionInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index fff901e8da037a..635f5bf1b48830 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -3718,6 +3718,8 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("contentControl", writeContentControlInteractionInfo); Map writeContentAppObserverInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("contentAppObserver", writeContentAppObserverInteractionInfo); + Map writeCommissionerControlInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("commissionerControl", writeCommissionerControlInteractionInfo); Map writeElectricalMeasurementInteractionInfo = new LinkedHashMap<>(); Map writeElectricalMeasurementAverageRmsVoltageMeasurementPeriodCommandParams = new LinkedHashMap(); CommandParameterInfo electricalMeasurementaverageRmsVoltageMeasurementPeriodCommandParameterInfo = diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt new file mode 100644 index 00000000000000..2a7a8d3c5b8ffb --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package chip.devicecontroller.cluster.eventstructs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class CommissionerControlClusterCommissioningRequestResultEvent( + val requestId: ULong, + val clientNodeId: ULong, + val statusCode: UInt, + val fabricIndex: UInt, +) { + override fun toString(): String = buildString { + append("CommissionerControlClusterCommissioningRequestResultEvent {\n") + append("\trequestId : $requestId\n") + append("\tclientNodeId : $clientNodeId\n") + append("\tstatusCode : $statusCode\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_REQUEST_ID), requestId) + put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeId) + put(ContextSpecificTag(TAG_STATUS_CODE), statusCode) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_REQUEST_ID = 0 + private const val TAG_CLIENT_NODE_ID = 1 + private const val TAG_STATUS_CODE = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): CommissionerControlClusterCommissioningRequestResultEvent { + tlvReader.enterStructure(tlvTag) + val requestId = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) + val clientNodeId = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) + val statusCode = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS_CODE)) + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return CommissionerControlClusterCommissioningRequestResultEvent( + requestId, + clientNodeId, + statusCode, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index a62e5ec79a241e..631feb9442d4c0 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -163,6 +163,7 @@ eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BooleanStateConfigurationClusterSensorFaultEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterReachableChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterStartUpEvent.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterResumedEvent.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt new file mode 100644 index 00000000000000..6a3d288d56e49c --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt @@ -0,0 +1,874 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class CommissionerControlCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class ReverseOpenCommissioningWindow( + val commissioningTimeout: UShort, + val PAKEPasscodeVerifier: ByteArray, + val discriminator: UShort, + val iterations: UInt, + val salt: ByteArray, + ) + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun requestCommissioningApproval( + requestId: ULong, + vendorId: UShort, + productId: UShort, + label: String?, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_REQUEST_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestId) + + val TAG_VENDOR_ID_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_VENDOR_ID_REQ), vendorId) + + val TAG_PRODUCT_ID_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_PRODUCT_ID_REQ), productId) + + val TAG_LABEL_REQ: Int = 3 + label?.let { tlvWriter.put(ContextSpecificTag(TAG_LABEL_REQ), label) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun commissionNode( + requestId: ULong, + responseTimeoutSeconds: UShort, + ipAddress: ByteArray?, + port: UShort?, + timedInvokeTimeout: Duration? = null, + ): ReverseOpenCommissioningWindow { + val commandId: UInt = 1u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_REQUEST_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_REQUEST_ID_REQ), requestId) + + val TAG_RESPONSE_TIMEOUT_SECONDS_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RESPONSE_TIMEOUT_SECONDS_REQ), responseTimeoutSeconds) + + val TAG_IP_ADDRESS_REQ: Int = 2 + ipAddress?.let { tlvWriter.put(ContextSpecificTag(TAG_IP_ADDRESS_REQ), ipAddress) } + + val TAG_PORT_REQ: Int = 3 + port?.let { tlvWriter.put(ContextSpecificTag(TAG_PORT_REQ), port) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMISSIONING_TIMEOUT: Int = 0 + var commissioningTimeout_decoded: UShort? = null + + val TAG_P_A_K_E_PASSCODE_VERIFIER: Int = 1 + var PAKEPasscodeVerifier_decoded: ByteArray? = null + + val TAG_DISCRIMINATOR: Int = 2 + var discriminator_decoded: UShort? = null + + val TAG_ITERATIONS: Int = 3 + var iterations_decoded: UInt? = null + + val TAG_SALT: Int = 4 + var salt_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMISSIONING_TIMEOUT)) { + commissioningTimeout_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_P_A_K_E_PASSCODE_VERIFIER)) { + PAKEPasscodeVerifier_decoded = tlvReader.getByteArray(tag) + } + + if (tag == ContextSpecificTag(TAG_DISCRIMINATOR)) { + discriminator_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_ITERATIONS)) { + iterations_decoded = tlvReader.getUInt(tag) + } + + if (tag == ContextSpecificTag(TAG_SALT)) { + salt_decoded = tlvReader.getByteArray(tag) + } else { + tlvReader.skipElement() + } + } + + if (commissioningTimeout_decoded == null) { + throw IllegalStateException("commissioningTimeout not found in TLV") + } + + if (PAKEPasscodeVerifier_decoded == null) { + throw IllegalStateException("PAKEPasscodeVerifier not found in TLV") + } + + if (discriminator_decoded == null) { + throw IllegalStateException("discriminator not found in TLV") + } + + if (iterations_decoded == null) { + throw IllegalStateException("iterations not found in TLV") + } + + if (salt_decoded == null) { + throw IllegalStateException("salt not found in TLV") + } + + tlvReader.exitContainer() + + return ReverseOpenCommissioningWindow( + commissioningTimeout_decoded, + PAKEPasscodeVerifier_decoded, + discriminator_decoded, + iterations_decoded, + salt_decoded, + ) + } + + suspend fun readSupportedDeviceCategoriesAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supporteddevicecategories attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeSupportedDeviceCategoriesAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Supporteddevicecategories attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(CommissionerControlCluster::class.java.name) + const val CLUSTER_ID: UInt = 1873u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt new file mode 100644 index 00000000000000..c8947776269773 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package matter.controller.cluster.eventstructs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class CommissionerControlClusterCommissioningRequestResultEvent( + val requestId: ULong, + val clientNodeId: ULong, + val statusCode: UByte, + val fabricIndex: UByte, +) { + override fun toString(): String = buildString { + append("CommissionerControlClusterCommissioningRequestResultEvent {\n") + append("\trequestId : $requestId\n") + append("\tclientNodeId : $clientNodeId\n") + append("\tstatusCode : $statusCode\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_REQUEST_ID), requestId) + put(ContextSpecificTag(TAG_CLIENT_NODE_ID), clientNodeId) + put(ContextSpecificTag(TAG_STATUS_CODE), statusCode) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_REQUEST_ID = 0 + private const val TAG_CLIENT_NODE_ID = 1 + private const val TAG_STATUS_CODE = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): CommissionerControlClusterCommissioningRequestResultEvent { + tlvReader.enterStructure(tlvTag) + val requestId = tlvReader.getULong(ContextSpecificTag(TAG_REQUEST_ID)) + val clientNodeId = tlvReader.getULong(ContextSpecificTag(TAG_CLIENT_NODE_ID)) + val statusCode = tlvReader.getUByte(ContextSpecificTag(TAG_STATUS_CODE)) + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return CommissionerControlClusterCommissioningRequestResultEvent( + requestId, + clientNodeId, + statusCode, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index ceeea1ba075f34..2bebadb13c36ce 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -163,6 +163,7 @@ matter_eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BooleanStateConfigurationClusterSensorFaultEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterReachableChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterStartUpEvent.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/DeviceEnergyManagementClusterResumedEvent.kt", @@ -254,6 +255,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/CarbonMonoxideConcentrationMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ColorControlCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/CommissionerControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentLauncherCluster.kt", diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index dc02a801afbcd8..01a75bcc216288 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -42400,6 +42400,164 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::CommissionerControl::Id: { + using namespace app::Clusters::CommissionerControl; + switch (aPath.mAttributeId) + { + case Attributes::SupportedDeviceCategories::Id: { + using TypeInfo = Attributes::SupportedDeviceCategories::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::ElectricalMeasurement::Id: { using namespace app::Clusters::ElectricalMeasurement; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 301efce5eb3634..a61c38ca0edcc6 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -7968,6 +7968,80 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::CommissionerControl::Id: { + using namespace app::Clusters::CommissionerControl; + switch (aPath.mEventId) + { + case Events::CommissioningRequestResult::Id: { + Events::CommissioningRequestResult::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value_requestId; + std::string value_requestIdClassName = "java/lang/Long"; + std::string value_requestIdCtorSignature = "(J)V"; + jlong jnivalue_requestId = static_cast(cppValue.requestId); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_requestIdClassName.c_str(), value_requestIdCtorSignature.c_str(), jnivalue_requestId, value_requestId); + + jobject value_clientNodeId; + std::string value_clientNodeIdClassName = "java/lang/Long"; + std::string value_clientNodeIdCtorSignature = "(J)V"; + jlong jnivalue_clientNodeId = static_cast(cppValue.clientNodeId); + chip::JniReferences::GetInstance().CreateBoxedObject(value_clientNodeIdClassName.c_str(), + value_clientNodeIdCtorSignature.c_str(), + jnivalue_clientNodeId, value_clientNodeId); + + jobject value_statusCode; + std::string value_statusCodeClassName = "java/lang/Integer"; + std::string value_statusCodeCtorSignature = "(I)V"; + jint jnivalue_statusCode = static_cast(cppValue.statusCode); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_statusCodeClassName.c_str(), value_statusCodeCtorSignature.c_str(), jnivalue_statusCode, value_statusCode); + + jobject value_fabricIndex; + std::string value_fabricIndexClassName = "java/lang/Integer"; + std::string value_fabricIndexCtorSignature = "(I)V"; + jint jnivalue_fabricIndex = static_cast(cppValue.fabricIndex); + chip::JniReferences::GetInstance().CreateBoxedObject(value_fabricIndexClassName.c_str(), + value_fabricIndexCtorSignature.c_str(), jnivalue_fabricIndex, + value_fabricIndex); + + jclass commissioningRequestResultStructClass; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipEventStructs$CommissionerControlClusterCommissioningRequestResultEvent", + commissioningRequestResultStructClass); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "Could not find class ChipEventStructs$CommissionerControlClusterCommissioningRequestResultEvent"); + return nullptr; + } + + jmethodID commissioningRequestResultStructCtor; + err = chip::JniReferences::GetInstance().FindMethod( + env, commissioningRequestResultStructClass, "", + "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;)V", &commissioningRequestResultStructCtor); + if (err != CHIP_NO_ERROR || commissioningRequestResultStructCtor == nullptr) + { + ChipLogError( + Zcl, "Could not find ChipEventStructs$CommissionerControlClusterCommissioningRequestResultEvent constructor"); + return nullptr; + } + + jobject value = env->NewObject(commissioningRequestResultStructClass, commissioningRequestResultStructCtor, + value_requestId, value_clientNodeId, value_statusCode, value_fabricIndex); + + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::ElectricalMeasurement::Id: { using namespace app::Clusters::ElectricalMeasurement; switch (aPath.mEventId) diff --git a/src/controller/python/chip/CertificateAuthority.py b/src/controller/python/chip/CertificateAuthority.py index bce921cfb785bf..0fbfcfdbdb93b8 100644 --- a/src/controller/python/chip/CertificateAuthority.py +++ b/src/controller/python/chip/CertificateAuthority.py @@ -28,6 +28,8 @@ from chip.native import PyChipError from chip.storage import PersistentStorage +LOGGER = logging.getLogger(__name__) + class CertificateAuthority: ''' This represents an operational Root Certificate Authority (CA) with a root key key pair with associated @@ -64,7 +66,7 @@ def __init__(self, chipStack: ChipStack.ChipStack, caIndex: int, persistentStora persistentStorage: An optional reference to a PersistentStorage object. If one is provided, it will pick that over the default PersistentStorage object retrieved from the chipStack. ''' - self.logger().warning(f"New CertificateAuthority at index {caIndex}") + LOGGER.info(f"New CertificateAuthority at index {caIndex}") self._chipStack = chipStack self._caIndex = caIndex @@ -105,7 +107,7 @@ def LoadFabricAdminsFromStorage(self): if (not (self._isActive)): raise RuntimeError("Object isn't active") - self.logger().warning("Loading fabric admins from storage...") + LOGGER.info("Loading fabric admins from storage...") caList = self._persistentStorage.GetReplKey(key='caList') if (str(self._caIndex) not in caList): @@ -244,7 +246,7 @@ def LoadAuthoritiesFromStorage(self): if (not (self._isActive)): raise RuntimeError("Object is not active") - self.logger().warning("Loading certificate authorities from storage...") + LOGGER.info("Loading certificate authorities from storage...") # # Persist details to storage (read modify write). diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index efadd7fd4f87c7..d9c9196015c96d 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -61,6 +61,8 @@ # Defined in $CHIP_ROOT/src/lib/core/CHIPError.h CHIP_ERROR_TIMEOUT: int = 50 +LOGGER = logging.getLogger(__name__) + _DevicePairingDelegate_OnPairingCompleteFunct = CFUNCTYPE(None, PyChipError) _DeviceUnpairingCompleteFunct = CFUNCTYPE(None, c_uint64, PyChipError) _DevicePairingDelegate_OnCommissioningCompleteFunct = CFUNCTYPE( @@ -401,9 +403,9 @@ def __init__(self, name: str = ''): def _set_dev_ctrl(self, devCtrl, pairingDelegate): def HandleCommissioningComplete(nodeId: int, err: PyChipError): if err.is_success: - logging.info("Commissioning complete") + LOGGER.info("Commissioning complete") else: - logging.warning("Failed to commission: {}".format(err)) + LOGGER.warning("Failed to commission: {}".format(err)) self._dmLib.pychip_DeviceController_SetIcdRegistrationParameters(False, None) @@ -411,7 +413,7 @@ def HandleCommissioningComplete(nodeId: int, err: PyChipError): err = self._dmLib.pychip_GetCompletionError() if self._commissioning_context.future is None: - logging.exception("HandleCommissioningComplete called unexpectedly") + LOGGER.exception("HandleCommissioningComplete called unexpectedly") return if err.is_success: @@ -425,14 +427,14 @@ def HandleFabricCheck(nodeId): def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: str, setupQRCode: str, err: PyChipError) -> None: if err.is_success: - logging.info("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) + LOGGER.info("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) commissioningParameters = CommissioningParameters( setupPinCode=setupPinCode, setupManualCode=setupManualCode.decode(), setupQRCode=setupQRCode.decode()) else: - logging.warning("Failed to open commissioning window: {}".format(err)) + LOGGER.warning("Failed to open commissioning window: {}".format(err)) if self._open_window_context.future is None: - logging.exception("HandleOpenWindowComplete called unexpectedly") + LOGGER.exception("HandleOpenWindowComplete called unexpectedly") return if err.is_success: @@ -442,12 +444,12 @@ def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: st def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): if err.is_success: - logging.info("Succesfully unpaired device with nodeid {}".format(nodeid)) + LOGGER.info("Succesfully unpaired device with nodeid {}".format(nodeid)) else: - logging.warning("Failed to unpair device: {}".format(err)) + LOGGER.warning("Failed to unpair device: {}".format(err)) if self._unpair_device_context.future is None: - logging.exception("HandleUnpairDeviceComplete called unexpectedly") + LOGGER.exception("HandleUnpairDeviceComplete called unexpectedly") return if err.is_success: @@ -457,9 +459,9 @@ def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): def HandlePASEEstablishmentComplete(err: PyChipError): if not err.is_success: - logging.warning("Failed to establish secure session to device: {}".format(err)) + LOGGER.warning("Failed to establish secure session to device: {}".format(err)) else: - logging.info("Established secure session with Device") + LOGGER.info("Established secure session with Device") if self._commissioning_context.future is not None: # During Commissioning, HandlePASEEstablishmentComplete will also be called. @@ -469,7 +471,7 @@ def HandlePASEEstablishmentComplete(err: PyChipError): return if self._pase_establishment_context.future is None: - logging.exception("HandlePASEEstablishmentComplete called unexpectedly") + LOGGER.exception("HandlePASEEstablishmentComplete called unexpectedly") return if err.is_success: @@ -926,7 +928,7 @@ def GetConnectedDeviceSync(self, nodeid, allowPASE=True, timeoutMs: int = None): res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: - logging.info('Using PASE connection') + LOGGER.info('Using PASE connection') return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) class DeviceAvailableClosure(): @@ -992,7 +994,7 @@ async def GetConnectedDevice(self, nodeid, allowPASE: bool = True, timeoutMs: in res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: - logging.info('Using PASE connection') + LOGGER.info('Using PASE connection') return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) eventLoop = asyncio.get_running_loop() @@ -1348,7 +1350,6 @@ def _parseEventPathTuple(self, pathTuple: typing.Union[ # Wildcard return ClusterAttribute.EventPath() elif not isinstance(pathTuple, tuple): - logging.debug(type(pathTuple)) if isinstance(pathTuple, int): return ClusterAttribute.EventPath(EndpointId=pathTuple) elif issubclass(pathTuple, ClusterObjects.Cluster): @@ -2115,7 +2116,7 @@ async def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int def NOCChainCallback(self, nocChain): if self._issue_node_chain_context.future is None: - logging.exception("NOCChainCallback while not expecting a callback") + LOGGER.exception("NOCChainCallback while not expecting a callback") return self._issue_node_chain_context.future.set_result(nocChain) return diff --git a/src/controller/python/chip/FabricAdmin.py b/src/controller/python/chip/FabricAdmin.py index fc20327e628bcc..d9e2e35cb2bcc4 100644 --- a/src/controller/python/chip/FabricAdmin.py +++ b/src/controller/python/chip/FabricAdmin.py @@ -25,6 +25,8 @@ from chip.crypto import p256keypair from chip.native import GetLibraryHandle +LOGGER = logging.getLogger(__name__) + class FabricAdmin: ''' Administers a fabric associated with a unique FabricID under a given CertificateAuthority @@ -34,10 +36,6 @@ class FabricAdmin: def _Handle(cls): return GetLibraryHandle() - @classmethod - def logger(cls): - return logging.getLogger('FabricAdmin') - def __init__(self, certificateAuthority: CertificateAuthority.CertificateAuthority, vendorId: int, fabricId: int = 1): ''' Initializes the object. @@ -60,7 +58,7 @@ def __init__(self, certificateAuthority: CertificateAuthority.CertificateAuthori self._fabricId = fabricId self._certificateAuthority = certificateAuthority - self.logger().warning(f"New FabricAdmin: FabricId: 0x{self._fabricId:016X}, VendorId = 0x{self.vendorId:04X}") + LOGGER.info(f"New FabricAdmin: FabricId: 0x{self._fabricId:016X}, VendorId = 0x{self.vendorId:04X}") self._isActive = True self._activeControllers = [] @@ -94,7 +92,7 @@ def NewController(self, nodeId: int = None, paaTrustStorePath: str = "", if (nodeId in nodeIdList): raise RuntimeError(f"Provided NodeId {nodeId} collides with an existing controller instance!") - self.logger().warning( + LOGGER.info( f"Allocating new controller with CaIndex: {self._certificateAuthority.caIndex}, " f"FabricId: 0x{self._fabricId:016X}, NodeId: 0x{nodeId:016X}, CatTags: {catTags}") diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py index 36f5a794f9e73e..ba4c5d4b72dbe6 100644 --- a/src/controller/python/chip/clusters/Attribute.py +++ b/src/controller/python/chip/clusters/Attribute.py @@ -40,6 +40,8 @@ from .ClusterObjects import Cluster, ClusterAttributeDescriptor, ClusterEvent +LOGGER = logging.getLogger(__name__) + @unique class EventTimestampType(Enum): @@ -569,7 +571,7 @@ def subscriptionId(self) -> int: def Shutdown(self): if (self._isDone): - print("Subscription was already terminated previously!") + LOGGER.warning("Subscription 0x%08x was already terminated previously!", self.subscriptionId) return handle = chip.native.GetLibraryHandle() @@ -675,7 +677,7 @@ def handleAttributeData(self, path: AttributePath, dataVersion: int, status: int self._changedPathSet.add(path) except Exception as ex: - logging.exception(ex) + LOGGER.exception(ex) def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, status: int): try: @@ -693,12 +695,12 @@ def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, sta try: eventValue = eventType.FromTLV(data) except Exception as ex: - logging.error( + LOGGER.error( f"Error convering TLV to Cluster Object for path: Endpoint = {path.EndpointId}/" f"Cluster = {path.ClusterId}/Event = {path.EventId}") - logging.error( + LOGGER.error( f"Failed Cluster Object: {str(eventType)}") - logging.error(ex) + LOGGER.error(ex) eventValue = ValueDecodeFailure( tlvData, ex) @@ -715,7 +717,7 @@ def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, sta eventResult, self._subscription_handler) except Exception as ex: - logging.exception(ex) + LOGGER.exception(ex) def handleError(self, chipError: PyChipError): self._resultError = chipError @@ -726,7 +728,6 @@ def _handleSubscriptionEstablished(self, subscriptionId): self, subscriptionId, self._devCtrl) self._future.set_result(self._subscription_handler) else: - logging.info("Re-subscription succeeded!") if self._subscription_handler._onResubscriptionSucceededCb is not None: if (self._subscription_handler._onResubscriptionSucceededCb_isAsync): self._event_loop.create_task( @@ -761,7 +762,7 @@ def _handleReportEnd(self): attribute_path = TypedAttributePath(Path=change) except (KeyError, ValueError) as err: # path could not be resolved into a TypedAttributePath - logging.getLogger(__name__).exception(err) + LOGGER.exception(err) continue self._subscription_handler.OnAttributeChangeCb( attribute_path, self._subscription_handler) @@ -816,7 +817,7 @@ def handleResponse(self, path: AttributePath, status: int): imStatus = chip.interaction_model.Status(status) self._resultData.append(AttributeWriteResult(Path=path, Status=imStatus)) except ValueError as ex: - logging.exception(ex) + LOGGER.exception(ex) def handleError(self, chipError: PyChipError): self._resultError = chipError diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 67bb0bc48134be..5d0d1ffd38fd3c 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -13199,6 +13199,76 @@ class ChipClusters: }, }, } + _COMMISSIONER_CONTROL_CLUSTER_INFO = { + "clusterName": "CommissionerControl", + "clusterId": 0x00000751, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "RequestCommissioningApproval", + "args": { + "requestId": "int", + "vendorId": "int", + "productId": "int", + "label": "str", + }, + }, + 0x00000001: { + "commandId": 0x00000001, + "commandName": "CommissionNode", + "args": { + "requestId": "int", + "responseTimeoutSeconds": "int", + "ipAddress": "bytes", + "port": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "SupportedDeviceCategories", + "attributeId": 0x00000000, + "type": "int", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _ELECTRICAL_MEASUREMENT_CLUSTER_INFO = { "clusterName": "ElectricalMeasurement", "clusterId": 0x00000B04, @@ -15110,6 +15180,7 @@ class ChipClusters: 0x0000050E: _ACCOUNT_LOGIN_CLUSTER_INFO, 0x0000050F: _CONTENT_CONTROL_CLUSTER_INFO, 0x00000510: _CONTENT_APP_OBSERVER_CLUSTER_INFO, + 0x00000751: _COMMISSIONER_CONTROL_CLUSTER_INFO, 0x00000B04: _ELECTRICAL_MEASUREMENT_CLUSTER_INFO, 0xFFF1FC05: _UNIT_TESTING_CLUSTER_INFO, 0xFFF1FC06: _FAULT_INJECTION_CLUSTER_INFO, @@ -15236,6 +15307,7 @@ class ChipClusters: "AccountLogin": _ACCOUNT_LOGIN_CLUSTER_INFO, "ContentControl": _CONTENT_CONTROL_CLUSTER_INFO, "ContentAppObserver": _CONTENT_APP_OBSERVER_CLUSTER_INFO, + "CommissionerControl": _COMMISSIONER_CONTROL_CLUSTER_INFO, "ElectricalMeasurement": _ELECTRICAL_MEASUREMENT_CLUSTER_INFO, "UnitTesting": _UNIT_TESTING_CLUSTER_INFO, "FaultInjection": _FAULT_INJECTION_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 2f207dc8da4126..a580620fdf4158 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -46370,6 +46370,244 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class CommissionerControl(Cluster): + id: typing.ClassVar[int] = 0x00000751 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="supportedDeviceCategories", Tag=0x00000000, Type=uint), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + supportedDeviceCategories: 'uint' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Bitmaps: + class SupportedDeviceCategoryBitmap(IntFlag): + kFabricSynchronization = 0x1 + + class Commands: + @dataclass + class RequestCommissioningApproval(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000751 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="vendorId", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="productId", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="label", Tag=3, Type=typing.Optional[str]), + ]) + + requestId: 'uint' = 0 + vendorId: 'uint' = 0 + productId: 'uint' = 0 + label: 'typing.Optional[str]' = None + + @dataclass + class CommissionNode(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000751 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'ReverseOpenCommissioningWindow' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="responseTimeoutSeconds", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="ipAddress", Tag=2, Type=typing.Optional[bytes]), + ClusterObjectFieldDescriptor(Label="port", Tag=3, Type=typing.Optional[uint]), + ]) + + requestId: 'uint' = 0 + responseTimeoutSeconds: 'uint' = 0 + ipAddress: 'typing.Optional[bytes]' = None + port: 'typing.Optional[uint]' = None + + @dataclass + class ReverseOpenCommissioningWindow(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000751 + command_id: typing.ClassVar[int] = 0x00000002 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="commissioningTimeout", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="PAKEPasscodeVerifier", Tag=1, Type=bytes), + ClusterObjectFieldDescriptor(Label="discriminator", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="iterations", Tag=3, Type=uint), + ClusterObjectFieldDescriptor(Label="salt", Tag=4, Type=bytes), + ]) + + commissioningTimeout: 'uint' = 0 + PAKEPasscodeVerifier: 'bytes' = b"" + discriminator: 'uint' = 0 + iterations: 'uint' = 0 + salt: 'bytes' = b"" + + class Attributes: + @dataclass + class SupportedDeviceCategories(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + class Events: + @dataclass + class CommissioningRequestResult(ClusterEvent): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000751 + + @ChipUtility.classproperty + def event_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="requestId", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="clientNodeId", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="statusCode", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + requestId: 'uint' = 0 + clientNodeId: 'uint' = 0 + statusCode: 'uint' = 0 + fabricIndex: 'uint' = 0 + + @dataclass class ElectricalMeasurement(Cluster): id: typing.ClassVar[int] = 0x00000B04 diff --git a/src/controller/python/chip/storage/__init__.py b/src/controller/python/chip/storage/__init__.py index 385efca6be1c8c..20432dcd01870b 100644 --- a/src/controller/python/chip/storage/__init__.py +++ b/src/controller/python/chip/storage/__init__.py @@ -29,6 +29,8 @@ import chip.exceptions import chip.native +LOGGER = logging.getLogger(__name__) + _SyncSetKeyValueCbFunct = CFUNCTYPE( None, py_object, c_char_p, POINTER(c_char), c_uint16) _SyncGetKeyValueCbFunct = CFUNCTYPE( @@ -91,9 +93,6 @@ class PersistentStorage: Object must be resident before the Matter stack starts up and last past its shutdown. ''' - @classmethod - def logger(cls): - return logging.getLogger('PersistentStorage') def __init__(self, path: str = None, jsonData: Dict = None): ''' Initializes the object with either a path to a JSON file that contains the configuration OR @@ -109,9 +108,9 @@ def __init__(self, path: str = None, jsonData: Dict = None): raise ValueError("Can't provide both a valid path and jsonData") if (path is not None): - self.logger().warn(f"Initializing persistent storage from file: {path}") + LOGGER.info(f"Initializing persistent storage from file: {path}") else: - self.logger().warn("Initializing persistent storage from dict") + LOGGER.info("Initializing persistent storage from dict") self._handle = chip.native.GetLibraryHandle() self._isActive = True @@ -125,24 +124,24 @@ def __init__(self, path: str = None, jsonData: Dict = None): self._file.seek(0) if (size != 0): - self.logger().warn(f"Loading configuration from {path}...") + LOGGER.info(f"Loading configuration from {path}...") self._jsonData = json.load(self._file) else: self._jsonData = {} except Exception as ex: - logging.error(ex) - logging.critical(f"Could not load configuration from {path} - resetting configuration...") + LOGGER.error(ex) + LOGGER.critical(f"Could not load configuration from {path} - resetting configuration...") self._jsonData = {} else: self._jsonData = jsonData if ('sdk-config' not in self._jsonData): - logging.warn("No valid SDK configuration present - clearing out configuration") + LOGGER.warn("No valid SDK configuration present - clearing out configuration") self._jsonData['sdk-config'] = {} if ('repl-config' not in self._jsonData): - logging.warn("No valid REPL configuration present - clearing out configuration") + LOGGER.warn("No valid REPL configuration present - clearing out configuration") self._jsonData['repl-config'] = {} # Clear out the file so that calling 'Commit' will re-open the file at that time in write mode. @@ -166,7 +165,6 @@ def Commit(self): ''' Commits the cached JSON configuration to file (if one was provided in the constructor). Otherwise, this is a no-op. ''' - self.logger().info("Committing...") if (self._path is None): return @@ -175,9 +173,8 @@ def Commit(self): try: self._file = open(self._path, 'w') except Exception as ex: - logging.warn( - f"Could not open {self._path} for writing configuration. Error:") - logging.warn(ex) + LOGGER.error( + f"Could not open {self._path} for writing configuration. Error: {ex}") return self._file.seek(0) @@ -188,7 +185,7 @@ def Commit(self): def SetReplKey(self, key: str, value): ''' Set a REPL key to a specific value. Creates the key if one doesn't exist already. ''' - self.logger().info(f"SetReplKey: {key} = {value}") + LOGGER.debug(f"SetReplKey: {key} = {value}") if (key is None or key == ''): raise ValueError("Invalid Key") @@ -212,7 +209,7 @@ def GetReplKey(self, key: str): def SetSdkKey(self, key: str, value: bytes): ''' Set an SDK key to a specific value. Creates the key if one doesn't exist already. ''' - self.logger().info(f"SetSdkKey: {key} = {value}") + LOGGER.debug(f"SetSdkKey: {key} = {value}") if (key is None or key == ''): raise ValueError("Invalid Key") @@ -236,7 +233,7 @@ def GetSdkKey(self, key: str): def DeleteSdkKey(self, key: str): ''' Deletes an SDK key if one exists. ''' - self.logger().info(f"DeleteSdkKey: {key}") + LOGGER.debug(f"DeleteSdkKey: {key}") del (self._jsonData['sdk-config'][key]) self.Commit() diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index 27f8e98964d7b9..79ad383ef3f2f0 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -19,6 +19,18 @@ # Commissioning test. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --log-level INFO -t 3600 --disable-test ClusterObjectTests.TestTimedRequestTimeout --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + import asyncio import os diff --git a/src/controller/tests/BUILD.gn b/src/controller/tests/BUILD.gn index 1e2b15d7778beb..7b3dff0e27d441 100644 --- a/src/controller/tests/BUILD.gn +++ b/src/controller/tests/BUILD.gn @@ -39,6 +39,7 @@ chip_test_suite("tests") { "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/app/tests:helpers", "${chip_root}/src/controller", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/messaging/tests:helpers", "${chip_root}/src/transport/raw/tests:helpers", diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index 6d9ef65db11e97..e113bc38add8f1 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include #include +#include #include using namespace chip; diff --git a/src/controller/tests/TestEventCaching.cpp b/src/controller/tests/TestEventCaching.cpp index e31e3ed358b6f0..cbff4b743ea0dd 100644 --- a/src/controller/tests/TestEventCaching.cpp +++ b/src/controller/tests/TestEventCaching.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ClusterStateCache.h" @@ -32,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/src/controller/tests/TestEventChunking.cpp b/src/controller/tests/TestEventChunking.cpp index fc71da8662596d..0aa0b9d0a5714f 100644 --- a/src/controller/tests/TestEventChunking.cpp +++ b/src/controller/tests/TestEventChunking.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/src/controller/tests/TestEventNumberCaching.cpp b/src/controller/tests/TestEventNumberCaching.cpp index 344d8a26ed2653..9b580f759e06c1 100644 --- a/src/controller/tests/TestEventNumberCaching.cpp +++ b/src/controller/tests/TestEventNumberCaching.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/src/controller/tests/TestReadChunking.cpp b/src/controller/tests/TestReadChunking.cpp index b64e715e013660..b00d0bed75ebcf 100644 --- a/src/controller/tests/TestReadChunking.cpp +++ b/src/controller/tests/TestReadChunking.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index e1a266c5f99d66..8c895008dfd67e 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include using namespace chip; diff --git a/src/controller/tests/TestWriteChunking.cpp b/src/controller/tests/TestWriteChunking.cpp index dcb4b36044c985..9ffad2c602835c 100644 --- a/src/controller/tests/TestWriteChunking.cpp +++ b/src/controller/tests/TestWriteChunking.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ConcreteAttributePath.h" @@ -35,6 +37,7 @@ #include #include #include +#include #include using namespace chip; diff --git a/src/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 2ec6db203bcaa0..99cb1e8e20d322 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -69,6 +69,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials", "${chip_root}/src/credentials:default_attestation_verifier", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:testing", ] } diff --git a/src/credentials/tests/TestCertificationDeclaration.cpp b/src/credentials/tests/TestCertificationDeclaration.cpp index 45c8d5027bac93..ecc1372dd43bf9 100644 --- a/src/credentials/tests/TestCertificationDeclaration.cpp +++ b/src/credentials/tests/TestCertificationDeclaration.cpp @@ -25,14 +25,15 @@ #include #include +#include + #include #include #include #include +#include #include -#include - using namespace chip; using namespace chip::ASN1; using namespace chip::Crypto; diff --git a/src/credentials/tests/TestChipCert.cpp b/src/credentials/tests/TestChipCert.cpp index 9a6e50b58561fb..94d53c7ae1619e 100644 --- a/src/credentials/tests/TestChipCert.cpp +++ b/src/credentials/tests/TestChipCert.cpp @@ -24,18 +24,19 @@ * */ +#include + #include #include #include #include #include #include +#include #include #include #include -#include - #include "CHIPCert_error_test_vectors.h" #include "CHIPCert_test_vectors.h" diff --git a/src/credentials/tests/TestCommissionerDUTVectors.cpp b/src/credentials/tests/TestCommissionerDUTVectors.cpp index c512776cc89a69..a3c0ac7f85f885 100644 --- a/src/credentials/tests/TestCommissionerDUTVectors.cpp +++ b/src/credentials/tests/TestCommissionerDUTVectors.cpp @@ -15,6 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + #include #include @@ -27,11 +30,10 @@ #include #include +#include #include #include -#include - #include #include #include diff --git a/src/credentials/tests/TestDeviceAttestationConstruction.cpp b/src/credentials/tests/TestDeviceAttestationConstruction.cpp index e624b257a32ef2..8fc949ca29c999 100644 --- a/src/credentials/tests/TestDeviceAttestationConstruction.cpp +++ b/src/credentials/tests/TestDeviceAttestationConstruction.cpp @@ -15,17 +15,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include + #include #include #include +#include #include #include #include #include -#include -#include - using namespace chip; using namespace chip::Credentials; diff --git a/src/credentials/tests/TestDeviceAttestationCredentials.cpp b/src/credentials/tests/TestDeviceAttestationCredentials.cpp index bf203c8321adf1..85a5d4edfa58a2 100644 --- a/src/credentials/tests/TestDeviceAttestationCredentials.cpp +++ b/src/credentials/tests/TestDeviceAttestationCredentials.cpp @@ -15,6 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + #include #include @@ -28,11 +31,10 @@ #include #include +#include #include #include -#include - #include "CHIPAttCert_test_vectors.h" using namespace chip; diff --git a/src/credentials/tests/TestFabricTable.cpp b/src/credentials/tests/TestFabricTable.cpp index 75f51c1c2cb402..c5b78fc13e5b4f 100644 --- a/src/credentials/tests/TestFabricTable.cpp +++ b/src/credentials/tests/TestFabricTable.cpp @@ -22,9 +22,12 @@ */ #include -#include +#include + +#include #include +#include #include @@ -41,8 +44,6 @@ #include -#include - using namespace chip; using namespace chip::Credentials; diff --git a/src/credentials/tests/TestGroupDataProvider.cpp b/src/credentials/tests/TestGroupDataProvider.cpp index 7718cf0ee49cd2..6628b939012624 100644 --- a/src/credentials/tests/TestGroupDataProvider.cpp +++ b/src/credentials/tests/TestGroupDataProvider.cpp @@ -16,17 +16,20 @@ * limitations under the License. */ +#include +#include +#include +#include + +#include + #include #include -#include +#include #include #include #include #include -#include -#include -#include -#include using namespace chip::Credentials; using GroupInfo = GroupDataProvider::GroupInfo; diff --git a/src/credentials/tests/TestPersistentStorageOpCertStore.cpp b/src/credentials/tests/TestPersistentStorageOpCertStore.cpp index c1a57e00e95af2..d558818bb40f89 100644 --- a/src/credentials/tests/TestPersistentStorageOpCertStore.cpp +++ b/src/credentials/tests/TestPersistentStorageOpCertStore.cpp @@ -18,8 +18,10 @@ #include +#include + #include -#include +#include #include #include #include diff --git a/src/crypto/tests/BUILD.gn b/src/crypto/tests/BUILD.gn index 8570ed3defc157..d495f68ab54317 100644 --- a/src/crypto/tests/BUILD.gn +++ b/src/crypto/tests/BUILD.gn @@ -68,6 +68,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/crypto", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:testing", "${chip_root}/src/platform", ] diff --git a/src/crypto/tests/TestChipCryptoPAL.cpp b/src/crypto/tests/TestChipCryptoPAL.cpp index b4e0fbb2558057..2d1f5c0612217a 100644 --- a/src/crypto/tests/TestChipCryptoPAL.cpp +++ b/src/crypto/tests/TestChipCryptoPAL.cpp @@ -35,10 +35,12 @@ #include "SPAKE2P_POINT_VALID_test_vectors.h" #include "SPAKE2P_RFC_test_vectors.h" +#include + #include #include -#include #include +#include #include #include diff --git a/src/crypto/tests/TestGroupOperationalCredentials.cpp b/src/crypto/tests/TestGroupOperationalCredentials.cpp index 941423e327f873..9185704acd9d1c 100644 --- a/src/crypto/tests/TestGroupOperationalCredentials.cpp +++ b/src/crypto/tests/TestGroupOperationalCredentials.cpp @@ -18,12 +18,13 @@ #include +#include + #include #include +#include #include -#include - using namespace chip; using namespace chip::Crypto; diff --git a/src/crypto/tests/TestPSAOpKeyStore.cpp b/src/crypto/tests/TestPSAOpKeyStore.cpp index 4a16a19e254b60..ae3b142c27e25b 100644 --- a/src/crypto/tests/TestPSAOpKeyStore.cpp +++ b/src/crypto/tests/TestPSAOpKeyStore.cpp @@ -18,16 +18,17 @@ #include +#include + #include #include +#include #include #include #include #include #include -#include - using namespace chip; using namespace chip::Crypto; diff --git a/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp b/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp index 4448004ff2d3a3..26cf12ca7c2a1a 100644 --- a/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp +++ b/src/crypto/tests/TestPersistentStorageOpKeyStore.cpp @@ -17,18 +17,18 @@ */ #include +#include + +#include #include +#include #include #include #include #include #include -#include - -#include - using namespace chip; using namespace chip::Crypto; diff --git a/src/crypto/tests/TestSessionKeystore.cpp b/src/crypto/tests/TestSessionKeystore.cpp index b3908d1695aaac..372ac0ad02c850 100644 --- a/src/crypto/tests/TestSessionKeystore.cpp +++ b/src/crypto/tests/TestSessionKeystore.cpp @@ -18,15 +18,16 @@ #include "AES_CCM_128_test_vectors.h" +#include + #include #include +#include #include #include #include #include -#include - #if CHIP_CRYPTO_PSA #include #endif diff --git a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h index ebcf3aae949433..9edd153fd2410c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h +++ b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,12 @@ class MTRBaseSubscriptionCallback : public chip::app::ClusterStateCache::Callbac chip::app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; } + // Methods to clear state from our cluster state cache. Must be called on + // the Matter queue. + void ClearCachedAttributeState(chip::EndpointId aEndpoint); + void ClearCachedAttributeState(const chip::app::ConcreteClusterPath & aCluster); + void ClearCachedAttributeState(const chip::app::ConcreteAttributePath & aAttribute); + // We need to exist to get a ReadClient, so can't take this as a constructor argument. void AdoptReadClient(std::unique_ptr aReadClient) { mReadClient = std::move(aReadClient); } void AdoptClusterStateCache(std::unique_ptr aClusterStateCache) diff --git a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm index ca91aed5016126..4d91c76a385a9f 100644 --- a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm +++ b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.mm @@ -201,3 +201,27 @@ }); } } + +void MTRBaseSubscriptionCallback::ClearCachedAttributeState(EndpointId aEndpoint) +{ + assertChipStackLockedByCurrentThread(); + if (mClusterStateCache) { + mClusterStateCache->ClearAttributes(aEndpoint); + } +} + +void MTRBaseSubscriptionCallback::ClearCachedAttributeState(const ConcreteClusterPath & aCluster) +{ + assertChipStackLockedByCurrentThread(); + if (mClusterStateCache) { + mClusterStateCache->ClearAttributes(aCluster); + } +} + +void MTRBaseSubscriptionCallback::ClearCachedAttributeState(const ConcreteAttributePath & aAttribute) +{ + assertChipStackLockedByCurrentThread(); + if (mClusterStateCache) { + mClusterStateCache->ClearAttribute(aAttribute); + } +} diff --git a/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm b/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm index 1521a8c54f6726..4ce1a3a93a8f72 100644 --- a/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm +++ b/src/darwin/Framework/CHIP/MTRDemuxingStorage.mm @@ -144,6 +144,8 @@ static bool IsMemoryOnlyGlobalKey(NSString * key) // We do not expect to see the "g/a/*" keys for attribute values. + // We do not expect to see the "g/sa/*" keys for attribute values. + // We do not expect to see the "g/bt" and "g/bt/*" keys for the binding // table. @@ -162,6 +164,9 @@ static bool IsMemoryOnlyGlobalKey(NSString * key) // We do not expect to see the "g/icd/cic" key; that's only used for an ICD // that sends check-in messages. + // We do not expect to see the "g/icdfl" key; that's only used by + // DefaultICDClientStorage, which Matter.framework does not use. + return false; } @@ -215,6 +220,9 @@ static bool IsMemoryOnlyIndexSpecificKey(NSString * key) // We do not expect to see the "e/*" scenes keys. + // We do not epect to see the "icdc" or "icdk" keys, since those are only + // used by DefaultICDClientStorage, which Matter.framework does not use. + return false; } diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index a8098a7174572e..1c31cbc26a661b 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -114,7 +114,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * The delegate will be called on the provided queue, for attribute reports, event reports, and device state changes. */ -- (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_NEWLY_DEPRECATED("Please use addDelegate:queue:interestedPaths:"); +- (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_DEPRECATED("Please use addDelegate:queue:interestedPaths:", ios(16.1, 18.0), macos(13.0, 15.0), watchos(9.1, 11.0), tvos(16.1, 18.0)); /** * Adds a delegate to receive asynchronous callbacks about the device. @@ -123,7 +123,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * MTRDevice holds a weak reference to the delegate object. */ -- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_NEWLY_AVAILABLE; +- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_AVAILABLE(ios(18.0), macos(15.0), watchos(11.0), tvos(18.0)); /** * Adds a delegate to receive asynchronous callbacks about the device, and limit attribute and/or event reports to a specific set of paths. @@ -138,12 +138,12 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * * MTRDevice holds a weak reference to the delegate object. */ -- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents MTR_NEWLY_AVAILABLE; +- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents MTR_AVAILABLE(ios(18.0), macos(15.0), watchos(11.0), tvos(18.0)); /** * Removes the delegate from receiving callbacks about the device. */ -- (void)removeDelegate:(id)delegate MTR_NEWLY_AVAILABLE; +- (void)removeDelegate:(id)delegate MTR_AVAILABLE(ios(18.0), macos(15.0), watchos(11.0), tvos(18.0)); /** * Read attribute in a designated attribute path. If there is no value available diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 30d96d3c2e9f43..767fcd9c8307eb 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -539,6 +539,9 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:_systemTimeChangeObserverToken]; + + // TODO: retain cycle and clean up https://github.com/project-chip/connectedhomeip/issues/34267 + MTR_LOG("MTRDevice dealloc: %p", self); } - (NSString *)description @@ -799,7 +802,7 @@ - (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queu [self _addDelegate:delegate queue:queue interestedPathsForAttributes:nil interestedPathsForEvents:nil]; } -- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents MTR_NEWLY_AVAILABLE; +- (void)addDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents { MTR_LOG("%@ addDelegate %@ with interested attribute paths %@ event paths %@", self, delegate, interestedPathsForAttributes, interestedPathsForEvents); [self _addDelegate:delegate queue:queue interestedPathsForAttributes:interestedPathsForAttributes interestedPathsForEvents:interestedPathsForEvents]; @@ -844,11 +847,13 @@ - (void)_addDelegate:(id)delegate queue:(dispatch_queue_t)que #endif if (shouldSetUpSubscription) { + MTR_LOG("%@ - starting subscription setup", self); // Record the time of first addDelegate call that triggers initial subscribe, and do not reset this value on subsequent addDelegate calls if (!_initialSubscribeStart) { _initialSubscribeStart = [NSDate now]; } if ([self _deviceUsesThread]) { + MTR_LOG(" => %@ - device is a thread device, scheduling in pool", self); [self _scheduleSubscriptionPoolWork:^{ std::lock_guard lock(self->_lock); [self _setupSubscriptionWithReason:@"delegate is set and scheduled subscription is happening"]; @@ -1301,7 +1306,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: // Sanity check we are not scheduling for this device multiple times in the pool if (_subscriptionPoolWorkCompletionBlock) { - MTR_LOG_ERROR("%@ already scheduled in subscription pool for this device - ignoring: %@", self, description); + MTR_LOG("%@ already scheduled in subscription pool for this device - ignoring: %@", self, description); return; } @@ -1310,6 +1315,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: // In the case where a resubscription triggering event happened and already established, running the work block should result in a no-op MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull completion) { + MTR_LOG("%@ - work item is ready to attempt pooled subscription", self); os_unfair_lock_lock(&self->_lock); #ifdef DEBUG [self _callDelegatesWithBlock:^(id testDelegate) { @@ -1335,6 +1341,7 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: workBlock(); }]; [self->_deviceController.concurrentSubscriptionPool enqueueWorkItem:workItem description:description]; + MTR_LOG("%@ - enqueued in the subscription pool", self); }); } @@ -3434,6 +3441,13 @@ - (void)_pruneEndpointsIn:(MTRDeviceDataValueDictionary)previousPartsListValue } [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:NO]; [self.deviceController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:endpoint]; + + [_deviceController asyncDispatchToMatterQueue:^{ + std::lock_guard lock(self->_lock); + if (self->_currentSubscriptionCallback) { + self->_currentSubscriptionCallback->ClearCachedAttributeState(static_cast(endpoint.unsignedLongLongValue)); + } + } errorHandler:nil]; } } @@ -3454,6 +3468,17 @@ - (void)_pruneClustersIn:(MTRDeviceDataValueDictionary)previousServerListValue } } [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:YES]; + + [_deviceController asyncDispatchToMatterQueue:^{ + std::lock_guard lock(self->_lock); + if (self->_currentSubscriptionCallback) { + for (NSNumber * cluster in toBeRemovedClusters) { + ConcreteClusterPath clusterPath(static_cast(endpointID.unsignedLongLongValue), + static_cast(cluster.unsignedLongLongValue)); + self->_currentSubscriptionCallback->ClearCachedAttributeState(clusterPath); + } + } + } errorHandler:nil]; } - (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListValue @@ -3467,6 +3492,18 @@ - (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListVa [toBeRemovedAttributes minusSet:attributesStillInCluster]; [self _removeAttributes:toBeRemovedAttributes fromCluster:clusterPath]; + + [_deviceController asyncDispatchToMatterQueue:^{ + std::lock_guard lock(self->_lock); + if (self->_currentSubscriptionCallback) { + for (NSNumber * attribute in toBeRemovedAttributes) { + ConcreteAttributePath attributePath(static_cast(clusterPath.endpoint.unsignedLongLongValue), + static_cast(clusterPath.cluster.unsignedLongLongValue), + static_cast(attribute.unsignedLongLongValue)); + self->_currentSubscriptionCallback->ClearCachedAttributeState(attributePath); + } + } + } errorHandler:nil]; } - (void)_pruneStoredDataForPath:(MTRAttributePath *)attributePath @@ -3630,7 +3667,9 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray 0) { + MTR_LOG("%@ report from reported values %@", self, attributePathsToReport); + } return attributesToReport; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index cea281551384d0..0f263d756c5e7b 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -295,6 +295,7 @@ - (void)shutdown return; } + MTR_LOG("Shutting down MTRDeviceController: %@", self); [self cleanupAfterStartup]; } @@ -306,6 +307,7 @@ - (void)cleanupAfterStartup // do the secure session shutdowns. Since we don't want to hold the lock // while calling out into arbitrary invalidation code, snapshot the list of // devices before we start invalidating. + MTR_LOG("cleanupAfterStartup MTRDeviceController: %@", self); os_unfair_lock_lock(&_deviceMapLock); NSEnumerator * devices = [_nodeIDToDeviceMap objectEnumerator]; [_nodeIDToDeviceMap removeAllObjects]; @@ -323,6 +325,7 @@ - (void)cleanupAfterStartup // in a very specific way that only MTRDeviceControllerFactory knows about. - (void)shutDownCppController { + MTR_LOG("shutDownCppController MTRDeviceController: %p", self); assertChipStackLockedByCurrentThread(); // Shut down all our endpoints. @@ -605,13 +608,26 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams MTR_LOG("Loaded attribute values for %lu nodes from storage for controller uuid %@", static_cast(clusterDataByNode.count), self->_uniqueIdentifier); std::lock_guard lock(self->_deviceMapLock); + NSMutableArray * deviceList = [NSMutableArray array]; for (NSNumber * nodeID in clusterDataByNode) { NSDictionary * clusterData = clusterDataByNode[nodeID]; MTRDevice * device = [self _setupDeviceForNodeID:nodeID prefetchedClusterData:clusterData]; MTR_LOG("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), device); + + [deviceList addObject:device]; } + +#define kSecondsToWaitBeforeAPIClientRetainsMTRDevice 60 + // Keep the devices retained for a while, in case API client doesn't immediately retain them. + // + // Note that this is just an optimization to avoid throwing the information away and immediately + // re-reading it from storage. + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (kSecondsToWaitBeforeAPIClientRetainsMTRDevice * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + MTR_LOG("MTRDeviceController: un-retain devices loaded at startup %lu", static_cast(deviceList.count)); + }); }]; } + MTR_LOG("MTRDeviceController startup: %@", self); return YES; } @@ -1101,7 +1117,7 @@ - (NSData * _Nullable)attestationChallengeForDeviceID:(NSNumber *)deviceID chip::CommissioneeDeviceProxy * deviceProxy; auto errorCode = CHIP_NO_ERROR; - MATTER_LOG_METRIC_SCOPE(kMetricPASEVerifierForSetupCode, errorCode); + MATTER_LOG_METRIC_SCOPE(kMetricAttestationChallengeForDevice, errorCode); errorCode = self->_cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetCommissionee error:nil], nil); @@ -1247,7 +1263,7 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error return YES; } - MTR_LOG_ERROR("Error: %s", [kErrorNotRunning UTF8String]); + MTR_LOG_ERROR("MTRDeviceController: %@ Error: %s", self, [kErrorNotRunning UTF8String]); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; } @@ -1257,15 +1273,12 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error - (void)getSessionForNode:(chip::NodeId)nodeID completion:(MTRInternalDeviceConnectionCallback)completion { - // First check if MTRDevice exists from having loaded from storage, or created by a client. - // Do not use deviceForNodeID here, because we don't want to create the device if it does not already exist. - os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * device = [_nodeIDToDeviceMap objectForKey:@(nodeID)]; - os_unfair_lock_unlock(&_deviceMapLock); + // Get the corresponding MTRDevice object to determine if the case/subscription pool is to be used + MTRDevice * device = [self deviceForNodeID:@(nodeID)]; // In the case that this device is known to use thread, queue this with subscription attempts as well, to // help with throttling Thread traffic. - if (device && [device deviceUsesThread]) { + if ([device deviceUsesThread]) { MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull workItemCompletion) { MTRInternalDeviceConnectionCallback completionWrapper = ^(chip::Messaging::ExchangeManager * _Nullable exchangeManager, @@ -1876,10 +1889,10 @@ - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error return NO; } - __block CHIP_ERROR errorCode = CHIP_NO_ERROR; - MATTER_LOG_METRIC_SCOPE(kMetricOpenPairingWindow, errorCode); - auto block = ^BOOL { + CHIP_ERROR errorCode = CHIP_NO_ERROR; + MATTER_LOG_METRIC_SCOPE(kMetricOpenPairingWindow, errorCode); + errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenBasicCommissioningWindow( self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorOpenPairingWindow error:error]; diff --git a/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm index 4522c7e69b4ad6..6afa2358c83b06 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceStorageBehaviorConfiguration.mm @@ -75,7 +75,7 @@ - (void)checkValuesAndResetToDefaultIfNecessary // Sanity check all the values, and if any is out of range, reset to default values if ((_reportToPersistenceDelayTime <= 0) || (_reportToPersistenceDelayTimeMax <= 0) || (_reportToPersistenceDelayTimeMax < _reportToPersistenceDelayTime) || (_recentReportTimesMaxCount < 2) || (_timeBetweenReportsTooShortThreshold <= 0) || (_timeBetweenReportsTooShortMinThreshold <= 0) || (_timeBetweenReportsTooShortMinThreshold > _timeBetweenReportsTooShortThreshold) || (_reportToPersistenceDelayMaxMultiplier <= 1) || (_deviceReportingExcessivelyIntervalThreshold <= 0)) { - MTR_LOG_ERROR("%@ storage behavior: MTRDeviceStorageBehaviorConfiguration values out of bounds - resetting to default", self); + MTR_LOG("%@ storage behavior: MTRDeviceStorageBehaviorConfiguration values out of bounds - resetting to default", self); _reportToPersistenceDelayTime = kReportToPersistenceDelayTimeDefault; _reportToPersistenceDelayTimeMax = kReportToPersistenceDelayTimeMaxDefault; diff --git a/src/darwin/Framework/CHIP/MTRError_Internal.h b/src/darwin/Framework/CHIP/MTRError_Internal.h index c79cc17d95f198..af19f4888ff050 100644 --- a/src/darwin/Framework/CHIP/MTRError_Internal.h +++ b/src/darwin/Framework/CHIP/MTRError_Internal.h @@ -26,6 +26,10 @@ NS_ASSUME_NONNULL_BEGIN +#ifndef YES_NO +#define YES_NO(x) ((x) ? @"YES" : @"NO") +#endif + MTR_DIRECT_MEMBERS @interface MTRError : NSObject + (NSError *)errorWithCode:(MTRErrorCode)code; diff --git a/src/darwin/Framework/CHIP/MTRMetricKeys.h b/src/darwin/Framework/CHIP/MTRMetricKeys.h index d20ec3395656a4..42064b7f049394 100644 --- a/src/darwin/Framework/CHIP/MTRMetricKeys.h +++ b/src/darwin/Framework/CHIP/MTRMetricKeys.h @@ -61,8 +61,11 @@ constexpr Tracing::MetricKey kMetricDeviceBeingCommissioned = "dwnfw_dev_being_c // Tracks the request to generate PASE verifier for a given setup code constexpr Tracing::MetricKey kMetricPASEVerifierForSetupCode = "dwnfw_pase_verifier_for_code"; +// Tracks the request to get attestation challenge for a device +constexpr Tracing::MetricKey kMetricAttestationChallengeForDevice = "dwnfw_attestation_challenge_for_device"; + // Marks the request to open pairing window -constexpr Tracing::MetricKey kMetricOpenPairingWindow = "dwnfw_pase_verifier_for_code"; +constexpr Tracing::MetricKey kMetricOpenPairingWindow = "dwnfw_open_pairing_window"; // Device Vendor ID constexpr Tracing::MetricKey kMetricDeviceVendorID = "dwnfw_device_vendor_id"; diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 88241256e2eca2..5d8aef90a50d95 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -9689,10 +9689,12 @@ versions: "future" provisional: clusters: - # Targeting Fall 2024 + # Targeting 1.4 + - CommissionerControl - ServiceArea - ThreadBorderRouterManagement - ThreadNetworkDirectory + - WaterHeaterManagement - WiFiNetworkManagement attributes: OccupancySensing: @@ -9711,10 +9713,10 @@ - HoldTimeLimitsStruct bitmaps: OccupancySensing: - # Targeting Fall 1.4 + # Targeting 1.4 - Feature bitmap values: Switch: Feature: - # Targeting Fall 2024 + # Targeting 1.4 - ActionSwitch diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index c4ca1e5d409bcb..b735da19e2edf6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -5996,6 +5996,36 @@ static BOOL AttributeIsSpecifiedInContentAppObserverCluster(AttributeId aAttribu } } } +static BOOL AttributeIsSpecifiedInCommissionerControlCluster(AttributeId aAttributeId) +{ + using namespace Clusters::CommissionerControl; + switch (aAttributeId) { + case Attributes::SupportedDeviceCategories::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInElectricalMeasurementCluster(AttributeId aAttributeId) { using namespace Clusters::ElectricalMeasurement; @@ -7065,6 +7095,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::ContentAppObserver::Id: { return AttributeIsSpecifiedInContentAppObserverCluster(aAttributeId); } + case Clusters::CommissionerControl::Id: { + return AttributeIsSpecifiedInCommissionerControlCluster(aAttributeId); + } case Clusters::ElectricalMeasurement::Id: { return AttributeIsSpecifiedInElectricalMeasurementCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 56728e6e7d944f..d55efa91505867 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -16942,6 +16942,29 @@ static id _Nullable DecodeAttributeValueForContentAppObserverCluster(AttributeId *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForCommissionerControlCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::CommissionerControl; + switch (aAttributeId) { + case Attributes::SupportedDeviceCategories::Id: { + using TypeInfo = Attributes::SupportedDeviceCategories::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedInt:cppValue.Raw()]; + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForElectricalMeasurementCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::ElectricalMeasurement; @@ -20163,6 +20186,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::ContentAppObserver::Id: { return DecodeAttributeValueForContentAppObserverCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::CommissionerControl::Id: { + return DecodeAttributeValueForCommissionerControlCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::ElectricalMeasurement::Id: { return DecodeAttributeValueForElectricalMeasurementCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 1625fc1bfd319c..65a0a2bf3c2a3e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -14979,6 +14979,86 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Commissioner Control + * + * Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterCommissionerControl : MTRGenericBaseCluster + +/** + * Command RequestCommissioningApproval + * + * This command is sent by a client to request approval for a future CommissionNode call. + */ +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command CommissionNode + * + * This command is sent by a client to request that the server begins commissioning a previously approved request. + */ +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSupportedDeviceCategoriesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedDeviceCategoriesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedDeviceCategoriesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterCommissionerControl (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Electrical Measurement * @@ -20720,6 +20800,10 @@ typedef NS_ENUM(uint8_t, MTRContentAppObserverStatus) { MTRContentAppObserverStatusUnexpectedData MTR_PROVISIONALLY_AVAILABLE = 0x01, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_OPTIONS(uint32_t, MTRCommissionerControlSupportedDeviceCategoryBitmap) { + MTRCommissionerControlSupportedDeviceCategoryBitmapFabricSynchronization MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRUnitTestingSimple) { MTRUnitTestingSimpleUnspecified MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00, MTRUnitTestingSimpleValueA MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 5ad1ae496448fa..fa9a4ef3fcf602 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -104667,6 +104667,311 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterCommissionerControl + +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::RequestCommissioningApproval::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterCommissionNodeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::CommissionNode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRCommissionerControlClusterReverseOpenCommissioningWindowParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeSupportedDeviceCategoriesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::SupportedDeviceCategories::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSupportedDeviceCategoriesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::SupportedDeviceCategories::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSupportedDeviceCategoriesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::SupportedDeviceCategories::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = CommissionerControl::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = CommissionerControl::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterElectricalMeasurement - (void)getProfileInfoCommandWithCompletion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index a662b4413ef6e0..02230b74b6483f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -203,6 +203,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeAccountLoginID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000050E, MTRClusterIDTypeContentControlID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F, MTRClusterIDTypeContentAppObserverID MTR_PROVISIONALLY_AVAILABLE = 0x00000510, + MTRClusterIDTypeCommissionerControlID MTR_PROVISIONALLY_AVAILABLE = 0x00000751, MTRClusterIDTypeElectricalMeasurementID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000B04, MTRClusterIDTypeUnitTestingID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0xFFF1FC05, MTRClusterIDTypeSampleMEIID MTR_PROVISIONALLY_AVAILABLE = 0xFFF1FC20, @@ -4874,6 +4875,15 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterContentAppObserverAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentAppObserverAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster CommissionerControl attributes + MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster ElectricalMeasurement deprecated attribute names MTRClusterElectricalMeasurementAttributeMeasurementTypeID MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterElectricalMeasurementAttributeMeasurementTypeID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6886,6 +6896,11 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterContentAppObserverCommandContentAppMessageID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterContentAppObserverCommandContentAppMessageResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster CommissionerControl commands + MTRCommandIDTypeClusterCommissionerControlCommandRequestCommissioningApprovalID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterCommissionerControlCommandCommissionNodeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterCommissionerControlCommandReverseOpenCommissioningWindowID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + // Cluster ElectricalMeasurement deprecated command id names MTRClusterElectricalMeasurementCommandGetProfileInfoResponseCommandID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterElectricalMeasurementCommandGetProfileInfoResponseCommandID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -7441,6 +7456,9 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { // Cluster ContentControl events MTREventIDTypeClusterContentControlEventRemainingScreenTimeExpiredID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + // Cluster CommissionerControl events + MTREventIDTypeClusterCommissionerControlEventCommissioningRequestResultID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + // Cluster TestCluster deprecated event names MTRClusterTestClusterEventTestEventID MTR_DEPRECATED("Please use MTREventIDTypeClusterUnitTestingEventTestEventID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index fb130c161b4f6d..4492c5895c3219 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -375,6 +375,9 @@ case MTRClusterIDTypeContentAppObserverID: result = @"ContentAppObserver"; break; + case MTRClusterIDTypeCommissionerControlID: + result = @"CommissionerControl"; + break; case MTRClusterIDTypeElectricalMeasurementID: result = @"ElectricalMeasurement"; break; @@ -8133,6 +8136,44 @@ break; } + case MTRClusterIDTypeCommissionerControlID: + + switch (attributeID) { + + // Cluster CommissionerControl attributes + case MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID: + result = @"SupportedDeviceCategories"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeElectricalMeasurementID: switch (attributeID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 437e1b030e46e2..1113a02929193b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -6948,6 +6948,47 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Commissioner Control + * Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterCommissionerControl : MTRGenericCluster + +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSupportedDeviceCategoriesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterCommissionerControl (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Electrical Measurement * Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster.. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 5316c8fb94905e..c9b3095c75b150 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -19906,6 +19906,99 @@ - (void)contentAppMessageWithParams:(MTRContentAppObserverClusterContentAppMessa @end +@implementation MTRClusterCommissionerControl + +- (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::RequestCommissioningApproval::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodeParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRCommissionerControlClusterCommissionNodeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = CommissionerControl::Commands::CommissionNode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRCommissionerControlClusterReverseOpenCommissioningWindowParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeSupportedDeviceCategoriesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterElectricalMeasurement - (void)getProfileInfoCommandWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 7a81facf60704e..acb7982d9f9283 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -10805,6 +10805,105 @@ MTR_PROVISIONALLY_AVAILABLE error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterRequestCommissioningApprovalParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull vendorId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull productId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable label MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterCommissionNodeParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull responseTimeoutSeconds MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSData * _Nullable ipAddress MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable port MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterReverseOpenCommissioningWindowParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull commissioningTimeout MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSData * _Nonnull pakePasscodeVerifier MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull discriminator MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull iterations MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSData * _Nonnull salt MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRCommissionerControlClusterReverseOpenCommissioningWindowParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRElectricalMeasurementClusterGetProfileInfoResponseCommandParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index c959fedea5a841..8ab9ac346812c5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -31033,6 +31033,312 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ContentA @end +@implementation MTRCommissionerControlClusterRequestCommissioningApprovalParams +- (instancetype)init +{ + if (self = [super init]) { + + _requestId = @(0); + + _vendorId = @(0); + + _productId = @(0); + + _label = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams alloc] init]; + + other.requestId = self.requestId; + other.vendorId = self.vendorId; + other.productId = self.productId; + other.label = self.label; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; vendorId:%@; productId:%@; label:%@; >", NSStringFromClass([self class]), _requestId, _vendorId, _productId, _label]; + return descriptionString; +} + +@end + +@implementation MTRCommissionerControlClusterRequestCommissioningApprovalParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.requestId = self.requestId.unsignedLongLongValue; + } + { + encodableStruct.vendorId = static_cast>(self.vendorId.unsignedShortValue); + } + { + encodableStruct.productId = self.productId.unsignedShortValue; + } + { + if (self.label != nil) { + auto & definedValue_0 = encodableStruct.label.Emplace(); + definedValue_0 = AsCharSpan(self.label); + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRCommissionerControlClusterCommissionNodeParams +- (instancetype)init +{ + if (self = [super init]) { + + _requestId = @(0); + + _responseTimeoutSeconds = @(0); + + _ipAddress = nil; + + _port = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRCommissionerControlClusterCommissionNodeParams alloc] init]; + + other.requestId = self.requestId; + other.responseTimeoutSeconds = self.responseTimeoutSeconds; + other.ipAddress = self.ipAddress; + other.port = self.port; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; responseTimeoutSeconds:%@; ipAddress:%@; port:%@; >", NSStringFromClass([self class]), _requestId, _responseTimeoutSeconds, [_ipAddress base64EncodedStringWithOptions:0], _port]; + return descriptionString; +} + +@end + +@implementation MTRCommissionerControlClusterCommissionNodeParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.requestId = self.requestId.unsignedLongLongValue; + } + { + encodableStruct.responseTimeoutSeconds = self.responseTimeoutSeconds.unsignedShortValue; + } + { + if (self.ipAddress != nil) { + auto & definedValue_0 = encodableStruct.ipAddress.Emplace(); + definedValue_0 = AsByteSpan(self.ipAddress); + } + } + { + if (self.port != nil) { + auto & definedValue_0 = encodableStruct.port.Emplace(); + definedValue_0 = self.port.unsignedShortValue; + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRCommissionerControlClusterReverseOpenCommissioningWindowParams +- (instancetype)init +{ + if (self = [super init]) { + + _commissioningTimeout = @(0); + + _pakePasscodeVerifier = [NSData data]; + + _discriminator = @(0); + + _iterations = @(0); + + _salt = [NSData data]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRCommissionerControlClusterReverseOpenCommissioningWindowParams alloc] init]; + + other.commissioningTimeout = self.commissioningTimeout; + other.pakePasscodeVerifier = self.pakePasscodeVerifier; + other.discriminator = self.discriminator; + other.iterations = self.iterations; + other.salt = self.salt; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: commissioningTimeout:%@; pakePasscodeVerifier:%@; discriminator:%@; iterations:%@; salt:%@; >", NSStringFromClass([self class]), _commissioningTimeout, [_pakePasscodeVerifier base64EncodedStringWithOptions:0], _discriminator, _iterations, [_salt base64EncodedStringWithOptions:0]]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRCommissionerControlClusterReverseOpenCommissioningWindowParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType &)decodableStruct +{ + { + self.commissioningTimeout = [NSNumber numberWithUnsignedShort:decodableStruct.commissioningTimeout]; + } + { + self.pakePasscodeVerifier = AsData(decodableStruct.PAKEPasscodeVerifier); + } + { + self.discriminator = [NSNumber numberWithUnsignedShort:decodableStruct.discriminator]; + } + { + self.iterations = [NSNumber numberWithUnsignedInt:decodableStruct.iterations]; + } + { + self.salt = AsData(decodableStruct.salt); + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRElectricalMeasurementClusterGetProfileInfoResponseCommandParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index a38602a4053044..7072a0db6c26ef 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -2020,6 +2020,24 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRCommissionerControlClusterRequestCommissioningApprovalParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRCommissionerControlClusterCommissionNodeParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRCommissionerControlClusterReverseOpenCommissioningWindowParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType &)decodableStruct; + +@end + @interface MTRElectricalMeasurementClusterGetProfileInfoResponseCommandParams (InternalMethods) - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType &)decodableStruct; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 23ef1d7ef1648d..5e09e32a955523 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -1145,6 +1145,15 @@ static BOOL CommandNeedsTimedInvokeInContentAppObserverCluster(AttributeId aAttr } } } +static BOOL CommandNeedsTimedInvokeInCommissionerControlCluster(AttributeId aAttributeId) +{ + using namespace Clusters::CommissionerControl; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInElectricalMeasurementCluster(AttributeId aAttributeId) { using namespace Clusters::ElectricalMeasurement; @@ -1530,6 +1539,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::ContentAppObserver::Id: { return CommandNeedsTimedInvokeInContentAppObserverCluster(commandID); } + case Clusters::CommissionerControl::Id: { + return CommandNeedsTimedInvokeInCommissionerControlCluster(commandID); + } case Clusters::ElectricalMeasurement::Id: { return CommandNeedsTimedInvokeInElectricalMeasurementCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 4a5dba79c49565..049f67951b7408 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -4446,6 +4446,50 @@ static id _Nullable DecodeEventPayloadForContentAppObserverCluster(EventId aEven *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForCommissionerControlCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::CommissionerControl; + switch (aEventId) { + case Events::CommissioningRequestResult::Id: { + Events::CommissioningRequestResult::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + + __auto_type * value = [MTRCommissionerControlClusterCommissioningRequestResultEvent new]; + + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.requestId]; + value.requestId = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.clientNodeId]; + value.clientNodeId = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedChar:cppValue.statusCode]; + value.statusCode = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedChar:cppValue.fabricIndex]; + value.fabricIndex = memberValue; + } while (0); + + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForElectricalMeasurementCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::ElectricalMeasurement; @@ -4988,6 +5032,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::ContentAppObserver::Id: { return DecodeEventPayloadForContentAppObserverCluster(aPath.mEventId, aReader, aError); } + case Clusters::CommissionerControl::Id: { + return DecodeEventPayloadForCommissionerControlCluster(aPath.mEventId, aReader, aError); + } case Clusters::ElectricalMeasurement::Id: { return DecodeEventPayloadForElectricalMeasurementCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 172c5f76731356..e72e520b198f79 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -2039,6 +2039,14 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRContentControlClusterRemainingScreenTimeExpiredEvent : NSObject @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRCommissionerControlClusterCommissioningRequestResultEvent : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull clientNodeId MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull statusCode MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRUnitTestingClusterSimpleStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull a MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index aee0f31d37afc6..09314a688222f6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -8391,6 +8391,42 @@ - (NSString *)description @end +@implementation MTRCommissionerControlClusterCommissioningRequestResultEvent +- (instancetype)init +{ + if (self = [super init]) { + + _requestId = @(0); + + _clientNodeId = @(0); + + _statusCode = @(0); + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRCommissionerControlClusterCommissioningRequestResultEvent alloc] init]; + + other.requestId = self.requestId; + other.clientNodeId = self.clientNodeId; + other.statusCode = self.statusCode; + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: requestId:%@; clientNodeId:%@; statusCode:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _requestId, _clientNodeId, _statusCode, _fabricIndex]; + return descriptionString; +} + +@end + @implementation MTRUnitTestingClusterSimpleStruct - (instancetype)init { diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 05037ef3e16822..df5949868d0012 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -2497,7 +2497,6 @@ "-Wl,-unexported_symbol,\"__Unwind_*\"", "-Wl,-unexported_symbol,\"_unw_*\"", "-Wl,-hidden-lCHIP", - "-Wl,-no_inits", ); "OTHER_LDFLAGS[sdk=macosx*]" = ( "-framework", @@ -2516,7 +2515,6 @@ "-Wl,-unexported_symbol,\"__Unwind_*\"", "-Wl,-unexported_symbol,\"_unw_*\"", "-Wl,-hidden-lCHIP", - "-Wl,-no_inits", ); PRODUCT_BUNDLE_IDENTIFIER = com.csa.matter; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp index bb9e56a8bb2a82..9b36f341042aa9 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp @@ -49,8 +49,6 @@ #include #endif -#include - // TODO : may be we can make it configurable #define BLE_ADVERTISEMENT_VERSION 0 @@ -58,9 +56,7 @@ namespace chip { namespace DeviceLayer { namespace Internal { -namespace { -std::optional gFirmwareBuildChipEpochTime; -} +static Optional sFirmwareBuildChipEpochTime; #if CHIP_USE_TRANSITIONAL_COMMISSIONABLE_DATA_PROVIDER @@ -292,9 +288,9 @@ template CHIP_ERROR GenericConfigurationManagerImpl::GetFirmwareBuildChipEpochTime(System::Clock::Seconds32 & chipEpochTime) { // If the setter was called and we have a value in memory, return this. - if (gFirmwareBuildChipEpochTime.has_value()) + if (sFirmwareBuildChipEpochTime.HasValue()) { - chipEpochTime = gFirmwareBuildChipEpochTime.value(); + chipEpochTime = sFirmwareBuildChipEpochTime.Value(); return CHIP_NO_ERROR; } #ifdef CHIP_DEVICE_CONFIG_FIRMWARE_BUILD_TIME_MATTER_EPOCH_S @@ -327,7 +323,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::SetFirmwareBuildChipEpo // // Implementations that can't use the hard-coded time for whatever reason // should set this at each init. - gFirmwareBuildChipEpochTime = chipEpochTime; + sFirmwareBuildChipEpochTime.SetValue(chipEpochTime); return CHIP_NO_ERROR; } diff --git a/src/inet/tests/BUILD.gn b/src/inet/tests/BUILD.gn index 151b08b7c18838..376693a15c205c 100755 --- a/src/inet/tests/BUILD.gn +++ b/src/inet/tests/BUILD.gn @@ -71,6 +71,7 @@ if (chip_build_tests) { ":helpers", "${chip_root}/src/inet", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", ] test_sources = [ "TestBasicPacketFilters.cpp", diff --git a/src/inet/tests/TestBasicPacketFilters.cpp b/src/inet/tests/TestBasicPacketFilters.cpp index 162fe5272d4b94..69494e48f35b78 100644 --- a/src/inet/tests/TestBasicPacketFilters.cpp +++ b/src/inet/tests/TestBasicPacketFilters.cpp @@ -18,11 +18,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/inet/tests/TestInetAddress.cpp b/src/inet/tests/TestInetAddress.cpp index 1b7e7bdfbefd40..900ce2d829b873 100644 --- a/src/inet/tests/TestInetAddress.cpp +++ b/src/inet/tests/TestInetAddress.cpp @@ -26,10 +26,11 @@ #include -#include +#include #include #include +#include #if CHIP_SYSTEM_CONFIG_USE_LWIP #include diff --git a/src/inet/tests/TestInetEndPoint.cpp b/src/inet/tests/TestInetEndPoint.cpp index 3e6f613a4cb179..10209c0ba9b50f 100644 --- a/src/inet/tests/TestInetEndPoint.cpp +++ b/src/inet/tests/TestInetEndPoint.cpp @@ -29,11 +29,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/inet/tests/TestInetErrorStr.cpp b/src/inet/tests/TestInetErrorStr.cpp index 8e92a040d8567b..60f88a6a5e4767 100644 --- a/src/inet/tests/TestInetErrorStr.cpp +++ b/src/inet/tests/TestInetErrorStr.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include #include #include +#include #include using namespace chip; diff --git a/src/lib/address_resolve/tests/BUILD.gn b/src/lib/address_resolve/tests/BUILD.gn index 994833f21a0020..9521e6f7b27c6d 100644 --- a/src/lib/address_resolve/tests/BUILD.gn +++ b/src/lib/address_resolve/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/address_resolve", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/protocols", ] } diff --git a/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp b/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp index 74dc3bd81b29d2..266939fa3f5d3b 100644 --- a/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp +++ b/src/lib/address_resolve/tests/TestAddressResolve_DefaultImpl.cpp @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include + +#include #include +#include using namespace chip; using namespace chip::AddressResolve; diff --git a/src/lib/asn1/tests/BUILD.gn b/src/lib/asn1/tests/BUILD.gn index 83c3ec8d3d9e43..a6b2d1a5a71248 100644 --- a/src/lib/asn1/tests/BUILD.gn +++ b/src/lib/asn1/tests/BUILD.gn @@ -25,6 +25,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/asn1", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", ] diff --git a/src/lib/asn1/tests/TestASN1.cpp b/src/lib/asn1/tests/TestASN1.cpp index db8b1ae8ccf595..6633867895e74a 100644 --- a/src/lib/asn1/tests/TestASN1.cpp +++ b/src/lib/asn1/tests/TestASN1.cpp @@ -24,14 +24,16 @@ * decode interfaces. * */ -#include #include #include #include +#include + #include #include +#include #include using namespace chip; diff --git a/src/lib/core/tests/BUILD.gn b/src/lib/core/tests/BUILD.gn index 94a6ace3636be1..eb17707dec1755 100644 --- a/src/lib/core/tests/BUILD.gn +++ b/src/lib/core/tests/BUILD.gn @@ -43,6 +43,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/core:vectortlv", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/platform", diff --git a/src/lib/core/tests/TestCATValues.cpp b/src/lib/core/tests/TestCATValues.cpp index a8563905ecb648..6e96610393357f 100644 --- a/src/lib/core/tests/TestCATValues.cpp +++ b/src/lib/core/tests/TestCATValues.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include #include +#include using namespace chip; diff --git a/src/lib/core/tests/TestCHIPCallback.cpp b/src/lib/core/tests/TestCHIPCallback.cpp index 88483dce445bc1..383aef254b140f 100644 --- a/src/lib/core/tests/TestCHIPCallback.cpp +++ b/src/lib/core/tests/TestCHIPCallback.cpp @@ -21,9 +21,11 @@ * This file implements a test for CHIP Callback * */ -#include + +#include #include +#include #include #include diff --git a/src/lib/core/tests/TestCHIPError.cpp b/src/lib/core/tests/TestCHIPError.cpp index ba0c25906623a8..f9dbbd9eb2a710 100644 --- a/src/lib/core/tests/TestCHIPError.cpp +++ b/src/lib/core/tests/TestCHIPError.cpp @@ -18,9 +18,9 @@ #include -#include +#include -#include +#include namespace chip { namespace { diff --git a/src/lib/core/tests/TestCHIPErrorStr.cpp b/src/lib/core/tests/TestCHIPErrorStr.cpp index 295dc895fc52fb..d466eb281fe0fb 100644 --- a/src/lib/core/tests/TestCHIPErrorStr.cpp +++ b/src/lib/core/tests/TestCHIPErrorStr.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include #include #include +#include using namespace chip; diff --git a/src/lib/core/tests/TestGroupedCallbackList.cpp b/src/lib/core/tests/TestGroupedCallbackList.cpp index da09d162ce1d00..f2d85ec13bf168 100644 --- a/src/lib/core/tests/TestGroupedCallbackList.cpp +++ b/src/lib/core/tests/TestGroupedCallbackList.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include #include +#include #include #include diff --git a/src/lib/core/tests/TestOTAImageHeader.cpp b/src/lib/core/tests/TestOTAImageHeader.cpp index 8413dbdce36f0e..bee9da3978bed0 100644 --- a/src/lib/core/tests/TestOTAImageHeader.cpp +++ b/src/lib/core/tests/TestOTAImageHeader.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include +#include -#include +#include +#include using namespace chip; diff --git a/src/lib/core/tests/TestOptional.cpp b/src/lib/core/tests/TestOptional.cpp index 9a0e95f1db8da2..e57657464369bd 100644 --- a/src/lib/core/tests/TestOptional.cpp +++ b/src/lib/core/tests/TestOptional.cpp @@ -28,11 +28,12 @@ #include #include +#include + #include +#include #include -#include - using namespace chip; struct Count diff --git a/src/lib/core/tests/TestReferenceCounted.cpp b/src/lib/core/tests/TestReferenceCounted.cpp index 4f3c3cd4182a3c..fc7d01e537bf61 100644 --- a/src/lib/core/tests/TestReferenceCounted.cpp +++ b/src/lib/core/tests/TestReferenceCounted.cpp @@ -27,9 +27,10 @@ #include #include -#include +#include -#include +#include +#include using namespace chip; diff --git a/src/lib/core/tests/TestTLV.cpp b/src/lib/core/tests/TestTLV.cpp index d7861291a56c73..a12411444385d0 100644 --- a/src/lib/core/tests/TestTLV.cpp +++ b/src/lib/core/tests/TestTLV.cpp @@ -23,21 +23,21 @@ * */ -#include #include +#include + #include +#include #include #include #include #include #include - #include #include #include #include - #include #include diff --git a/src/lib/core/tests/TestTLVVectorWriter.cpp b/src/lib/core/tests/TestTLVVectorWriter.cpp index d2b604fa7e876f..01c2a445a52de9 100644 --- a/src/lib/core/tests/TestTLVVectorWriter.cpp +++ b/src/lib/core/tests/TestTLVVectorWriter.cpp @@ -16,19 +16,19 @@ * limitations under the License. */ -#include - -#include - #include #include #include #include +#include + #include #include +#include #include #include +#include #include #include diff --git a/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn index 39b59bb999c9ad..9a84057e18cd66 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/core/tests/BUILD.gn @@ -41,6 +41,7 @@ chip_test_suite("tests") { public_deps = [ ":support", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd/minimal_mdns/core", ] } diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp index c9ab4f222ef6f0..5ae56f46a8e2a6 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestFlatAllocatedQName.cpp @@ -14,8 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include + +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp index 22287751ac5f05..7857ce4335b1bd 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestHeapQName.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp index 46c0b517162133..26bed1aea129b4 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestQName.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp b/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp index f8dbc220978c87..6f0885932bcb1b 100644 --- a/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp +++ b/src/lib/dnssd/minimal_mdns/core/tests/TestRecordWriter.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn index 90a73141ff61d0..243da1423a08a2 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/records/tests/BUILD.gn @@ -32,6 +32,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd/minimal_mdns/records", ] } diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp index 3139635c54a56b..c828d23b2f934b 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecord.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp index c79507d2f454e6..bff8a50d9da1d5 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordIP.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp index 52cab32b727fd0..adbfd6aba1359b 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordPtr.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp index b213f11efd32cc..8bab8b856edac9 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordSrv.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp index f77066b8361fdc..f97ba2dc0a0329 100644 --- a/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp +++ b/src/lib/dnssd/minimal_mdns/records/tests/TestResourceRecordTxt.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn index 940cc82698e14a..3c8437c068cc84 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/responders/tests/BUILD.gn @@ -30,6 +30,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd/minimal_mdns", "${chip_root}/src/lib/dnssd/minimal_mdns:default_policy", "${chip_root}/src/lib/dnssd/minimal_mdns/responders", diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp b/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp index b24f2bedd4a1a8..691a458c9343d6 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp +++ b/src/lib/dnssd/minimal_mdns/responders/tests/TestIPResponder.cpp @@ -18,11 +18,12 @@ #include +#include + +#include #include #include -#include - namespace { using namespace chip; diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp b/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp index f1c2ba6f9e25c2..b10e19a0ad0407 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp +++ b/src/lib/dnssd/minimal_mdns/responders/tests/TestPtrResponder.cpp @@ -18,11 +18,12 @@ #include +#include + +#include #include #include -#include - namespace { using namespace chip; diff --git a/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp b/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp index bf0ff0413e38f6..80d0029ffa78d4 100644 --- a/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp +++ b/src/lib/dnssd/minimal_mdns/responders/tests/TestQueryResponder.cpp @@ -18,9 +18,10 @@ #include -#include +#include -#include +#include +#include namespace { diff --git a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn index 17f9868609748c..47e83650d41acc 100644 --- a/src/lib/dnssd/minimal_mdns/tests/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/tests/BUILD.gn @@ -37,6 +37,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/dnssd", "${chip_root}/src/lib/dnssd/minimal_mdns", "${chip_root}/src/transport/raw/tests:helpers", diff --git a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h index 1aabc6738d00e6..fe85abdbf53179 100644 --- a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h +++ b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h @@ -22,6 +22,9 @@ #include #include +#include + +#include #include #include #include @@ -31,8 +34,6 @@ #include #include -#include - namespace mdns { namespace Minimal { namespace test { diff --git a/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp b/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp index c868939573f1c7..1a66865c143a2e 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestAdvertiser.cpp @@ -20,6 +20,9 @@ #include #include +#include + +#include #include #include #include @@ -33,8 +36,6 @@ #include #include -#include - namespace { using namespace std; diff --git a/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp b/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp index f571e81fcf27d1..41577dc4797f1a 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestMinimalMdnsAllocator.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include using namespace chip; diff --git a/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp b/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp index 234b6876c6b7fe..769bcfaa8f8eae 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestQueryReplyFilter.cpp @@ -14,8 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include + +#include #include namespace { diff --git a/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp b/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp index 295ed2296215bf..dcd48959be01ea 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestRecordData.cpp @@ -14,12 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include #include -#include +#include + +#include namespace { diff --git a/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp b/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp index e248a647bf2f6d..abfceb52080f13 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestResponseSender.cpp @@ -14,13 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include #include -#include +#include +#include #include #include #include @@ -28,7 +30,6 @@ #include #include #include - #include namespace { diff --git a/src/lib/dnssd/platform/tests/BUILD.gn b/src/lib/dnssd/platform/tests/BUILD.gn index 966923eebae998..b28ba928c6e827 100644 --- a/src/lib/dnssd/platform/tests/BUILD.gn +++ b/src/lib/dnssd/platform/tests/BUILD.gn @@ -22,6 +22,9 @@ chip_test_suite("tests") { if (chip_device_platform == "fake") { test_sources = [ "TestPlatform.cpp" ] - public_deps = [ "${chip_root}/src/lib/dnssd" ] + public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/dnssd", + ] } } diff --git a/src/lib/dnssd/platform/tests/TestPlatform.cpp b/src/lib/dnssd/platform/tests/TestPlatform.cpp index 324863a948902d..5494bbcc3d402c 100644 --- a/src/lib/dnssd/platform/tests/TestPlatform.cpp +++ b/src/lib/dnssd/platform/tests/TestPlatform.cpp @@ -16,15 +16,15 @@ * limitations under the License. */ +#include + #include +#include #include - #include #include #include -#include - #if CHIP_DEVICE_LAYER_TARGET_FAKE != 1 #error "This test is designed for use only with the fake platform" #endif diff --git a/src/lib/dnssd/tests/BUILD.gn b/src/lib/dnssd/tests/BUILD.gn index cdcb4bab0e27a1..e8ab101ae8e09f 100644 --- a/src/lib/dnssd/tests/BUILD.gn +++ b/src/lib/dnssd/tests/BUILD.gn @@ -25,7 +25,10 @@ chip_test_suite("tests") { "TestTxtFields.cpp", ] - public_deps = [ "${chip_root}/src/lib/dnssd" ] + public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/dnssd", + ] if (chip_mdns == "minimal") { test_sources += [ diff --git a/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp b/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp index 6d778808f3e669..308cede6957103 100644 --- a/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp +++ b/src/lib/dnssd/tests/TestActiveResolveAttempts.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include + +#include +#include namespace { diff --git a/src/lib/dnssd/tests/TestIncrementalResolve.cpp b/src/lib/dnssd/tests/TestIncrementalResolve.cpp index 88e183b91ce2bb..930b837fbbfbbb 100644 --- a/src/lib/dnssd/tests/TestIncrementalResolve.cpp +++ b/src/lib/dnssd/tests/TestIncrementalResolve.cpp @@ -20,6 +20,9 @@ #include +#include + +#include #include #include #include @@ -29,8 +32,6 @@ #include #include -#include - using namespace chip; using namespace chip::Dnssd; using namespace mdns::Minimal; diff --git a/src/lib/dnssd/tests/TestServiceNaming.cpp b/src/lib/dnssd/tests/TestServiceNaming.cpp index 0fa26723dab779..485595ab7d8410 100644 --- a/src/lib/dnssd/tests/TestServiceNaming.cpp +++ b/src/lib/dnssd/tests/TestServiceNaming.cpp @@ -20,7 +20,9 @@ #include -#include +#include + +#include using namespace chip; using namespace chip::Dnssd; diff --git a/src/lib/dnssd/tests/TestTxtFields.cpp b/src/lib/dnssd/tests/TestTxtFields.cpp index 873ce0bc4eb6f0..3de62f235be98b 100644 --- a/src/lib/dnssd/tests/TestTxtFields.cpp +++ b/src/lib/dnssd/tests/TestTxtFields.cpp @@ -22,9 +22,10 @@ #include #include -#include +#include -#include +#include +#include using namespace chip; using namespace chip::Dnssd; diff --git a/src/lib/format/tests/BUILD.gn b/src/lib/format/tests/BUILD.gn index 1001a3bd9e77d4..840a2eede60c78 100644 --- a/src/lib/format/tests/BUILD.gn +++ b/src/lib/format/tests/BUILD.gn @@ -36,6 +36,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/controller/data_model:cluster-tlv-metadata", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/format:flat-tree", "${chip_root}/src/lib/format:protocol-decoder", "${chip_root}/src/lib/format:protocol-tlv-metadata", diff --git a/src/lib/format/tests/TestDecoding.cpp b/src/lib/format/tests/TestDecoding.cpp index ae5c2efc553fb6..2fc7cf8f59fd6c 100644 --- a/src/lib/format/tests/TestDecoding.cpp +++ b/src/lib/format/tests/TestDecoding.cpp @@ -14,15 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include #include #include #include - #include #include -#include - #include "sample_data.h" namespace { diff --git a/src/lib/format/tests/TestFlatTree.cpp b/src/lib/format/tests/TestFlatTree.cpp index fcf8e2713bf6b5..05f401b7d8232d 100644 --- a/src/lib/format/tests/TestFlatTree.cpp +++ b/src/lib/format/tests/TestFlatTree.cpp @@ -14,15 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include - -#include #include - #include -#include +#include + +#include +#include +#include namespace { diff --git a/src/lib/format/tests/TestFlatTreePosition.cpp b/src/lib/format/tests/TestFlatTreePosition.cpp index cf5a26e6c8662f..b578f68583cbd2 100644 --- a/src/lib/format/tests/TestFlatTreePosition.cpp +++ b/src/lib/format/tests/TestFlatTreePosition.cpp @@ -14,17 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include - -#include #include #include #include -#include +#include + +#include +#include +#include +#include namespace { diff --git a/src/lib/shell/commands/Config.cpp b/src/lib/shell/commands/Config.cpp index e1452f9b35ba67..cf5ac39e07983f 100644 --- a/src/lib/shell/commands/Config.cpp +++ b/src/lib/shell/commands/Config.cpp @@ -142,7 +142,7 @@ static CHIP_ERROR ConfigSetSetupDiscriminator(char * argv) } else { - streamer_printf(sout, "Setup discriminator setting failed with code: %d\r\n", error); + streamer_printf(sout, "Setup discriminator setting failed with code: %d\r\n", error.AsInteger()); } return error; diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index 2c7cc02c7a54b2..18e0841dccce83 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -122,18 +122,18 @@ class DnsShellResolverDelegate : public Dnssd::DiscoverNodeDelegate, public Addr auto retryInterval = nodeData.GetMrpRetryIntervalIdle(); if (retryInterval.has_value()) - streamer_printf(streamer_get(), " MRP retry interval (idle): %" PRIu32 "ms\r\n", *retryInterval); + streamer_printf(streamer_get(), " MRP retry interval (idle): %" PRIu32 "ms\r\n", retryInterval->count()); retryInterval = nodeData.GetMrpRetryIntervalActive(); if (retryInterval.has_value()) - streamer_printf(streamer_get(), " MRP retry interval (active): %" PRIu32 "ms\r\n", *retryInterval); + streamer_printf(streamer_get(), " MRP retry interval (active): %" PRIu32 "ms\r\n", retryInterval->count()); auto activeThreshold = nodeData.GetMrpRetryActiveThreshold(); if (activeThreshold.has_value()) { - streamer_printf(streamer_get(), " MRP retry active threshold time: %" PRIu32 "ms\r\n", *activeThreshold); + streamer_printf(streamer_get(), " MRP retry active threshold time: %" PRIu32 "ms\r\n", activeThreshold->count()); } streamer_printf(streamer_get(), " Supports TCP Client: %s\r\n", nodeData.supportsTcpClient ? "yes" : "no"); diff --git a/src/lib/shell/tests/BUILD.gn b/src/lib/shell/tests/BUILD.gn index 0b5f7d5fd43222..9b71114424d8de 100644 --- a/src/lib/shell/tests/BUILD.gn +++ b/src/lib/shell/tests/BUILD.gn @@ -29,6 +29,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/shell", ] } diff --git a/src/lib/shell/tests/TestShellStreamerStdio.cpp b/src/lib/shell/tests/TestShellStreamerStdio.cpp index dde770c950183c..b71ebaf80ae50d 100644 --- a/src/lib/shell/tests/TestShellStreamerStdio.cpp +++ b/src/lib/shell/tests/TestShellStreamerStdio.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/lib/shell/tests/TestShellTokenizeLine.cpp b/src/lib/shell/tests/TestShellTokenizeLine.cpp index 8ed6c0eecde779..64bb301dc52141 100644 --- a/src/lib/shell/tests/TestShellTokenizeLine.cpp +++ b/src/lib/shell/tests/TestShellTokenizeLine.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include // Include entire C++ file to have access to functions-under-test diff --git a/src/lib/support/IntrusiveList.h b/src/lib/support/IntrusiveList.h index be9c139babc3dc..961113e8d1ee6b 100644 --- a/src/lib/support/IntrusiveList.h +++ b/src/lib/support/IntrusiveList.h @@ -84,7 +84,7 @@ enum class IntrusiveMode class IntrusiveListNodePrivateBase { public: - constexpr IntrusiveListNodePrivateBase() : mPrev(nullptr), mNext(nullptr) {} + IntrusiveListNodePrivateBase() : mPrev(nullptr), mNext(nullptr) {} ~IntrusiveListNodePrivateBase() { VerifyOrDie(!IsInList()); } // Note: The copy construct/assignment is not provided because the list node state is not copyable. @@ -98,7 +98,7 @@ class IntrusiveListNodePrivateBase private: friend class IntrusiveListBase; - constexpr IntrusiveListNodePrivateBase(IntrusiveListNodePrivateBase * prev, IntrusiveListNodePrivateBase * next) : + IntrusiveListNodePrivateBase(IntrusiveListNodePrivateBase * prev, IntrusiveListNodePrivateBase * next) : mPrev(prev), mNext(next) {} @@ -284,7 +284,7 @@ class IntrusiveListBase // ^ | // \------------------------------------------/ // - constexpr IntrusiveListBase() : mNode(&mNode, &mNode) {} + IntrusiveListBase() : mNode(&mNode, &mNode) {} ~IntrusiveListBase() { VerifyOrDie(Empty()); @@ -399,7 +399,7 @@ template -#include - #include +#include + +#include +#include + namespace chip { namespace Thread { @@ -70,7 +72,7 @@ class ThreadTLV final mLength = aLength; } - const void * GetValue() const + const uint8_t * GetValue() const { assert(mLength != kLengthEscape); @@ -79,75 +81,44 @@ class ThreadTLV final return reinterpret_cast(this) + sizeof(*this); } - void * GetValue() { return const_cast(const_cast(this)->GetValue()); } + uint8_t * GetValue() { return const_cast(const_cast(this)->GetValue()); } + + ByteSpan GetValueAsSpan() const { return ByteSpan(static_cast(GetValue()), GetLength()); } void Get64(uint64_t & aValue) const { assert(GetLength() >= sizeof(aValue)); - - const uint8_t * p = reinterpret_cast(GetValue()); - aValue = // - (static_cast(p[0]) << 56) | // - (static_cast(p[1]) << 48) | // - (static_cast(p[2]) << 40) | // - (static_cast(p[3]) << 32) | // - (static_cast(p[4]) << 24) | // - (static_cast(p[5]) << 16) | // - (static_cast(p[6]) << 8) | // - (static_cast(p[7])); + aValue = Encoding::BigEndian::Get64(GetValue()); } - void Get16(uint16_t & aValue) const + void Get32(uint32_t & aValue) const { assert(GetLength() >= sizeof(aValue)); - - const uint8_t * p = static_cast(GetValue()); - - aValue = static_cast(p[0] << 8 | p[1]); + aValue = Encoding::BigEndian::Get32(GetValue()); } - void Get8(uint8_t & aValue) const + void Get16(uint16_t & aValue) const { assert(GetLength() >= sizeof(aValue)); - aValue = *static_cast(GetValue()); + aValue = Encoding::BigEndian::Get16(GetValue()); } void Set64(uint64_t aValue) { - uint8_t * value = static_cast(GetValue()); - SetLength(sizeof(aValue)); - - value[0] = static_cast((aValue >> 56) & 0xff); - value[1] = static_cast((aValue >> 48) & 0xff); - value[2] = static_cast((aValue >> 40) & 0xff); - value[3] = static_cast((aValue >> 32) & 0xff); - value[4] = static_cast((aValue >> 24) & 0xff); - value[5] = static_cast((aValue >> 16) & 0xff); - value[6] = static_cast((aValue >> 8) & 0xff); - value[7] = static_cast(aValue & 0xff); + Encoding::BigEndian::Put64(GetValue(), aValue); } - void Set16(uint16_t aValue) + void Set32(uint32_t aValue) { - uint8_t * value = static_cast(GetValue()); - SetLength(sizeof(aValue)); - - value[0] = static_cast(aValue >> 8); - value[1] = static_cast(aValue & 0xff); - } - - void Set8(uint8_t aValue) - { - SetLength(sizeof(aValue)); - *static_cast(GetValue()) = aValue; + Encoding::BigEndian::Put32(GetValue(), aValue); } - void Set8(int8_t aValue) + void Set16(uint16_t aValue) { SetLength(sizeof(aValue)); - *static_cast(GetValue()) = aValue; + Encoding::BigEndian::Put16(GetValue(), aValue); } void SetValue(const void * aValue, uint8_t aLength) @@ -218,24 +189,16 @@ CHIP_ERROR OperationalDataset::Init(ByteSpan aData) CHIP_ERROR OperationalDataset::GetActiveTimestamp(uint64_t & aActiveTimestamp) const { const ThreadTLV * tlv = Locate(ThreadTLV::kActiveTimestamp); - - if (tlv != nullptr) - { - tlv->Get64(aActiveTimestamp); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aActiveTimestamp), CHIP_ERROR_INVALID_TLV_ELEMENT); + tlv->Get64(aActiveTimestamp); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetActiveTimestamp(uint64_t aActiveTimestamp) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kActiveTimestamp, sizeof(*tlv) + sizeof(aActiveTimestamp)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->Set64(aActiveTimestamp); @@ -247,26 +210,19 @@ CHIP_ERROR OperationalDataset::SetActiveTimestamp(uint64_t aActiveTimestamp) CHIP_ERROR OperationalDataset::GetChannel(uint16_t & aChannel) const { const ThreadTLV * tlv = Locate(ThreadTLV::kChannel); - - if (tlv != nullptr) - { - const uint8_t * value = reinterpret_cast(tlv->GetValue()); - aChannel = static_cast((value[1] << 8) | value[2]); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == 3, CHIP_ERROR_INVALID_TLV_ELEMENT); + // Note: The channel page (byte 0) is not returned + const uint8_t * value = tlv->GetValue(); + aChannel = static_cast((value[1] << 8) | value[2]); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetChannel(uint16_t aChannel) { uint8_t value[] = { 0, static_cast(aChannel >> 8), static_cast(aChannel & 0xff) }; ThreadTLV * tlv = MakeRoom(ThreadTLV::kChannel, sizeof(*tlv) + sizeof(value)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(value, sizeof(value)); @@ -278,13 +234,7 @@ CHIP_ERROR OperationalDataset::SetChannel(uint16_t aChannel) CHIP_ERROR OperationalDataset::GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const { ByteSpan extPanIdSpan; - CHIP_ERROR error = GetExtendedPanIdAsByteSpan(extPanIdSpan); - - if (error != CHIP_NO_ERROR) - { - return error; - } - + ReturnErrorOnFailure(GetExtendedPanIdAsByteSpan(extPanIdSpan)); memcpy(aExtendedPanId, extPanIdSpan.data(), extPanIdSpan.size()); return CHIP_NO_ERROR; } @@ -292,17 +242,8 @@ CHIP_ERROR OperationalDataset::GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeE CHIP_ERROR OperationalDataset::GetExtendedPanIdAsByteSpan(ByteSpan & span) const { const ThreadTLV * tlv = Locate(ThreadTLV::kExtendedPanId); - - if (tlv == nullptr) - { - return CHIP_ERROR_TLV_TAG_NOT_FOUND; - } - - if (tlv->GetLength() != kSizeExtendedPanId) - { - return CHIP_ERROR_INVALID_TLV_ELEMENT; - } - + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == kSizeExtendedPanId, CHIP_ERROR_INVALID_TLV_ELEMENT); span = ByteSpan(static_cast(tlv->GetValue()), tlv->GetLength()); return CHIP_NO_ERROR; } @@ -310,11 +251,7 @@ CHIP_ERROR OperationalDataset::GetExtendedPanIdAsByteSpan(ByteSpan & span) const CHIP_ERROR OperationalDataset::SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kExtendedPanId, sizeof(*tlv) + sizeof(aExtendedPanId)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aExtendedPanId, sizeof(aExtendedPanId)); @@ -328,24 +265,16 @@ CHIP_ERROR OperationalDataset::SetExtendedPanId(const uint8_t (&aExtendedPanId)[ CHIP_ERROR OperationalDataset::GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kMasterKey); - - if (tlv != nullptr) - { - memcpy(aMasterKey, tlv->GetValue(), sizeof(aMasterKey)); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aMasterKey), CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aMasterKey, tlv->GetValue(), sizeof(aMasterKey)); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kMasterKey, sizeof(*tlv) + sizeof(aMasterKey)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aMasterKey, sizeof(aMasterKey)); @@ -359,24 +288,16 @@ CHIP_ERROR OperationalDataset::SetMasterKey(const uint8_t (&aMasterKey)[kSizeMas CHIP_ERROR OperationalDataset::GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kMeshLocalPrefix); - - if (tlv != nullptr) - { - memcpy(aMeshLocalPrefix, tlv->GetValue(), sizeof(aMeshLocalPrefix)); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aMeshLocalPrefix), CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aMeshLocalPrefix, tlv->GetValue(), sizeof(aMeshLocalPrefix)); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kMeshLocalPrefix, sizeof(*tlv) + sizeof(aMeshLocalPrefix)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aMeshLocalPrefix, sizeof(aMeshLocalPrefix)); @@ -388,32 +309,21 @@ CHIP_ERROR OperationalDataset::SetMeshLocalPrefix(const uint8_t (&aMeshLocalPref CHIP_ERROR OperationalDataset::GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kNetworkName); - - if (tlv != nullptr) - { - memcpy(aNetworkName, tlv->GetValue(), tlv->GetLength()); - aNetworkName[tlv->GetLength()] = '\0'; - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() <= kSizeNetworkName, CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aNetworkName, tlv->GetValue(), tlv->GetLength()); + aNetworkName[tlv->GetLength()] = '\0'; + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetNetworkName(const char * aNetworkName) { + VerifyOrReturnError(aNetworkName != nullptr, CHIP_ERROR_INVALID_ARGUMENT); size_t len = strlen(aNetworkName); + VerifyOrReturnError(0 < len && len <= kSizeNetworkName, CHIP_ERROR_INVALID_STRING_LENGTH); - if (len > kSizeNetworkName || len == 0) - { - return CHIP_ERROR_INVALID_STRING_LENGTH; - } - - ThreadTLV * tlv = MakeRoom(ThreadTLV::kNetworkName, static_cast(sizeof(*tlv) + static_cast(len))); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + ThreadTLV * tlv = MakeRoom(ThreadTLV::kNetworkName, sizeof(*tlv) + len); + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aNetworkName, static_cast(len)); @@ -425,24 +335,16 @@ CHIP_ERROR OperationalDataset::SetNetworkName(const char * aNetworkName) CHIP_ERROR OperationalDataset::GetPanId(uint16_t & aPanId) const { const ThreadTLV * tlv = Locate(ThreadTLV::kPanId); - - if (tlv != nullptr) - { - tlv->Get16(aPanId); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aPanId), CHIP_ERROR_INVALID_TLV_ELEMENT); + tlv->Get16(aPanId); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetPanId(uint16_t aPanId) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kPanId, sizeof(*tlv) + sizeof(aPanId)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->Set16(aPanId); @@ -454,24 +356,16 @@ CHIP_ERROR OperationalDataset::SetPanId(uint16_t aPanId) CHIP_ERROR OperationalDataset::GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const { const ThreadTLV * tlv = Locate(ThreadTLV::kPSKc); - - if (tlv != nullptr) - { - memcpy(aPSKc, tlv->GetValue(), sizeof(aPSKc)); - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_TLV_TAG_NOT_FOUND; + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_TLV_TAG_NOT_FOUND); + VerifyOrReturnError(tlv->GetLength() == sizeof(aPSKc), CHIP_ERROR_INVALID_TLV_ELEMENT); + memcpy(aPSKc, tlv->GetValue(), sizeof(aPSKc)); + return CHIP_NO_ERROR; } CHIP_ERROR OperationalDataset::SetPSKc(const uint8_t (&aPSKc)[kSizePSKc]) { ThreadTLV * tlv = MakeRoom(ThreadTLV::kPSKc, sizeof(*tlv) + sizeof(aPSKc)); - - if (tlv == nullptr) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(tlv != nullptr, CHIP_ERROR_NO_MEMORY); tlv->SetValue(aPSKc, sizeof(aPSKc)); @@ -533,7 +427,7 @@ void OperationalDataset::Remove(uint8_t aType) } } -ThreadTLV * OperationalDataset::MakeRoom(uint8_t aType, uint8_t aSize) +ThreadTLV * OperationalDataset::MakeRoom(uint8_t aType, size_t aSize) { ThreadTLV * tlv = Locate(aType); diff --git a/src/lib/support/ThreadOperationalDataset.h b/src/lib/support/ThreadOperationalDataset.h index e4de3ddaa8d2c5..7bb528d691c193 100644 --- a/src/lib/support/ThreadOperationalDataset.h +++ b/src/lib/support/ThreadOperationalDataset.h @@ -54,7 +54,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully initialized the dataset. * @retval CHIP_ERROR_INVALID_ARGUMENT The dataset length @p aLength is too long or @p data is corrupted. - * */ CHIP_ERROR Init(ByteSpan aData); @@ -65,7 +64,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the active timestamp. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread active timestamp is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetActiveTimestamp(uint64_t & aActiveTimestamp) const; @@ -76,7 +75,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the active timestamp. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread active timestamp. - * */ CHIP_ERROR SetActiveTimestamp(uint64_t aActiveTimestamp); @@ -87,7 +85,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the channel. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread channel is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetChannel(uint16_t & aChannel) const; @@ -98,7 +96,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the channel. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread channel. - * */ CHIP_ERROR SetChannel(uint16_t aChannel); @@ -109,7 +106,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the extended PAN ID. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread extended PAN ID is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetExtendedPanId(uint8_t (&aExtendedPanId)[kSizeExtendedPanId]) const; @@ -121,7 +118,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the extended PAN ID. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread extended PAN ID is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetExtendedPanIdAsByteSpan(ByteSpan & span) const; @@ -132,7 +129,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the extended PAN ID. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread extended PAN ID. - * */ CHIP_ERROR SetExtendedPanId(const uint8_t (&aExtendedPanId)[kSizeExtendedPanId]); @@ -143,7 +139,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the master key. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread master key is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetMasterKey(uint8_t (&aMasterKey)[kSizeMasterKey]) const; @@ -154,13 +150,11 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the master key. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread master key. - * */ CHIP_ERROR SetMasterKey(const uint8_t (&aMasterKey)[kSizeMasterKey]); /** * This method unsets Thread master key to the dataset. - * */ void UnsetMasterKey(void); @@ -171,7 +165,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the mesh local prefix. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread mesh local prefix is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetMeshLocalPrefix(uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]) const; @@ -182,7 +176,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the Thread mesh local prefix. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread mesh local prefix. - * */ CHIP_ERROR SetMeshLocalPrefix(const uint8_t (&aMeshLocalPrefix)[kSizeMeshLocalPrefix]); @@ -193,7 +186,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the network name. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread network name is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetNetworkName(char (&aNetworkName)[kSizeNetworkName + 1]) const; @@ -204,7 +197,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the network name. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread network name. - * */ CHIP_ERROR SetNetworkName(const char * aNetworkName); @@ -215,7 +207,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the PAN ID. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread PAN ID is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetPanId(uint16_t & aPanId) const; @@ -226,7 +218,6 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the PAN ID. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread PAN ID. - * */ CHIP_ERROR SetPanId(uint16_t aPanId); @@ -237,7 +228,7 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully retrieved the PSKc. * @retval CHIP_ERROR_TLV_TAG_NOT_FOUND Thread PSKc is not present in the dataset. - * + * @retval CHIP_ERROR_INVALID_TLV_ELEMENT If the TLV element is invalid. */ CHIP_ERROR GetPSKc(uint8_t (&aPSKc)[kSizePSKc]) const; @@ -248,13 +239,11 @@ class OperationalDataset * * @retval CHIP_NO_ERROR Successfully set the PSKc. * @retval CHIP_ERROR_NO_MEMORY Insufficient memory in the dataset for setting Thread PSKc. - * */ CHIP_ERROR SetPSKc(const uint8_t (&aPSKc)[kSizePSKc]); /** * This method unsets Thread PSKc to the dataset. - * */ void UnsetPSKc(void); @@ -296,12 +285,12 @@ class OperationalDataset ThreadTLV & End(void) { return const_cast(const_cast(this)->End()); } void Remove(uint8_t aType); void Remove(ThreadTLV & aTlv); - ThreadTLV * MakeRoom(uint8_t aType, uint8_t aSize); + ThreadTLV * MakeRoom(uint8_t aType, size_t aSize); bool Has(uint8_t aType) const { return Locate(aType) != nullptr; } uint8_t mData[kSizeOperationalDataset]; - uint8_t mLength; + uint8_t mLength = 0; }; } // namespace Thread -}; // namespace chip +} // namespace chip diff --git a/src/lib/support/tests/BUILD.gn b/src/lib/support/tests/BUILD.gn index 659ba00d0395ff..c6bfddb9269a7a 100644 --- a/src/lib/support/tests/BUILD.gn +++ b/src/lib/support/tests/BUILD.gn @@ -88,6 +88,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/credentials", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support:static-support", "${chip_root}/src/lib/support:testing", "${chip_root}/src/lib/support/jsontlv", diff --git a/src/lib/support/tests/TestBitMask.cpp b/src/lib/support/tests/TestBitMask.cpp index f19c90fb2e20af..7d7798a4fa85ee 100644 --- a/src/lib/support/tests/TestBitMask.cpp +++ b/src/lib/support/tests/TestBitMask.cpp @@ -14,13 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include + #include #include #include #include +#include + +#include + using namespace chip; namespace { diff --git a/src/lib/support/tests/TestBufferReader.cpp b/src/lib/support/tests/TestBufferReader.cpp index 6d14c3973f58ed..97db9cf09737b9 100644 --- a/src/lib/support/tests/TestBufferReader.cpp +++ b/src/lib/support/tests/TestBufferReader.cpp @@ -22,11 +22,13 @@ * */ -#include -#include - #include +#include + +#include +#include + using namespace chip; using namespace chip::Encoding::LittleEndian; diff --git a/src/lib/support/tests/TestBufferWriter.cpp b/src/lib/support/tests/TestBufferWriter.cpp index e5d8951d4cf152..1be61f35ad206d 100644 --- a/src/lib/support/tests/TestBufferWriter.cpp +++ b/src/lib/support/tests/TestBufferWriter.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include + +#include +#include namespace { diff --git a/src/lib/support/tests/TestBytesCircularBuffer.cpp b/src/lib/support/tests/TestBytesCircularBuffer.cpp index 90305e0cf8590a..4ee192b652649e 100644 --- a/src/lib/support/tests/TestBytesCircularBuffer.cpp +++ b/src/lib/support/tests/TestBytesCircularBuffer.cpp @@ -23,8 +23,9 @@ #include #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestBytesToHex.cpp b/src/lib/support/tests/TestBytesToHex.cpp index 1e304811b5e42b..7384958befd415 100644 --- a/src/lib/support/tests/TestBytesToHex.cpp +++ b/src/lib/support/tests/TestBytesToHex.cpp @@ -20,13 +20,15 @@ #include #include -#include +#include +#include #include #include #include #include #include + namespace { using namespace chip; diff --git a/src/lib/support/tests/TestCHIPArgParser.cpp b/src/lib/support/tests/TestCHIPArgParser.cpp index 426758aff1e5c8..f7bcc84fbaf3d6 100644 --- a/src/lib/support/tests/TestCHIPArgParser.cpp +++ b/src/lib/support/tests/TestCHIPArgParser.cpp @@ -22,9 +22,10 @@ #include #include -#include +#include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestCHIPCounter.cpp b/src/lib/support/tests/TestCHIPCounter.cpp index b2c5e21b5038c2..f84ce7e50e0c18 100644 --- a/src/lib/support/tests/TestCHIPCounter.cpp +++ b/src/lib/support/tests/TestCHIPCounter.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestCHIPMem.cpp b/src/lib/support/tests/TestCHIPMem.cpp index c19d356abfeceb..6f4aa8aa6bcfdb 100644 --- a/src/lib/support/tests/TestCHIPMem.cpp +++ b/src/lib/support/tests/TestCHIPMem.cpp @@ -29,8 +29,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestCHIPMemString.cpp b/src/lib/support/tests/TestCHIPMemString.cpp index 10101bd193c0f6..11409d18dc6f69 100644 --- a/src/lib/support/tests/TestCHIPMemString.cpp +++ b/src/lib/support/tests/TestCHIPMemString.cpp @@ -22,8 +22,9 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/lib/support/tests/TestDefer.cpp b/src/lib/support/tests/TestDefer.cpp index 9b5159bf557830..d0b65fe9cb10c5 100644 --- a/src/lib/support/tests/TestDefer.cpp +++ b/src/lib/support/tests/TestDefer.cpp @@ -20,7 +20,9 @@ #include -#include +#include + +#include namespace { diff --git a/src/lib/support/tests/TestErrorStr.cpp b/src/lib/support/tests/TestErrorStr.cpp index 49ae9f5a9b40ac..809d69b302af0b 100644 --- a/src/lib/support/tests/TestErrorStr.cpp +++ b/src/lib/support/tests/TestErrorStr.cpp @@ -19,10 +19,11 @@ #include #include -#include +#include #include #include +#include using namespace chip; diff --git a/src/lib/support/tests/TestFixedBufferAllocator.cpp b/src/lib/support/tests/TestFixedBufferAllocator.cpp index c5c588041ef65c..a2e30ba7464d3b 100644 --- a/src/lib/support/tests/TestFixedBufferAllocator.cpp +++ b/src/lib/support/tests/TestFixedBufferAllocator.cpp @@ -19,7 +19,10 @@ #include #include -#include + +#include + +#include using namespace chip; diff --git a/src/lib/support/tests/TestFold.cpp b/src/lib/support/tests/TestFold.cpp index 48dbb454dfac3b..b8b1b813c191d0 100644 --- a/src/lib/support/tests/TestFold.cpp +++ b/src/lib/support/tests/TestFold.cpp @@ -16,12 +16,15 @@ * limitations under the License. */ -#include -#include - #include #include #include + +#include + +#include +#include + using namespace chip; namespace { diff --git a/src/lib/support/tests/TestIniEscaping.cpp b/src/lib/support/tests/TestIniEscaping.cpp index 90570add67b18d..61c7db20130150 100644 --- a/src/lib/support/tests/TestIniEscaping.cpp +++ b/src/lib/support/tests/TestIniEscaping.cpp @@ -16,10 +16,13 @@ * limitations under the License. */ -#include -#include #include +#include + +#include +#include + using namespace chip; using namespace chip::IniEscaping; diff --git a/src/lib/support/tests/TestIntrusiveList.cpp b/src/lib/support/tests/TestIntrusiveList.cpp index 50ace6a561e699..6e89b3e344c11e 100644 --- a/src/lib/support/tests/TestIntrusiveList.cpp +++ b/src/lib/support/tests/TestIntrusiveList.cpp @@ -18,8 +18,9 @@ #include #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestJsonToTlv.cpp b/src/lib/support/tests/TestJsonToTlv.cpp index 9bc8696fd88621..6499e1dfa573aa 100644 --- a/src/lib/support/tests/TestJsonToTlv.cpp +++ b/src/lib/support/tests/TestJsonToTlv.cpp @@ -17,16 +17,18 @@ #include -#include +#include #include #include #include +#include #include #include #include #include #include + namespace { using namespace chip::Encoding; diff --git a/src/lib/support/tests/TestJsonToTlvToJson.cpp b/src/lib/support/tests/TestJsonToTlvToJson.cpp index 665df4dcb30cab..3321ed8f9ee2e2 100644 --- a/src/lib/support/tests/TestJsonToTlvToJson.cpp +++ b/src/lib/support/tests/TestJsonToTlvToJson.cpp @@ -18,11 +18,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestPersistedCounter.cpp b/src/lib/support/tests/TestPersistedCounter.cpp index 3d9b13583e49a0..a743369537ae91 100644 --- a/src/lib/support/tests/TestPersistedCounter.cpp +++ b/src/lib/support/tests/TestPersistedCounter.cpp @@ -23,8 +23,10 @@ * */ -#include +#include + #include +#include #include #include #include diff --git a/src/lib/support/tests/TestPool.cpp b/src/lib/support/tests/TestPool.cpp index da76d7ebb70d7b..84eea0c3e3bef7 100644 --- a/src/lib/support/tests/TestPool.cpp +++ b/src/lib/support/tests/TestPool.cpp @@ -25,11 +25,13 @@ #include -#include +#include +#include #include #include #include + namespace chip { template diff --git a/src/lib/support/tests/TestPrivateHeap.cpp b/src/lib/support/tests/TestPrivateHeap.cpp index f808c16cb8e5f6..2a68bb9c925021 100644 --- a/src/lib/support/tests/TestPrivateHeap.cpp +++ b/src/lib/support/tests/TestPrivateHeap.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestSafeInt.cpp b/src/lib/support/tests/TestSafeInt.cpp index 1464c0e9735b8c..298b23071e5709 100644 --- a/src/lib/support/tests/TestSafeInt.cpp +++ b/src/lib/support/tests/TestSafeInt.cpp @@ -22,7 +22,9 @@ * */ -#include +#include + +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestSafeString.cpp b/src/lib/support/tests/TestSafeString.cpp index 09e7d89e4054f7..6fe71cb5df723a 100644 --- a/src/lib/support/tests/TestSafeString.cpp +++ b/src/lib/support/tests/TestSafeString.cpp @@ -22,8 +22,9 @@ * */ -#include +#include +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestScoped.cpp b/src/lib/support/tests/TestScoped.cpp index fef70a443dcfb1..f89a374e8ee601 100644 --- a/src/lib/support/tests/TestScoped.cpp +++ b/src/lib/support/tests/TestScoped.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestScopedBuffer.cpp b/src/lib/support/tests/TestScopedBuffer.cpp index c7ec072726c2be..123dca1d2456a7 100644 --- a/src/lib/support/tests/TestScopedBuffer.cpp +++ b/src/lib/support/tests/TestScopedBuffer.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestSorting.cpp b/src/lib/support/tests/TestSorting.cpp index 1d04604c110fd5..459f41d53b72a7 100644 --- a/src/lib/support/tests/TestSorting.cpp +++ b/src/lib/support/tests/TestSorting.cpp @@ -20,8 +20,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestSpan.cpp b/src/lib/support/tests/TestSpan.cpp index 6849138861065c..4813bc460b6be3 100644 --- a/src/lib/support/tests/TestSpan.cpp +++ b/src/lib/support/tests/TestSpan.cpp @@ -24,8 +24,9 @@ #include -#include +#include +#include #include using namespace chip; diff --git a/src/lib/support/tests/TestStateMachine.cpp b/src/lib/support/tests/TestStateMachine.cpp index 4b6af3a73d85cf..3d282b5e5c6e76 100644 --- a/src/lib/support/tests/TestStateMachine.cpp +++ b/src/lib/support/tests/TestStateMachine.cpp @@ -16,8 +16,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestStaticSupportSmartPtr.cpp b/src/lib/support/tests/TestStaticSupportSmartPtr.cpp index 5ffe1cee4d284b..9110c6005b544e 100644 --- a/src/lib/support/tests/TestStaticSupportSmartPtr.cpp +++ b/src/lib/support/tests/TestStaticSupportSmartPtr.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestStringBuilder.cpp b/src/lib/support/tests/TestStringBuilder.cpp index 2f4ad518da3dd1..3b0a3299a80c80 100644 --- a/src/lib/support/tests/TestStringBuilder.cpp +++ b/src/lib/support/tests/TestStringBuilder.cpp @@ -14,9 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include + +#include +#include namespace { diff --git a/src/lib/support/tests/TestStringSplitter.cpp b/src/lib/support/tests/TestStringSplitter.cpp index c8dd1e9f802c47..1301049890ac3b 100644 --- a/src/lib/support/tests/TestStringSplitter.cpp +++ b/src/lib/support/tests/TestStringSplitter.cpp @@ -14,9 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include #include -#include namespace { using namespace chip; diff --git a/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp b/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp index a53f43c0febaaa..f9d403e3d920b0 100644 --- a/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp +++ b/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp @@ -16,15 +16,16 @@ * limitations under the License. */ -#include -#include - #include #include #include #include -#include +#include + +#include +#include +#include using namespace chip; diff --git a/src/lib/support/tests/TestThreadOperationalDataset.cpp b/src/lib/support/tests/TestThreadOperationalDataset.cpp index d9e13c8c25705f..3c60230a573a2a 100644 --- a/src/lib/support/tests/TestThreadOperationalDataset.cpp +++ b/src/lib/support/tests/TestThreadOperationalDataset.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include #include @@ -30,11 +31,9 @@ class TestThreadOperationalDataset : public ::testing::Test static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } - static Thread::OperationalDataset dataset; + Thread::OperationalDataset dataset; }; -Thread::OperationalDataset TestThreadOperationalDataset::dataset; - TEST_F(TestThreadOperationalDataset, TestInit) { @@ -103,6 +102,10 @@ TEST_F(TestThreadOperationalDataset, TestMasterKey) EXPECT_EQ(dataset.SetMasterKey(kMasterKey), CHIP_NO_ERROR); EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); EXPECT_EQ(memcmp(masterKey, kMasterKey, sizeof(kMasterKey)), 0); + + dataset.UnsetMasterKey(); + EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_ERROR_TLV_TAG_NOT_FOUND); + EXPECT_EQ(dataset.SetMasterKey(masterKey), CHIP_NO_ERROR); } TEST_F(TestThreadOperationalDataset, TestMeshLocalPrefix) @@ -129,6 +132,7 @@ TEST_F(TestThreadOperationalDataset, TestNetworkName) EXPECT_EQ(dataset.SetNetworkName("0123456789abcdef"), CHIP_NO_ERROR); EXPECT_EQ(dataset.SetNetworkName("0123456789abcdefg"), CHIP_ERROR_INVALID_STRING_LENGTH); EXPECT_EQ(dataset.SetNetworkName(""), CHIP_ERROR_INVALID_STRING_LENGTH); + EXPECT_EQ(dataset.SetNetworkName(nullptr), CHIP_ERROR_INVALID_ARGUMENT); } TEST_F(TestThreadOperationalDataset, TestPanId) @@ -152,25 +156,7 @@ TEST_F(TestThreadOperationalDataset, TestPSKc) EXPECT_EQ(dataset.SetPSKc(kPSKc), CHIP_NO_ERROR); EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_NO_ERROR); EXPECT_FALSE(memcmp(pskc, kPSKc, sizeof(kPSKc))); -} - -TEST_F(TestThreadOperationalDataset, TestUnsetMasterKey) -{ - - uint8_t masterKey[Thread::kSizeMasterKey] = { 0 }; - EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); - dataset.UnsetMasterKey(); - EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_ERROR_TLV_TAG_NOT_FOUND); - EXPECT_EQ(dataset.SetMasterKey(masterKey), CHIP_NO_ERROR); -} - -TEST_F(TestThreadOperationalDataset, TestUnsetPSKc) -{ - - uint8_t pskc[Thread::kSizePSKc] = { 0 }; - - EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_NO_ERROR); dataset.UnsetPSKc(); EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_ERROR_TLV_TAG_NOT_FOUND); EXPECT_EQ(dataset.SetPSKc(pskc), CHIP_NO_ERROR); @@ -178,45 +164,19 @@ TEST_F(TestThreadOperationalDataset, TestUnsetPSKc) TEST_F(TestThreadOperationalDataset, TestClear) { - - { - uint64_t activeTimestamp; - EXPECT_EQ(dataset.GetActiveTimestamp(activeTimestamp), CHIP_NO_ERROR); - } - - { - uint16_t channel; - EXPECT_EQ(dataset.GetChannel(channel), CHIP_NO_ERROR); - } - - { - uint8_t extendedPanId[Thread::kSizeExtendedPanId] = { 0 }; - EXPECT_EQ(dataset.GetExtendedPanId(extendedPanId), CHIP_NO_ERROR); - } - { + EXPECT_EQ(dataset.SetActiveTimestamp(123), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetChannel(5), CHIP_NO_ERROR); + uint8_t extendedPanId[Thread::kSizeExtendedPanId] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + EXPECT_EQ(dataset.SetExtendedPanId(extendedPanId), CHIP_NO_ERROR); uint8_t masterKey[Thread::kSizeMasterKey] = { 0 }; - EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); - } - - { + EXPECT_EQ(dataset.SetMasterKey(masterKey), CHIP_NO_ERROR); uint8_t meshLocalPrefix[Thread::kSizeMeshLocalPrefix] = { 0 }; - EXPECT_EQ(dataset.GetMeshLocalPrefix(meshLocalPrefix), CHIP_NO_ERROR); - } - - { - char networkName[Thread::kSizeNetworkName + 1] = { 0 }; - EXPECT_EQ(dataset.GetNetworkName(networkName), CHIP_NO_ERROR); - } - - { - uint16_t panid; - EXPECT_EQ(dataset.GetPanId(panid), CHIP_NO_ERROR); - } - - { + EXPECT_EQ(dataset.SetMeshLocalPrefix(meshLocalPrefix), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetNetworkName("w00tw00t"), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetPanId(0x4242), CHIP_NO_ERROR); uint8_t pskc[Thread::kSizePSKc] = { 0 }; - EXPECT_EQ(dataset.GetPSKc(pskc), CHIP_NO_ERROR); + EXPECT_EQ(dataset.SetPSKc(pskc), CHIP_NO_ERROR); } dataset.Clear(); @@ -262,4 +222,103 @@ TEST_F(TestThreadOperationalDataset, TestClear) } } +TEST_F(TestThreadOperationalDataset, TestExampleDataset) +{ + const uint8_t example[] = { + 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Active Timestamp 1 + 0x00, 0x03, 0x00, 0x00, 0x0f, // Channel 15 + 0x35, 0x04, 0x07, 0xff, 0xf8, 0x00, // Channel Mask 0x07fff800 + 0x02, 0x08, 0x39, 0x75, 0x8e, 0xc8, 0x14, 0x4b, 0x07, 0xfb, // Ext PAN ID 39758ec8144b07fb + 0x07, 0x08, 0xfd, 0xf1, 0xf1, 0xad, 0xd0, 0x79, 0x7d, 0xc0, // Mesh Local Prefix fdf1:f1ad:d079:7dc0::/64 + 0x05, 0x10, 0xf3, 0x66, 0xce, 0xc7, 0xa4, 0x46, 0xba, 0xb9, 0x78, 0xd9, 0x0d, 0x27, 0xab, 0xe3, 0x8f, 0x23, // Network Key + 0x03, 0x0f, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x35, 0x39, 0x33, 0x38, // "OpenThread-5938" + 0x01, 0x02, 0x59, 0x38, // PAN ID : 0x5938 + 0x04, 0x10, 0x3c, 0xa6, 0x7c, 0x96, 0x9e, 0xfb, 0x0d, 0x0c, 0x74, 0xa4, 0xd8, 0xee, 0x92, 0x3b, 0x57, 0x6c, // PKSc + 0x0c, 0x04, 0x02, 0xa0, 0xf7, 0xf8, // Security Policy + }; + EXPECT_EQ(dataset.Init(ByteSpan(example)), CHIP_NO_ERROR); + + uint64_t activeTimestamp; + EXPECT_EQ(dataset.GetActiveTimestamp(activeTimestamp), CHIP_NO_ERROR); + EXPECT_EQ(activeTimestamp, 1u); + + uint16_t channel; + EXPECT_EQ(dataset.GetChannel(channel), CHIP_NO_ERROR); + EXPECT_EQ(channel, 15u); + + uint8_t extPanId[Thread::kSizeExtendedPanId]; + EXPECT_EQ(dataset.GetExtendedPanId(extPanId), CHIP_NO_ERROR); + const uint8_t expectedExtPanId[] = { 0x39, 0x75, 0x8e, 0xc8, 0x14, 0x4b, 0x07, 0xfb }; + EXPECT_TRUE(ByteSpan(extPanId).data_equal(ByteSpan(expectedExtPanId))); + + uint8_t meshLocalPrefix[Thread::kSizeMeshLocalPrefix]; + EXPECT_EQ(dataset.GetMeshLocalPrefix(meshLocalPrefix), CHIP_NO_ERROR); + const uint8_t expectedMeshLocalPrefix[] = { 0xfd, 0xf1, 0xf1, 0xad, 0xd0, 0x79, 0x7d, 0xc0 }; + EXPECT_TRUE(ByteSpan(meshLocalPrefix).data_equal(ByteSpan(expectedMeshLocalPrefix))); + + uint8_t masterKey[Thread::kSizeMasterKey]; + EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_NO_ERROR); + const uint8_t expectedMasterKey[] = { 0xf3, 0x66, 0xce, 0xc7, 0xa4, 0x46, 0xba, 0xb9, + 0x78, 0xd9, 0x0d, 0x27, 0xab, 0xe3, 0x8f, 0x23 }; + EXPECT_TRUE(ByteSpan(masterKey).data_equal(ByteSpan(expectedMasterKey))); + + char networkName[Thread::kSizeNetworkName + 1]; + EXPECT_EQ(dataset.GetNetworkName(networkName), CHIP_NO_ERROR); + EXPECT_EQ(strncmp(networkName, "OpenThread-5938", sizeof(networkName)), 0); + + uint16_t panId; + EXPECT_EQ(dataset.GetPanId(panId), CHIP_NO_ERROR); + EXPECT_EQ(panId, 0x5938u); + + uint8_t pksc[Thread::kSizePSKc]; + EXPECT_EQ(dataset.GetPSKc(pksc), CHIP_NO_ERROR); + const uint8_t expectedPksc[] = { + 0x3c, 0xa6, 0x7c, 0x96, 0x9e, 0xfb, 0x0d, 0x0c, 0x74, 0xa4, 0xd8, 0xee, 0x92, 0x3b, 0x57, 0x6c + }; + EXPECT_TRUE(ByteSpan(pksc).data_equal(ByteSpan(expectedPksc))); +} + +TEST_F(TestThreadOperationalDataset, TestInvalidExampleDataset) +{ + const uint8_t invalid[] = { + 0x0e, 0x01, 0x01, // Active Timestamp + 0x00, 0x01, 0x0f, // Channel + 0x35, 0x00, // Channel Mask + 0x02, 0x09, 0x39, 0x75, 0x8e, 0xc8, 0x14, 0x4b, 0x07, 0xfb, 0xff, // Ext PAN ID + 0x07, 0x01, 0x01, // Mesh Local Prefix + 0x05, 0x0f, 0xf3, 0x66, 0xce, 0xc7, 0xa4, 0x46, 0xba, 0xb9, 0x78, 0xd9, 0x0d, 0x27, 0xab, 0xe3, 0x8f, // Network Key + 0x03, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x35, 0x39, 0x33, 0x38, 0xff, 0xff, // Name + 0x01, 0x01, 0xff, // PAN ID + 0x04, 0x01, 0x3c, // PKSc + 0x0c, 0x01, 0x01, // Security Policy + }; + + // The overall TLV structure is valid, but all TLVs have invalid sizes + EXPECT_EQ(dataset.Init(ByteSpan(invalid)), CHIP_NO_ERROR); + + uint64_t activeTimestamp; + EXPECT_EQ(dataset.GetActiveTimestamp(activeTimestamp), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint16_t channel; + EXPECT_EQ(dataset.GetChannel(channel), CHIP_ERROR_INVALID_TLV_ELEMENT); + + ByteSpan extPanId; + EXPECT_EQ(dataset.GetExtendedPanIdAsByteSpan(extPanId), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint8_t meshLocalPrefix[Thread::kSizeMeshLocalPrefix]; + EXPECT_EQ(dataset.GetMeshLocalPrefix(meshLocalPrefix), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint8_t masterKey[Thread::kSizeMasterKey]; + EXPECT_EQ(dataset.GetMasterKey(masterKey), CHIP_ERROR_INVALID_TLV_ELEMENT); + + char networkName[Thread::kSizeNetworkName + 1]; + EXPECT_EQ(dataset.GetNetworkName(networkName), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint16_t panId; + EXPECT_EQ(dataset.GetPanId(panId), CHIP_ERROR_INVALID_TLV_ELEMENT); + + uint8_t pksc[Thread::kSizePSKc]; + EXPECT_EQ(dataset.GetPSKc(pksc), CHIP_ERROR_INVALID_TLV_ELEMENT); +} + } // namespace diff --git a/src/lib/support/tests/TestTimeUtils.cpp b/src/lib/support/tests/TestTimeUtils.cpp index 7d0a69709b8bc4..1b3140399e3c77 100644 --- a/src/lib/support/tests/TestTimeUtils.cpp +++ b/src/lib/support/tests/TestTimeUtils.cpp @@ -29,8 +29,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/lib/support/tests/TestTlvJson.cpp b/src/lib/support/tests/TestTlvJson.cpp index 83b538dad4a755..a845f5fd08be58 100644 --- a/src/lib/support/tests/TestTlvJson.cpp +++ b/src/lib/support/tests/TestTlvJson.cpp @@ -15,11 +15,12 @@ * limitations under the License. */ -#include +#include #include #include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestTlvToJson.cpp b/src/lib/support/tests/TestTlvToJson.cpp index b313b843616671..4fd807303c251a 100644 --- a/src/lib/support/tests/TestTlvToJson.cpp +++ b/src/lib/support/tests/TestTlvToJson.cpp @@ -17,11 +17,12 @@ #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/lib/support/tests/TestUtf8.cpp b/src/lib/support/tests/TestUtf8.cpp index dd078804c1ed5d..1a1062630c2ac5 100644 --- a/src/lib/support/tests/TestUtf8.cpp +++ b/src/lib/support/tests/TestUtf8.cpp @@ -17,10 +17,12 @@ * limitations under the License. */ -#include - #include -#include + +#include + +#include +#include namespace { diff --git a/src/lib/support/tests/TestVariant.cpp b/src/lib/support/tests/TestVariant.cpp index cd51d252dd3a0c..cc8e3031306e73 100644 --- a/src/lib/support/tests/TestVariant.cpp +++ b/src/lib/support/tests/TestVariant.cpp @@ -18,8 +18,9 @@ #include -#include +#include +#include #include namespace { diff --git a/src/lib/support/tests/TestZclString.cpp b/src/lib/support/tests/TestZclString.cpp index 13174248af62d7..cecede7fdf53e5 100644 --- a/src/lib/support/tests/TestZclString.cpp +++ b/src/lib/support/tests/TestZclString.cpp @@ -26,8 +26,9 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/messaging/ReliableMessageProtocolConfig.cpp b/src/messaging/ReliableMessageProtocolConfig.cpp index 01e5779d0c004f..352e89cf4576c1 100644 --- a/src/messaging/ReliableMessageProtocolConfig.cpp +++ b/src/messaging/ReliableMessageProtocolConfig.cpp @@ -32,33 +32,28 @@ #include // nogncheck #endif -#include - namespace chip { using namespace System::Clock::Literals; #if CONFIG_BUILD_FOR_HOST_UNIT_TEST -namespace { -// Use std::optional for globals to avoid static initializers -std::optional gIdleRetransTimeoutOverride; -std::optional gActiveRetransTimeoutOverride; -std::optional gActiveThresholdTimeOverride; -} // namespace +static Optional idleRetransTimeoutOverride = NullOptional; +static Optional activeRetransTimeoutOverride = NullOptional; +static Optional activeThresholdTimeOverride = NullOptional; void OverrideLocalMRPConfig(System::Clock::Timeout idleRetransTimeout, System::Clock::Timeout activeRetransTimeout, System::Clock::Timeout activeThresholdTime) { - gIdleRetransTimeoutOverride = idleRetransTimeout; - gActiveRetransTimeoutOverride = activeRetransTimeout; - gActiveThresholdTimeOverride = activeThresholdTime; + idleRetransTimeoutOverride.SetValue(idleRetransTimeout); + activeRetransTimeoutOverride.SetValue(activeRetransTimeout); + activeThresholdTimeOverride.SetValue(activeThresholdTime); } void ClearLocalMRPConfigOverride() { - gActiveRetransTimeoutOverride = std::nullopt; - gIdleRetransTimeoutOverride = std::nullopt; - gActiveThresholdTimeOverride = std::nullopt; + activeRetransTimeoutOverride.ClearValue(); + idleRetransTimeoutOverride.ClearValue(); + activeThresholdTimeOverride.ClearValue(); } #endif @@ -67,15 +62,14 @@ namespace { // This is not a static member of ReliableMessageProtocolConfig because the free // function GetLocalMRPConfig() needs access to it. -// Use std::optional to avoid a static initializer -std::optional sDynamicLocalMPRConfig; +Optional sDynamicLocalMPRConfig; } // anonymous namespace bool ReliableMessageProtocolConfig::SetLocalMRPConfig(const Optional & localMRPConfig) { auto oldConfig = GetLocalMRPConfig(); - sDynamicLocalMPRConfig = localMRPConfig.std_optional(); + sDynamicLocalMPRConfig = localMRPConfig; return oldConfig != GetLocalMRPConfig(); } #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG @@ -95,9 +89,9 @@ Optional GetLocalMRPConfig() ReliableMessageProtocolConfig config(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); #if CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG - if (sDynamicLocalMPRConfig.has_value()) + if (sDynamicLocalMPRConfig.HasValue()) { - config = sDynamicLocalMPRConfig.value(); + config = sDynamicLocalMPRConfig.Value(); } #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG @@ -111,19 +105,19 @@ Optional GetLocalMRPConfig() #endif #if CONFIG_BUILD_FOR_HOST_UNIT_TEST - if (gIdleRetransTimeoutOverride.has_value()) + if (idleRetransTimeoutOverride.HasValue()) { - config.mIdleRetransTimeout = gIdleRetransTimeoutOverride.value(); + config.mIdleRetransTimeout = idleRetransTimeoutOverride.Value(); } - if (gActiveRetransTimeoutOverride.has_value()) + if (activeRetransTimeoutOverride.HasValue()) { - config.mActiveRetransTimeout = gActiveRetransTimeoutOverride.value(); + config.mActiveRetransTimeout = activeRetransTimeoutOverride.Value(); } - if (gActiveThresholdTimeOverride.has_value()) + if (activeThresholdTimeOverride.HasValue()) { - config.mActiveThresholdTime = gActiveThresholdTimeOverride.value(); + config.mActiveThresholdTime = activeRetransTimeoutOverride.Value(); } #endif diff --git a/src/messaging/ReliableMessageProtocolConfig.h b/src/messaging/ReliableMessageProtocolConfig.h index f8d8cfa9bbf2fe..beceee6c52de46 100644 --- a/src/messaging/ReliableMessageProtocolConfig.h +++ b/src/messaging/ReliableMessageProtocolConfig.h @@ -191,9 +191,8 @@ inline constexpr System::Clock::Milliseconds32 kDefaultActiveTime = System::Cloc */ struct ReliableMessageProtocolConfig { - constexpr ReliableMessageProtocolConfig(System::Clock::Milliseconds32 idleInterval, - System::Clock::Milliseconds32 activeInterval, - System::Clock::Milliseconds16 activeThreshold = kDefaultActiveTime) : + ReliableMessageProtocolConfig(System::Clock::Milliseconds32 idleInterval, System::Clock::Milliseconds32 activeInterval, + System::Clock::Milliseconds16 activeThreshold = kDefaultActiveTime) : mIdleRetransTimeout(idleInterval), mActiveRetransTimeout(activeInterval), mActiveThresholdTime(activeThreshold) {} diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index 9cb017ea512c3a..24e3f47e6806ae 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -65,6 +65,7 @@ chip_test_suite("tests") { ":helpers", "${chip_root}/src/inet/tests:helpers", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/messaging", diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index b5b16cbce73ab8..2b3058a8771515 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -16,6 +16,8 @@ */ #pragma once +#include + #include #include #include @@ -26,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/src/messaging/tests/TestAbortExchangesForFabric.cpp b/src/messaging/tests/TestAbortExchangesForFabric.cpp index 4d54a159bd27be..6bf161bc157d26 100644 --- a/src/messaging/tests/TestAbortExchangesForFabric.cpp +++ b/src/messaging/tests/TestAbortExchangesForFabric.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/src/messaging/tests/TestExchange.cpp b/src/messaging/tests/TestExchange.cpp index ce8a89b3215aa7..f221c999ac4e22 100644 --- a/src/messaging/tests/TestExchange.cpp +++ b/src/messaging/tests/TestExchange.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/src/messaging/tests/TestExchangeHolder.cpp b/src/messaging/tests/TestExchangeHolder.cpp index 44e28b48c2fae3..cafac38bdcb726 100644 --- a/src/messaging/tests/TestExchangeHolder.cpp +++ b/src/messaging/tests/TestExchangeHolder.cpp @@ -25,6 +25,7 @@ #include "messaging/ExchangeDelegate.h" #include "system/SystemClock.h" +#include #include #include #include diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index f944f7792d4b21..679a8cc4050d05 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/src/messaging/tests/TestMessagingLayer.cpp b/src/messaging/tests/TestMessagingLayer.cpp index eafffff1ce6753..2f16cd97cc51a0 100644 --- a/src/messaging/tests/TestMessagingLayer.cpp +++ b/src/messaging/tests/TestMessagingLayer.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 48e26b17b791dd..68b6ed2852d377 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/src/platform/Darwin/ConfigurationManagerImpl.cpp b/src/platform/Darwin/ConfigurationManagerImpl.cpp index ae00faf58d81a1..10a2ad0a8eb600 100644 --- a/src/platform/Darwin/ConfigurationManagerImpl.cpp +++ b/src/platform/Darwin/ConfigurationManagerImpl.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -139,13 +138,10 @@ CHIP_ERROR GetMACAddressFromInterfaces(io_iterator_t primaryInterfaceIterator, u } #endif // TARGET_OS_OSX -namespace { -AtomicGlobal gInstance; -} - ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() { - return gInstance.get(); + static ConfigurationManagerImpl sInstance; + return sInstance; } CHIP_ERROR ConfigurationManagerImpl::Init() diff --git a/src/platform/Darwin/ConfigurationManagerImpl.h b/src/platform/Darwin/ConfigurationManagerImpl.h index 5f99243b95adc4..74a13606be9c53 100644 --- a/src/platform/Darwin/ConfigurationManagerImpl.h +++ b/src/platform/Darwin/ConfigurationManagerImpl.h @@ -34,7 +34,7 @@ namespace chip { namespace DeviceLayer { -inline constexpr int kCountryCodeLength = 2; +static constexpr int kCountryCodeLength = 2; /** * Concrete implementation of the ConfigurationManager singleton object for the Darwin platform. diff --git a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp index caf4e25191575e..6bb1d1bfd79c65 100644 --- a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp +++ b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.cpp @@ -18,7 +18,6 @@ #include "DeviceInstanceInfoProviderImpl.h" -#include #include namespace chip { @@ -34,14 +33,5 @@ CHIP_ERROR DeviceInstanceInfoProviderImpl::GetProductId(uint16_t & productId) return Internal::PosixConfig::ReadConfigValue(Internal::PosixConfig::kConfigKey_ProductId, productId); } -namespace { -AtomicGlobal gInstance; -} // namespace - -DeviceInstanceInfoProviderImpl & DeviceInstanceInfoProviderMgrImpl() -{ - return gInstance.get(); -} - } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h index 48603b583d9f86..630fdbe24c8a12 100644 --- a/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h +++ b/src/platform/Darwin/DeviceInstanceInfoProviderImpl.h @@ -30,13 +30,15 @@ class DeviceInstanceInfoProviderImpl : public Internal::GenericDeviceInstanceInf CHIP_ERROR GetVendorId(uint16_t & vendorId) override; CHIP_ERROR GetProductId(uint16_t & productId) override; - DeviceInstanceInfoProviderImpl() : DeviceInstanceInfoProviderImpl(ConfigurationManagerImpl::GetDefaultInstance()) {} DeviceInstanceInfoProviderImpl(ConfigurationManagerImpl & configManager) : Internal::GenericDeviceInstanceInfoProvider(configManager) {} }; -DeviceInstanceInfoProviderImpl & DeviceInstanceInfoProviderMgrImpl(); - +inline DeviceInstanceInfoProviderImpl & DeviceInstanceInfoProviderMgrImpl() +{ + static DeviceInstanceInfoProviderImpl sInstance(ConfigurationManagerImpl::GetDefaultInstance()); + return sInstance; +} } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 4ff4f9d2d29678..95d2be5c5d1957 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -98,11 +98,15 @@ CHIP_ERROR ESP32FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifi CHIP_ERROR ESP32FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CertDeclaration, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) @@ -123,15 +127,11 @@ CHIP_ERROR ESP32FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & CHIP_ERROR ESP32FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { -#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API - return CopySpanToMutableSpan(mCD, outBuffer); -#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_PAICert, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; -#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) diff --git a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h index fba6a32fa26326..28e26038e6a3e2 100644 --- a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h +++ b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h @@ -106,3 +106,15 @@ #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY 1 #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 #endif + +#ifndef CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE +#define CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE 1 +#endif // CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE + +#ifndef CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD +#define CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD 0 +#endif // CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD + +#ifndef CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM +#define CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM 1 +#endif // CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM diff --git a/src/platform/nxp/common/CHIPDevicePlatformEvent.h b/src/platform/nxp/common/CHIPDevicePlatformEvent.h index 4ea4ffcd304dbe..5c6a5c3c39ecf9 100644 --- a/src/platform/nxp/common/CHIPDevicePlatformEvent.h +++ b/src/platform/nxp/common/CHIPDevicePlatformEvent.h @@ -24,7 +24,7 @@ */ #pragma once -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE #include #include #include @@ -74,7 +74,7 @@ enum InternalPlatformSpecificEventTypes } // namespace DeviceEventType -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE struct BleConnEventType { bt_conn * BtConn; @@ -108,7 +108,7 @@ struct ChipDevicePlatformEvent final { union { -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_USE_ZEPHYR_BLE BleConnEventType BleConnEvent; BleCCCWriteEventType BleCCCWriteEvent; BleC1WriteEventType BleC1WriteEvent; diff --git a/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h index 9282ffb5fe868e..0c263fc6ae3cfa 100644 --- a/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h +++ b/src/platform/nxp/common/CHIPNXPPlatformDefaultConfig.h @@ -217,6 +217,34 @@ #define WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT 2 #endif // WDM_PUBLISHER_MAX_NOTIFIES_IN_FLIGHT +// ==================== ICD Configuration Overrides ==================== + +#ifndef NXP_ICD_ENABLED +#define NXP_ICD_ENABLED 0 +#endif // NXP_ICD_ENABLED + +#if NXP_ICD_ENABLED +#ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC +#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_DURATION_SEC +#endif // CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC + +#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS +#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_DURATION_MS +#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS + +#ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS +#define CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS NXP_ACTIVE_MODE_THRESHOLD +#endif // CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS + +#ifndef CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC +#define CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC +#endif // CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC + +#ifndef CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED +#define CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED 1 +#endif +#endif // NXP_ICD_ENABLED + // ==================== Other Configuration Overrides ==================== #ifndef CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS diff --git a/src/platform/nxp/common/ConfigurationManagerImpl.cpp b/src/platform/nxp/common/ConfigurationManagerImpl.cpp index e99f913369eda8..ad8f00eaf3a4cb 100644 --- a/src/platform/nxp/common/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/common/ConfigurationManagerImpl.cpp @@ -33,6 +33,10 @@ #include "fsl_device_registers.h" +#if CONFIG_BOOT_REASON_SDK_SUPPORT +#include "fsl_power.h" +#endif + #if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA #include "FactoryDataProvider.h" #endif @@ -54,12 +58,61 @@ ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() return sInstance; } +#if CONFIG_BOOT_REASON_SDK_SUPPORT +CHIP_ERROR ConfigurationManagerImpl::DetermineBootReason(uint8_t rebootCause) +{ + /* + With current implementation kBrownOutReset couldn't be catched + */ + BootReasonType bootReason = BootReasonType::kUnspecified; + + if (rebootCause == 0) + { + bootReason = BootReasonType::kPowerOnReboot; + } + + else if (rebootCause == kPOWER_ResetCauseWdt) + { + /* Reboot can be due to hardware or software watchdog */ + bootReason = BootReasonType::kHardwareWatchdogReset; + } + else if (rebootCause == kPOWER_ResetCauseSysResetReq) + { + /* + kConfigKey_SoftwareUpdateCompleted not supported for now + if (NXPConfig::ConfigValueExists(NXPConfig::kConfigKey_SoftwareUpdateCompleted)) + { + bootReason = BootReasonType::kSoftwareUpdateCompleted; + } + else + { + bootReason = BootReasonType::kSoftwareReset; + } + */ + bootReason = BootReasonType::kSoftwareReset; + } + + return StoreBootReason(to_underlying(bootReason)); +} +#endif + +CHIP_ERROR ConfigurationManagerImpl::StoreSoftwareUpdateCompleted() +{ + /* Empty implementation*/ + return CHIP_NO_ERROR; +} + CHIP_ERROR ConfigurationManagerImpl::Init() { CHIP_ERROR err; uint32_t rebootCount = 0; bool failSafeArmed; +#if CONFIG_BOOT_REASON_SDK_SUPPORT + uint8_t rebootCause = POWER_GetResetCause(); + POWER_ClearResetCause(rebootCause); +#endif + // Initialize the generic implementation base class. err = Internal::GenericConfigurationManagerImpl::Init(); SuccessOrExit(err); @@ -84,12 +137,15 @@ CHIP_ERROR ConfigurationManagerImpl::Init() err = StoreTotalOperationalHours(0); SuccessOrExit(err); } - +#if CONFIG_BOOT_REASON_SDK_SUPPORT + SuccessOrExit(err = DetermineBootReason(rebootCause)); +#else if (!NXPConfig::ConfigValueExists(NXPConfig::kCounterKey_BootReason)) { err = StoreBootReason(to_underlying(BootReasonType::kUnspecified)); SuccessOrExit(err); } +#endif // TODO: Initialize the global GroupKeyStore object here diff --git a/src/platform/nxp/common/ConfigurationManagerImpl.h b/src/platform/nxp/common/ConfigurationManagerImpl.h index 062cc9dcac3901..e680942af6e6fe 100644 --- a/src/platform/nxp/common/ConfigurationManagerImpl.h +++ b/src/platform/nxp/common/ConfigurationManagerImpl.h @@ -39,6 +39,7 @@ class ConfigurationManagerImpl final : public Internal::GenericConfigurationMana public: // This returns an instance of this class. static ConfigurationManagerImpl & GetDefaultInstance(); + CHIP_ERROR StoreSoftwareUpdateCompleted(); private: // ===== Members that implement the ConfigurationManager public interface. @@ -78,6 +79,9 @@ class ConfigurationManagerImpl final : public Internal::GenericConfigurationMana // ===== Private members reserved for use by this class only. static void DoFactoryReset(intptr_t arg); +#if CONFIG_BOOT_REASON_SDK_SUPPORT + CHIP_ERROR DetermineBootReason(uint8_t rebootCause); +#endif }; /** diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp index 0386de643455ef..cbdb866ae71973 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp +++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp @@ -32,10 +32,12 @@ #include #endif +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include #include #include #include +#endif #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE #include diff --git a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp index 0dd9b52f6a0aba..93a73d2767b8d3 100644 --- a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp @@ -29,7 +29,10 @@ #include #include + +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include +#endif #if CHIP_DEVICE_CONFIG_ENABLE_WPA extern "C" { diff --git a/src/platform/nxp/common/ThreadStackManagerImpl.cpp b/src/platform/nxp/common/ThreadStackManagerImpl.cpp index b15ad60f0e9578..5667eefc7650ed 100644 --- a/src/platform/nxp/common/ThreadStackManagerImpl.cpp +++ b/src/platform/nxp/common/ThreadStackManagerImpl.cpp @@ -20,8 +20,7 @@ /** * @file * Provides an implementation of the ThreadStackManager object for - * NXP platforms using the NXP SDK and the OpenThread - * stack. + * NXP platforms using the NXP SDK and the OpenThread stack. * */ @@ -32,7 +31,11 @@ #include #include +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include +#else +#include +#endif #include @@ -59,21 +62,44 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) { CHIP_ERROR err = CHIP_NO_ERROR; +#if CHIP_DEVICE_CONFIG_INIT_OT_PLAT_ALARM /* Initialize the OpenThread Alarm module to make sure that if calling otInstance, * it can schedule events */ otPlatAlarmInit(); +#endif // Initialize the generic implementation base classes. err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); SuccessOrExit(err); +#if CHIP_SYSTEM_CONFIG_USE_LWIP err = GenericThreadStackManagerImpl_OpenThread_LwIP::DoInit(NULL); +#else + err = GenericThreadStackManagerImpl_OpenThread::DoInit(NULL); +#endif SuccessOrExit(err); exit: return err; } +#if CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD +void ThreadStackManagerImpl::ProcessThreadActivity() +{ + /* reuse thread task for ble processing. + * by doing this, we avoid allocating a new stack for short-lived + * BLE processing (e.g.: only during Matter commissioning) + */ +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + auto * bleManager = &chip::DeviceLayer::Internal::BLEMgrImpl(); + bleManager->DoBleProcessing(); +#endif + + otTaskletsProcess(OTInstance()); + otSysProcessDrivers(OTInstance()); +} +#endif + bool ThreadStackManagerImpl::IsInitialized() { return sInstance.mThreadStackLock != NULL; @@ -112,3 +138,8 @@ extern "C" void otPlatFree(void * aPtr) { return CHIPPlatformMemoryFree(aPtr); } + +extern "C" void * otPlatRealloc(void * p, size_t aSize) +{ + return CHIPPlatformMemoryRealloc(p, aSize); +} diff --git a/src/platform/nxp/common/ThreadStackManagerImpl.h b/src/platform/nxp/common/ThreadStackManagerImpl.h index 6f9fae80950670..83990db21569dc 100644 --- a/src/platform/nxp/common/ThreadStackManagerImpl.h +++ b/src/platform/nxp/common/ThreadStackManagerImpl.h @@ -28,7 +28,11 @@ #include #include #include +#if CHIP_SYSTEM_CONFIG_USE_LWIP #include +#else +#include +#endif extern "C" void otSysEventSignalPending(void); @@ -43,7 +47,11 @@ class ThreadStackManagerImpl; * using the NXP SDK and the OpenThread stack. */ class ThreadStackManagerImpl final : public ThreadStackManager, +#if CHIP_SYSTEM_CONFIG_USE_LWIP public Internal::GenericThreadStackManagerImpl_OpenThread_LwIP, +#else + public Internal::GenericThreadStackManagerImpl_OpenThread, +#endif public Internal::GenericThreadStackManagerImpl_FreeRTOS { // Allow the ThreadStackManager interface class to delegate method calls to @@ -53,8 +61,11 @@ class ThreadStackManagerImpl final : public ThreadStackManager, // Allow the generic implementation base classes to call helper methods on // this class. #ifndef DOXYGEN_SHOULD_SKIP_THIS - friend Internal::GenericThreadStackManagerImpl_OpenThread; +#if CHIP_SYSTEM_CONFIG_USE_LWIP friend Internal::GenericThreadStackManagerImpl_OpenThread_LwIP; +#else + friend Internal::GenericThreadStackManagerImpl_OpenThread; +#endif friend Internal::GenericThreadStackManagerImpl_FreeRTOS; #endif @@ -66,6 +77,11 @@ class ThreadStackManagerImpl final : public ThreadStackManager, public: // ===== Platform-specific members that may be accessed directly by the application. +#if CHIP_DEVICE_CONFIG_PROCESS_BLE_IN_THREAD + using ThreadStackManager::ProcessThreadActivity; + void ProcessThreadActivity(); +#endif + protected: // ===== Methods that implement the ThreadStackManager abstract interface. CHIP_ERROR _InitThreadStack(void); diff --git a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp new file mode 100644 index 00000000000000..e977708fe4862a --- /dev/null +++ b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 2023-2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BLEAdvertisingArbiter.h" + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace BLEAdvertisingArbiter { +namespace { + +// List of advertising requests ordered by priority +sys_slist_t sRequests; + +// Cast an intrusive list node to the containing request object +const BLEAdvertisingArbiter::Request & ToRequest(const sys_snode_t * node) +{ + return *static_cast(node); +} + +// Notify application about stopped advertising if the callback has been provided +void NotifyAdvertisingStopped(const sys_snode_t * node) +{ + VerifyOrReturn(node); + + const Request & request = ToRequest(node); + + if (request.onStopped != nullptr) + { + request.onStopped(); + } +} + +// Restart advertising using the top-priority request +CHIP_ERROR RestartAdvertising() +{ + // Note: bt_le_adv_stop() returns success when the advertising was not started + ReturnErrorOnFailure(MapErrorZephyr(bt_le_adv_stop())); + ReturnErrorCodeIf(sys_slist_is_empty(&sRequests), CHIP_NO_ERROR); + + const Request & top = ToRequest(sys_slist_peek_head(&sRequests)); + const bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(top.options, top.minInterval, top.maxInterval, nullptr); + const int result = bt_le_adv_start(¶ms, top.advertisingData.data(), top.advertisingData.size(), top.scanResponseData.data(), + top.scanResponseData.size()); + + if (top.onStarted != nullptr) + { + top.onStarted(result); + } + + return MapErrorZephyr(result); +} + +} // namespace + +CHIP_ERROR InsertRequest(Request & request) +{ + CancelRequest(request); + + sys_snode_t * prev = nullptr; + sys_snode_t * node = nullptr; + + // Find position of the request in the list that preserves ordering by priority + SYS_SLIST_FOR_EACH_NODE(&sRequests, node) + { + if (request.priority < ToRequest(node).priority) + { + break; + } + + prev = node; + } + + if (prev == nullptr) + { + NotifyAdvertisingStopped(sys_slist_peek_head(&sRequests)); + sys_slist_prepend(&sRequests, &request); + } + else + { + sys_slist_insert(&sRequests, prev, &request); + } + + // If the request is top-priority, restart the advertising + if (sys_slist_peek_head(&sRequests) == &request) + { + return RestartAdvertising(); + } + + return CHIP_NO_ERROR; +} + +void CancelRequest(Request & request) +{ + const bool isTopPriority = (sys_slist_peek_head(&sRequests) == &request); + VerifyOrReturn(sys_slist_find_and_remove(&sRequests, &request)); + + // If cancelled request was top-priority, restart the advertising. + if (isTopPriority) + { + RestartAdvertising(); + } +} + +} // namespace BLEAdvertisingArbiter + +/** + * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the + * Zephyr OS user API stack errors into the POSIX range. + * + * @param[in] aError The native Zephyr API error to map. + * + * @return The mapped POSIX error. + */ +DLL_EXPORT CHIP_ERROR MapErrorZephyr(int aError) +{ + return chip::System::Internal::MapErrorPOSIX(-aError); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h new file mode 100644 index 00000000000000..9c00edbb8e746d --- /dev/null +++ b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h @@ -0,0 +1,107 @@ +/* + * + * Copyright (c) 2023-2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include + +#include + +/** + * @file + * Bluetooth LE advertising arbiter. + * + * The purpose for this module is to coordinate BLE advertising between + * different application components. + * + * An application component that wants to advertise BLE services is expected to + * define a request with a desired priority, and pass it to the BLE advertising + * arbiter. If there are multiple components that request BLE advertising at the + * same time, the arbiter selects the one with the highest priority (represented + * by the lowest numeric value) and starts the BLE advertising using parameters + * defined in the winning request. + * + * The BLE arbiter does not take ownership of a submitted request, so the + * request object must be sustained until it is cancelled by the application. + */ + +namespace chip { +namespace DeviceLayer { +namespace BLEAdvertisingArbiter { + +using OnAdvertisingStarted = void (*)(int result); +using OnAdvertisingStopped = void (*)(); + +struct Request : public sys_snode_t +{ + uint8_t priority; ///< Advertising request priority. Lower value means higher priority + uint32_t options; ///< Advertising options: bitmask of BT_LE_ADV_OPT_XXX constants from Zephyr + uint16_t minInterval; ///< Minimum advertising interval in 0.625 ms units + uint16_t maxInterval; ///< Maximum advertising interval in 0.625 ms units + Span advertisingData; ///< Advertising data fields + Span scanResponseData; ///< Scan response data fields + OnAdvertisingStarted onStarted; ///< (Optional) Callback invoked when the request becomes top-priority. + OnAdvertisingStopped onStopped; ///< (Optional) Callback invoked when the request stops being top-priority. +}; + +/** + * @brief Request BLE advertising + * + * Add the request to the internal list of competing requests. If the request + * has higher priority than other requests in the list, restart the BLE + * advertising immediately using parameters defined in the new request. + * + * Inserting a request object that is already registered at the advertising + * arbiter automatically cancels the previous request. + * + * @note This method does not take ownership of the request object so the object + * must not get destroyed before it is cancelled. + * + * @param request Reference to advertising request that contains priority and + * other advertising parameters. + * @return error If the request is top-priority and failed to restart the + * advertising. + * @return success Otherwise. + */ +CHIP_ERROR InsertRequest(Request & request); + +/** + * @brief Cancel BLE advertising request + * + * Remove the request from the internal list of competing requests. If the + * request is the winning (top-priority) one at the time of calling this + * function, restart the BLE advertising using parameters defined in the 2nd + * top-priority request in the list, or stop the BLE advertising completely if + * this is the last request in the list. + * + * An attempt to cancel a request that has not been registered at the + * advertising arbiter is a no-op. That is, it returns immediately. + * + * @param request Reference to advertising request that contains priority and + * other advertising parameters. + */ +void CancelRequest(Request & request); + +} // namespace BLEAdvertisingArbiter + +extern CHIP_ERROR MapErrorZephyr(int code); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.cpp b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..0b986033054fbe --- /dev/null +++ b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.cpp @@ -0,0 +1,849 @@ +/* + * + * Copyright (c) 2020-2022, 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for Zephyr platforms. + */ + +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include "BLEManagerImpl.h" + +#include +#include +#include +#include +#include +#include +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +using namespace ::chip; +using namespace ::chip::Ble; +using namespace ::chip::System; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { + +constexpr uint32_t kAdvertisingOptions = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME; +constexpr uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR; + +const bt_uuid_128 UUID128_CHIPoBLEChar_RX = + BT_UUID_INIT_128(0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +const bt_uuid_128 UUID128_CHIPoBLEChar_TX = + BT_UUID_INIT_128(0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +const bt_uuid_128 UUID128_CHIPoBLEChar_C3 = + BT_UUID_INIT_128(0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64); +#endif + +bt_uuid_16 UUID16_CHIPoBLEService = BT_UUID_INIT_16(0xFFF6); + +const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; + +const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; + +_bt_gatt_ccc CHIPoBLEChar_TX_CCC = BT_GATT_CCC_INITIALIZER(nullptr, BLEManagerImpl::HandleTXCCCWrite, nullptr); + +// clang-format off + +bt_gatt_attr sChipoBleAttributes[] = { + BT_GATT_PRIMARY_SERVICE(&UUID16_CHIPoBLEService.uuid), + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_RX.uuid, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, + nullptr, BLEManagerImpl::HandleRXWrite, nullptr), + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_TX.uuid, + BT_GATT_CHRC_INDICATE, + BT_GATT_PERM_NONE, + nullptr, nullptr, nullptr), + BT_GATT_CCC_MANAGED(&CHIPoBLEChar_TX_CCC, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_C3.uuid, + BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, + BLEManagerImpl::HandleC3Read, nullptr, nullptr), +#endif +}; + +bt_gatt_service sChipoBleService = BT_GATT_SERVICE(sChipoBleAttributes); + +// clang-format on + +// Index of the CCC descriptor in the CHIPoBLE_Service array of attributes. +// This value should be adjusted accordingly if the service declaration changes. +constexpr int kCHIPoBLE_CCC_AttributeIndex = 3; + +CHIP_ERROR InitRandomStaticAddress() +{ + // Generate a random static address for the default identity. + // This must be done before bt_enable() as after that updating the default identity is not possible. + int error = 0; + bt_addr_le_t addr; + + // generating the address + addr.type = BT_ADDR_LE_RANDOM; + error = sys_csrand_get(addr.a.val, sizeof(addr.a.val)); + BT_ADDR_SET_STATIC(&addr.a); + + if (error) + { + ChipLogError(DeviceLayer, "Failed to create BLE address: %d", error); + return MapErrorZephyr(error); + } + + error = bt_id_create(&addr, nullptr); + + if (error < 0) + { + ChipLogError(DeviceLayer, "Failed to create BLE identity: %d", error); + return MapErrorZephyr(error); + } + + ChipLogProgress(DeviceLayer, "BLE address: %02X:%02X:%02X:%02X:%02X:%02X", addr.a.val[5], addr.a.val[4], addr.a.val[3], + addr.a.val[2], addr.a.val[1], addr.a.val[0]); + return CHIP_NO_ERROR; +} + +} // unnamed namespace + +BLEManagerImpl BLEManagerImpl::sInstance; + +CHIP_ERROR BLEManagerImpl::_Init() +{ + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + mGAPConns = 0; + + memset(mSubscribedConns, 0, sizeof(mSubscribedConns)); + + ReturnErrorOnFailure(InitRandomStaticAddress()); + int err = bt_enable(NULL); + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + memset(&mConnCallbacks, 0, sizeof(mConnCallbacks)); + mConnCallbacks.connected = HandleConnect; + mConnCallbacks.disconnected = HandleDisconnect; + + bt_conn_cb_register(&mConnCallbacks); + + // Initialize the CHIP BleLayer. + ReturnErrorOnFailure(BleLayer::Init(this, this, &DeviceLayer::SystemLayer())); + + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return CHIP_NO_ERROR; +} + +void BLEManagerImpl::DriveBLEState(intptr_t arg) +{ + BLEMgrImpl().DriveBLEState(); +} + +void BLEManagerImpl::DriveBLEState() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Perform any initialization actions that must occur after the CHIP task is running. + if (!mFlags.Has(Flags::kAsyncInitCompleted)) + { + mFlags.Set(Flags::kAsyncInitCompleted); + } + + // If the application has enabled CHIPoBLE and BLE advertising... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && + mFlags.Has(Flags::kAdvertisingEnabled) +#if CHIP_DEVICE_CONFIG_CHIPOBLE_SINGLE_CONNECTION + // and no connections are active... + && (NumConnections() == 0) +#endif + ) + { + // Start/re-start advertising if not already advertising, or if the + // advertising state needs to be refreshed. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kAdvertisingRefreshNeeded)) + { + mFlags.Clear(Flags::kAdvertisingRefreshNeeded); + err = StartAdvertising(); + SuccessOrExit(err); + } + } + else + { + if (mFlags.Has(Flags::kAdvertising)) + { + err = StopAdvertising(); + SuccessOrExit(err); + } + + // If no connections are active unregister also CHIPoBLE GATT service + if (NumConnections() == 0 && mFlags.Has(Flags::kChipoBleGattServiceRegister)) + { + // Unregister CHIPoBLE service to not allow discovering it when pairing is disabled. + if (bt_gatt_service_unregister(&sChipoBleService) != 0) + { + ChipLogError(DeviceLayer, "Failed to unregister CHIPoBLE GATT service"); + } + else + { + mFlags.Clear(Flags::kChipoBleGattServiceRegister); + } + } + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format()); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +struct BLEManagerImpl::ServiceData +{ + uint8_t uuid[2]; + ChipBLEDeviceIdentificationInfo deviceIdInfo; +} __attribute__((packed)); + +inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest() +{ + static ServiceData serviceData; + static std::array advertisingData; + static std::array scanResponseData; + static_assert(sizeof(serviceData) == 10, "Unexpected size of BLE advertising data!"); + + const char * name = bt_get_name(); + const uint8_t nameSize = static_cast(strlen(name)); + + Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val); + ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo)); + + advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags)); + advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData)); + scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize); + + mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY; + mAdvertisingRequest.options = kAdvertisingOptions; + mAdvertisingRequest.minInterval = mFlags.Has(Flags::kFastAdvertisingEnabled) + ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN + : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + mAdvertisingRequest.maxInterval = mFlags.Has(Flags::kFastAdvertisingEnabled) + ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX + : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + mAdvertisingRequest.advertisingData = Span(advertisingData); + mAdvertisingRequest.scanResponseData = nameSize ? Span(scanResponseData) : Span{}; + + mAdvertisingRequest.onStarted = [](int rc) { + if (rc == 0) + { + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising started"); + } + else + { + ChipLogError(DeviceLayer, "Failed to start CHIPoBLE advertising: %d", rc); + } + }; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::StartAdvertising() +{ + // Prepare advertising request + ReturnErrorOnFailure(PrepareAdvertisingRequest()); + + // Register dynamically CHIPoBLE GATT service + if (!mFlags.Has(Flags::kChipoBleGattServiceRegister)) + { + int err = bt_gatt_service_register(&sChipoBleService); + + if (err != 0) + ChipLogError(DeviceLayer, "Failed to register CHIPoBLE GATT service"); + + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + mFlags.Set(Flags::kChipoBleGattServiceRegister); + } + + // Initialize C3 characteristic data +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + ReturnErrorOnFailure(PrepareC3CharData()); +#endif + + // Request advertising + ReturnErrorOnFailure(BLEAdvertisingArbiter::InsertRequest(mAdvertisingRequest)); + + // Transition to the Advertising state... + if (!mFlags.Has(Flags::kAdvertising)) + { + mFlags.Set(Flags::kAdvertising); + + // Post a CHIPoBLEAdvertisingChange(Started) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&advChange)); + } + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + // Start timer to change advertising interval. + DeviceLayer::SystemLayer().StartTimer( + System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME), + HandleBLEAdvertisementIntervalChange, this); + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::StopAdvertising() +{ + BLEAdvertisingArbiter::CancelRequest(mAdvertisingRequest); + + // Transition to the not Advertising state... + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); + + // Post a CHIPoBLEAdvertisingChange(Stopped) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&advChange)); + } + + // Cancel timer event changing CHIPoBLE advertisement interval + DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off"); + + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + break; + case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, false); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + Platform::CopyString(buf, bufSize, bt_get_name()); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + ChipLogDetail(DeviceLayer, "Device name set to: %s", deviceName); + return MapErrorZephyr(bt_set_name(deviceName)); +} + +CHIP_ERROR BLEManagerImpl::HandleGAPConnect(const ChipDeviceEvent * event) +{ + const BleConnEventType * connEvent = &event->Platform.BleConnEvent; + + if (connEvent->HciResult == BT_HCI_ERR_SUCCESS) + { + ChipLogProgress(DeviceLayer, "BLE connection established (ConnId: 0x%02x)", bt_conn_index(connEvent->BtConn)); + mGAPConns++; + } + else + { + ChipLogError(DeviceLayer, "BLE connection failed (reason: 0x%02x)", connEvent->HciResult); + } + + ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", NumConnections(), CONFIG_BT_MAX_CONN); + + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + bt_conn_unref(connEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event) +{ + const BleConnEventType * connEvent = &event->Platform.BleConnEvent; + + ChipLogProgress(DeviceLayer, "BLE GAP connection terminated (reason 0x%02x)", connEvent->HciResult); + + mGAPConns--; + + // If indications were enabled for this connection, record that they are now disabled and + // notify the BLE Layer of a disconnect. + if (UnsetSubscribed(connEvent->BtConn)) + { + CHIP_ERROR disconReason; + switch (connEvent->HciResult) + { + case BT_HCI_ERR_REMOTE_USER_TERM_CONN: + // Do not treat proper connection termination as an error and exit. + VerifyOrExit(!ConfigurationMgr().IsFullyProvisioned(), ); + disconReason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + break; + case BT_HCI_ERR_LOCALHOST_TERM_CONN: + disconReason = BLE_ERROR_APP_CLOSED_CONNECTION; + break; + default: + disconReason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; + break; + } + HandleConnectionError(connEvent->BtConn, disconReason); + } + +exit: + // Unref bt_conn before scheduling DriveBLEState. + bt_conn_unref(connEvent->BtConn); + + ChipLogProgress(DeviceLayer, "Current number of connections: %u/%u", NumConnections(), CONFIG_BT_MAX_CONN); + + ChipDeviceEvent disconnectEvent; + disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&disconnectEvent)); + + // Force a reconfiguration of advertising in case we switched to non-connectable mode when + // the BLE connection was established. + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleTXCharCCCDWrite(const ChipDeviceEvent * event) +{ + const BleCCCWriteEventType * writeEvent = &event->Platform.BleCCCWriteEvent; + + ChipLogDetail(DeviceLayer, "ConnId: 0x%02x, New CCCD value: 0x%04x", bt_conn_index(writeEvent->BtConn), writeEvent->Value); + + // If the client has requested to enable indications and if it is not yet subscribed + if (writeEvent->Value == BT_GATT_CCC_INDICATE && SetSubscribed(writeEvent->BtConn)) + { + // Alert the BLE layer that CHIPoBLE "subscribe" has been received and increment the bt_conn reference counter. + HandleSubscribeReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + + ChipLogProgress(DeviceLayer, "CHIPoBLE connection established (ConnId: 0x%02x, GATT MTU: %u)", + bt_conn_index(writeEvent->BtConn), GetMTU(writeEvent->BtConn)); + + // Post a CHIPoBLEConnectionEstablished event to the DeviceLayer and the application. + { + ChipDeviceEvent conEstEvent; + conEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + ReturnErrorOnFailure(PlatformMgr().PostEvent(&conEstEvent)); + } + } + else + { + if (UnsetSubscribed(writeEvent->BtConn)) + { + HandleUnsubscribeReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + } + } + + bt_conn_unref(writeEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleRXCharWrite(const ChipDeviceEvent * event) +{ + const BleC1WriteEventType * c1WriteEvent = &event->Platform.BleC1WriteEvent; + + ChipLogDetail(DeviceLayer, "Write request received for CHIPoBLE RX characteristic (ConnId 0x%02x)", + bt_conn_index(c1WriteEvent->BtConn)); + + HandleWriteReceived(c1WriteEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(c1WriteEvent->Data)); + bt_conn_unref(c1WriteEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleTXCharComplete(const ChipDeviceEvent * event) +{ + const BleC2IndDoneEventType * c2IndDoneEvent = &event->Platform.BleC2IndDoneEvent; + + ChipLogDetail(DeviceLayer, "Indication for CHIPoBLE TX characteristic done (ConnId 0x%02x, result 0x%02x)", + bt_conn_index(c2IndDoneEvent->BtConn), c2IndDoneEvent->Result); + + // Signal the BLE Layer that the outstanding indication is complete. + HandleIndicationConfirmation(c2IndDoneEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + bt_conn_unref(c2IndDoneEvent->BtConn); + + return CHIP_NO_ERROR; +} + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +CHIP_ERROR BLEManagerImpl::PrepareC3CharData() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BitFlags additionalDataFields; + AdditionalDataPayloadGeneratorParams additionalDataPayloadParams; + +#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) + uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {}; + MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId); + + err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan); + SuccessOrExit(err); + err = ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter); + SuccessOrExit(err); + additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan; + additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId); +#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) */ + + err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(additionalDataPayloadParams, c3CharDataBufferHandle, + additionalDataFields); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); + } + + return err; +} +#endif + +void BLEManagerImpl::HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param) +{ + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to slow"); +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + switch (event->Type) + { + case DeviceEventType::kPlatformZephyrBleConnected: + err = HandleGAPConnect(event); + break; + + case DeviceEventType::kPlatformZephyrBleDisconnected: + err = HandleGAPDisconnect(event); + break; + + case DeviceEventType::kPlatformZephyrBleCCCWrite: + err = HandleTXCharCCCDWrite(event); + break; + + case DeviceEventType::kPlatformZephyrBleC1WriteEvent: + err = HandleRXCharWrite(event); + break; + + case DeviceEventType::kPlatformZephyrBleC2IndDoneEvent: + err = HandleTXCharComplete(event); + break; + + default: + break; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %" CHIP_ERROR_FORMAT, err.Format()); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + return mGAPConns; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (ConnId %02x)", bt_conn_index(conId)); + return bt_conn_disconnect(conId, BT_HCI_ERR_REMOTE_USER_TERM_CONN) == 0; +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + return bt_gatt_get_mtu(conId); +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + int status = 0; + uint8_t index = bt_conn_index(conId); + bt_gatt_indicate_params * params = &mIndicateParams[index]; + + VerifyOrExit(IsSubscribed(conId) == true, err = CHIP_ERROR_INVALID_ARGUMENT); + + ChipLogDetail(DeviceLayer, "Sending indication for CHIPoBLE TX characteristic (ConnId %02x, len %u)", index, + pBuf->DataLength()); + + params->uuid = nullptr; + params->attr = &sChipoBleAttributes[kCHIPoBLE_CCC_AttributeIndex]; + params->func = HandleTXIndicated; + params->data = pBuf->Start(); + params->len = pBuf->DataLength(); + + status = bt_gatt_indicate(conId, params); + VerifyOrExit(status == 0, err = MapErrorZephyr(status)); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %" CHIP_ERROR_FORMAT, err.Format()); + } + + return err == CHIP_NO_ERROR; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogDetail(DeviceLayer, "BLE central not implemented"); + return false; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + CloseConnection(conId); +} + +bool BLEManagerImpl::IsSubscribed(bt_conn * conn) +{ + return mSubscribedConns[bt_conn_index(conn)]; +} + +bool BLEManagerImpl::SetSubscribed(bt_conn * conn) +{ + uint8_t index = bt_conn_index(conn); + bool isSubscribed = mSubscribedConns[index]; + mSubscribedConns[index] = true; + + // If we were not subscribed previously, increment the reference counter of the connection. + if (!isSubscribed) + { + bt_conn_ref(conn); + } + + return !isSubscribed; +} + +bool BLEManagerImpl::UnsetSubscribed(bt_conn * conn) +{ + uint8_t index = bt_conn_index(conn); + bool isSubscribed = mSubscribedConns[index]; + mSubscribedConns[index] = false; + + // If we were subscribed previously, decrement the reference counter of the connection. + if (isSubscribed) + { + bt_conn_unref(conn); + } + + return isSubscribed; +} + +ssize_t BLEManagerImpl::HandleRXWrite(struct bt_conn * conId, const struct bt_gatt_attr * attr, const void * buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + ChipDeviceEvent event; + PacketBufferHandle packetBuf = PacketBufferHandle::NewWithData(buf, len); + + if (!packetBuf.IsNull()) + { + // Arrange to post a CHIPoBLERXWriteEvent event to the CHIP queue. + event.Type = DeviceEventType::kPlatformZephyrBleC1WriteEvent; + event.Platform.BleC1WriteEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleC1WriteEvent.Data = std::move(packetBuf).UnsafeRelease(); + } + + // If we failed to allocate a buffer, post a kPlatformZephyrBleOutOfBuffersEvent event. + else + { + event.Type = DeviceEventType::kPlatformZephyrBleOutOfBuffersEvent; + } + + PlatformMgr().PostEventOrDie(&event); + + return len; +} + +ssize_t BLEManagerImpl::HandleTXCCCWrite(struct bt_conn * conId, const struct bt_gatt_attr * attr, uint16_t value) +{ + ChipDeviceEvent event; + + if (value != BT_GATT_CCC_INDICATE && value != 0) + { + return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED); + } + + event.Type = DeviceEventType::kPlatformZephyrBleCCCWrite; + event.Platform.BleCCCWriteEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleCCCWriteEvent.Value = value; + + PlatformMgr().PostEventOrDie(&event); + + return sizeof(value); +} + +void BLEManagerImpl::HandleTXIndicated(struct bt_conn * conId, bt_gatt_indicate_params *, uint8_t err) +{ + ChipDeviceEvent event; + + event.Type = DeviceEventType::kPlatformZephyrBleC2IndDoneEvent; + event.Platform.BleC2IndDoneEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleC2IndDoneEvent.Result = err; + + PlatformMgr().PostEventOrDie(&event); +} + +void BLEManagerImpl::HandleConnect(struct bt_conn * conId, uint8_t err) +{ + ChipDeviceEvent event; + + PlatformMgr().LockChipStack(); + + // Don't handle BLE connecting events when it is not related to CHIPoBLE + VerifyOrExit(sInstance.mFlags.Has(Flags::kChipoBleGattServiceRegister), ); + + event.Type = DeviceEventType::kPlatformZephyrBleConnected; + event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleConnEvent.HciResult = err; + + PlatformMgr().PostEventOrDie(&event); + +exit: + PlatformMgr().UnlockChipStack(); +} + +void BLEManagerImpl::HandleDisconnect(struct bt_conn * conId, uint8_t reason) +{ + ChipDeviceEvent event; + + PlatformMgr().LockChipStack(); + + // Don't handle BLE disconnecting events when it is not related to CHIPoBLE + VerifyOrExit(sInstance.mFlags.Has(Flags::kChipoBleGattServiceRegister), ); + + event.Type = DeviceEventType::kPlatformZephyrBleDisconnected; + event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleConnEvent.HciResult = reason; + + PlatformMgr().PostEventOrDie(&event); + +exit: + PlatformMgr().UnlockChipStack(); +} + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +ssize_t BLEManagerImpl::HandleC3Read(struct bt_conn * conId, const struct bt_gatt_attr * attr, void * buf, uint16_t len, + uint16_t offset) +{ + ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE C3 (ConnId 0x%02x)", bt_conn_index(conId)); + + if (sInstance.c3CharDataBufferHandle.IsNull()) + { + return 0; + } + + return bt_gatt_attr_read(conId, attr, buf, len, offset, sInstance.c3CharDataBufferHandle->Start(), + sInstance.c3CharDataBufferHandle->DataLength()); +} +#endif + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h index 411392aa3c6a8c..e80faebe45abc1 100644 --- a/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h +++ b/src/platform/nxp/common/ble_zephyr/BLEManagerImpl.h @@ -1,8 +1,6 @@ /* * - * Copyright (c) 2020-2021 Project CHIP Authors - * Copyright (c) 2020 Nest Labs, Inc. - * All rights reserved. + * Copyright (c) 2020-2021, 2024 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +18,180 @@ /** * @file * Provides an implementation of the BLEManager singleton object - * for the nxp platforms. + * for the NXP platforms. */ #pragma once +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include "BLEAdvertisingArbiter.h" + +#include +#include +#include + #include -#include #include #include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +/** + * Concrete implementation of the BLEManager singleton object for the Zephyr platforms. + */ +class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + +private: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + void _Shutdown() {} + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId); + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId); + bool CloseConnection(BLE_CONNECTION_OBJECT conId); + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const; + bool SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, + const ChipBleUUID * charId); + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId); + + // ===== Private members reserved for use by this class only. + + enum class Flags : uint8_t + { + kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */ + kAdvertisingEnabled = 0x0002, /**< The application has enabled CHIPoBLE advertising. */ + kFastAdvertisingEnabled = 0x0004, /**< The application has enabled fast advertising. */ + kAdvertising = 0x0008, /**< The system is currently CHIPoBLE advertising. */ + kAdvertisingRefreshNeeded = + 0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */ + kChipoBleGattServiceRegister = 0x0020, /**< The system has currently CHIPoBLE GATT service registered. */ + }; + + struct ServiceData; + + BitFlags mFlags; + uint16_t mGAPConns; + CHIPoBLEServiceMode mServiceMode; + bool mSubscribedConns[CONFIG_BT_MAX_CONN]; + bt_gatt_indicate_params mIndicateParams[CONFIG_BT_MAX_CONN]; + bt_conn_cb mConnCallbacks; + BLEAdvertisingArbiter::Request mAdvertisingRequest = {}; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + PacketBufferHandle c3CharDataBufferHandle; +#endif + + void DriveBLEState(void); + CHIP_ERROR PrepareAdvertisingRequest(); + CHIP_ERROR StartAdvertising(void); + CHIP_ERROR StopAdvertising(void); + CHIP_ERROR HandleGAPConnect(const ChipDeviceEvent * event); + CHIP_ERROR HandleGAPDisconnect(const ChipDeviceEvent * event); + CHIP_ERROR HandleRXCharWrite(const ChipDeviceEvent * event); + CHIP_ERROR HandleTXCharCCCDWrite(const ChipDeviceEvent * event); + CHIP_ERROR HandleTXCharComplete(const ChipDeviceEvent * event); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + CHIP_ERROR PrepareC3CharData(); +#endif + bool IsSubscribed(bt_conn * conn); + bool SetSubscribed(bt_conn * conn); + bool UnsetSubscribed(bt_conn * conn); + uint32_t GetAdvertisingInterval(); + + static void DriveBLEState(intptr_t arg); + + // Below callbacks run from the system workqueue context and have a limited stack capacity. + static void HandleTXIndicated(bt_conn * conn, bt_gatt_indicate_params * attr, uint8_t err); + static void HandleConnect(bt_conn * conn, uint8_t err); + static void HandleDisconnect(bt_conn * conn, uint8_t reason); + static void HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param); + + // ===== Members for internal use by the following friends. + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; + +public: + // Below callbacks are public in order to be visible from the global scope. + static ssize_t HandleRXWrite(bt_conn * conn, const bt_gatt_attr * attr, const void * buf, uint16_t len, uint16_t offset, + uint8_t flags); + static ssize_t HandleTXCCCWrite(bt_conn * conn, const bt_gatt_attr * attr, uint16_t value); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + static ssize_t HandleC3Read(struct bt_conn * conn, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset); +#endif +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr(void) +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the BLEManager singleton object. + * + * Internal components can use this to gain access to features of the BLEManager + * that are specific to the Zephyr platforms. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +inline bool BLEManagerImpl::_IsAdvertisingEnabled(void) +{ + return mFlags.Has(Flags::kAdvertisingEnabled); +} + +inline bool BLEManagerImpl::_IsAdvertising(void) +{ + return mFlags.Has(Flags::kAdvertising); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 0e3558b8bf916a..7337f896c8ddcc 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -83,20 +83,20 @@ static_library("nxp_platform") { sources += [ "../../common/NXPConfigKS.cpp" ] } - public_deps = [ "${chip_root}/src/platform:platform_base" ] - - deps += [ "${chip_root}/src/platform/logging:headers" ] - if (chip_enable_ble) { sources += [ # Adding random file which defines the function sys_csrand_get which is called by BLEManagerImpl from Zephyr "${nxp_sdk_build_root}/${nxp_sdk_name}/sdk_hook/zephyr/random/random.cpp", - "../../../Zephyr/BLEAdvertisingArbiter.cpp", - "../../../Zephyr/BLEManagerImpl.cpp", + "../../common/ble_zephyr/BLEAdvertisingArbiter.cpp", + "../../common/ble_zephyr/BLEManagerImpl.cpp", "../../common/ble_zephyr/BLEManagerImpl.h", ] } + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + deps += [ "${chip_root}/src/platform/logging:headers" ] + # define CHIP_PLAT_NVM_SUPPORT - See NXPConfig.cpp for definition if (rt_nvm_component == "nvm_fwk") { defines += [ "CHIP_PLAT_NVM_SUPPORT=1" ] diff --git a/src/platform/silabs/KeyValueStoreManagerImpl.cpp b/src/platform/silabs/KeyValueStoreManagerImpl.cpp index 8f886dba84ba67..012c951aaaa729 100644 --- a/src/platform/silabs/KeyValueStoreManagerImpl.cpp +++ b/src/platform/silabs/KeyValueStoreManagerImpl.cpp @@ -164,15 +164,9 @@ void KeyValueStoreManagerImpl::ScheduleKeyMapSave(void) During commissioning, the key map will be modified multiples times subsequently. Commit the key map in nvm once it as stabilized. */ -#if SLI_SI91X_MCU_INTERFACE && CHIP_CONFIG_ENABLE_ICD_SERVER - // TODO: Remove this when RTC timer is added MATTER-2705 - SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsKeyMap), - sizeof(mKvsKeyMap)); -#else SystemLayer().StartTimer( std::chrono::duration_cast(System::Clock::Seconds32(SILABS_KVS_SAVE_DELAY_SECONDS)), KeyValueStoreManagerImpl::OnScheduledKeyMapSave, NULL); -#endif // defined(SLI_SI91X_MCU_INTERFACE) && CHIP_CONFIG_ENABLE_ICD_SERVER } CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, diff --git a/src/platform/tests/BUILD.gn b/src/platform/tests/BUILD.gn index bf4c2ee6ff90f4..ba092e2f7ee5dd 100644 --- a/src/platform/tests/BUILD.gn +++ b/src/platform/tests/BUILD.gn @@ -38,6 +38,7 @@ if (chip_device_platform != "none" && chip_device_platform != "fake") { } public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/platform", diff --git a/src/platform/tests/TestCHIPoBLEStackMgr.cpp b/src/platform/tests/TestCHIPoBLEStackMgr.cpp index 2ec392849c7eca..fb39b6b6462568 100644 --- a/src/platform/tests/TestCHIPoBLEStackMgr.cpp +++ b/src/platform/tests/TestCHIPoBLEStackMgr.cpp @@ -16,14 +16,14 @@ */ #include "platform/internal/CHIPDeviceLayerInternal.h" -#include -#include + +#include + +#include #include #include -#include - -#include "platform/PlatformManager.h" -#include "platform/internal/BLEManager.h" +#include +#include void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t) { diff --git a/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp b/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp index 38e3f23a10b59c..7e56479513fbf7 100644 --- a/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp +++ b/src/platform/tests/TestCHIPoBLEStackMgrDriver.cpp @@ -15,10 +15,12 @@ * limitations under the License. */ -#include -#include #include +#include + +#include + int main(int argc, char * argv[]) { testing::InitGoogleTest(&argc, argv); diff --git a/src/platform/tests/TestConfigurationMgr.cpp b/src/platform/tests/TestConfigurationMgr.cpp index ad60d44583250f..d40c600c5d03f3 100644 --- a/src/platform/tests/TestConfigurationMgr.cpp +++ b/src/platform/tests/TestConfigurationMgr.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include + +#include #include #include - #include #include #include diff --git a/src/platform/tests/TestConnectivityMgr.cpp b/src/platform/tests/TestConnectivityMgr.cpp index 0699f971dfc493..55a7e97f7c24f6 100644 --- a/src/platform/tests/TestConnectivityMgr.cpp +++ b/src/platform/tests/TestConnectivityMgr.cpp @@ -28,11 +28,11 @@ #include #include +#include + +#include #include #include - -#include - #include #include diff --git a/src/platform/tests/TestDnssd.cpp b/src/platform/tests/TestDnssd.cpp index 43a3d62d61dc9a..5aa7565274f657 100644 --- a/src/platform/tests/TestDnssd.cpp +++ b/src/platform/tests/TestDnssd.cpp @@ -17,12 +17,13 @@ #include -#include +#include #include "lib/dnssd/platform/Dnssd.h" #include "platform/CHIPDeviceLayer.h" #include "platform/ConnectivityManager.h" #include "platform/PlatformManager.h" +#include #include #include #include diff --git a/src/platform/tests/TestKeyValueStoreMgr.cpp b/src/platform/tests/TestKeyValueStoreMgr.cpp index 49ddcb99752492..0429182e0c40c8 100644 --- a/src/platform/tests/TestKeyValueStoreMgr.cpp +++ b/src/platform/tests/TestKeyValueStoreMgr.cpp @@ -22,10 +22,10 @@ * */ -#include +#include +#include #include - #include #include diff --git a/src/platform/tests/TestPlatformMgr.cpp b/src/platform/tests/TestPlatformMgr.cpp index 96c989aa7455b2..51ec10bf8766dc 100644 --- a/src/platform/tests/TestPlatformMgr.cpp +++ b/src/platform/tests/TestPlatformMgr.cpp @@ -30,7 +30,9 @@ #include -#include +#include + +#include #include #include #include diff --git a/src/platform/tests/TestPlatformTime.cpp b/src/platform/tests/TestPlatformTime.cpp index 54cf60202b4440..ad7a59052b21f4 100644 --- a/src/platform/tests/TestPlatformTime.cpp +++ b/src/platform/tests/TestPlatformTime.cpp @@ -28,7 +28,9 @@ #include #include -#include +#include + +#include #include #include #include diff --git a/src/platform/tests/TestThreadStackMgr.cpp b/src/platform/tests/TestThreadStackMgr.cpp index 143de88587ccd5..ee381280529250 100644 --- a/src/platform/tests/TestThreadStackMgr.cpp +++ b/src/platform/tests/TestThreadStackMgr.cpp @@ -18,7 +18,9 @@ #include #include -#include +#include + +#include #include #include diff --git a/src/protocols/bdx/tests/BUILD.gn b/src/protocols/bdx/tests/BUILD.gn index 055301b3432916..25c8f2b8462995 100644 --- a/src/protocols/bdx/tests/BUILD.gn +++ b/src/protocols/bdx/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/protocols/bdx", ] diff --git a/src/protocols/bdx/tests/TestBdxMessages.cpp b/src/protocols/bdx/tests/TestBdxMessages.cpp index 6475cbd89c14c2..2bed80ae8aecf4 100644 --- a/src/protocols/bdx/tests/TestBdxMessages.cpp +++ b/src/protocols/bdx/tests/TestBdxMessages.cpp @@ -1,12 +1,12 @@ -#include +#include -#include +#include +#include #include #include #include - -#include +#include using namespace chip; using namespace chip::bdx; diff --git a/src/protocols/bdx/tests/TestBdxTransferSession.cpp b/src/protocols/bdx/tests/TestBdxTransferSession.cpp index a3a76df6bddf67..8fcc4fab312f26 100644 --- a/src/protocols/bdx/tests/TestBdxTransferSession.cpp +++ b/src/protocols/bdx/tests/TestBdxTransferSession.cpp @@ -1,15 +1,15 @@ -#include -#include -#include - #include -#include +#include +#include #include #include #include #include +#include +#include +#include #include #include #include diff --git a/src/protocols/bdx/tests/TestBdxUri.cpp b/src/protocols/bdx/tests/TestBdxUri.cpp index e94b88ec0d9f21..60125695809dc7 100644 --- a/src/protocols/bdx/tests/TestBdxUri.cpp +++ b/src/protocols/bdx/tests/TestBdxUri.cpp @@ -15,10 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include #include -#include + +#include + +#include +#include using namespace ::chip; diff --git a/src/protocols/interaction_model/tests/BUILD.gn b/src/protocols/interaction_model/tests/BUILD.gn index 875146e3958ec6..b3a5c3c157244a 100644 --- a/src/protocols/interaction_model/tests/BUILD.gn +++ b/src/protocols/interaction_model/tests/BUILD.gn @@ -24,6 +24,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/protocols/interaction_model", ] diff --git a/src/protocols/interaction_model/tests/TestStatusCode.cpp b/src/protocols/interaction_model/tests/TestStatusCode.cpp index 3183d68e2e5f22..83f2dc3525c846 100644 --- a/src/protocols/interaction_model/tests/TestStatusCode.cpp +++ b/src/protocols/interaction_model/tests/TestStatusCode.cpp @@ -18,8 +18,10 @@ #include -#include +#include + #include +#include #include using namespace ::chip; diff --git a/src/protocols/secure_channel/tests/BUILD.gn b/src/protocols/secure_channel/tests/BUILD.gn index 0760998e818422..a5e6d73455eaea 100644 --- a/src/protocols/secure_channel/tests/BUILD.gn +++ b/src/protocols/secure_channel/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/crypto/tests:tests.lib", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/lib/support:testing", diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index aafda3c548fce7..67b4cdd7d69faf 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -21,6 +21,10 @@ * This file implements unit tests for the CASESession implementation. */ +#include + +#include + #include #include #include @@ -30,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -38,8 +43,6 @@ #include #include #include -#include -#include #include "credentials/tests/CHIPCert_test_vectors.h" diff --git a/src/protocols/secure_channel/tests/TestCheckInCounter.cpp b/src/protocols/secure_channel/tests/TestCheckInCounter.cpp index 57dbd4b3496cdd..f3d85d98815638 100644 --- a/src/protocols/secure_channel/tests/TestCheckInCounter.cpp +++ b/src/protocols/secure_channel/tests/TestCheckInCounter.cpp @@ -16,11 +16,14 @@ * limitations under the License. */ -#include +#include + +#include + #include +#include #include #include -#include using namespace chip; using namespace chip::Protocols::SecureChannel; diff --git a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp index d5885f3a6d06bb..23f3b2f2d68ca4 100644 --- a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp +++ b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp @@ -16,9 +16,11 @@ * limitations under the License. */ +#include + #include #include -#include +#include #include #include #include diff --git a/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp b/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp index 59dcf3080a8ec3..70b841aec80581 100644 --- a/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp +++ b/src/protocols/secure_channel/tests/TestDefaultSessionResumptionStorage.cpp @@ -15,7 +15,9 @@ * limitations under the License. */ -#include +#include + +#include #include #include diff --git a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp index edd0bf5f3aa68d..838e14cf6bd302 100644 --- a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp +++ b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp @@ -21,9 +21,14 @@ * This file implements unit tests for the MessageCounterManager implementation. */ +#include + +#include +#include + #include +#include #include - #include #include #include @@ -34,11 +39,6 @@ #include #include -#include -#include - -#include - namespace { using namespace chip; diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index 2d054821728379..bf120b20823ceb 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -22,11 +22,13 @@ */ #include + #include #include #include #include +#include #include #include #include diff --git a/src/protocols/secure_channel/tests/TestPairingSession.cpp b/src/protocols/secure_channel/tests/TestPairingSession.cpp index 5a12f61fc5c69e..b8d29c1c1742b8 100644 --- a/src/protocols/secure_channel/tests/TestPairingSession.cpp +++ b/src/protocols/secure_channel/tests/TestPairingSession.cpp @@ -22,14 +22,15 @@ */ #include -#include +#include + +#include #include +#include #include - #include #include -#include #include #include diff --git a/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp b/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp index ee107f695542a9..c90ec3550e0068 100644 --- a/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp +++ b/src/protocols/secure_channel/tests/TestSimpleSessionResumptionStorage.cpp @@ -15,8 +15,9 @@ * limitations under the License. */ -#include +#include +#include #include #include diff --git a/src/protocols/secure_channel/tests/TestStatusReport.cpp b/src/protocols/secure_channel/tests/TestStatusReport.cpp index 65bc639dcca7c3..a76376f6925320 100644 --- a/src/protocols/secure_channel/tests/TestStatusReport.cpp +++ b/src/protocols/secure_channel/tests/TestStatusReport.cpp @@ -16,17 +16,17 @@ * limitations under the License. */ +#include + +#include #include #include #include - #include #include #include #include -#include - using namespace chip; using namespace chip::Protocols; using namespace chip::Protocols::SecureChannel; diff --git a/src/protocols/user_directed_commissioning/tests/BUILD.gn b/src/protocols/user_directed_commissioning/tests/BUILD.gn index ee67f0492ece92..c7e8f711bd0a5c 100644 --- a/src/protocols/user_directed_commissioning/tests/BUILD.gn +++ b/src/protocols/user_directed_commissioning/tests/BUILD.gn @@ -22,6 +22,7 @@ chip_test_suite("tests") { public_deps = [ "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/protocols", ] diff --git a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp index 9dd05083de6ced..d6115a73913778 100644 --- a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp +++ b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp @@ -1,8 +1,9 @@ #include -#include +#include #include +#include #include #include #include diff --git a/src/python_testing/TC_ACE_1_2.py b/src/python_testing/TC_ACE_1_2.py index 2c6f07a217183a..9bd26523f3cbba 100644 --- a/src/python_testing/TC_ACE_1_2.py +++ b/src/python_testing/TC_ACE_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import queue diff --git a/src/python_testing/TC_ACE_1_3.py b/src/python_testing/TC_ACE_1_3.py index 150683357e1e9c..3c64171571eb95 100644 --- a/src/python_testing/TC_ACE_1_3.py +++ b/src/python_testing/TC_ACE_1_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_ACE_1_4.py b/src/python_testing/TC_ACE_1_4.py index 31cc7cb0c15a3a..f6f04e3508860b 100644 --- a/src/python_testing/TC_ACE_1_4.py +++ b/src/python_testing/TC_ACE_1_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --int-arg PIXIT.ACE.APPENDPOINT:1 PIXIT.ACE.APPDEVTYPEID:0x0100 --string-arg PIXIT.ACE.APPCLUSTER:OnOff PIXIT.ACE.APPATTRIBUTE:OnOff --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import sys diff --git a/src/python_testing/TC_ACE_1_5.py b/src/python_testing/TC_ACE_1_5.py index e88a040e31b983..00bd343d461cb3 100644 --- a/src/python_testing/TC_ACE_1_5.py +++ b/src/python_testing/TC_ACE_1_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_AccessChecker.py b/src/python_testing/TC_AccessChecker.py index f2bbf36330ec6a..36c643407937e2 100644 --- a/src/python_testing/TC_AccessChecker.py +++ b/src/python_testing/TC_AccessChecker.py @@ -1,9 +1,14 @@ +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from copy import deepcopy diff --git a/src/python_testing/TC_CGEN_2_4.py b/src/python_testing/TC_CGEN_2_4.py index ef22360dac341d..7d9d075dc16cb9 100644 --- a/src/python_testing/TC_CGEN_2_4.py +++ b/src/python_testing/TC_CGEN_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import random diff --git a/src/python_testing/TC_DA_1_2.py b/src/python_testing/TC_DA_1_2.py index f324a2d3571c77..30a5285a4a4b68 100644 --- a/src/python_testing/TC_DA_1_2.py +++ b/src/python_testing/TC_DA_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import os import random diff --git a/src/python_testing/TC_DA_1_5.py b/src/python_testing/TC_DA_1_5.py index 7e3bd92cda26e9..d37f236a9fccf4 100644 --- a/src/python_testing/TC_DA_1_5.py +++ b/src/python_testing/TC_DA_1_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import random diff --git a/src/python_testing/TC_DA_1_7.py b/src/python_testing/TC_DA_1_7.py index 9e25bdee88fa6a..8338cf4713a2a5 100644 --- a/src/python_testing/TC_DA_1_7.py +++ b/src/python_testing/TC_DA_1_7.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --bool-arg allow_sdk_dac:true --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from glob import glob diff --git a/src/python_testing/TC_DGGEN_2_4.py b/src/python_testing/TC_DGGEN_2_4.py index f68cefa260c76f..ee80d927a9b6c1 100644 --- a/src/python_testing/TC_DGGEN_2_4.py +++ b/src/python_testing/TC_DGGEN_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import asyncio import logging diff --git a/src/python_testing/TC_DRLK_2_12.py b/src/python_testing/TC_DRLK_2_12.py index 81c2271f52c0dd..4578aa01cd2ba0 100644 --- a/src/python_testing/TC_DRLK_2_12.py +++ b/src/python_testing/TC_DRLK_2_12.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from drlk_2_x_common import DRLK_COMMON from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_DRLK_2_2.py b/src/python_testing/TC_DRLK_2_2.py index fcb6c1068b26eb..e7f3e6fa8e421e 100644 --- a/src/python_testing/TC_DRLK_2_2.py +++ b/src/python_testing/TC_DRLK_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from drlk_2_x_common import DRLK_COMMON from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_DRLK_2_3.py b/src/python_testing/TC_DRLK_2_3.py index e30ac7b2a02635..8c6f40f19c5449 100644 --- a/src/python_testing/TC_DRLK_2_3.py +++ b/src/python_testing/TC_DRLK_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from drlk_2_x_common import DRLK_COMMON from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_DeviceBasicComposition.py b/src/python_testing/TC_DeviceBasicComposition.py index cff612b33f6497..7af7b865542e42 100644 --- a/src/python_testing/TC_DeviceBasicComposition.py +++ b/src/python_testing/TC_DeviceBasicComposition.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from dataclasses import dataclass diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index ec28db53693c96..f4785e49e78395 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_LOCK_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 +# === END CI TEST ARGUMENTS === from typing import Callable diff --git a/src/python_testing/TC_EEM_2_1.py b/src/python_testing/TC_EEM_2_1.py index 1e975a8e681f7d..d5a2c0751145d1 100644 --- a/src/python_testing/TC_EEM_2_1.py +++ b/src/python_testing/TC_EEM_2_1.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_EEM_2_2.py b/src/python_testing/TC_EEM_2_2.py index 2aef2964789534..e8094a0d834ca3 100644 --- a/src/python_testing/TC_EEM_2_2.py +++ b/src/python_testing/TC_EEM_2_2.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -48,7 +53,7 @@ def steps_TC_EEM_2_2(self) -> list[TestStep]: TestStep("4", "Wait 3 seconds"), TestStep("4a", "TH reads from the DUT the CumulativeEnergyImported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 3 seconds"), + TestStep("5", "Wait 5 seconds"), TestStep("5a", "TH reads from the DUT the CumulativeEnergyImported attribute", "Verify the read is successful and that the value is greater than the value measured in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -75,7 +80,7 @@ async def test_TC_EEM_2_2(self): cumulative_energy_imported = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") self.step("5") - time.sleep(3) + time.sleep(5) self.step("5a") cumulative_energy_imported_2 = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") diff --git a/src/python_testing/TC_EEM_2_3.py b/src/python_testing/TC_EEM_2_3.py index b9df334f16ee71..2364f0d012530c 100644 --- a/src/python_testing/TC_EEM_2_3.py +++ b/src/python_testing/TC_EEM_2_3.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -48,7 +53,7 @@ def steps_TC_EEM_2_3(self) -> list[TestStep]: TestStep("4", "Wait 6 seconds"), TestStep("4a", "TH reads from the DUT the CumulativeEnergyExported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 6 seconds"), + TestStep("5", "Wait 11 seconds"), TestStep("5a", "TH reads from the DUT the CumulativeEnergyExported attribute", "Verify the read is successful and that the value is greater than the value measured in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -75,7 +80,7 @@ async def test_TC_EEM_2_3(self): cumulative_energy_exported = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") self.step("5") - time.sleep(6) + time.sleep(11) self.step("5a") cumulative_energy_exported_2 = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") diff --git a/src/python_testing/TC_EEM_2_4.py b/src/python_testing/TC_EEM_2_4.py index 5a77885cb9f17a..b3f052bc968411 100644 --- a/src/python_testing/TC_EEM_2_4.py +++ b/src/python_testing/TC_EEM_2_4.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -48,7 +53,7 @@ def steps_TC_EEM_2_4(self) -> list[TestStep]: TestStep("4", "Wait 3 seconds"), TestStep("4a", "TH reads from the DUT the PeriodicEnergyImported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 3 seconds"), + TestStep("5", "Wait 5 seconds"), TestStep("5a", "TH reads from the DUT the PeriodicEnergyImported attribute", "Verify the read is successful and that the value read has to be different from value measure in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -75,7 +80,7 @@ async def test_TC_EEM_2_4(self): periodic_energy_imported = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") self.step("5") - time.sleep(3) + time.sleep(5) self.step("5a") periodic_energy_imported_2 = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") diff --git a/src/python_testing/TC_EEM_2_5.py b/src/python_testing/TC_EEM_2_5.py index 239317c0b776fe..f7fd34a0d05eca 100644 --- a/src/python_testing/TC_EEM_2_5.py +++ b/src/python_testing/TC_EEM_2_5.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time @@ -48,7 +53,7 @@ def steps_TC_EEM_2_5(self) -> list[TestStep]: TestStep("4", "Wait 6 seconds"), TestStep("4a", "TH reads from the DUT the PeriodicEnergyExported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 6 seconds"), + TestStep("5", "Wait 11 seconds"), TestStep("5a", "TH reads from the DUT the PeriodicEnergyExported attribute", "Verify the read is successful and that the value read has to be different from value measure in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -75,7 +80,7 @@ async def test_TC_EEM_2_5(self): periodic_energy_exported = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") self.step("5") - time.sleep(6) + time.sleep(11) self.step("5a") periodic_energy_exported_2 = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") diff --git a/src/python_testing/TC_EEVSE_2_2.py b/src/python_testing/TC_EEVSE_2_2.py index 6c41f4e684e8ea..833375e0fb7523 100644 --- a/src/python_testing/TC_EEVSE_2_2.py +++ b/src/python_testing/TC_EEVSE_2_2.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_EEVSE_2_4.py b/src/python_testing/TC_EEVSE_2_4.py index b2618f4e6035af..3b2db653e86b63 100644 --- a/src/python_testing/TC_EEVSE_2_4.py +++ b/src/python_testing/TC_EEVSE_2_4.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_EEVSE_2_5.py b/src/python_testing/TC_EEVSE_2_5.py index 914a4a83d9c9a7..89ee987ace2f66 100644 --- a/src/python_testing/TC_EEVSE_2_5.py +++ b/src/python_testing/TC_EEVSE_2_5.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_EPM_2_1.py b/src/python_testing/TC_EPM_2_1.py index c856fecf21fb9a..81f0406a182f49 100644 --- a/src/python_testing/TC_EPM_2_1.py +++ b/src/python_testing/TC_EPM_2_1.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_EPM_2_2.py b/src/python_testing/TC_EPM_2_2.py index 68c6c5919bbedc..89c49928b3baa1 100644 --- a/src/python_testing/TC_EPM_2_2.py +++ b/src/python_testing/TC_EPM_2_2.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time @@ -56,7 +61,7 @@ def steps_TC_EPM_2_2(self) -> list[TestStep]: "Verify the read is successful and that the value is between 3'848 and 4'848 mA. Note the value read."), TestStep("4c", "TH reads from the DUT the Voltage attribute", "Verify the read is successful and that the value is between 229'000 and 231'000 mV. Note the value read."), - TestStep("5", "Wait 3 seconds"), + TestStep("5", "Wait 5 seconds"), TestStep("5a", "TH reads from the DUT the ActivePower attribute", "Verify the read is successful, that the value is between '980'000 and 1'020'000 mW, and the value is different from the value read in step 4a."), TestStep("5b", "TH reads from the DUT the ActiveCurrent attribute", @@ -100,8 +105,8 @@ async def test_TC_EPM_2_2(self): voltage = await self.check_epm_attribute_in_range("Voltage", 229000, 231000) self.step("5") - # After 3 seconds... - time.sleep(3) + # After 5 seconds... + time.sleep(5) self.step("5a") # Active power is Mandatory diff --git a/src/python_testing/TC_FAN_3_1.py b/src/python_testing/TC_FAN_3_1.py index f16eaf35f6c4a2..9e4477e9a258fa 100644 --- a/src/python_testing/TC_FAN_3_1.py +++ b/src/python_testing/TC_FAN_3_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_FAN_3_2.py b/src/python_testing/TC_FAN_3_2.py index 85a733a14c4033..e38706313db50d 100644 --- a/src/python_testing/TC_FAN_3_2.py +++ b/src/python_testing/TC_FAN_3_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_FAN_3_3.py b/src/python_testing/TC_FAN_3_3.py index 0ef571dffb0aa1..a70c457aed25d3 100644 --- a/src/python_testing/TC_FAN_3_3.py +++ b/src/python_testing/TC_FAN_3_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_FAN_3_4.py b/src/python_testing/TC_FAN_3_4.py index 1d7e7c8c9f81c5..95a2240c4eae5c 100644 --- a/src/python_testing/TC_FAN_3_4.py +++ b/src/python_testing/TC_FAN_3_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_FAN_3_5.py b/src/python_testing/TC_FAN_3_5.py index 67a15919db8a6c..a80e4b15aa91eb 100644 --- a/src/python_testing/TC_FAN_3_5.py +++ b/src/python_testing/TC_FAN_3_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import time diff --git a/src/python_testing/TC_ICDM_2_1.py b/src/python_testing/TC_ICDM_2_1.py index 44fde90aee7813..ac20cf2c001fb0 100644 --- a/src/python_testing/TC_ICDM_2_1.py +++ b/src/python_testing/TC_ICDM_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${LIT_ICD_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import re diff --git a/src/python_testing/TC_ICDM_3_1.py b/src/python_testing/TC_ICDM_3_1.py index f5a37cd763c7af..938479a9147f5f 100644 --- a/src/python_testing/TC_ICDM_3_1.py +++ b/src/python_testing/TC_ICDM_3_1.py @@ -16,12 +16,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${LIT_ICD_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import os diff --git a/src/python_testing/TC_ICDManagementCluster.py b/src/python_testing/TC_ICDManagementCluster.py index 6db1863e45bc1e..6030830cacded2 100644 --- a/src/python_testing/TC_ICDManagementCluster.py +++ b/src/python_testing/TC_ICDManagementCluster.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${LIT_ICD_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import ctypes from enum import IntEnum diff --git a/src/python_testing/TC_IDM_1_2.py b/src/python_testing/TC_IDM_1_2.py index c91cef571d952f..d5985c8ae967f1 100644 --- a/src/python_testing/TC_IDM_1_2.py +++ b/src/python_testing/TC_IDM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import inspect import logging diff --git a/src/python_testing/TC_IDM_1_4.py b/src/python_testing/TC_IDM_1_4.py index 07d3cde29ba326..fcfb5915ed136a 100644 --- a/src/python_testing/TC_IDM_1_4.py +++ b/src/python_testing/TC_IDM_1_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --hex-arg PIXIT.DGGEN.TEST_EVENT_TRIGGER_KEY:000102030405060708090a0b0c0d0e0f --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_IDM_4_2.py b/src/python_testing/TC_IDM_4_2.py index b159bb76a1e31c..8cd84011a4fdfe 100644 --- a/src/python_testing/TC_IDM_4_2.py +++ b/src/python_testing/TC_IDM_4_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import copy import logging diff --git a/src/python_testing/TC_MWOCTRL_2_1.py b/src/python_testing/TC_MWOCTRL_2_1.py index 225a4569b345f0..0de3bee72ec12f 100644 --- a/src/python_testing/TC_MWOCTRL_2_1.py +++ b/src/python_testing/TC_MWOCTRL_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status diff --git a/src/python_testing/TC_MWOCTRL_2_2.py b/src/python_testing/TC_MWOCTRL_2_2.py index 54cf7a90463831..0edc2ac6616fde 100644 --- a/src/python_testing/TC_MWOCTRL_2_2.py +++ b/src/python_testing/TC_MWOCTRL_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_MWOCTRL_2_4.py b/src/python_testing/TC_MWOCTRL_2_4.py index 136f9f882ab20e..fce17c4175d6c5 100644 --- a/src/python_testing/TC_MWOCTRL_2_4.py +++ b/src/python_testing/TC_MWOCTRL_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_MWOM_1_2.py b/src/python_testing/TC_MWOM_1_2.py index c92f8d5c5804fc..7d29c3f43eba35 100644 --- a/src/python_testing/TC_MWOM_1_2.py +++ b/src/python_testing/TC_MWOM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_MICROWAVE_OVEN_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_OPCREDS_3_1.py b/src/python_testing/TC_OPCREDS_3_1.py index b29fb84999cc41..dd92fd7a2f88b9 100644 --- a/src/python_testing/TC_OPCREDS_3_1.py +++ b/src/python_testing/TC_OPCREDS_3_1.py @@ -14,12 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import copy import logging import random diff --git a/src/python_testing/TC_OPCREDS_3_2.py b/src/python_testing/TC_OPCREDS_3_2.py index 384540c249e7ca..3eab07bc9dae06 100644 --- a/src/python_testing/TC_OPCREDS_3_2.py +++ b/src/python_testing/TC_OPCREDS_3_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from chip.tlv import TLVReader diff --git a/src/python_testing/TC_OPSTATE_2_1.py b/src/python_testing/TC_OPSTATE_2_1.py index ef9afa0a14b741..c3be8a438c14b8 100644 --- a/src/python_testing/TC_OPSTATE_2_1.py +++ b/src/python_testing/TC_OPSTATE_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OPSTATE_2_2.py b/src/python_testing/TC_OPSTATE_2_2.py index e8b5286af5ee5c..09e4c6591813e4 100644 --- a/src/python_testing/TC_OPSTATE_2_2.py +++ b/src/python_testing/TC_OPSTATE_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OPSTATE_2_3.py b/src/python_testing/TC_OPSTATE_2_3.py index c8abb6bc88a38b..b9a62b275c52aa 100644 --- a/src/python_testing/TC_OPSTATE_2_3.py +++ b/src/python_testing/TC_OPSTATE_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OPSTATE_2_4.py b/src/python_testing/TC_OPSTATE_2_4.py index 21e18fd10cd8a5..512802467f8f2c 100644 --- a/src/python_testing/TC_OPSTATE_2_4.py +++ b/src/python_testing/TC_OPSTATE_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.OPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OPSTATE_2_5.py b/src/python_testing/TC_OPSTATE_2_5.py index fe42a59ffb0b8f..ad79765e8890fd 100644 --- a/src/python_testing/TC_OPSTATE_2_5.py +++ b/src/python_testing/TC_OPSTATE_2_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OVENOPSTATE_2_1.py b/src/python_testing/TC_OVENOPSTATE_2_1.py index 56d7fe2087818a..1d1a2890802e33 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_1.py +++ b/src/python_testing/TC_OVENOPSTATE_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_OVENOPSTATE_2_2.py b/src/python_testing/TC_OVENOPSTATE_2_2.py index 158bae59260ff3..254464eaa661f9 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_2.py +++ b/src/python_testing/TC_OVENOPSTATE_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OVENOPSTATE_2_3.py b/src/python_testing/TC_OVENOPSTATE_2_3.py index 1f882b3b4ba987..77d4358788afad 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_3.py +++ b/src/python_testing/TC_OVENOPSTATE_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OVENOPSTATE_2_4.py b/src/python_testing/TC_OVENOPSTATE_2_4.py index 7fa53e73dd8e5f..70a3a6f0207cee 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_4.py +++ b/src/python_testing/TC_OVENOPSTATE_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.OVENOPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_OVENOPSTATE_2_5.py b/src/python_testing/TC_OVENOPSTATE_2_5.py index 0982ec4f2ff64c..39edb670ff6f5c 100644 --- a/src/python_testing/TC_OVENOPSTATE_2_5.py +++ b/src/python_testing/TC_OVENOPSTATE_2_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py index 93e0e946fe19ea..7216031a9374f4 100644 --- a/src/python_testing/TC_PWRTL_2_1.py +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_RR_1_1.py b/src/python_testing/TC_RR_1_1.py index 5e25f2a77ff086..0cb53a4fb491dc 100644 --- a/src/python_testing/TC_RR_1_1.py +++ b/src/python_testing/TC_RR_1_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import asyncio import logging diff --git a/src/python_testing/TC_RVCCLEANM_1_2.py b/src/python_testing/TC_RVCCLEANM_1_2.py index a0b5fa4b6fb551..d1b3018772af23 100644 --- a/src/python_testing/TC_RVCCLEANM_1_2.py +++ b/src/python_testing/TC_RVCCLEANM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_RVCCLEANM_2_1.py b/src/python_testing/TC_RVCCLEANM_2_1.py index 0a6e72b30cf283..cac18f9601f6ff 100644 --- a/src/python_testing/TC_RVCCLEANM_2_1.py +++ b/src/python_testing/TC_RVCCLEANM_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:1 PIXIT.RVCCLEANM.MODE_CHANGE_OK:2 +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCCLEANM_2_2.py b/src/python_testing/TC_RVCCLEANM_2_2.py index b5f9a108a944f4..8aaae7ff78738f 100644 --- a/src/python_testing/TC_RVCCLEANM_2_2.py +++ b/src/python_testing/TC_RVCCLEANM_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from time import sleep diff --git a/src/python_testing/TC_RVCOPSTATE_2_1.py b/src/python_testing/TC_RVCOPSTATE_2_1.py index 01d4e0c88c4b13..42a2d02d6fae9c 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_1.py +++ b/src/python_testing/TC_RVCOPSTATE_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCOPSTATE_2_3.py b/src/python_testing/TC_RVCOPSTATE_2_3.py index 3b75515f1a23d2..1d915641260d3b 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_3.py +++ b/src/python_testing/TC_RVCOPSTATE_2_3.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCOPSTATE_2_4.py b/src/python_testing/TC_RVCOPSTATE_2_4.py index 43b64b9595a172..b680453b06c287 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_4.py +++ b/src/python_testing/TC_RVCOPSTATE_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCRUNM_1_2.py b/src/python_testing/TC_RVCRUNM_1_2.py index e3e55ddcd07fa4..308e79ab261e23 100644 --- a/src/python_testing/TC_RVCRUNM_1_2.py +++ b/src/python_testing/TC_RVCRUNM_1_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TC_RVCRUNM_2_1.py b/src/python_testing/TC_RVCRUNM_2_1.py index ca6986dcbb5840..e98a1840629864 100644 --- a/src/python_testing/TC_RVCRUNM_2_1.py +++ b/src/python_testing/TC_RVCRUNM_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:0 PIXIT.RVCRUNM.MODE_CHANGE_FAIL:2 +# === END CI TEST ARGUMENTS === import logging from time import sleep diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py index 5723e1ec2f6fb8..dca866adb9f62e 100644 --- a/src/python_testing/TC_RVCRUNM_2_2.py +++ b/src/python_testing/TC_RVCRUNM_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${CHIP_RVC_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_A:1 PIXIT.RVCRUNM.MODE_B:2 +# === END CI TEST ARGUMENTS === from time import sleep diff --git a/src/python_testing/TC_SC_3_6.py b/src/python_testing/TC_SC_3_6.py index 9247cb546e19c6..53353ea85f8bdb 100644 --- a/src/python_testing/TC_SC_3_6.py +++ b/src/python_testing/TC_SC_3_6.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import asyncio diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index febaea6f1e9d49..cba8ad9570ad2d 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import ipaddress from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_2_10.py b/src/python_testing/TC_TIMESYNC_2_10.py index d6b772bcaa1064..c7eb9860b9a8d0 100644 --- a/src/python_testing/TC_TIMESYNC_2_10.py +++ b/src/python_testing/TC_TIMESYNC_2_10.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_11.py b/src/python_testing/TC_TIMESYNC_2_11.py index 7272109525011c..5815baeacadca0 100644 --- a/src/python_testing/TC_TIMESYNC_2_11.py +++ b/src/python_testing/TC_TIMESYNC_2_11.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_12.py b/src/python_testing/TC_TIMESYNC_2_12.py index 1fd05ca352fb38..f530554591202c 100644 --- a/src/python_testing/TC_TIMESYNC_2_12.py +++ b/src/python_testing/TC_TIMESYNC_2_12.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_13.py b/src/python_testing/TC_TIMESYNC_2_13.py index ded6769c7d3828..c667b71edaba55 100644 --- a/src/python_testing/TC_TIMESYNC_2_13.py +++ b/src/python_testing/TC_TIMESYNC_2_13.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import queue import time diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index 949fac75f2f4f7..83c07355d688d3 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_2_4.py b/src/python_testing/TC_TIMESYNC_2_4.py index 89c284b21024f6..21d98fd8ca7f9b 100644 --- a/src/python_testing/TC_TIMESYNC_2_4.py +++ b/src/python_testing/TC_TIMESYNC_2_4.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_2_5.py b/src/python_testing/TC_TIMESYNC_2_5.py index ae2b3debbb8569..5c19e3722956d9 100644 --- a/src/python_testing/TC_TIMESYNC_2_5.py +++ b/src/python_testing/TC_TIMESYNC_2_5.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing diff --git a/src/python_testing/TC_TIMESYNC_2_6.py b/src/python_testing/TC_TIMESYNC_2_6.py index 7a121cb2a2f0ca..deae1123213a67 100644 --- a/src/python_testing/TC_TIMESYNC_2_6.py +++ b/src/python_testing/TC_TIMESYNC_2_6.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing diff --git a/src/python_testing/TC_TIMESYNC_2_7.py b/src/python_testing/TC_TIMESYNC_2_7.py index 0e4e80f87a5548..a405aae1f901a3 100644 --- a/src/python_testing/TC_TIMESYNC_2_7.py +++ b/src/python_testing/TC_TIMESYNC_2_7.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time import typing diff --git a/src/python_testing/TC_TIMESYNC_2_8.py b/src/python_testing/TC_TIMESYNC_2_8.py index eb78c40cd7318a..418d6e8e41040d 100644 --- a/src/python_testing/TC_TIMESYNC_2_8.py +++ b/src/python_testing/TC_TIMESYNC_2_8.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import time import typing diff --git a/src/python_testing/TC_TIMESYNC_2_9.py b/src/python_testing/TC_TIMESYNC_2_9.py index f52241f9730c24..0fd6872d704684 100644 --- a/src/python_testing/TC_TIMESYNC_2_9.py +++ b/src/python_testing/TC_TIMESYNC_2_9.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import typing from datetime import timedelta diff --git a/src/python_testing/TC_TIMESYNC_3_1.py b/src/python_testing/TC_TIMESYNC_3_1.py index 6d3148872e6ece..ad972345db5828 100644 --- a/src/python_testing/TC_TIMESYNC_3_1.py +++ b/src/python_testing/TC_TIMESYNC_3_1.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main diff --git a/src/python_testing/TC_TestEventTrigger.py b/src/python_testing/TC_TestEventTrigger.py index ee227a8bfbec9d..373fabf704078f 100644 --- a/src/python_testing/TC_TestEventTrigger.py +++ b/src/python_testing/TC_TestEventTrigger.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f # test-runner-run/run1/script-args: --storage-path admin_storage.json --bool-arg allow_sdk_dac:true --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TestBatchInvoke.py b/src/python_testing/TestBatchInvoke.py index 8af874fa7b0b27..230ebc9bbc1705 100644 --- a/src/python_testing/TestBatchInvoke.py +++ b/src/python_testing/TestBatchInvoke.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/TestGroupTableReports.py b/src/python_testing/TestGroupTableReports.py index d827752f1ee176..cc9b9a0718a25e 100644 --- a/src/python_testing/TestGroupTableReports.py +++ b/src/python_testing/TestGroupTableReports.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${ALL_CLUSTERS_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging import queue diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index c35a5eb0f6bb22..fadd6a517a4531 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -377,8 +377,7 @@ def test_known_aliased_clusters(self): (0x040D, 'Carbon Dioxide Concentration Measurement', 'CDOCONC'), (0x0413, 'Nitrogen Dioxide Concentration Measurement', 'NDOCONC'), (0x0415, 'Ozone Concentration Measurement', 'OZCONC'), - # Change to "PM2.5 Concentration Measurement" once https://github.com/csa-data-model/projects/issues/453 is fixed - (0x042A, 'PM2', 'PMICONC'), + (0x042A, 'PM2.5 Concentration Measurement', 'PMICONC'), (0x042B, 'Formaldehyde Concentration Measurement', 'FLDCONC'), (0x042C, 'PM1 Concentration Measurement', 'PMHCONC'), (0x042D, 'PM10 Concentration Measurement', 'PMKCONC'), diff --git a/src/python_testing/hello_test.py b/src/python_testing/hello_test.py index 01657bf1bded6a..041f28ebeefb0d 100644 --- a/src/python_testing/hello_test.py +++ b/src/python_testing/hello_test.py @@ -15,12 +15,17 @@ # limitations under the License. # +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === # test-runner-runs: run1 # test-runner-run/run1/app: ${TYPE_OF_APP} # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === import logging diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index bc36049de54cd5..c2819960146ed3 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -130,7 +130,8 @@ class CommandType(Enum): 0x042F: 'RNCONC', 0x0071: 'HEPAFREMON', 0x0072: 'ACFREMON', - 0x0405: 'RH'} + 0x0405: 'RH', + 0x001C: 'PWM'} class ClusterParser: diff --git a/src/python_testing/test_testing/example_pics_xml_basic_info.xml b/src/python_testing/test_testing/example_pics_xml_basic_info.xml index 96f1a34f3e9557..3d488c3ae90ace 100644 --- a/src/python_testing/test_testing/example_pics_xml_basic_info.xml +++ b/src/python_testing/test_testing/example_pics_xml_basic_info.xml @@ -22,6 +22,14 @@ Draft O true + + + LVL.S + Does the device implement the Level Control Cluster as a server? + 9.1. Role - index.html[pdf] + O + true + diff --git a/src/python_testing/test_testing/test_IDM_10_4.py b/src/python_testing/test_testing/test_IDM_10_4.py index ccf713450e2348..8634e94129b86a 100644 --- a/src/python_testing/test_testing/test_IDM_10_4.py +++ b/src/python_testing/test_testing/test_IDM_10_4.py @@ -38,40 +38,48 @@ def create_read(include_reachable: bool = False, include_max_paths: bool = False, include_vendor_id: bool = True) -> Attribute.AsyncReadTransaction.ReadResponse: # Attribute read here is set to match the example_pics_xml_basic_info.xml in this directory bi = Clusters.BasicInformation.Attributes - attrs = {bi.DataModelRevision: 1, - bi.VendorName: 'testVendor', - bi.ProductName: 'testProduct', - bi.ProductID: 0x8000, - bi.NodeLabel: 'label', - bi.Location: 'XX', - bi.HardwareVersion: 1, - bi.HardwareVersionString: 'one', - bi.SoftwareVersion: 2, - bi.SoftwareVersionString: 'two', - bi.ManufacturingDate: 'today', - bi.PartNumber: 'three', - bi.ProductURL: 'example.com', - bi.ProductLabel: 'myProduct', - bi.SerialNumber: 'ABCD1234', - bi.LocalConfigDisabled: False, - bi.UniqueID: 'Hashy-McHashface'} + lvl = Clusters.LevelControl.Attributes + attrs_bi = {bi.DataModelRevision: 1, + bi.VendorName: 'testVendor', + bi.ProductName: 'testProduct', + bi.ProductID: 0x8000, + bi.NodeLabel: 'label', + bi.Location: 'XX', + bi.HardwareVersion: 1, + bi.HardwareVersionString: 'one', + bi.SoftwareVersion: 2, + bi.SoftwareVersionString: 'two', + bi.ManufacturingDate: 'today', + bi.PartNumber: 'three', + bi.ProductURL: 'example.com', + bi.ProductLabel: 'myProduct', + bi.SerialNumber: 'ABCD1234', + bi.LocalConfigDisabled: False, + bi.UniqueID: 'Hashy-McHashface'} if include_reachable: - attrs[bi.Reachable] = True + attrs_bi[bi.Reachable] = True if include_max_paths: - attrs[bi.MaxPathsPerInvoke] = 2 + attrs_bi[bi.MaxPathsPerInvoke] = 2 if include_vendor_id: - attrs[bi.VendorID] = 0xFFF1 + attrs_bi[bi.VendorID] = 0xFFF1 - attrs[bi.AttributeList] = [a.attribute_id for a in attrs.keys()] - attrs[bi.AcceptedCommandList] = [] - attrs[bi.GeneratedCommandList] = [] - attrs[bi.FeatureMap] = 0 + attrs_bi[bi.AttributeList] = [a.attribute_id for a in attrs_bi.keys()] + attrs_bi[bi.AcceptedCommandList] = [] + attrs_bi[bi.GeneratedCommandList] = [] + attrs_bi[bi.FeatureMap] = 0 + + attrs_lvl = {} + attrs_lvl[lvl.AttributeList] = [] + attrs_lvl[lvl.AcceptedCommandList] = [] + attrs_lvl[lvl.GeneratedCommandList] = [] + attrs_lvl[lvl.FeatureMap] = 0 resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) - resp.attributes = {0: {Clusters.BasicInformation: attrs}} + resp.attributes = {0: {Clusters.BasicInformation: attrs_bi, Clusters.LevelControl: attrs_lvl}} - tlv_attrs = {a.attribute_id: value for a, value in attrs.items()} - resp.tlvAttributes = {0: {Clusters.BasicInformation.id: tlv_attrs}} + tlv_attrs_bi = {a.attribute_id: value for a, value in attrs_bi.items()} + tlv_attrs_lvl = {a.attribute_id: value for a, value in attrs_lvl.items()} + resp.tlvAttributes = {0: {Clusters.BasicInformation.id: tlv_attrs_bi, Clusters.LevelControl.id: tlv_attrs_lvl}} return resp diff --git a/src/setup_payload/tests/TestAdditionalDataPayload.cpp b/src/setup_payload/tests/TestAdditionalDataPayload.cpp index d59eac34a0b20b..c0671994ff96b4 100644 --- a/src/setup_payload/tests/TestAdditionalDataPayload.cpp +++ b/src/setup_payload/tests/TestAdditionalDataPayload.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/src/tracing/tests/BUILD.gn b/src/tracing/tests/BUILD.gn index e44bb6b14cf741..6fb830d6e75e35 100644 --- a/src/tracing/tests/BUILD.gn +++ b/src/tracing/tests/BUILD.gn @@ -30,6 +30,7 @@ if (matter_enable_tracing_support && ] public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/platform", "${chip_root}/src/tracing", "${chip_root}/src/tracing:macros", diff --git a/src/tracing/tests/TestMetricEvents.cpp b/src/tracing/tests/TestMetricEvents.cpp index 01c2c6e5a93eeb..20c6f7788ad69e 100644 --- a/src/tracing/tests/TestMetricEvents.cpp +++ b/src/tracing/tests/TestMetricEvents.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include diff --git a/src/tracing/tests/TestTracing.cpp b/src/tracing/tests/TestTracing.cpp index fa519a02163cbe..b3e4e87562397a 100644 --- a/src/tracing/tests/TestTracing.cpp +++ b/src/tracing/tests/TestTracing.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include diff --git a/src/transport/raw/tests/BUILD.gn b/src/transport/raw/tests/BUILD.gn index 1ac84f3d097700..195e164ec32c73 100644 --- a/src/transport/raw/tests/BUILD.gn +++ b/src/transport/raw/tests/BUILD.gn @@ -54,6 +54,7 @@ chip_test_suite("tests") { ":helpers", "${chip_root}/src/inet/tests:helpers", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:test_utils", "${chip_root}/src/transport", diff --git a/src/transport/raw/tests/TestMessageHeader.cpp b/src/transport/raw/tests/TestMessageHeader.cpp index 4c807afc5c3608..27bbf74790bf97 100644 --- a/src/transport/raw/tests/TestMessageHeader.cpp +++ b/src/transport/raw/tests/TestMessageHeader.cpp @@ -23,9 +23,10 @@ * */ -#include +#include #include +#include #include #include #include diff --git a/src/transport/raw/tests/TestPeerAddress.cpp b/src/transport/raw/tests/TestPeerAddress.cpp index d96bc1990e0755..a4561ad4ebdc4c 100644 --- a/src/transport/raw/tests/TestPeerAddress.cpp +++ b/src/transport/raw/tests/TestPeerAddress.cpp @@ -21,11 +21,12 @@ #include #include -#include +#include #include #include #include +#include #include namespace { diff --git a/src/transport/raw/tests/TestTCP.cpp b/src/transport/raw/tests/TestTCP.cpp index 4f78da5dcdce86..80531491f288a0 100644 --- a/src/transport/raw/tests/TestTCP.cpp +++ b/src/transport/raw/tests/TestTCP.cpp @@ -28,11 +28,12 @@ #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/src/transport/raw/tests/TestUDP.cpp b/src/transport/raw/tests/TestUDP.cpp index 39167b89a58bb7..d96a781237d18b 100644 --- a/src/transport/raw/tests/TestUDP.cpp +++ b/src/transport/raw/tests/TestUDP.cpp @@ -25,9 +25,10 @@ #include -#include +#include #include +#include #include #include #include diff --git a/src/transport/retransmit/tests/BUILD.gn b/src/transport/retransmit/tests/BUILD.gn index cd762b2c755571..23482412716463 100644 --- a/src/transport/retransmit/tests/BUILD.gn +++ b/src/transport/retransmit/tests/BUILD.gn @@ -25,5 +25,8 @@ chip_test_suite("tests") { test_sources = [ "TestCache.cpp" ] - public_deps = [ "${chip_root}/src/transport/retransmit" ] + public_deps = [ + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/transport/retransmit", + ] } diff --git a/src/transport/retransmit/tests/TestCache.cpp b/src/transport/retransmit/tests/TestCache.cpp index 6142f4910dbf44..09e8cced0f1101 100644 --- a/src/transport/retransmit/tests/TestCache.cpp +++ b/src/transport/retransmit/tests/TestCache.cpp @@ -14,10 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include #include -#include + +#include + +#include +#include // Helpers for simple payload management namespace { diff --git a/src/transport/tests/BUILD.gn b/src/transport/tests/BUILD.gn index 7c38cea5e7e8eb..f0be95ff5ac8dd 100644 --- a/src/transport/tests/BUILD.gn +++ b/src/transport/tests/BUILD.gn @@ -57,6 +57,7 @@ chip_test_suite("tests") { "${chip_root}/src/credentials/tests:cert_test_vectors", "${chip_root}/src/inet/tests:helpers", "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/lib/support", "${chip_root}/src/lib/support:testing", "${chip_root}/src/protocols", diff --git a/src/transport/tests/TestCryptoContext.cpp b/src/transport/tests/TestCryptoContext.cpp index 45c3f3e5eb441e..76194a795ff531 100644 --- a/src/transport/tests/TestCryptoContext.cpp +++ b/src/transport/tests/TestCryptoContext.cpp @@ -18,10 +18,11 @@ #include -#include +#include #include #include +#include #include #include diff --git a/src/transport/tests/TestGroupMessageCounter.cpp b/src/transport/tests/TestGroupMessageCounter.cpp index 72fe57754e8976..266decb34ce614 100644 --- a/src/transport/tests/TestGroupMessageCounter.cpp +++ b/src/transport/tests/TestGroupMessageCounter.cpp @@ -22,8 +22,10 @@ */ #include -#include +#include + +#include #include #include #include diff --git a/src/transport/tests/TestPeerConnections.cpp b/src/transport/tests/TestPeerConnections.cpp index 9beb263f1d15c8..5da94eb66dd708 100644 --- a/src/transport/tests/TestPeerConnections.cpp +++ b/src/transport/tests/TestPeerConnections.cpp @@ -23,9 +23,10 @@ * */ -#include +#include #include +#include #include #include diff --git a/src/transport/tests/TestPeerMessageCounter.cpp b/src/transport/tests/TestPeerMessageCounter.cpp index 75f296b1bcba21..6b0c151d9209cc 100644 --- a/src/transport/tests/TestPeerMessageCounter.cpp +++ b/src/transport/tests/TestPeerMessageCounter.cpp @@ -24,8 +24,9 @@ #include #include -#include +#include +#include #include #include diff --git a/src/transport/tests/TestSecureSession.cpp b/src/transport/tests/TestSecureSession.cpp index 672ba04e8fd38c..695f6642b79d3c 100644 --- a/src/transport/tests/TestSecureSession.cpp +++ b/src/transport/tests/TestSecureSession.cpp @@ -24,10 +24,11 @@ #include #include -#include +#include #include #include +#include #include #include diff --git a/src/transport/tests/TestSecureSessionTable.cpp b/src/transport/tests/TestSecureSessionTable.cpp index 323558a0cecd24..da5ca96951c6ed 100644 --- a/src/transport/tests/TestSecureSessionTable.cpp +++ b/src/transport/tests/TestSecureSessionTable.cpp @@ -24,11 +24,12 @@ #include #include -#include +#include -#include "system/SystemClock.h" #include +#include #include +#include #include #include diff --git a/src/transport/tests/TestSessionManager.cpp b/src/transport/tests/TestSessionManager.cpp index c5384a7be40328..154071a56418c5 100644 --- a/src/transport/tests/TestSessionManager.cpp +++ b/src/transport/tests/TestSessionManager.cpp @@ -21,6 +21,10 @@ * This file implements unit tests for the SessionManager implementation. */ +#include + +#include + #define CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API // Up here in case some other header // includes SessionManager.h indirectly @@ -29,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -39,10 +44,6 @@ #include #include -#include - -#include - #undef CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API namespace { diff --git a/src/transport/tests/TestSessionManagerDispatch.cpp b/src/transport/tests/TestSessionManagerDispatch.cpp index 3ef66057adfbc8..099ccec4b2f6c6 100644 --- a/src/transport/tests/TestSessionManagerDispatch.cpp +++ b/src/transport/tests/TestSessionManagerDispatch.cpp @@ -21,6 +21,10 @@ * This file implements unit tests for the SessionManager implementation. */ +#include + +#include + #define CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API // Up here in case some other header // includes SessionManager.h indirectly @@ -29,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -36,10 +41,6 @@ #include #include -#include - -#include - #undef CHIP_ENABLE_TEST_ENCRYPTED_BUFFER_API namespace { diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index a7bfe1456c0b4d..5faba08acd3d3b 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -291,14 +291,20 @@ template("siwx917_sdk") { if (invoker.enable_dic) { _include_dirs += [ "${chip_root}/third_party/silabs/mqtt/stack" ] } + + if (chip_enable_icd_server || !disable_lcd) { + defines += [ + "SL_SLEEP_TIMER=1", + "SI91X_SYSRTC_COUNT=1", + ] + } + if (!disable_lcd) { defines += [ "CONFIG_ENABLE_UART", - "SI91X_SYSRTC_COUNT=1", "SYSCALLS_WRITE", "SPI_MULTI_SLAVE", "SL_ULP_TIMER", - "SL_SLEEP_TIMER", ] } @@ -755,6 +761,14 @@ template("siwx917_sdk") { ] } + if (chip_enable_icd_server || !disable_lcd) { + sources += [ + "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_sysrtc.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/sleeptimer/src/sl_sleeptimer_hal_si91x_sysrtc.c", + ] + } + if (!disable_lcd) { sources += [ "${efr32_sdk_root}/platform/middleware/glib/dmd/display/dmd_memlcd.c", @@ -769,13 +783,10 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/middleware/glib/glib/glib_polygon.c", "${efr32_sdk_root}/platform/middleware/glib/glib/glib_rectangle.c", "${efr32_sdk_root}/platform/middleware/glib/glib/glib_string.c", - "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/SPI.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/memlcd/src/memlcd_917/sl_memlcd_spi.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/memlcd/src/sl_memlcd.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/memlcd/src/sl_memlcd_display.c", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_sysrtc.c", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/sleeptimer/src/sl_sleeptimer_hal_si91x_sysrtc.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_ulp_timer.c", ] } diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 780c47550b30c2..5ea642c2490387 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -38645,6 +38645,154 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Attributes { + +namespace SupportedDeviceCategories { + +Protocols::InteractionModel::Status +Get(chip::EndpointId endpoint, chip::BitMask * value) +{ + using Traits = NumericAttributeTraits>; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::CommissionerControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value) +{ + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace SupportedDeviceCategories + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::CommissionerControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::CommissionerControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::CommissionerControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index fc4bd864dac3e6..2e9f20115c2738 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 @@ -5961,6 +5961,35 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Attributes { + +namespace SupportedDeviceCategories { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::BitMask * + value); // SupportedDeviceCategoryBitmap +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value); +Protocols::InteractionModel::Status +Set(chip::EndpointId endpoint, chip::BitMask value, + MarkAttributeDirty markDirty); +} // namespace SupportedDeviceCategories + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 8276f84a1128a7..7be9f882fd37ef 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -628,6 +628,11 @@ void emberAfContentControlClusterInitCallback(chip::EndpointId endpoint); */ void emberAfContentAppObserverClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfCommissionerControlClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -5249,6 +5254,44 @@ chip::Protocols::InteractionModel::Status MatterContentAppObserverClusterServerP */ void emberAfContentAppObserverClusterServerTickCallback(chip::EndpointId endpoint); +// +// Commissioner Control Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfCommissionerControlClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterCommissionerControlClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfCommissionerControlClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterCommissionerControlClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterCommissionerControlClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfCommissionerControlClusterServerTickCallback(chip::EndpointId endpoint); + // // Electrical Measurement Cluster // @@ -6685,6 +6728,18 @@ bool emberAfContentControlClusterSetScheduledContentRatingThresholdCallback( bool emberAfContentAppObserverClusterContentAppMessageCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::DecodableType & commandData); +/** + * @brief Commissioner Control Cluster RequestCommissioningApproval Command callback (from client) + */ +bool emberAfCommissionerControlClusterRequestCommissioningApprovalCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::DecodableType & commandData); +/** + * @brief Commissioner Control Cluster CommissionNode Command callback (from client) + */ +bool emberAfCommissionerControlClusterCommissionNodeCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::CommissionerControl::Commands::CommissionNode::DecodableType & commandData); /** * @brief Electrical Measurement Cluster GetProfileInfoCommand Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index dbdbd4aa3d48cf..37562af207838f 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 @@ -5176,6 +5176,15 @@ enum class StatusEnum : uint8_t }; } // namespace ContentAppObserver +namespace CommissionerControl { + +// Bitmap for SupportedDeviceCategoryBitmap +enum class SupportedDeviceCategoryBitmap : uint32_t +{ + kFabricSynchronization = 0x1, +}; +} // namespace CommissionerControl + namespace ElectricalMeasurement {} // namespace ElectricalMeasurement namespace UnitTesting { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index f2f6869b217ffb..d821d185f11272 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 @@ -27947,6 +27947,242 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace ContentAppObserver +namespace CommissionerControl { + +namespace Commands { +namespace RequestCommissioningApproval { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRequestId), requestId); + encoder.Encode(to_underlying(Fields::kVendorId), vendorId); + encoder.Encode(to_underlying(Fields::kProductId), productId); + encoder.Encode(to_underlying(Fields::kLabel), label); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRequestId)) + { + err = DataModel::Decode(reader, requestId); + } + else if (__context_tag == to_underlying(Fields::kVendorId)) + { + err = DataModel::Decode(reader, vendorId); + } + else if (__context_tag == to_underlying(Fields::kProductId)) + { + err = DataModel::Decode(reader, productId); + } + else if (__context_tag == to_underlying(Fields::kLabel)) + { + err = DataModel::Decode(reader, label); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace RequestCommissioningApproval. +namespace CommissionNode { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRequestId), requestId); + encoder.Encode(to_underlying(Fields::kResponseTimeoutSeconds), responseTimeoutSeconds); + encoder.Encode(to_underlying(Fields::kIpAddress), ipAddress); + encoder.Encode(to_underlying(Fields::kPort), port); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRequestId)) + { + err = DataModel::Decode(reader, requestId); + } + else if (__context_tag == to_underlying(Fields::kResponseTimeoutSeconds)) + { + err = DataModel::Decode(reader, responseTimeoutSeconds); + } + else if (__context_tag == to_underlying(Fields::kIpAddress)) + { + err = DataModel::Decode(reader, ipAddress); + } + else if (__context_tag == to_underlying(Fields::kPort)) + { + err = DataModel::Decode(reader, port); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace CommissionNode. +namespace ReverseOpenCommissioningWindow { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kCommissioningTimeout), commissioningTimeout); + encoder.Encode(to_underlying(Fields::kPAKEPasscodeVerifier), PAKEPasscodeVerifier); + encoder.Encode(to_underlying(Fields::kDiscriminator), discriminator); + encoder.Encode(to_underlying(Fields::kIterations), iterations); + encoder.Encode(to_underlying(Fields::kSalt), salt); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kCommissioningTimeout)) + { + err = DataModel::Decode(reader, commissioningTimeout); + } + else if (__context_tag == to_underlying(Fields::kPAKEPasscodeVerifier)) + { + err = DataModel::Decode(reader, PAKEPasscodeVerifier); + } + else if (__context_tag == to_underlying(Fields::kDiscriminator)) + { + err = DataModel::Decode(reader, discriminator); + } + else if (__context_tag == to_underlying(Fields::kIterations)) + { + err = DataModel::Decode(reader, iterations); + } + else if (__context_tag == to_underlying(Fields::kSalt)) + { + err = DataModel::Decode(reader, salt); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ReverseOpenCommissioningWindow. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::SupportedDeviceCategories::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedDeviceCategories); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events { +namespace CommissioningRequestResult { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kRequestId), requestId)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kClientNodeId), clientNodeId)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kStatusCode), statusCode)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kFabricIndex), fabricIndex)); + return aWriter.EndContainer(outer); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kRequestId)) + { + err = DataModel::Decode(reader, requestId); + } + else if (__context_tag == to_underlying(Fields::kClientNodeId)) + { + err = DataModel::Decode(reader, clientNodeId); + } + else if (__context_tag == to_underlying(Fields::kStatusCode)) + { + err = DataModel::Decode(reader, statusCode); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace CommissioningRequestResult. +} // namespace Events + +} // namespace CommissionerControl namespace ElectricalMeasurement { namespace Commands { @@ -31766,6 +32002,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::CommissionerControl::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::ElectricalMeasurement::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 338820b159e47b..a32e52a5c072f8 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 @@ -40989,6 +40989,274 @@ struct TypeInfo }; } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace RequestCommissioningApproval { +struct Type; +struct DecodableType; +} // namespace RequestCommissioningApproval + +namespace CommissionNode { +struct Type; +struct DecodableType; +} // namespace CommissionNode + +namespace ReverseOpenCommissioningWindow { +struct Type; +struct DecodableType; +} // namespace ReverseOpenCommissioningWindow + +} // namespace Commands + +namespace Commands { +namespace RequestCommissioningApproval { +enum class Fields : uint8_t +{ + kRequestId = 0, + kVendorId = 1, + kProductId = 2, + kLabel = 3, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::RequestCommissioningApproval::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + chip::VendorId vendorId = static_cast(0); + uint16_t productId = static_cast(0); + Optional label; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::RequestCommissioningApproval::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + chip::VendorId vendorId = static_cast(0); + uint16_t productId = static_cast(0); + Optional label; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace RequestCommissioningApproval +namespace CommissionNode { +enum class Fields : uint8_t +{ + kRequestId = 0, + kResponseTimeoutSeconds = 1, + kIpAddress = 2, + kPort = 3, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::CommissionNode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + uint16_t responseTimeoutSeconds = static_cast(0); + Optional ipAddress; + Optional port; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::CommissionNode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + uint16_t responseTimeoutSeconds = static_cast(0); + Optional ipAddress; + Optional port; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace CommissionNode +namespace ReverseOpenCommissioningWindow { +enum class Fields : uint8_t +{ + kCommissioningTimeout = 0, + kPAKEPasscodeVerifier = 1, + kDiscriminator = 2, + kIterations = 3, + kSalt = 4, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ReverseOpenCommissioningWindow::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint16_t commissioningTimeout = static_cast(0); + chip::ByteSpan PAKEPasscodeVerifier; + uint16_t discriminator = static_cast(0); + uint32_t iterations = static_cast(0); + chip::ByteSpan salt; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ReverseOpenCommissioningWindow::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint16_t commissioningTimeout = static_cast(0); + chip::ByteSpan PAKEPasscodeVerifier; + uint16_t discriminator = static_cast(0); + uint32_t iterations = static_cast(0); + chip::ByteSpan salt; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ReverseOpenCommissioningWindow +} // namespace Commands + +namespace Attributes { + +namespace SupportedDeviceCategories { +struct TypeInfo +{ + using Type = chip::BitMask; + using DecodableType = chip::BitMask; + using DecodableArgType = chip::BitMask; + + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedDeviceCategories::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedDeviceCategories +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::SupportedDeviceCategories::TypeInfo::DecodableType supportedDeviceCategories = + static_cast>(0); + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +namespace Events { +namespace CommissioningRequestResult { +static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; + +enum class Fields : uint8_t +{ + kRequestId = 0, + kClientNodeId = 1, + kStatusCode = 2, + kFabricIndex = 254, +}; + +struct Type +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::CommissioningRequestResult::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + static constexpr bool kIsFabricScoped = true; + + uint64_t requestId = static_cast(0); + chip::NodeId clientNodeId = static_cast(0); + uint8_t statusCode = static_cast(0); + chip::FabricIndex fabricIndex = static_cast(0); + + auto GetFabricIndex() const { return fabricIndex; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +struct DecodableType +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::CommissioningRequestResult::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } + + uint64_t requestId = static_cast(0); + chip::NodeId clientNodeId = static_cast(0); + uint8_t statusCode = static_cast(0); + chip::FabricIndex fabricIndex = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +} // namespace CommissioningRequestResult +} // namespace Events +} // namespace CommissionerControl namespace ElectricalMeasurement { namespace Commands { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index f45a7cb875af24..b025f1ccf57811 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 @@ -7413,6 +7413,40 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Attributes { + +namespace SupportedDeviceCategories { +static constexpr AttributeId Id = 0x00000000; +} // namespace SupportedDeviceCategories + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index 8aec311faafcff..ba42f10b50ffae 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 @@ -382,6 +382,9 @@ static constexpr ClusterId Id = 0x0000050F; namespace ContentAppObserver { static constexpr ClusterId Id = 0x00000510; } // namespace ContentAppObserver +namespace CommissionerControl { +static constexpr ClusterId Id = 0x00000751; +} // namespace CommissionerControl namespace ElectricalMeasurement { static constexpr ClusterId Id = 0x00000B04; } // namespace ElectricalMeasurement diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index 0e58f97f149575..608b7d7c7565a7 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 @@ -1783,6 +1783,24 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace ContentAppObserver +namespace CommissionerControl { +namespace Commands { + +namespace RequestCommissioningApproval { +static constexpr CommandId Id = 0x00000000; +} // namespace RequestCommissioningApproval + +namespace CommissionNode { +static constexpr CommandId Id = 0x00000001; +} // namespace CommissionNode + +namespace ReverseOpenCommissioningWindow { +static constexpr CommandId Id = 0x00000002; +} // namespace ReverseOpenCommissioningWindow + +} // namespace Commands +} // namespace CommissionerControl + namespace ElectricalMeasurement { namespace Commands { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h index 1592020a008379..cc619b581dc3e6 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Events.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Events.h @@ -661,6 +661,16 @@ static constexpr EventId Id = 0x00000000; } // namespace Events } // namespace ContentControl +namespace CommissionerControl { +namespace Events { + +namespace CommissioningRequestResult { +static constexpr EventId Id = 0x00000000; +} // namespace CommissioningRequestResult + +} // namespace Events +} // namespace CommissionerControl + namespace UnitTesting { namespace Events { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 74e8b95d769ab7..63b07843fd2703 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -154,6 +154,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| | FaultInjection | 0xFFF1FC06| @@ -13755,6 +13756,108 @@ class ContentAppObserverContentAppMessage : public ClusterCommand chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster CommissionerControl | 0x0751 | +|------------------------------------------------------------------------------| +| Commands: | | +| * RequestCommissioningApproval | 0x00 | +| * CommissionNode | 0x01 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedDeviceCategories | 0x0000 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +| * CommissioningRequestResult | 0x0000 | +\*----------------------------------------------------------------------------*/ + +/* + * Command RequestCommissioningApproval + */ +class CommissionerControlRequestCommissioningApproval : public ClusterCommand +{ +public: + CommissionerControlRequestCommissioningApproval(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("request-commissioning-approval", credsIssuerConfig) + { + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("VendorId", 0, UINT16_MAX, &mRequest.vendorId); + AddArgument("ProductId", 0, UINT16_MAX, &mRequest.productId); + AddArgument("Label", &mRequest.label); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type mRequest; +}; + +/* + * Command CommissionNode + */ +class CommissionerControlCommissionNode : public ClusterCommand +{ +public: + CommissionerControlCommissionNode(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("commission-node", credsIssuerConfig) + { + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); + AddArgument("ResponseTimeoutSeconds", 0, UINT16_MAX, &mRequest.responseTimeoutSeconds); + AddArgument("IpAddress", &mRequest.ipAddress); + AddArgument("Port", 0, UINT16_MAX, &mRequest.port); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster ElectricalMeasurement | 0x0B04 | |------------------------------------------------------------------------------| @@ -26471,6 +26574,69 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterCommissionerControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::CommissionerControl; + + const char * clusterName = "CommissionerControl"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-device-categories", Attributes::SupportedDeviceCategories::Id, + credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "supported-device-categories", 0, UINT32_MAX, Attributes::SupportedDeviceCategories::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-device-categories", Attributes::SupportedDeviceCategories::Id, + credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "commissioning-request-result", Events::CommissioningRequestResult::Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "commissioning-request-result", Events::CommissioningRequestResult::Id, + credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterElectricalMeasurement(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::ElectricalMeasurement; @@ -27880,6 +28046,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterAccountLogin(commands, credsIssuerConfig); registerClusterContentControl(commands, credsIssuerConfig); registerClusterContentAppObserver(commands, credsIssuerConfig); + registerClusterCommissionerControl(commands, credsIssuerConfig); registerClusterElectricalMeasurement(commands, credsIssuerConfig); registerClusterUnitTesting(commands, credsIssuerConfig); registerClusterFaultInjection(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index c41f5734712528..1bf30e655ab661 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -7468,6 +7468,46 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const CommissionerControl::Events::CommissioningRequestResult::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = DataModelLogger::LogValue("RequestId", indent + 1, value.requestId); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'RequestId'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("ClientNodeId", indent + 1, value.clientNodeId); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ClientNodeId'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("StatusCode", indent + 1, value.statusCode); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'StatusCode'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("FabricIndex", indent + 1, value.fabricIndex); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'FabricIndex'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const UnitTesting::Events::TestEvent::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); @@ -8212,6 +8252,18 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("commissioningTimeout", indent + 1, value.commissioningTimeout)); + ReturnErrorOnFailure(DataModelLogger::LogValue("PAKEPasscodeVerifier", indent + 1, value.PAKEPasscodeVerifier)); + ReturnErrorOnFailure(DataModelLogger::LogValue("discriminator", indent + 1, value.discriminator)); + ReturnErrorOnFailure(DataModelLogger::LogValue("iterations", indent + 1, value.iterations)); + ReturnErrorOnFailure(DataModelLogger::LogValue("salt", indent + 1, value.salt)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType & value) { @@ -17526,6 +17578,47 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case CommissionerControl::Id: { + switch (path.mAttributeId) + { + case CommissionerControl::Attributes::SupportedDeviceCategories::Id: { + chip::BitMask value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SupportedDeviceCategories", 1, value); + } + case CommissionerControl::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case CommissionerControl::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case CommissionerControl::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case CommissionerControl::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case CommissionerControl::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case CommissionerControl::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case ElectricalMeasurement::Id: { switch (path.mAttributeId) { @@ -19305,6 +19398,17 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case CommissionerControl::Id: { + switch (path.mCommandId) + { + case CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id: { + CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ReverseOpenCommissioningWindow", 1, value); + } + } + break; + } case ElectricalMeasurement::Id: { switch (path.mCommandId) { @@ -20192,6 +20296,17 @@ CHIP_ERROR DataModelLogger::LogEvent(const chip::app::EventHeader & header, chip } break; } + case CommissionerControl::Id: { + switch (header.mPath.mEventId) + { + case CommissionerControl::Events::CommissioningRequestResult::Id: { + chip::app::Clusters::CommissionerControl::Events::CommissioningRequestResult::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CommissioningRequestResult", 1, value); + } + } + break; + } case UnitTesting::Id: { switch (header.mPath.mEventId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 922ae495192512..7aecdf187d7a49 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -637,6 +637,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccountLogin::Events::LoggedOut::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ContentControl::Events::RemainingScreenTimeExpired::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::CommissionerControl::Events::CommissioningRequestResult::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Events::TestEvent::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, @@ -797,6 +800,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::DecodableType & value); static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ElectricalMeasurement::Commands::GetProfileInfoResponseCommand::DecodableType & value); static CHIP_ERROR diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 493b8a45376696..9d6610f69f3faf 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -156,6 +156,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| | FaultInjection | 0xFFF1FC06| @@ -162276,6 +162277,784 @@ class SubscribeAttributeContentAppObserverClusterRevision : public SubscribeAttr } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster CommissionerControl | 0x0751 | +|------------------------------------------------------------------------------| +| Commands: | | +| * RequestCommissioningApproval | 0x00 | +| * CommissionNode | 0x01 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedDeviceCategories | 0x0000 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +| * CommissioningRequestResult | 0x0000 | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command RequestCommissioningApproval + */ +class CommissionerControlRequestCommissioningApproval : public ClusterCommand { +public: + CommissionerControlRequestCommissioningApproval() + : ClusterCommand("request-commissioning-approval") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("VendorId", 0, UINT16_MAX, &mRequest.vendorId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ProductId", 0, UINT16_MAX, &mRequest.productId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Label", &mRequest.label); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRCommissionerControlClusterRequestCommissioningApprovalParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.requestId = [NSNumber numberWithUnsignedLongLong:mRequest.requestId]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.vendorId = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.vendorId)]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.productId = [NSNumber numberWithUnsignedShort:mRequest.productId]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.label.HasValue()) { + params.label = [[NSString alloc] initWithBytes:mRequest.label.Value().data() length:mRequest.label.Value().size() encoding:NSUTF8StringEncoding]; + } else { + params.label = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster requestCommissioningApprovalWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command CommissionNode + */ +class CommissionerControlCommissionNode : public ClusterCommand { +public: + CommissionerControlCommissionNode() + : ClusterCommand("commission-node") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("RequestId", 0, UINT64_MAX, &mRequest.requestId); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ResponseTimeoutSeconds", 0, UINT16_MAX, &mRequest.responseTimeoutSeconds); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("IpAddress", &mRequest.ipAddress); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Port", 0, UINT16_MAX, &mRequest.port); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRCommissionerControlClusterCommissionNodeParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.requestId = [NSNumber numberWithUnsignedLongLong:mRequest.requestId]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.responseTimeoutSeconds = [NSNumber numberWithUnsignedShort:mRequest.responseTimeoutSeconds]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.ipAddress.HasValue()) { + params.ipAddress = [NSData dataWithBytes:mRequest.ipAddress.Value().data() length:mRequest.ipAddress.Value().size()]; + } else { + params.ipAddress = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.port.HasValue()) { + params.port = [NSNumber numberWithUnsignedShort:mRequest.port.Value()]; + } else { + params.port = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster commissionNodeWithParams:params completion: + ^(MTRCommissionerControlClusterReverseOpenCommissioningWindowParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SupportedDeviceCategories + */ +class ReadCommissionerControlSupportedDeviceCategories : public ReadAttribute { +public: + ReadCommissionerControlSupportedDeviceCategories() + : ReadAttribute("supported-device-categories") + { + } + + ~ReadCommissionerControlSupportedDeviceCategories() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSupportedDeviceCategoriesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.SupportedDeviceCategories response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl SupportedDeviceCategories read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlSupportedDeviceCategories : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlSupportedDeviceCategories() + : SubscribeAttribute("supported-device-categories") + { + } + + ~SubscribeAttributeCommissionerControlSupportedDeviceCategories() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSupportedDeviceCategoriesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.SupportedDeviceCategories response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadCommissionerControlGeneratedCommandList : public ReadAttribute { +public: + ReadCommissionerControlGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadCommissionerControlGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeCommissionerControlGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadCommissionerControlAcceptedCommandList : public ReadAttribute { +public: + ReadCommissionerControlAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadCommissionerControlAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeCommissionerControlAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadCommissionerControlEventList : public ReadAttribute { +public: + ReadCommissionerControlEventList() + : ReadAttribute("event-list") + { + } + + ~ReadCommissionerControlEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlEventList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeCommissionerControlEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadCommissionerControlAttributeList : public ReadAttribute { +public: + ReadCommissionerControlAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadCommissionerControlAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeCommissionerControlAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadCommissionerControlFeatureMap : public ReadAttribute { +public: + ReadCommissionerControlFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadCommissionerControlFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeCommissionerControlFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadCommissionerControlClusterRevision : public ReadAttribute { +public: + ReadCommissionerControlClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadCommissionerControlClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("CommissionerControl ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeCommissionerControlClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeCommissionerControlClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeCommissionerControlClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CommissionerControl.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + #endif // MTR_ENABLE_PROVISIONAL #endif // MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ @@ -194405,6 +195184,59 @@ void registerClusterContentAppObserver(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterCommissionerControl(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::CommissionerControl; + + const char * clusterName = "CommissionerControl"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterElectricalMeasurement(Commands & commands) { using namespace chip::app::Clusters::ElectricalMeasurement; @@ -195207,6 +196039,7 @@ void registerClusters(Commands & commands) registerClusterAccountLogin(commands); registerClusterContentControl(commands); registerClusterContentAppObserver(commands); + registerClusterCommissionerControl(commands); registerClusterElectricalMeasurement(commands); registerClusterUnitTesting(commands); registerClusterSampleMei(commands);