diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index d92158e3277bc1..21708845b4ccfb 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -465,6 +465,7 @@ EchoMessage EchoRequests EchoResponse EchoService +ECW edaf edc EDR @@ -738,6 +739,7 @@ kCase Kconfig kDacPublicKey KeypadInput +keypair keyset kGroup kInvalidCommandId @@ -884,6 +886,7 @@ mlan MLD mmevk moal +Mobly ModeSelect modprobe Modustoolbox @@ -948,6 +951,7 @@ nrfdks nrfutil nrfxlib NTAG +NTP nullable nullptr NUM @@ -1013,6 +1017,7 @@ OTBR otcli outform outgoingCommands +overridable OxygenConcentrationMeasurement OzoneConcentrationMeasurement PAA @@ -1051,6 +1056,7 @@ perfetto periodicQueryTimeout pexpect pickString +PICSCODE PID Pigweed PinCode @@ -1366,6 +1372,7 @@ TestGenExample TestGroupDemoConfig TestMultiRead TestName +TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke TESTPASSWD TestPICS TESTSSID diff --git a/.github/actions/checkout-submodules-and-bootstrap/action.yaml b/.github/actions/checkout-submodules-and-bootstrap/action.yaml index 8ddaec14e7bc47..b514b8dd795509 100644 --- a/.github/actions/checkout-submodules-and-bootstrap/action.yaml +++ b/.github/actions/checkout-submodules-and-bootstrap/action.yaml @@ -15,6 +15,8 @@ inputs: runs: using: "composite" steps: + - name: Maximize runner disk + uses: ./.github/actions/maximize-runner-disk - name: Dump disk info uses: ./.github/actions/dump-disk-info - name: Set git safe directory for local act runs diff --git a/.github/actions/maximize-runner-disk/action.yaml b/.github/actions/maximize-runner-disk/action.yaml new file mode 100644 index 00000000000000..fe5f95352aa53e --- /dev/null +++ b/.github/actions/maximize-runner-disk/action.yaml @@ -0,0 +1,50 @@ +name: Maximize runner disk +description: Free up disk space on the github runner +runs: + using: "composite" + steps: + - name: Free up disk space on the github runner + if: ${{ !env.ACT }} + shell: bash + run: | + # maximize-runner-disk + if [[ "$RUNNER_OS" == Linux ]]; then + # Directories to prune to free up space. Candidates: + # 1.6G /usr/share/dotnet + # 1.1G /usr/local/lib/android/sdk/platforms + # 1000M /usr/local/lib/android/sdk/build-tools + # 8.9G /usr/local/lib/android/sdk + # This list can be amended later to change the trade-off between the amount of + # disk space freed up, and how long it takes to do so (deleting many files is slow). + prune=(/usr/share/dotnet /usr/local/lib/android/sdk/platforms /usr/local/lib/android/sdk/build-tools) + + if [[ "$UID" -eq 0 && -d /__w ]]; then + root=/runner-root-volume + if [[ ! -d "$root" ]]; then + echo "Unable to maximize disk space, job is running inside a container and $root is not mounted" + exit 0 + fi + function sudo() { "$@"; } # we're already root (and sudo is probably unavailable) + elif [[ "$UID" -ne 0 && "$RUNNER_ENVIRONMENT" == github-hosted ]]; then + root= + else + echo "Unable to maximize disk space, unknown runner environment" + exit 0 + fi + + echo "Freeing up runner disk space on ${root:-/}" + function avail() { df -k --output=avail "${root:-/}" | grep '^[0-9]*$'; } + function now() { date '+%s'; } + before="$(avail)" start="$(now)" + for dir in "${prune[@]}"; do + if [[ -d "${root}${dir}" ]]; then + echo "- $dir" + # du -sh -- "${root}${dir}" + sudo rm -rf -- "${root}${dir}" + else + echo "- $dir (not found)" + fi + done + after="$(avail)" end="$(now)" + echo "Done, freed up $(( (after - before) / 1024 ))M of disk space in $(( end - start )) seconds." + fi diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 23dd3d3eb0f309..e509aab995c682 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,6 +42,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -137,6 +138,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -221,6 +223,7 @@ jobs: run: | ./scripts/run_in_build_env.sh "./scripts/codepregen.py ./zzz_pregenerated" mv scripts/codegen.py scripts/codegen.py.renamed + mv scripts/tools/zap/generate.py scripts/tools/zap/generate.py.renamed - name: Clean output run: rm -rf ./out - name: Build using build_examples.py (pregen) @@ -232,18 +235,11 @@ jobs: --pregen-dir ./zzz_pregenerated \ build \ " - - name: Check no code generation in output - run: | - CNT=$(find out -name "CHIPClusters.h" | wc -l) - if [ "${CNT}" != "0" ]; then - echo "ERROR: found unexpected generated files:" - find out -name "CHIPClusters.h" - exit 1 - fi - name: Undo code pre-generation changes (make compile time codegen work again) 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 - name: Run fake linux tests with build_examples run: | ./scripts/run_in_build_env.sh \ @@ -285,6 +281,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" options: --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -345,6 +342,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" options: --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -453,6 +451,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" diff --git a/.github/workflows/cirque.yaml b/.github/workflows/cirque.yaml index 9f1bfc207f92c8..c9fe4b296d6edb 100644 --- a/.github/workflows/cirque.yaml +++ b/.github/workflows/cirque.yaml @@ -71,7 +71,7 @@ jobs: - name: Get Cirque Bootstrap cache key id: cirque-bootstrap-cache-key run: echo "val=$(scripts/tests/cirque_tests.sh cachekeyhash)" >> $GITHUB_OUTPUT - - uses: Wandalen/wretry.action@v1.4.4 + - uses: Wandalen/wretry.action@v1.4.5 name: Cirque Bootstrap cache if: ${{ !env.ACT }} continue-on-error: true diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index 2d7443f9e9758c..088c541495665b 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -49,6 +49,11 @@ jobs: - name: Validate zap-cli is NOT available # run_in_build_env.sh is used to ensure PATH is set to something that would otherwise find zap-cli run: scripts/run_in_build_env.sh '(zap-cli --version && exit 1) || exit 0' + - name: Run watchOS Build Debug + working-directory: src/darwin/Framework + # Disable availability annotations, since we are not building a system + # Matter.framework. + run: xcodebuild -target "Matter" -sdk watchos -configuration Debug GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1' - name: Run iOS Build Debug working-directory: src/darwin/Framework # Disable availability annotations, since we are not building a system @@ -105,31 +110,24 @@ jobs: mkdir -p /tmp/darwin/framework-tests ../../../out/debug/chip-all-clusters-app --interface-id -1 > >(tee /tmp/darwin/framework-tests/all-cluster-app.log) 2> >(tee /tmp/darwin/framework-tests/all-cluster-app-err.log >&2) & ../../../out/debug/chip-all-clusters-app --interface-id -1 --dac_provider ../../../credentials/development/commissioner_dut/struct_cd_origin_pid_vid_correct/test_case_vector.json --product-id 32768 --discriminator 3839 --secured-device-port 5539 --KVS /tmp/chip-all-clusters-app-kvs2 > >(tee /tmp/darwin/framework-tests/all-cluster-app-origin-vid.log) 2> >(tee /tmp/darwin/framework-tests/all-cluster-app-origin-vid-err.log >&2) & - # Disable BLE because the app does not have the permission to use - # it and that may crash the CI. - # - # -enableUndefinedBehaviorSanitizer instruments the code in Matter.framework, - # but to instrument the code in the underlying libCHIP we need to pass CHIP_IS_UBSAN=YES - TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion' CHIP_IS_UBSAN=YES CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1'> >(tee /tmp/darwin/framework-tests/darwin-tests-asan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-err.log >&2) + # Disable BLE (CHIP_IS_BLE=NO) because the app does not have the permission to use it and that may crash the CI. + + TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion' CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1'> >(tee /tmp/darwin/framework-tests/darwin-tests-asan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-err.log >&2) # And the same thing, but with MTR_PER_CONTROLLER_STORAGE_ENABLED turned off, so we test that it does not break for now. - TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion' CHIP_IS_UBSAN=YES CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1 MTR_PER_CONTROLLER_STORAGE_ENABLED=0' > >(tee /tmp/darwin/framework-tests/darwin-tests-asan-controller-storage.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-controller-storage-err.log >&2) + TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion' CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1 MTR_PER_CONTROLLER_STORAGE_ENABLED=0' > >(tee /tmp/darwin/framework-tests/darwin-tests-asan-controller-storage.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-controller-storage-err.log >&2) # And the same thing, but with MTR_NO_AVAILABILITY not turned on. This requires -Wno-unguarded-availability-new to avoid availability errors. - TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_UBSAN=YES CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited}' > >(tee /tmp/darwin/framework-tests/darwin-tests-asan-with-availability-annotations.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-with-availability-annotations-err.log >&2) - # -enableThreadSanitizer instruments the code in Matter.framework, - # but to instrument the code in the underlying libCHIP we need to pass CHIP_IS_TSAN=YES - xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableThreadSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion' CHIP_IS_TSAN=YES CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1' > >(tee /tmp/darwin/framework-tests/darwin-tests-tsan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-tsan-err.log >&2) + TEST_RUNNER_ASAN_OPTIONS=__CURRENT_VALUE__:detect_stack_use_after_return=1 xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableAddressSanitizer YES -enableUndefinedBehaviorSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-unguarded-availability-new' CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited}' > >(tee /tmp/darwin/framework-tests/darwin-tests-asan-with-availability-annotations.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-asan-with-availability-annotations-err.log >&2) + + xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx -enableThreadSanitizer YES OTHER_CFLAGS='${inherited} -Werror -Wconversion' CHIP_IS_BLE=NO GCC_PREPROCESSOR_DEFINITIONS='${inherited} MTR_NO_AVAILABILITY=1' > >(tee /tmp/darwin/framework-tests/darwin-tests-tsan.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-tsan-err.log >&2) working-directory: src/darwin/Framework - name: Build Matter TV Casting Bridge run: | xcodebuild -target "MatterTvCastingBridge" -sdk iphoneos working-directory: examples/tv-casting-app/darwin/MatterTvCastingBridge - - name: Uploading .ips files in Xcode derived data to debug the failure - uses: actions/upload-artifact@v4 - if: ${{ failure() && !env.ACT }} - with: - name: darwin-framework-derived-data - path: ~/Library/Developer/Xcode/DerivedData/**/*.ips - retention-days: 5 + - name: Collect crash logs + run: | + mkdir -p /tmp/darwin/framework-tests + find ~/Library/Developer/Xcode/DerivedData /Library/Logs/DiagnosticReports -name '*.ips' -print0 | xargs -0 -J % cp % /tmp/darwin/framework-tests - name: Uploading log files uses: actions/upload-artifact@v4 if: ${{ failure() && !env.ACT }} diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index e24492d94e60a7..2317da776e6a95 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -71,6 +71,7 @@ jobs: run: | ./scripts/run_in_build_env.sh "./scripts/codepregen.py ./zzz_pregenerated" mv scripts/codegen.py scripts/codegen.py.renamed + mv scripts/tools/zap/generate.py scripts/tools/zap/generate.py.renamed - name: Clean output run: rm -rf ./out - name: Build some M5Stack variations with pregen @@ -84,18 +85,11 @@ jobs: build \ --copy-artifacts-to out/artifacts \ " - - name: Check no code generation in output - run: | - CNT=$(find out -name "CHIPClusters.h" | wc -l) - if [ "${CNT}" != "0" ]; then - echo "ERROR: found unexpected generated files:" - find out -name "CHIPClusters.h" - exit 1 - fi - name: Undo code pregeneration changes 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 - name: Build example All Clusters App C3 run: scripts/examples/esp_example.sh all-clusters-app sdkconfig_c3devkit.defaults - name: Copy aside build products diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index fadc0da4a42f3c..97617480d8f292 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: Wandalen/wretry.action@v1.4.4 + - uses: Wandalen/wretry.action@v1.4.5 name: Gradle Validation continue-on-error: true with: diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index f19d451fbc2df6..8d21ca0bd4c56d 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -132,6 +132,17 @@ jobs: --tool-cluster "im" \ --tool-args "onnetwork-long-im-invoke --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \ --factoryreset \ + ' + - name: Run IM Extendable Invoke Test + run: | + scripts/run_in_python_env.sh out/venv \ + './scripts/tests/run_java_test.py \ + --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app \ + --app-args "--discriminator 3840 --interface-id -1" \ + --tool-path out/linux-x64-java-matter-controller \ + --tool-cluster "im" \ + --tool-args "onnetwork-long-im-extendable-invoke --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \ + --factoryreset \ ' - name: Run IM Read Test run: | diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 69613217033e8b..70edd539eee0bf 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -92,16 +92,11 @@ jobs: --known-failure controller/ExamplePersistentStorage.h \ --known-failure app/AttributeAccessInterface.h \ --known-failure app/AttributeAccessToken.h \ - --known-failure app/att-storage.h \ --known-failure app/CommandHandler.h \ --known-failure app/CommandHandlerInterface.h \ --known-failure app/CommandSenderLegacyCallback.h \ - --known-failure app/CompatEnumNames.h \ --known-failure app/data-model/ListLargeSystemExtensions.h \ - --known-failure app/EventHeader.h \ - --known-failure app/EventLoggingTypes.h \ --known-failure app/ReadHandler.h \ - --known-failure app/ReadPrepareParams.h \ --known-failure app/reporting/tests/MockReportScheduler.cpp \ --known-failure app/reporting/tests/MockReportScheduler.h \ --known-failure app/TestEventTriggerDelegate.h \ @@ -114,23 +109,19 @@ jobs: --known-failure app/util/attribute-table.h \ --known-failure app/util/binding-table.cpp \ --known-failure app/util/binding-table.h \ - --known-failure app/util/common.h \ --known-failure app/util/config.h \ --known-failure app/util/DataModelHandler.cpp \ --known-failure app/util/DataModelHandler.h \ --known-failure app/util/ember-compatibility-functions.cpp \ --known-failure app/util/endpoint-config-api.h \ - --known-failure app/util/endpoint-config-defines.h \ --known-failure app/util/generic-callbacks.h \ --known-failure app/util/generic-callback-stubs.cpp \ --known-failure app/util/im-client-callbacks.h \ --known-failure app/util/MatterCallbacks.h \ - --known-failure app/util/message.cpp \ --known-failure app/util/odd-sized-integers.h \ --known-failure app/util/util.cpp \ --known-failure app/util/util.h \ --known-failure app/WriteHandler.h \ - --known-failure lib/core/CHIPVendorIdentifiers.hpp \ --known-failure platform/DeviceSafeQueue.cpp \ --known-failure platform/DeviceSafeQueue.h \ --known-failure platform/GLibTypeDeleter.h \ @@ -205,7 +196,7 @@ jobs: # TODO: TLVDebug should ideally not be excluded here. # TODO: protocol_decoder.cpp should ideally not be excluded here. # TODO: PersistentStorageMacros.h should ideally not be excluded here. - git grep -I -n "PRI.64" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)examples/chip-tool' ':(exclude)examples/tv-casting-app' ':(exclude)src/app/MessageDef/MessageDefHelper.cpp' ':(exclude)src/app/tests/integration/chip_im_initiator.cpp' ':(exclude)src/lib/core/TLVDebug.cpp' ':(exclude)src/lib/dnssd/tests/TestTxtFields.cpp' ':(exclude)src/lib/format/protocol_decoder.cpp' ':(exclude)src/lib/support/PersistentStorageMacros.h' ':(exclude)src/messaging/tests/echo/echo_requester.cpp' ':(exclude)src/platform/Linux' ':(exclude)src/platform/Ameba' ':(exclude)src/platform/ESP32' ':(exclude)src/platform/webos' ':(exclude)zzz_generated/chip-tool' ':(exclude)src/tools/chip-cert/Cmd_PrintCert.cpp' && exit 1 || exit 0 + git grep -I -n "PRI.64" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)examples/chip-tool' ':(exclude)examples/tv-casting-app' ':(exclude)src/app/MessageDef/MessageDefHelper.cpp' ':(exclude)src/app/tests/integration/chip_im_initiator.cpp' ':(exclude)src/lib/core/TLVDebug.cpp' ':(exclude)src/lib/dnssd/tests/TestTxtFields.cpp' ':(exclude)src/lib/format/protocol_decoder.cpp' ':(exclude)src/lib/support/PersistentStorageMacros.h' ':(exclude)src/messaging/tests/echo/echo_requester.cpp' ':(exclude)src/platform/Linux' ':(exclude)src/platform/Ameba' ':(exclude)src/platform/ESP32' ':(exclude)src/platform/Darwin' ':(exclude)src/darwin' ':(exclude)src/platform/webos' ':(exclude)zzz_generated/chip-tool' ':(exclude)src/tools/chip-cert/Cmd_PrintCert.cpp' && exit 1 || exit 0 # git grep exits with 0 if it finds a match, but we want # to fail (exit nonzero) on match. And we want to exclude this file, diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index 396fb3ae153a46..64efaeb82ff20f 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -39,6 +39,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build-android:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" steps: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 83d921c2fa4188..41138dd787360c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -508,7 +508,6 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-lit-icd-ipv6only-no-ble-no-wifi-tsan-clang-test/lit-icd-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_ICDM_2_1.py" --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:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_IDM_1_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json --enable-key 000102030405060708090a0b0c0d0e0f" --script "src/python_testing/TC_IDM_1_4.py" --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:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' - scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_IDM_4_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_PWRTL_2_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RR_1_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_SC_3_6.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index 62231116bb92c1..15199d4d6532e3 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -39,6 +39,7 @@ jobs: container: image: ghcr.io/project-chip/chip-build:35 volumes: + - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" diff --git a/.spellcheck.yml b/.spellcheck.yml index 27a48c7de8e174..7313f64ebd6976 100644 --- a/.spellcheck.yml +++ b/.spellcheck.yml @@ -65,7 +65,7 @@ matrix: # converts markdown to HTML - pyspelling.filters.markdown: sources: - - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md' + - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md | !docs/testing/python.md | !docs/testing/ChipDeviceCtrlAPI.md' aspell: ignore-case: true camel-case: true diff --git a/build/chip/chip_codegen.gni b/build/chip/chip_codegen.gni index 02acd08150aae8..ee82204af22f40 100644 --- a/build/chip/chip_codegen.gni +++ b/build/chip/chip_codegen.gni @@ -31,11 +31,7 @@ template("_chip_build_time_codegen") { _name = target_name _generator = invoker.generator - config("${_name}_config") { - include_dirs = [ target_gen_dir ] - } - - pw_python_action("${_name}_codegen") { + pw_python_action("${_name}_generate") { script = "${chip_root}/scripts/codegen.py" # TODO: this seems to touch internals. Is this ok? speeds up builds! @@ -99,7 +95,7 @@ template("_chip_build_time_codegen") { if (!defined(deps)) { deps = [] } - deps += [ ":${_name}_codegen" ] + deps += [ ":${_name}_generate" ] } } @@ -124,10 +120,6 @@ template("_chip_build_time_zapgen") { _name = target_name _generator = invoker.generator - config("${_name}_config") { - include_dirs = [ "${target_gen_dir}/zapgen/" ] - } - assert(_generator == "app-templates") if (_generator == "app-templates") { @@ -152,7 +144,7 @@ template("_chip_build_time_zapgen") { _output_subdir = "zap-generated" } - pw_python_action("${_name}_zap_pregen") { + pw_python_action("${_name}_generate") { script = "${chip_root}/scripts/tools/zap/generate.py" # TODO: this seems to touch internals. Is this ok? speeds up builds! @@ -165,7 +157,7 @@ template("_chip_build_time_zapgen") { "--templates", _template_path, "--output-dir", - rebase_path(target_gen_dir) + "/zap_pregen/" + _output_subdir, + rebase_path(target_gen_dir) + "/zapgen/" + _output_subdir, # TODO: lock file support should be removed as this serializes zap # (slower), however this is currently done because on Darwin zap startup @@ -188,54 +180,10 @@ template("_chip_build_time_zapgen") { sources = [ _idl_file ] - outputs = [] - foreach(name, invoker.outputs) { - outputs += [ "${target_gen_dir}/zap_pregen/${name}" ] - } - - forward_variables_from(invoker, [ "prune_outputs" ]) - if (defined(prune_outputs)) { - foreach(name, prune_outputs) { - outputs += [ "${target_gen_dir}/zap_pregen/${name}" ] - } - } - } - - # This action ensures that any "extra" files generated by zap codegen - # are actually deleted. - # - # This is to avoid double-codegen of configurations like endpoint config - # or access credentials being generated for both "controller client" and - # application-specific - pw_python_action("${_name}_files") { - # TODO: this seems to touch internals. Is this ok? speeds up builds! - _pw_internal_run_in_venv = false - - script = "${chip_root}/scripts/tools/zap/prune_outputs.py" - - _keep_file = rebase_path("${target_gen_dir}/${_name}.keep.outputs") - write_file(_keep_file, invoker.outputs, "list lines") - - args = [ - "--keep", - _keep_file, - "--input-dir", - rebase_path("${target_gen_dir}/zap_pregen/"), - "--output-dir", - rebase_path("${target_gen_dir}/zapgen/"), - ] - - inputs = [] - foreach(name, invoker.outputs) { - inputs += [ "${target_gen_dir}/zap_pregen/${name}" ] - } - outputs = [] foreach(name, invoker.outputs) { outputs += [ "${target_gen_dir}/zapgen/${name}" ] } - - deps = [ ":${_name}_zap_pregen" ] } source_set(_name) { @@ -255,10 +203,7 @@ template("_chip_build_time_zapgen") { if (!defined(public_deps)) { public_deps = [] } - public_deps += [ - ":${_name}_files", - ":${_name}_zap_pregen", - ] + public_deps += [ ":${_name}_generate" ] } } @@ -272,6 +217,9 @@ template("_chip_build_time_zapgen") { # generator # Name of the generator to use (e.g. java-jni, java-class, cpp-app) # +# outputs MUST share the same directory prefix (e.g. 'app/' or 'tlv/meta' +# or 'jni') +# # outputs # Explicit names of the expected outputs. Enforced to validate that # expected outputs are generated when processing input files. @@ -312,7 +260,17 @@ template("_chip_build_time_zapgen") { # ] # } # +# Guarantees a target named "${target_name}_generate" exists and contains all +# generated files (this works even in the case of using a pre-generated directory +# by using a copy target to import pre-generated data) +# template("chip_codegen") { + _name = target_name + + config("${_name}_config") { + include_dirs = [ target_gen_dir ] + } + if (chip_code_pre_generated_directory == "") { _chip_build_time_codegen(target_name) { forward_variables_from(invoker, @@ -326,8 +284,6 @@ template("chip_codegen") { ]) } } else { - _name = target_name - not_needed(invoker, [ "options" ]) # This constructs a path like: @@ -339,8 +295,21 @@ template("chip_codegen") { string_replace(rebase_path(invoker.input, chip_root), ".matter", "") + "/codegen/" + invoker.generator - config("${_name}_config") { - include_dirs = [ "${_generation_dir}" ] + # Generation in this case just involves some files copying + copy("${_name}_generate") { + sources = [] + + foreach(name, invoker.outputs) { + sources += [ "${_generation_dir}/${name}" ] + } + + # NOTE: we assume ALL outputs have a common subdir. This is generally the case with + # paths like "app/callback-stub.cpp" and "app/PluginApplicationCallbacks.h" + _outputs = invoker.outputs + _dir_name = get_path_info(_outputs[0], "dir") + outputs = [ "${target_gen_dir}/${_dir_name}/{{source_file_part}}" ] + + public_configs = [ ":${_name}_config" ] } source_set(_name) { @@ -349,13 +318,13 @@ template("chip_codegen") { if (defined(invoker.public_configs)) { public_configs += invoker.public_configs } + sources = get_target_outputs(":${_name}_generate") forward_variables_from(invoker, [ "deps" ]) - - sources = [] - foreach(name, invoker.outputs) { - sources += [ "${_generation_dir}/${name}" ] + if (!defined(deps)) { + deps = [] } + deps += [ ":${_name}_generate" ] } } } @@ -374,6 +343,9 @@ template("chip_codegen") { # Explicit names of the expected outputs. Enforced to validate that # expected outputs are generated when processing input files. # +# outputs MUST share the same directory prefix (e.g. 'app/' or 'tlv/meta' +# or 'jni') +# # deps, public_configs # Forwarded to the resulting source set # @@ -399,18 +371,28 @@ template("chip_codegen") { # # Example usage: # -# chip_codegen("java-jni-generate") { -# input = "controller-clusters.matter" -# generator = "java-jni" +# chip_zapgen("controller-clusters-zap") { +# input = "controller-clusters.zap" +# generator = "app-templates" # -# outputs = [ -# "jni/IdentifyClient-ReadImpl.cpp", -# "jni/IdentifyClient-InvokeSubscribeImpl.cpp", -# # ... more to follow -# ] -# } +# outputs = [ +# "zap-generated/access.h", +# "zap-generated/gen_config.h", +# "zap-generated/endpoint_config.h", +# ] +# } +# +# Guarantees a target named "${target_name}_generate" exists and contains all +# generated files (this works even in the case of using a pre-generated directory +# by using a copy target to import pre-generated data) # template("chip_zapgen") { + _name = target_name + + config("${_name}_config") { + include_dirs = [ "${target_gen_dir}/zapgen/" ] + } + if (chip_code_pre_generated_directory == "") { _chip_build_time_zapgen(target_name) { forward_variables_from(invoker, @@ -420,12 +402,9 @@ template("chip_zapgen") { "input", "outputs", "public_configs", - "prune_outputs", ]) } } else { - _name = target_name - # This contstructs a path like: # FROM all-clusters-app.zap (inside examples/all-clusters-app/all-clusters-common/) # USING "cpp-app" for generator: @@ -435,10 +414,6 @@ template("chip_zapgen") { string_replace(rebase_path(invoker.input, chip_root), ".zap", "") + "/zap/" + invoker.generator - config("${_name}_config") { - include_dirs = [ "${_generation_dir}" ] - } - # Pick up only the headers and mark them available to use # Specifically controller seems to require header files but NOT cpp (does) # not want to include cpp compilation of IM command handler data @@ -477,22 +452,40 @@ template("chip_zapgen") { public_deps = [ ":${_name}_headers" ] } + # Generation in this case just involves some files copying + copy("${_name}_generate") { + sources = [] + + foreach(name, invoker.outputs) { + sources += [ "${_generation_dir}/${name}" ] + } + + # NOTE: we assume ALL outputs have a common subdir. This is generally the case with + # paths like "app/callback-stub.cpp" and "app/PluginApplicationCallbacks.h" + _outputs = invoker.outputs + _dir_name = get_path_info(_outputs[0], "dir") + outputs = [ "${target_gen_dir}/zapgen/${_dir_name}/{{source_file_part}}" ] + + public_configs = [ ":${_name}_config" ] + } + source_set(_name) { forward_variables_from(invoker, [ "deps", "public_configs", - "prune_outputs", ]) if (!defined(public_configs)) { public_configs = [] } public_configs += [ ":${_name}_config" ] - sources = [] - foreach(name, invoker.outputs) { - sources += [ "${_generation_dir}/${name}" ] + if (!defined(public_deps)) { + public_deps = [] } + public_deps += [ ":${_name}_generate" ] + + sources = get_target_outputs(":${_name}_generate") # Ugly, but references WILL reference back into main code. check_includes = false diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 01626726e0b9af..7eb09b79c4c22d 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -76,11 +76,11 @@ if (_chip_defaults.custom_toolchain != "") { } else { _target_compiler = "gcc" } - _default_toolchain = "${_build_overrides.build_root}/toolchain/linux:linux_${target_cpu}_${_target_compiler}" -} else if (target_os == host_os && - (target_cpu == host_cpu || - (target_cpu == "arm64e" && host_cpu == "arm64"))) { +} else if (host_os == "mac" && (target_os == "mac" || target_os == "ios")) { + # On Mac the host toolchain supports building for all mac and ios targets + _default_toolchain = host_toolchain +} else if (target_os == host_os && target_cpu == host_cpu) { _default_toolchain = host_toolchain } else if (target_os == "freertos") { if (_chip_defaults.is_clang) { @@ -113,9 +113,6 @@ if (_chip_defaults.custom_toolchain != "") { } else { assert(false, "Unsupported target_cpu: ${current_cpu}") } -} else if (target_os == "ios") { - _default_toolchain = - "${_build_overrides.build_root}/toolchain/ios:ios_${target_cpu}" } else if (target_os == "tizen") { _default_toolchain = "${_build_overrides.build_root}/toolchain/tizen:tizen_${target_cpu}" diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index b6ad67a64944fd..df85153297cad7 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -343,7 +343,7 @@ config("cosmetic_default") { } config("runtime_default") { - if (is_clang) { + if (is_clang) { # Using Pigweed clang instead of Darwin host clang configs = [ "$dir_pw_toolchain/host_clang:no_system_libcpp", "$dir_pw_toolchain/host_clang:xcode_sysroot", @@ -395,11 +395,16 @@ declare_args() { } config("sanitize_address") { + defines = [] cflags = [ "-fsanitize=address", "-fno-omit-frame-pointer", ] ldflags = cflags + + if ((target_os == "mac" || target_os == "ios") && !is_clang) { + defines += [ "_LIBCPP_HAS_NO_ASAN" ] + } } config("sanitize_thread") { diff --git a/config/esp32/.gn b/config/esp32/.gn index 9f5db65cdad79b..52535ffabaf95d 100644 --- a/config/esp32/.gn +++ b/config/esp32/.gn @@ -13,6 +13,7 @@ # limitations under the License. import("//build_overrides/build.gni") +import("//build_overrides/pigweed.gni") # The location of the build configuration file. buildconfig = "${build_root}/config/BUILDCONFIG.gn" @@ -24,6 +25,15 @@ default_args = { target_cpu = "esp32" target_os = "freertos" + pw_sys_io_BACKEND = dir_pw_sys_io_stdio + pw_assert_BACKEND = dir_pw_assert_log + pw_log_BACKEND = dir_pw_log_basic + + pw_build_LINK_DEPS = [ + "$dir_pw_assert:impl", + "$dir_pw_log:impl", + ] + pw_build_PIP_CONSTRAINTS = [ "//third_party/connectedhomeip/scripts/setup/constraints.txt" ] pw_build_PIP_REQUIREMENTS = [ diff --git a/config/esp32/BUILD.gn b/config/esp32/BUILD.gn index 1aacff5567ecf6..fe8c51af257713 100644 --- a/config/esp32/BUILD.gn +++ b/config/esp32/BUILD.gn @@ -36,6 +36,9 @@ group("esp32") { } if (chip_build_tests) { - deps += [ "${chip_root}/src:tests" ] + deps += [ + "${chip_root}/src:tests", + "${chip_root}/src/lib/support:pw_tests_wrapper", + ] } } diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index 7f62ce6cc0087a..14594a03b74352 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -131,6 +131,25 @@ endif() if(CONFIG_ENABLE_ICD_SERVER) chip_gn_arg_append("chip_enable_icd_server" "true") + if(CONFIG_ICD_ENFORCE_SIT_SLOW_POLL_LIMIT) + chip_gn_arg_append("icd_enforce_sit_slow_poll_limit" "true") + endif() + if(CONFIG_ICD_REPORT_ON_ACTIVE_MODE) + chip_gn_arg_append("chip_icd_report_on_active_mode" "true") + endif() + if(CONFIG_ENABLE_ICD_LIT) + chip_gn_arg_append("chip_enable_icd_lit" "true") + if(CONFIG_ENABLE_ICD_CIP) + chip_gn_arg_append("chip_enable_icd_checkin" "true") + else() + chip_gn_arg_append("chip_enable_icd_checkin" "false") + endif() + if(CONFIG_ENABLE_ICD_USER_ACTIVE_MODE_TRIGGER) + chip_gn_arg_append("chip_enable_icd_user_active_mode_trigger" "true") + else() + chip_gn_arg_append("chip_enable_icd_user_active_mode_trigger" "false") + endif() + endif() endif() if(CONFIG_ENABLE_PW_RPC) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index 0dce48b5f720be..589f33b1c70830 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -271,6 +271,12 @@ menu "CHIP Core" Opens the commissioning window automatically at application boot time if the node is not yet commissioned. + config ENABLE_SNTP_TIME_SYNC + bool "Enable SNTP time synchronization" + default n + help + Enable this option to enable SNTP time synchronization + endmenu # "System Options" menu "Security Options" @@ -340,13 +346,27 @@ menu "CHIP Device Layer" help Enables or Disables the support for Commissionable Device Type. - config ENABLE_ICD_SERVER + menuconfig ENABLE_ICD_SERVER bool "Enable ICD server" depends on OPENTHREAD_MTD default n help Enables or Disables ICD server + config ICD_ENFORCE_SIT_SLOW_POLL_LIMIT + bool "Enforce SIT Slow Polling Max value to 15 seconds" + depends on ENABLE_ICD_SERVER + default n + help + Set to true to enforce SIT Slow Polling Max value to 15seconds + + config ICD_REPORT_ON_ACTIVE_MODE + bool "Emit a report on entering active mode" + depends on ENABLE_ICD_SERVER + default n + help + Make the ICD manager emit a report on entering active mode + config ICD_SLOW_POLL_INTERVAL_MS int "ICD Slow Polling Interval(ms)" depends on ENABLE_ICD_SERVER @@ -389,14 +409,48 @@ menu "CHIP Device Layer" This value indicates the minimum amount of time in milliseconds the server typically will stay active after network activity when in active mode. + config ENABLE_ICD_LIT + bool "Enable Long Idle Time ICD" + depends on ENABLE_ICD_SERVER + default n + help + Enables or Disables LIT ICD + + config ENABLE_ICD_CIP + bool "Enable Check-in protocol" + depends on ENABLE_ICD_LIT + default y + help + Enables or Disables ICD Check-in protocol + config ICD_CLIENTS_SUPPORTED_PER_FABRIC int "ICD Clients Number Supported Per Fabric" - depends on ENABLE_ICD_SERVER + depends on ENABLE_ICD_CIP default 1 help This value indicates the maximum number of entries that the ICD server is able to store for each fabric in the RegisteredClients attribute. + config ICD_MAX_NOTIFICATION_SUBSCRIBERS + int "Max ICD notification subscribers" + depends on ENABLE_ICD_SERVER + default 1 + help + The ICDManager implements the ICDListener functions and is always subscribed to the ICDNotifier + This allows other Matter modules to inform the ICDManager that it needs to go and may have to stay in Active Mode, + outside of its standard ActiveModeDuration and IdleModeDuration, without being tightly coupled the application + data model + + This implementation also allows other modules to implement an ICDListener and subscribe to ICDNotifier + to couple behaviours with the ICD cycles. In such cases, ICD_MAX_NOTIFICATION_SUBSCRIBERS need to be adjusted + + config ENABLE_ICD_USER_ACTIVE_MODE_TRIGGER + bool "Enable User Active Mode Trigger feature" + depends on ENABLE_ICD_LIT + default y + help + Enables or Disables ICD User Active Mode Trigger feature + config ENABLE_BG_EVENT_PROCESSING bool "Enable Background event processing" default n diff --git a/config/nrfconnect/chip-gn/.gn b/config/nrfconnect/chip-gn/.gn index bf81e1e8f52cef..b8e1a5a86cc803 100644 --- a/config/nrfconnect/chip-gn/.gn +++ b/config/nrfconnect/chip-gn/.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") # The location of the build configuration file. buildconfig = "${build_root}/config/BUILDCONFIG.gn" @@ -25,5 +26,14 @@ default_args = { target_cpu = "arm" target_os = "zephyr" + pw_sys_io_BACKEND = dir_pw_sys_io_stdio + pw_assert_BACKEND = dir_pw_assert_log + pw_log_BACKEND = dir_pw_log_basic + + pw_build_LINK_DEPS = [ + "$dir_pw_assert:impl", + "$dir_pw_log:impl", + ] + import("${chip_root}/config/nrfconnect/chip-gn/args.gni") } diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index 3414bdd26c9687..c72080b7005409 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -206,6 +206,11 @@ choice CHIP_FACTORY_DATA_CERT_SOURCE endchoice +config CHIP_FACTORY_DATA_GENERATE_CD + bool "Generates Certification Declaration to the output build directory" + help + Generates the new Certification Declaration and stores it to the output build directory. + if CHIP_FACTORY_DATA_CERT_SOURCE_USER config CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT @@ -230,6 +235,7 @@ endif # CHIP_FACTORY_DATA_CERT_SOURCE_USER # Configs for SPAKE2+ generation config CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER bool "Generate SPAKE2+ verifier" + default y help Enables the generation of the SPAKE2+ verifier for the configured SPAKE2+ passcode, iteration count and salt. diff --git a/config/nrfconnect/chip-module/generate_factory_data.cmake b/config/nrfconnect/chip-module/generate_factory_data.cmake index dc1794562d89cf..3c286fc21dddee 100644 --- a/config/nrfconnect/chip-module/generate_factory_data.cmake +++ b/config/nrfconnect/chip-module/generate_factory_data.cmake @@ -48,14 +48,25 @@ string(APPEND script_args "--hw_ver ${CONFIG_CHIP_DEVICE_HARDWARE_VERSION}\n") string(APPEND script_args "--hw_ver_str \"${CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING}\"\n") # check if Rotating Device Id Unique Id should be generated -if(NOT CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID) - if(NOT DEFINED CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID) - message(FATAL_ERROR "CHIP_DEVICE_ROTATING_DEVICE_UID was not provided. To generate it use CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID=y") +if(CONFIG_CHIP_ROTATING_DEVICE_ID) + if(NOT CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID) + if(NOT DEFINED CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID) + message(FATAL_ERROR "CHIP_DEVICE_ROTATING_DEVICE_UID was not provided. To generate it use CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID=y") + else() + string(APPEND script_args "--rd_uid \"${CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID}\"\n") + endif() else() - string(APPEND script_args "--rd_uid \"${CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID}\"\n") + string(APPEND script_args "--generate_rd_uid\n") endif() -else() - string(APPEND script_args "--generate_rd_uid\n") +endif() + +if(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED OR CONFIG_CHIP_FACTORY_DATA_GENERATE_CD) + find_program(chip_cert_exe NAMES chip-cert REQUIRED) + string(APPEND script_args "--chip_cert_path ${chip_cert_exe}\n") +endif() + +if(CONFIG_CHIP_FACTORY_DATA_GENERATE_CD) + string(APPEND script_args "--gen_cd\n") endif() # for development purpose user can use default certs instead of generating or providing them @@ -77,10 +88,8 @@ elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER) string(APPEND script_args "--dac_cert \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT}\"\n") string(APPEND script_args "--dac_key \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY}\"\n") string(APPEND script_args "--pai_cert \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT}\"\n") -else() - find_program(chip_cert_exe NAMES chip-cert REQUIRED) - string(APPEND script_args "--gen_cd\n") - string(APPEND script_args "--chip_cert_path ${chip_cert_exe}\n") +elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED) + string(APPEND script_args "--gen_certs\n") endif() # add Password-Authenticated Key Exchange parameters @@ -90,8 +99,14 @@ string(APPEND script_args "--discriminator ${CONFIG_CHIP_DEVICE_DISCRIMINATOR}\n string(APPEND script_args "--passcode ${CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE}\n") string(APPEND script_args "--include_passcode\n") string(APPEND script_args "--overwrite\n") -string(APPEND script_args "--product_finish ${CONFIG_CHIP_DEVICE_PRODUCT_FINISH}\n") +# check if spake2 verifier should be generated using script +if(NOT CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER) + # Spake2 verifier should be provided using kConfig + string(APPEND script_args "--spake2_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n") +endif() +# Product appearance +string(APPEND script_args "--product_finish ${CONFIG_CHIP_DEVICE_PRODUCT_FINISH}\n") if(CONFIG_CHIP_DEVICE_PRODUCT_COLOR) string(APPEND script_args "--product_color ${CONFIG_CHIP_DEVICE_PRODUCT_COLOR}\n") endif() @@ -100,12 +115,6 @@ if(CONFIG_CHIP_FACTORY_DATA_GENERATE_ONBOARDING_CODES) string(APPEND script_args "--generate_onboarding\n") endif() -# check if spake2 verifier should be generated using script -if(NOT CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER) - # Spake2 verifier should be provided using kConfig - string(APPEND script_args "--spake2_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n") -endif() - if(CONFIG_CHIP_DEVICE_ENABLE_KEY) # Add optional EnableKey that triggers user-specific action. string(APPEND script_args "--enable_key \"${CONFIG_CHIP_DEVICE_ENABLE_KEY}\"\n") diff --git a/data_model/clusters/Binding-Cluster.xml b/data_model/clusters/Binding-Cluster.xml index eca291a7d895ff..937b9164e2a4f8 100644 --- a/data_model/clusters/Binding-Cluster.xml +++ b/data_model/clusters/Binding-Cluster.xml @@ -78,6 +78,7 @@ Davis, CA 95616, USA + diff --git a/data_model/clusters/ColorControl.xml b/data_model/clusters/ColorControl.xml index b913009f852761..14d471b78a3043 100644 --- a/data_model/clusters/ColorControl.xml +++ b/data_model/clusters/ColorControl.xml @@ -107,6 +107,7 @@ Davis, CA 95616, USA + diff --git a/data_model/clusters/DoorLock.xml b/data_model/clusters/DoorLock.xml index 6284b973eb63e1..16d26420fe2009 100644 --- a/data_model/clusters/DoorLock.xml +++ b/data_model/clusters/DoorLock.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + @@ -66,7 +66,6 @@ Davis, CA 95616, USA - @@ -104,19 +103,14 @@ Davis, CA 95616, USA - - - - - - - - - - - - - + + + + + + + + @@ -130,14 +124,6 @@ Davis, CA 95616, USA - - - - - - - - @@ -220,23 +206,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - @@ -370,21 +339,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - @@ -533,11 +487,6 @@ Davis, CA 95616, USA - - - - - @@ -1109,81 +1058,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2059,13 +1933,6 @@ Davis, CA 95616, USA - - - - - - - @@ -2092,36 +1959,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data_model/clusters/GeneralCommissioningCluster.xml b/data_model/clusters/GeneralCommissioningCluster.xml index 635a6635990654..e7877635bbac68 100644 --- a/data_model/clusters/GeneralCommissioningCluster.xml +++ b/data_model/clusters/GeneralCommissioningCluster.xml @@ -128,5 +128,62 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ICDManagement.xml b/data_model/clusters/ICDManagement.xml index 2a770a4f97f2b4..534b8340143083 100644 --- a/data_model/clusters/ICDManagement.xml +++ b/data_model/clusters/ICDManagement.xml @@ -69,6 +69,7 @@ Davis, CA 95616, USA + @@ -77,6 +78,7 @@ Davis, CA 95616, USA + @@ -84,7 +86,10 @@ Davis, CA 95616, USA - + + + + @@ -156,9 +161,12 @@ Davis, CA 95616, USA - - - + + + + + + @@ -168,9 +176,12 @@ Davis, CA 95616, USA - - - + + + + + + diff --git a/data_model/clusters/LevelControl.xml b/data_model/clusters/LevelControl.xml index 6b2b3cace52ec3..13522bf0698b9e 100644 --- a/data_model/clusters/LevelControl.xml +++ b/data_model/clusters/LevelControl.xml @@ -126,6 +126,7 @@ Davis, CA 95616, USA + diff --git a/data_model/clusters/MediaPlayback.xml b/data_model/clusters/MediaPlayback.xml index 0a457a446208dd..e9194b6854c569 100644 --- a/data_model/clusters/MediaPlayback.xml +++ b/data_model/clusters/MediaPlayback.xml @@ -202,6 +202,7 @@ Davis, CA 95616, USA + @@ -389,12 +390,13 @@ Davis, CA 95616, USA - + - - + + + @@ -404,7 +406,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Messages.xml b/data_model/clusters/Messages.xml index cea28ac15f54c9..61f21bef9c95f3 100644 --- a/data_model/clusters/Messages.xml +++ b/data_model/clusters/Messages.xml @@ -186,15 +186,11 @@ Davis, CA 95616, USA - - - + - - - + @@ -216,7 +212,7 @@ Davis, CA 95616, USA - + @@ -268,18 +264,20 @@ Davis, CA 95616, USA - + + + @@ -288,6 +286,7 @@ Davis, CA 95616, USA + diff --git a/data_model/clusters/NetworkCommissioningCluster.xml b/data_model/clusters/NetworkCommissioningCluster.xml index 86c7a01ce9f951..745a659f1b900b 100644 --- a/data_model/clusters/NetworkCommissioningCluster.xml +++ b/data_model/clusters/NetworkCommissioningCluster.xml @@ -59,8 +59,7 @@ Davis, CA 95616, USA - + @@ -76,11 +75,6 @@ Added support for Wi-Fi Per-Device Credentials (PDC feature; QueryIdentity and Q - - - - - @@ -177,9 +171,6 @@ Added support for Wi-Fi Per-Device Credentials (PDC feature; QueryIdentity and Q - - - @@ -189,22 +180,6 @@ Added support for Wi-Fi Per-Device Credentials (PDC feature; QueryIdentity and Q - - - - - - - - - - - - - - - - @@ -431,18 +406,6 @@ Added support for Wi-Fi Per-Device Credentials (PDC feature; QueryIdentity and Q - - - - - - - - - - - - @@ -492,18 +455,6 @@ Added support for Wi-Fi Per-Device Credentials (PDC feature; QueryIdentity and Q - - - - - - - - - - - - @@ -559,32 +510,5 @@ Added support for Wi-Fi Per-Device Credentials (PDC feature; QueryIdentity and Q - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/data_model/clusters/NetworkIdentityManagement.xml b/data_model/clusters/NetworkIdentityManagement.xml index 8769b68583e4b9..20e264277a4330 100644 --- a/data_model/clusters/NetworkIdentityManagement.xml +++ b/data_model/clusters/NetworkIdentityManagement.xml @@ -57,14 +57,14 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - + - + diff --git a/data_model/clusters/OperationalState.xml b/data_model/clusters/OperationalState.xml index 0062b38b4b3981..37dc6b6e2f8cf4 100644 --- a/data_model/clusters/OperationalState.xml +++ b/data_model/clusters/OperationalState.xml @@ -65,6 +65,17 @@ Davis, CA 95616, USA + + + + + + + + + + + @@ -77,18 +88,7 @@ Davis, CA 95616, USA - - - - - - - - - - - - + diff --git a/data_model/clusters/PowerSourceCluster.xml b/data_model/clusters/PowerSourceCluster.xml index ffd628de6686b8..28a9154116ed7c 100644 --- a/data_model/clusters/PowerSourceCluster.xml +++ b/data_model/clusters/PowerSourceCluster.xml @@ -55,11 +55,10 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - @@ -82,16 +81,6 @@ Davis, CA 95616, USA - - - - - - - - - - @@ -229,24 +218,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - @@ -259,23 +230,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - @@ -289,12 +243,6 @@ Davis, CA 95616, USA - - - - - - @@ -541,17 +489,6 @@ Davis, CA 95616, USA - - - - - - - - - - - @@ -838,125 +775,7 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1006,77 +825,5 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/Thermostat.xml b/data_model/clusters/Thermostat.xml index 756e27940c2cba..71a0c48c6a8eb8 100644 --- a/data_model/clusters/Thermostat.xml +++ b/data_model/clusters/Thermostat.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + @@ -63,7 +63,6 @@ Davis, CA 95616, USA - @@ -106,17 +105,6 @@ Davis, CA 95616, USA - - - - - - - - - - - @@ -227,36 +215,13 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - + @@ -410,14 +375,6 @@ Davis, CA 95616, USA - - - - - - - - @@ -497,149 +454,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1012,107 +826,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1223,67 +936,5 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/clusters/TimeSync.xml b/data_model/clusters/TimeSync.xml index 99ec173bc7e6e1..c6c57ece628bbd 100644 --- a/data_model/clusters/TimeSync.xml +++ b/data_model/clusters/TimeSync.xml @@ -100,6 +100,59 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -157,6 +210,163 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/WaterHeaterManagement.xml b/data_model/clusters/WaterHeaterManagement.xml index 4b6368555bf1d6..cc641c8269fb3c 100644 --- a/data_model/clusters/WaterHeaterManagement.xml +++ b/data_model/clusters/WaterHeaterManagement.xml @@ -134,7 +134,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/WiFiNetworkManagement.xml b/data_model/clusters/WiFiNetworkManagement.xml index fbb7a84a4e17b2..1a3fceec2747d3 100644 --- a/data_model/clusters/WiFiNetworkManagement.xml +++ b/data_model/clusters/WiFiNetworkManagement.xml @@ -62,9 +62,9 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 1dd336ef3656a3..db85cc296b8922 100644 --- a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml +++ b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -150,6 +150,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/device_types/BaseDeviceType.xml b/data_model/device_types/BaseDeviceType.xml index 22cec956aa6061..0df3ba00d26e2b 100644 --- a/data_model/device_types/BaseDeviceType.xml +++ b/data_model/device_types/BaseDeviceType.xml @@ -62,4 +62,30 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/device_types/BasicVideoPlayer.xml b/data_model/device_types/BasicVideoPlayer.xml index 75d54e18d1c33f..2b9b52c3b43ee6 100644 --- a/data_model/device_types/BasicVideoPlayer.xml +++ b/data_model/device_types/BasicVideoPlayer.xml @@ -55,10 +55,11 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + @@ -68,6 +69,9 @@ Davis, CA 95616, USA + + + @@ -94,5 +98,11 @@ Davis, CA 95616, USA + + + + + + \ No newline at end of file diff --git a/data_model/device_types/CastingVideoClient.xml b/data_model/device_types/CastingVideoClient.xml index 8089f57507dd18..d79506b9cf66a0 100644 --- a/data_model/device_types/CastingVideoClient.xml +++ b/data_model/device_types/CastingVideoClient.xml @@ -55,10 +55,11 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + @@ -69,6 +70,9 @@ Davis, CA 95616, USA + + + @@ -105,5 +109,14 @@ Davis, CA 95616, USA + + + + + + + + + \ No newline at end of file diff --git a/data_model/device_types/CastingVideoPlayer.xml b/data_model/device_types/CastingVideoPlayer.xml index 9997b276a6af5e..336416508660a8 100644 --- a/data_model/device_types/CastingVideoPlayer.xml +++ b/data_model/device_types/CastingVideoPlayer.xml @@ -55,10 +55,11 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + @@ -71,6 +72,9 @@ launch Content Apps and represent these apps as separate endpoints."/> + + + @@ -113,5 +117,11 @@ launch Content Apps and represent these apps as separate endpoints."/> + + + + + + \ No newline at end of file diff --git a/data_model/device_types/ColorDimmerSwitch.xml b/data_model/device_types/ColorDimmerSwitch.xml index 0adcfcedcdc92a..0da15b82a2cd08 100644 --- a/data_model/device_types/ColorDimmerSwitch.xml +++ b/data_model/device_types/ColorDimmerSwitch.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/ColorTemperatureLight.xml b/data_model/device_types/ColorTemperatureLight.xml index 5d6ac140803e23..5a54a36a7a0fbf 100644 --- a/data_model/device_types/ColorTemperatureLight.xml +++ b/data_model/device_types/ColorTemperatureLight.xml @@ -55,12 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/ContentApp.xml b/data_model/device_types/ContentApp.xml index 0db03141e7f9a1..84bf58698f426d 100644 --- a/data_model/device_types/ContentApp.xml +++ b/data_model/device_types/ContentApp.xml @@ -55,13 +55,19 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + + + + + + @@ -91,5 +97,10 @@ Davis, CA 95616, USA + + + + + \ No newline at end of file diff --git a/data_model/device_types/ControlBridge.xml b/data_model/device_types/ControlBridge.xml index f97439b77f8c3b..f427becc14f791 100644 --- a/data_model/device_types/ControlBridge.xml +++ b/data_model/device_types/ControlBridge.xml @@ -55,12 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/CookSurface.xml b/data_model/device_types/CookSurface.xml index a9548d3ac6e3dd..b18897b3f0f9ff 100644 --- a/data_model/device_types/CookSurface.xml +++ b/data_model/device_types/CookSurface.xml @@ -62,6 +62,14 @@ Davis, CA 95616, USA + + + + + + + + diff --git a/data_model/device_types/DeviceEnergyManagement.xml b/data_model/device_types/DeviceEnergyManagement.xml index 9d993a9454ea15..cf148dabc13679 100644 --- a/data_model/device_types/DeviceEnergyManagement.xml +++ b/data_model/device_types/DeviceEnergyManagement.xml @@ -62,10 +62,16 @@ Davis, CA 95616, USA - + + + + - + + + + \ No newline at end of file diff --git a/data_model/device_types/DimmableLight.xml b/data_model/device_types/DimmableLight.xml index 42c7d20fb4caad..ce0c280de6f0a6 100644 --- a/data_model/device_types/DimmableLight.xml +++ b/data_model/device_types/DimmableLight.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/DimmablePlug-InUnit.xml b/data_model/device_types/DimmablePlug-InUnit.xml index a41db3ad0ae255..98895640fe1bc5 100644 --- a/data_model/device_types/DimmablePlug-InUnit.xml +++ b/data_model/device_types/DimmablePlug-InUnit.xml @@ -55,12 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/DimmerSwitch.xml b/data_model/device_types/DimmerSwitch.xml index 8be246f3a16056..137adfd9117cf7 100644 --- a/data_model/device_types/DimmerSwitch.xml +++ b/data_model/device_types/DimmerSwitch.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/DoorLock.xml b/data_model/device_types/DoorLock.xml index b7a0beaa3946e6..9b6c7fd145621d 100644 --- a/data_model/device_types/DoorLock.xml +++ b/data_model/device_types/DoorLock.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + @@ -70,41 +71,12 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - @@ -118,10 +90,11 @@ Davis, CA 95616, USA - - - - + + + + + @@ -130,54 +103,7 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/DoorLockController.xml b/data_model/device_types/DoorLockController.xml index 0e4529c8b5e381..0279f0100a5fc0 100644 --- a/data_model/device_types/DoorLockController.xml +++ b/data_model/device_types/DoorLockController.xml @@ -55,26 +55,28 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + + - + + + + - - - diff --git a/data_model/device_types/ExtendedColorLight.xml b/data_model/device_types/ExtendedColorLight.xml index 73490485fa27fa..97cb3eaf66377c 100644 --- a/data_model/device_types/ExtendedColorLight.xml +++ b/data_model/device_types/ExtendedColorLight.xml @@ -55,12 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/GenericSwitch.xml b/data_model/device_types/GenericSwitch.xml index 24645b511ea5e7..e381914be42921 100644 --- a/data_model/device_types/GenericSwitch.xml +++ b/data_model/device_types/GenericSwitch.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/NetworkInfraManager.xml b/data_model/device_types/NetworkInfraManager.xml index cc7e22295f40be..67c3ee49f75f92 100644 --- a/data_model/device_types/NetworkInfraManager.xml +++ b/data_model/device_types/NetworkInfraManager.xml @@ -55,17 +55,17 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - + diff --git a/data_model/device_types/OnOffLight.xml b/data_model/device_types/OnOffLight.xml index 9762c718dcc05b..59e8739cab0275 100644 --- a/data_model/device_types/OnOffLight.xml +++ b/data_model/device_types/OnOffLight.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/OnOffLightSwitch.xml b/data_model/device_types/OnOffLightSwitch.xml index eb2c3ff938060a..9b9d72ba4f0964 100644 --- a/data_model/device_types/OnOffLightSwitch.xml +++ b/data_model/device_types/OnOffLightSwitch.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/OnOffPlug-inUnit.xml b/data_model/device_types/OnOffPlug-inUnit.xml index 41d0a1398ad6f3..4b4f49725cf9fa 100644 --- a/data_model/device_types/OnOffPlug-inUnit.xml +++ b/data_model/device_types/OnOffPlug-inUnit.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/OnOffSensor.xml b/data_model/device_types/OnOffSensor.xml index 904b5f6da74c7c..e1bd3c3806c8a4 100644 --- a/data_model/device_types/OnOffSensor.xml +++ b/data_model/device_types/OnOffSensor.xml @@ -55,12 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/Pump.xml b/data_model/device_types/Pump.xml index 4662ce0945b06d..9ab8700abb10f5 100644 --- a/data_model/device_types/Pump.xml +++ b/data_model/device_types/Pump.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/PumpController.xml b/data_model/device_types/PumpController.xml index 274eefb764de41..ca1486e4ea657e 100644 --- a/data_model/device_types/PumpController.xml +++ b/data_model/device_types/PumpController.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/RoomAirConditioner.xml b/data_model/device_types/RoomAirConditioner.xml index 888ec8a448a501..e8c557a21800b9 100644 --- a/data_model/device_types/RoomAirConditioner.xml +++ b/data_model/device_types/RoomAirConditioner.xml @@ -55,9 +55,10 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA --> - + + @@ -85,6 +86,14 @@ Davis, CA 95616, USA + + + + + + + + diff --git a/data_model/device_types/RootNodeDeviceType.xml b/data_model/device_types/RootNodeDeviceType.xml index 1696791ab8a2b3..57b204036092c7 100644 --- a/data_model/device_types/RootNodeDeviceType.xml +++ b/data_model/device_types/RootNodeDeviceType.xml @@ -153,5 +153,27 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/device_types/Thermostat.xml b/data_model/device_types/Thermostat.xml index cbdedb7c039ed5..9f5c8e7de5b11c 100644 --- a/data_model/device_types/Thermostat.xml +++ b/data_model/device_types/Thermostat.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + @@ -97,15 +98,18 @@ Davis, CA 95616, USA - - - - + + + + + + + diff --git a/data_model/device_types/VideoRemoteControl.xml b/data_model/device_types/VideoRemoteControl.xml index eafa4cd63780b2..33bab95b9207c1 100644 --- a/data_model/device_types/VideoRemoteControl.xml +++ b/data_model/device_types/VideoRemoteControl.xml @@ -55,10 +55,11 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + @@ -102,5 +103,11 @@ Davis, CA 95616, USA + + + + + + \ No newline at end of file diff --git a/data_model/device_types/WindowCovering.xml b/data_model/device_types/WindowCovering.xml index 1a56bbd753f63a..b9a33b47ac4d9b 100644 --- a/data_model/device_types/WindowCovering.xml +++ b/data_model/device_types/WindowCovering.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/device_types/WindowCoveringController.xml b/data_model/device_types/WindowCoveringController.xml index 5bae9d81103247..76f0cf1b1e2147 100644 --- a/data_model/device_types/WindowCoveringController.xml +++ b/data_model/device_types/WindowCoveringController.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + diff --git a/data_model/spec_sha b/data_model/spec_sha index 97f7f06deb9fe9..e9d780b94f334a 100644 --- a/data_model/spec_sha +++ b/data_model/spec_sha @@ -1 +1 @@ -b0310bae0264a29665f23a8f3d4dc4f742be6075 +c1a1e1e6bcf201334eb0b5216a464b39d9827ec4 diff --git a/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md b/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md index 9e34e961ae6d87..f4c1c5eb890e71 100644 --- a/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md +++ b/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md @@ -16,14 +16,17 @@ types in the SDK. - XML - Describes the structures, enums, attributes, commands, events etc. - Direct translation of the spec into code - - src/app/zap-templates/zcl/data-model/chip/ + - [src/app/zap-templates/zcl/data-model/chip/](https://github.com/project-chip/connectedhomeip/tree/master/src/app/zap-templates/zcl/data-model/chip) - Cluster Implementation - Client side - codegen, you write the glue - Server side - cpp implementation through Ember and / or - AttributeAccessInterface & CommandHandlerInterface + [AttributeAccessInterface](https://github.com/project-chip/connectedhomeip/blob/master/src/app/AttributeAccessInterface.h) + and + [CommandHandlerInterface](https://github.com/project-chip/connectedhomeip/blob/master/src/app/CommandHandlerInterface.h) - src/app/clusters/ - - build file: src/app/chip_data_model.gni + - build file: + [src/app/chip_data_model.gni](https://github.com/project-chip/connectedhomeip/blob/master/src/app/chip_data_model.gni) - build file uses data from the codegen to auto-populate the cluster list. - Follow examples in there to get your code building into the image @@ -31,7 +34,7 @@ types in the SDK. - Device Type Definitions - XML defines conformance - - src/app/zap-templates/zcl/data-model/chip/matter-devices.xml + - [src/app/zap-templates/zcl/data-model/chip/matter-devices.xml](https://github.com/project-chip/connectedhomeip/blob/master/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml) The following wiki page has a detailed description of how and where to add cluster and device type definitions so they are picked up properly by ZAP/ember @@ -208,7 +211,7 @@ be used across examples ##### Command Handler Code -- CommandHandlerInterface +- [CommandHandlerInterface](https://github.com/project-chip/connectedhomeip/blob/master/src/app/CommandHandlerInterface.h) - Can use HandleCommand function for convenience (sets handled) - If not, need to set whether the command was handled - if no, falls through to ember by default @@ -238,7 +241,9 @@ pure CommandHandlerInterface implementations. - **MatterReportingAttributeChangeCallback** - **Events** - No direct ember support - - Call LogEvent function in EventLogging.h + - Call LogEvent function in EventLogging.h. Caller has to either lock the + Matter stack lock or queue the event to the Matter event queue when + using LogEvent. #### A note on Dynamic Endpoints diff --git a/docs/cluster_and_device_type_dev/img/cluster_commands.png b/docs/cluster_and_device_type_dev/img/cluster_commands.png index 959774e071b717..c04dbe7279b28b 100644 Binary files a/docs/cluster_and_device_type_dev/img/cluster_commands.png and b/docs/cluster_and_device_type_dev/img/cluster_commands.png differ diff --git a/docs/guides/nrfconnect_factory_data_configuration.md b/docs/guides/nrfconnect_factory_data_configuration.md index d30a12f1e82025..e4c3be4899df4e 100644 --- a/docs/guides/nrfconnect_factory_data_configuration.md +++ b/docs/guides/nrfconnect_factory_data_configuration.md @@ -51,6 +51,7 @@ data secure by applying hardware write protection. - [Building an example with factory data](#building-an-example-with-factory-data) - [Providing factory data parameters as a build argument list](#providing-factory-data-parameters-as-a-build-argument-list) - [Setting factory data parameters using interactive Kconfig interfaces](#setting-factory-data-parameters-using-interactive-kconfig-interfaces) + - [Default Kconfig values and developing aspects](#default-kconfig-values-and-developing-aspects) - [Programming factory data](#programming-factory-data) - [Using own factory data implementation](#using-own-factory-data-implementation) @@ -272,6 +273,7 @@ To use this script, complete the following steps: ``` --chip_cert_path + --gen_certs ``` > **Note:** To generate new certificates, you need the `chip-cert` @@ -293,7 +295,7 @@ To use this script, complete the following steps: --rd_uid ``` - - Generate a new ID and provide it (): + - (optional) Generate a new ID and provide it: ``` --generate_rd_uid @@ -328,6 +330,17 @@ To use this script, complete the following steps: --product_color ``` + j. (optional) Generate Certification Declaration for testing purposes + + ``` + --chip_cert_path + --gen_cd + ``` + + > **Note:** To generate new Certification Declaration, you need the + > `chip-cert` executable. See the note at the end of this section to learn + > how to get it. + 4. Run the script using the prepared list of arguments: ``` @@ -794,6 +807,55 @@ snippet: > interfaces, read the > [Kconfig documentation](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/build/kconfig/menuconfig.html). +### Default Kconfig values and developing aspects + +Each factory data parameter has its default value reflected in the Kconfig. The +list below shows some Kconfig settings that are configured in the nRF Connect +build system and have an impact on the application. You can modify them to +achieve the desired behavior of your application. + +- The device uses the test certificates located in the + `credentials/development/attestation/` directory, which are generated using + all default values. If you want to change the default `vendor_id`, + `product_id`, `vendor_name`, or `device_name` and generate new test + certificates, add the `CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED=y` + Kconfig option. Remember to build the `chip-cert` application and add it to + the system PATH. + + For developing a production-ready product, you need to write the + certificates obtained during the certification process. To do this, add the + `CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER=y` Kconfig option and set the + appropriate paths for the following Kconfig options: + + - `CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT` + - `CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY` + - `CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT` + +- By default, the SPAKE2+ verifier is generated during each example's build. + This means that this value will change automatically if you change any of + the following parameters: + + - `CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE` + - `CONFIG_CHIP_DEVICE_SPAKE2_SALT` + - `CONFIG_CHIP_DEVICE_SPAKE2_IT` + + You can disable the generation of the SPAKE2+ verifier by setting the + `CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER=n` Kconfig option. Then, + you will need to provide the externally-generated SPAKE2+ verifier using the + `CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER` Kconfig value. + +- Generating the rotating device ID unique ID is disabled by default, but you + can enable it by setting the `CONFIG_CHIP_ROTATING_DEVICE_ID=y` and + `CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID=y` Kconfig values. + Moreover, if you set the `CONFIG_CHIP_ROTATING_DEVICE_ID` Kconfig option to + `y` and disable the `CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID` + Kconfig option, you will need to provide it manually using the + `CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID` Kconfig value. + +- You can generate the test Certification Declaration by using the + `CONFIG_CHIP_FACTORY_DATA_GENERATE_CD=y` Kconfig option. Remember to build + the `chip-cert` application and add it to the system PATH. +
## Programming factory data diff --git a/docs/testing/ChipDeviceCtrlAPI.md b/docs/testing/ChipDeviceCtrlAPI.md new file mode 100644 index 00000000000000..944c787d647207 --- /dev/null +++ b/docs/testing/ChipDeviceCtrlAPI.md @@ -0,0 +1,1079 @@ +# Table of Contents + +- [Table of Contents](#table-of-contents) +- [chip.ChipDeviceCtrl](#chipchipdevicectrl) + - [CommissionableNode](#commissionablenode) + - [Commission](#commission) + - [DeviceProxyWrapper](#deviceproxywrapper) + - [ChipDeviceControllerBase](#chipdevicecontrollerbase) + - [Shutdown](#shutdown) + - [ShutdownAll](#shutdownall) + - [ExpireSessions](#expiresessions) + - [DiscoverCommissionableNodes](#discovercommissionablenodes) + - [DiscoverCommissionableNodesLongDiscriminator](#discovercommissionablenodeslongdiscriminator) + - [DiscoverCommissionableNodesShortDiscriminator](#discovercommissionablenodesshortdiscriminator) + - [DiscoverCommissionableNodesVendor](#discovercommissionablenodesvendor) + - [DiscoverCommissionableNodesDeviceType](#discovercommissionablenodesdevicetype) + - [DiscoverCommissionableNodesCommissioningEnabled](#discovercommissionablenodescommissioningenabled) + - [PrintDiscoveredDevices](#printdiscovereddevices) + - [DiscoverAllCommissioning](#discoverallcommissioning) + - [OpenCommissioningWindow](#opencommissioningwindow) + - [GetFabricIdInternal](#getfabricidinternal) + - [GetNodeIdInternal](#getnodeidinternal) + - [GetConnectedDeviceSync](#getconnecteddevicesync) + - [ComputeRoundTripTimeout](#computeroundtriptimeout) + - [GetRemoteSessionParameters](#getremotesessionparameters) + - [TestOnlySendBatchCommands](#testonlysendbatchcommands) + - [TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke](#testonlysendcommandtimedrequestflagwithnotimedinvoke) + - [SendCommand](#sendcommand) + - [SendBatchCommands](#sendbatchcommands) + - [SendGroupCommand](#sendgroupcommand) + - [WriteAttribute](#writeattribute) + - [WriteGroupAttribute](#writegroupattribute) + - [Read](#read) + - [ReadAttribute](#readattribute) + - [ReadEvent](#readevent) + - [ZCLSend](#zclsend) + - [ZCLReadAttribute](#zclreadattribute) + - [ZCLWriteAttribute](#zclwriteattribute) + - [ZCLSubscribeAttribute](#zclsubscribeattribute) + - [InitGroupTestingData](#initgrouptestingdata) + - [ChipDeviceController](#chipdevicecontroller) + - [Commission](#commission-1) + - [CommissionThread](#commissionthread) + - [CommissionWiFi](#commissionwifi) + - [SetWiFiCredentials](#setwificredentials) + - [SetThreadOperationalDataset](#setthreadoperationaldataset) + - [ResetCommissioningParameters](#resetcommissioningparameters) + - [SetTimeZone](#settimezone) + - [SetDSTOffset](#setdstoffset) + - [SetDefaultNTP](#setdefaultntp) + - [SetTrustedTimeSource](#settrustedtimesource) + - [SetCheckMatchingFabric](#setcheckmatchingfabric) + - [GetFabricCheckResult](#getfabriccheckresult) + - [CommissionOnNetwork](#commissiononnetwork) + - [CommissionWithCode](#commissionwithcode) + - [CommissionIP](#commissionip) + - [IssueNOCChain](#issuenocchain) + - [BareChipDeviceController](#barechipdevicecontroller) + - [\_\_init\_\_](#__init__) + + + +# chip.ChipDeviceCtrl + +Chip Device Controller interface + + + +## CommissionableNode + +```python +class CommissionableNode(discovery.CommissionableNode) +``` + + + +#### Commission + +```python +def Commission(nodeId: int, setupPinCode: int) -> PyChipError +``` + +Commission the device using the device controller discovered this device. + +nodeId: The nodeId commissioned to the device setupPinCode: The setup pin code +of the device + + + +## DeviceProxyWrapper + +```python +class DeviceProxyWrapper() +``` + +Encapsulates a pointer to OperationalDeviceProxy on the c++ side that needs to +be freed when DeviceProxyWrapper goes out of scope. There is a potential issue +where if this is copied around that a double free will occur, but how this is +used today that is not an issue that needs to be accounted for and it will +become very apparent if that happens. + + + +## ChipDeviceControllerBase + +```python +class ChipDeviceControllerBase() +``` + + + +#### Shutdown + +```python +def Shutdown() +``` + +Shuts down this controller and reclaims any used resources, including the bound +C++ constructor instance in the SDK. + + + +#### ShutdownAll + +```python +def ShutdownAll() +``` + +Shut down all active controllers and reclaim any used resources. + + + +#### ExpireSessions + +```python +def ExpireSessions(nodeid) +``` + +Close all sessions with `nodeid` (if any existed) so that sessions get +re-established. + +This is needed to properly handle operations that invalidate a node's state, +such as UpdateNOC. + +WARNING: ONLY CALL THIS IF YOU UNDERSTAND THE SIDE-EFFECTS + + + +#### DiscoverCommissionableNodes + +```python +def DiscoverCommissionableNodes( + filterType: discovery.FilterType = discovery.FilterType.NONE, + filter: typing.Any = None, + stopOnFirst: bool = False, + timeoutSecond: int = 5 +) -> typing.Union[None, CommissionableNode, typing.List[CommissionableNode]] +``` + +Discover commissionable nodes via DNS-SD with specified filters. Supported +filters are: + + discovery.FilterType.NONE + discovery.FilterType.SHORT_DISCRIMINATOR + discovery.FilterType.LONG_DISCRIMINATOR + discovery.FilterType.VENDOR_ID + discovery.FilterType.DEVICE_TYPE + discovery.FilterType.COMMISSIONING_MODE + discovery.FilterType.INSTANCE_NAME + discovery.FilterType.COMMISSIONER + discovery.FilterType.COMPRESSED_FABRIC_ID + +This function will always return a list of CommissionableDevice. When +stopOnFirst is set, this function will return when at least one device is +discovered or on timeout. + + + +#### DiscoverCommissionableNodesLongDiscriminator + +```python +def DiscoverCommissionableNodesLongDiscriminator(long_discriminator) +``` + +Deprecated, use DiscoverCommissionableNodes + + + +#### DiscoverCommissionableNodesShortDiscriminator + +```python +def DiscoverCommissionableNodesShortDiscriminator(short_discriminator) +``` + +Deprecated, use DiscoverCommissionableNodes + + + +#### DiscoverCommissionableNodesVendor + +```python +def DiscoverCommissionableNodesVendor(vendor) +``` + +Deprecated, use DiscoverCommissionableNodes + + + +#### DiscoverCommissionableNodesDeviceType + +```python +def DiscoverCommissionableNodesDeviceType(device_type) +``` + +Deprecated, use DiscoverCommissionableNodes + + + +#### DiscoverCommissionableNodesCommissioningEnabled + +```python +def DiscoverCommissionableNodesCommissioningEnabled() +``` + +Deprecated, use DiscoverCommissionableNodes + + + +#### PrintDiscoveredDevices + +```python +def PrintDiscoveredDevices() +``` + +Deprecated, use GetCommissionableNodes + + + +#### DiscoverAllCommissioning + +```python +def DiscoverAllCommissioning() +``` + +Deprecated, use DiscoverCommissionableNodes + + + +#### OpenCommissioningWindow + +```python +def OpenCommissioningWindow( + nodeid: int, timeout: int, iteration: int, discriminator: int, + option: CommissioningWindowPasscode) -> CommissioningParameters +``` + +Opens a commissioning window on the device with the given nodeid. nodeid: Node +id of the device timeout: Command timeout iteration: The PAKE iteration count +associated with the PAKE Passcode ID and ephemeral PAKE passcode verifier to be +used for this commissioning. Valid range: 1000 - 100000 Ignored if option == 0 +discriminator: The long discriminator for the DNS-SD advertisement. Valid range: +0-4095 Ignored if option == 0 option: 0 = kOriginalSetupCode 1 = +kTokenWithRandomPIN + +Returns CommissioningParameters + + + +#### GetFabricIdInternal + +```python +def GetFabricIdInternal() +``` + +Get the fabric ID from the object. Only used to validate cached value from +property. + + + +#### GetNodeIdInternal + +```python +def GetNodeIdInternal() -> int +``` + +Get the node ID from the object. Only used to validate cached value from +property. + + + +#### GetConnectedDeviceSync + +```python +def GetConnectedDeviceSync(nodeid, allowPASE=True, timeoutMs: int = None) +``` + +Returns DeviceProxyWrapper upon success. + + + +#### ComputeRoundTripTimeout + +```python +def ComputeRoundTripTimeout(nodeid, upperLayerProcessingTimeoutMs: int = 0) +``` + +Returns a computed timeout value based on the round-trip time it takes for the +peer at the other end of the session to receive a message, process it and send +it back. This is computed based on the session type, the type of transport, +sleepy characteristics of the target and a caller-provided value for the time it +takes to process a message at the upper layer on the target For group sessions. + +This will result in a session being established if one wasn't already. + + + +#### GetRemoteSessionParameters + +```python +def GetRemoteSessionParameters(nodeid) -> typing.Optional[SessionParameters] +``` + +Returns the SessionParameters of reported by the remote node associated with +`nodeid`. If there is some error in getting SessionParameters None is returned. + +This will result in a session being established if one wasn't already +established. + + + +#### TestOnlySendBatchCommands + +```python +async def TestOnlySendBatchCommands( + nodeid: int, + commands: typing.List[ClusterCommand.InvokeRequestInfo], + timedRequestTimeoutMs: typing.Optional[int] = None, + interactionTimeoutMs: typing.Optional[int] = None, + busyWaitMs: typing.Optional[int] = None, + suppressResponse: typing.Optional[bool] = None, + remoteMaxPathsPerInvoke: typing.Optional[int] = None, + suppressTimedRequestMessage: bool = False, + commandRefsOverride: typing.Optional[typing.List[int]] = None) +``` + +Please see SendBatchCommands for description. TestOnly overridable arguments: +remoteMaxPathsPerInvoke: Overrides the number of batch commands we think can be +sent to remote node. suppressTimedRequestMessage: When set to true, we suppress +sending Timed Request Message. commandRefsOverride: List of commandRefs to use +for each command with the same index in `commands`. + +**Returns**: + +- TestOnlyBatchCommandResponse + + + +#### TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke + +```python +async def TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke( + nodeid: int, + endpoint: int, + payload: ClusterObjects.ClusterCommand, + responseType=None) +``` + +Please see SendCommand for description. + + + +#### SendCommand + +```python +async def SendCommand(nodeid: int, + endpoint: int, + payload: ClusterObjects.ClusterCommand, + responseType=None, + timedRequestTimeoutMs: typing.Union[None, int] = None, + interactionTimeoutMs: typing.Union[None, int] = None, + busyWaitMs: typing.Union[None, int] = None, + suppressResponse: typing.Union[None, bool] = None) +``` + +Send a cluster-object encapsulated command to a node and get returned a future +that can be awaited upon to receive the response. If a valid responseType is +passed in, that will be used to de-serialize the object. If not, the type will +be automatically deduced from the metadata received over the wire. + +timedWriteTimeoutMs: Timeout for a timed invoke request. Omit or set to 'None' +to indicate a non-timed request. interactionTimeoutMs: Overall timeout for the +interaction. Omit or set to 'None' to have the SDK automatically compute the +right timeout value based on transport characteristics as well as the +responsiveness of the target. + +**Returns**: + +- command response. The type of the response is defined by the command. + +**Raises**: + +- InteractionModelError on error + + + +#### SendBatchCommands + +```python +async def SendBatchCommands( + nodeid: int, + commands: typing.List[ClusterCommand.InvokeRequestInfo], + timedRequestTimeoutMs: typing.Optional[int] = None, + interactionTimeoutMs: typing.Optional[int] = None, + busyWaitMs: typing.Optional[int] = None, + suppressResponse: typing.Optional[bool] = None) +``` + +Send a batch of cluster-object encapsulated commands to a node and get returned +a future that can be awaited upon to receive the responses. If a valid +responseType is passed in, that will be used to de-serialize the object. If not, +the type will be automatically deduced from the metadata received over the wire. + +nodeId: Target's Node ID commands: A list of InvokeRequestInfo containing the +commands to invoke. timedWriteTimeoutMs: Timeout for a timed invoke request. +Omit or set to 'None' to indicate a non-timed request. interactionTimeoutMs: +Overall timeout for the interaction. Omit or set to 'None' to have the SDK +automatically compute the right timeout value based on transport characteristics +as well as the responsiveness of the target. busyWaitMs: How long to wait in ms +after sending command to device before performing any other operations. +suppressResponse: Do not send a response to this action + +**Returns**: + +- List of command responses in the same order as what was given in `commands`. + The type of the response is defined by the command. +- A value of `None` indicates success. +- If only a single command fails, for example with `UNSUPPORTED_COMMAND`, the + corresponding index associated with the command will, contain + `interaction_model.Status.UnsupportedCommand`. +- If a command is not responded to by server, command will contain + `interaction_model.Status.NoCommandResponse` + +**Raises**: + +- InteractionModelError if error with sending of InvokeRequestMessage fails as + a whole. + + + +#### SendGroupCommand + +```python +def SendGroupCommand(groupid: int, + payload: ClusterObjects.ClusterCommand, + busyWaitMs: typing.Union[None, int] = None) +``` + +Send a group cluster-object encapsulated command to a group_id and get returned +a future that can be awaited upon to get confirmation command was sent. + +**Returns**: + +- None: responses are not sent to group commands + +**Raises**: + +- InteractionModelError on error + + + +#### WriteAttribute + +```python +async def WriteAttribute(nodeid: int, + attributes: typing.List[typing.Tuple[ + int, ClusterObjects.ClusterAttributeDescriptor]], + timedRequestTimeoutMs: typing.Union[None, int] = None, + interactionTimeoutMs: typing.Union[None, int] = None, + busyWaitMs: typing.Union[None, int] = None) +``` + +Write a list of attributes on a target node. + +nodeId: Target's Node ID timedWriteTimeoutMs: Timeout for a timed write request. +Omit or set to 'None' to indicate a non-timed request. attributes: A list of +tuples of type (endpoint, cluster-object): interactionTimeoutMs: Overall timeout +for the interaction. Omit or set to 'None' to have the SDK automatically compute +the right timeout value based on transport characteristics as well as the +responsiveness of the target. + +E.g (1, Clusters.UnitTesting.Attributes.XYZAttribute('hello')) -- Write 'hello' +to the XYZ attribute on the test cluster to endpoint 1 + +**Returns**: + +- [AttributeStatus] (list - one for each path) + + + +#### WriteGroupAttribute + +```python +def WriteGroupAttribute(groupid: int, + attributes: typing.List[typing.Tuple[ + ClusterObjects.ClusterAttributeDescriptor, int]], + busyWaitMs: typing.Union[None, int] = None) +``` + +Write a list of attributes on a target group. + +groupid: Group ID to send write attribute to. attributes: A list of tuples of +type (cluster-object, data-version). The data-version can be omitted. + +E.g (Clusters.UnitTesting.Attributes.XYZAttribute('hello'), 1) -- Group Write +'hello' with data version 1 + + + +#### Read + +```python +async def Read( + nodeid: int, + attributes: typing. + List[typing.Union[ + None, # Empty tuple, all wildcard + typing.Tuple[int], # Endpoint + # Wildcard endpoint, Cluster id present + typing.Tuple[typing.Type[ClusterObjects.Cluster]], + # Wildcard endpoint, Cluster + Attribute present + typing.Tuple[typing.Type[ClusterObjects.ClusterAttributeDescriptor]], + # Wildcard attribute id + typing.Tuple[int, typing.Type[ClusterObjects.Cluster]], + # Concrete path + typing.Tuple[ + int, + typing.Type[ClusterObjects.ClusterAttributeDescriptor]]]] = None, + dataVersionFilters: typing.List[typing.Tuple[ + int, typing.Type[ClusterObjects.Cluster], int]] = None, + events: typing.List[typing.Union[ + None, # Empty tuple, all wildcard + typing.Tuple[str, int], # all wildcard with urgency set + typing.Tuple[int, int], # Endpoint, + # Wildcard endpoint, Cluster id present + typing.Tuple[typing.Type[ClusterObjects.Cluster], int], + # Wildcard endpoint, Cluster + Event present + typing.Tuple[typing.Type[ClusterObjects.ClusterEvent], int], + # Wildcard event id + typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int], + # Concrete path + typing.Tuple[int, typing.Type[ClusterObjects.ClusterEvent], + int]]] = None, + eventNumberFilter: typing.Optional[int] = None, + returnClusterObject: bool = False, + reportInterval: typing.Tuple[int, int] = None, + fabricFiltered: bool = True, + keepSubscriptions: bool = False, + autoResubscribe: bool = True) +``` + +Read a list of attributes and/or events from a target node + +nodeId: Target's Node ID attributes: A list of tuples of varying types depending +on the type of read being requested: (endpoint, Clusters.ClusterA.AttributeA): +Endpoint = specific, Cluster = specific, Attribute = specific (endpoint, +Clusters.ClusterA): Endpoint = specific, Cluster = specific, Attribute = _ +(Clusters.ClusterA.AttributeA): Endpoint = _, Cluster = specific, Attribute = +specific endpoint: Endpoint = specific, Cluster = _, Attribute = _ +Clusters.ClusterA: Endpoint = _, Cluster = specific, Attribute = _ '_' or (): +Endpoint = _, Cluster = _, Attribute = _ + +The cluster and attributes specified above are to be selected from the generated +cluster objects. + +e.g. ReadAttribute(1, [ 1 ] ) -- case 4 above. ReadAttribute(1, [ +Clusters.BasicInformation ] ) -- case 5 above. ReadAttribute(1, [ (1, +Clusters.BasicInformation.Attributes.Location ] ) -- case 1 above. + +dataVersionFilters: A list of tuples of (endpoint, cluster, data version). + +events: A list of tuples of varying types depending on the type of read being +requested: (endpoint, Clusters.ClusterA.EventA, urgent): Endpoint = specific, +Cluster = specific, Event = specific, Urgent = True/False (endpoint, +Clusters.ClusterA, urgent): Endpoint = specific, Cluster = specific, Event = _, +Urgent = True/False (Clusters.ClusterA.EventA, urgent): Endpoint = _, Cluster = +specific, Event = specific, Urgent = True/False endpoint: Endpoint = specific, +Cluster = _, Event = _, Urgent = True/False Clusters.ClusterA: Endpoint = _, +Cluster = specific, Event = _, Urgent = True/False '_' or (): Endpoint = _, +Cluster = _, Event = _, Urgent = True/False + +eventNumberFilter: Optional minimum event number filter. + +returnClusterObject: This returns the data as consolidated cluster objects, with +all attributes for a cluster inside a single cluster-wide cluster object. + +reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). +Used by establishing subscriptions. When not provided, a read request will be +sent. + +**Returns**: + +- AsyncReadTransaction.ReadResponse. Please see ReadAttribute and ReadEvent + for examples of how to access data. + +**Raises**: + +- InteractionModelError (chip.interaction_model) on error + + + +#### ReadAttribute + +```python +async def ReadAttribute( + nodeid: int, + attributes: typing. + List[typing.Union[ + None, # Empty tuple, all wildcard + typing.Tuple[int], # Endpoint + # Wildcard endpoint, Cluster id present + typing.Tuple[typing.Type[ClusterObjects.Cluster]], + # Wildcard endpoint, Cluster + Attribute present + typing.Tuple[typing.Type[ClusterObjects.ClusterAttributeDescriptor]], + # Wildcard attribute id + typing.Tuple[int, typing.Type[ClusterObjects.Cluster]], + # Concrete path + typing.Tuple[int, + typing.Type[ClusterObjects.ClusterAttributeDescriptor]]]], + dataVersionFilters: typing.List[typing.Tuple[ + int, typing.Type[ClusterObjects.Cluster], int]] = None, + returnClusterObject: bool = False, + reportInterval: typing.Tuple[int, int] = None, + fabricFiltered: bool = True, + keepSubscriptions: bool = False, + autoResubscribe: bool = True) +``` + +Read a list of attributes from a target node, this is a wrapper of +DeviceController.Read() + +nodeId: Target's Node ID attributes: A list of tuples of varying types depending +on the type of read being requested: (endpoint, Clusters.ClusterA.AttributeA): +Endpoint = specific, Cluster = specific, Attribute = specific (endpoint, +Clusters.ClusterA): Endpoint = specific, Cluster = specific, Attribute = _ +(Clusters.ClusterA.AttributeA): Endpoint = _, Cluster = specific, Attribute = +specific endpoint: Endpoint = specific, Cluster = _, Attribute = _ +Clusters.ClusterA: Endpoint = _, Cluster = specific, Attribute = _ '_' or (): +Endpoint = _, Cluster = _, Attribute = _ + +The cluster and attributes specified above are to be selected from the generated +cluster objects. + +e.g. ReadAttribute(1, [ 1 ] ) -- case 4 above. ReadAttribute(1, [ +Clusters.BasicInformation ] ) -- case 5 above. ReadAttribute(1, [ (1, +Clusters.BasicInformation.Attributes.Location ] ) -- case 1 above. + +returnClusterObject: This returns the data as consolidated cluster objects, with +all attributes for a cluster inside a single cluster-wide cluster object. + +reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). +Used by establishing subscriptions. When not provided, a read request will be +sent. + +**Returns**: + +- subscription request: ClusterAttribute.SubscriptionTransaction To get + notified on attribute change use SetAttributeUpdateCallback on the returned + SubscriptionTransaction. This is used to set a callback function, which is a + callable of type Callable[[TypedAttributePath, SubscriptionTransaction], + None] Get the attribute value from the change path using GetAttribute on the + SubscriptionTransaction You can await changes in the main loop using a + trigger mechanism from the callback. ex. queue.SimpleQueue + +- read request: AsyncReadTransaction.ReadResponse.attributes. This is of type + AttributeCache.attributeCache (Attribute.py), which is a dict mapping + endpoints to a list of Cluster (ClusterObjects.py) classes (dict[int, + List[Cluster]]) Access as + returned_object[endpoint_id][][] Ex. To + access the OnTime attribute from the OnOff cluster on endpoint 1 + returned_object[1][clusters.onoff][Clusters.OnOff.Attributes.OnTime] + +**Raises**: + +- InteractionModelError (chip.interaction_model) on error + + + +#### ReadEvent + +```python +async def ReadEvent( + nodeid: int, + events: typing.List[typing.Union[ + None, # Empty tuple, all wildcard + typing.Tuple[str, int], # all wildcard with urgency set + typing.Tuple[int, int], # Endpoint, + # Wildcard endpoint, Cluster id present + typing.Tuple[typing.Type[ClusterObjects.Cluster], int], + # Wildcard endpoint, Cluster + Event present + typing.Tuple[typing.Type[ClusterObjects.ClusterEvent], int], + # Wildcard event id + typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int], + # Concrete path + typing.Tuple[int, typing.Type[ClusterObjects.ClusterEvent], int]]], + eventNumberFilter: typing.Optional[int] = None, + fabricFiltered: bool = True, + reportInterval: typing.Tuple[int, int] = None, + keepSubscriptions: bool = False, + autoResubscribe: bool = True) +``` + +Read a list of events from a target node, this is a wrapper of +DeviceController.Read() + +nodeId: Target's Node ID events: A list of tuples of varying types depending on +the type of read being requested: (endpoint, Clusters.ClusterA.EventA, urgent): +Endpoint = specific, Cluster = specific, Event = specific, Urgent = True/False +(endpoint, Clusters.ClusterA, urgent): Endpoint = specific, Cluster = specific, +Event = _, Urgent = True/False (Clusters.ClusterA.EventA, urgent): Endpoint = _, +Cluster = specific, Event = specific, Urgent = True/False endpoint: Endpoint = +specific, Cluster = _, Event = _, Urgent = True/False Clusters.ClusterA: +Endpoint = _, Cluster = specific, Event = _, Urgent = True/False '_' or (): +Endpoint = _, Cluster = _, Event = _, Urgent = True/False + +The cluster and events specified above are to be selected from the generated +cluster objects. + +e.g. ReadEvent(1, [ 1 ] ) -- case 4 above. ReadEvent(1, [ +Clusters.BasicInformation ] ) -- case 5 above. ReadEvent(1, [ (1, +Clusters.BasicInformation.Events.Location ] ) -- case 1 above. + +eventNumberFilter: Optional minimum event number filter. reportInterval: A tuple +of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing +subscriptions. When not provided, a read request will be sent. + +**Returns**: + +- subscription request: ClusterAttribute.SubscriptionTransaction To get + notified on event subscriptions, use the SetEventUpdateCallback function on + the returned SubscriptionTransaction. This is a callable of type + Callable[[EventReadResult, SubscriptionTransaction], None] You can await + events using a trigger mechanism in the callback. ex. queue.SimpleQueue + +- read request: AsyncReadTransaction.ReadResponse.events. This is a + List[ClusterEvent]. + +**Raises**: + +- InteractionModelError (chip.interaction_model) on error + + + +#### ZCLSend + +```python +def ZCLSend(cluster, command, nodeid, endpoint, groupid, args, blocking=False) +``` + +Wrapper over SendCommand that catches the exceptions Returns a tuple of +(errorCode, CommandResponse) + + + +#### ZCLReadAttribute + +```python +def ZCLReadAttribute(cluster, + attribute, + nodeid, + endpoint, + groupid, + blocking=True) +``` + +Wrapper over ReadAttribute for a single attribute Returns an AttributeReadResult + + + +#### ZCLWriteAttribute + +```python +def ZCLWriteAttribute(cluster: str, + attribute: str, + nodeid, + endpoint, + groupid, + value, + dataVersion=0, + blocking=True) +``` + +Wrapper over WriteAttribute for a single attribute return PyChipError + + + +#### ZCLSubscribeAttribute + +```python +def ZCLSubscribeAttribute(cluster, + attribute, + nodeid, + endpoint, + minInterval, + maxInterval, + blocking=True, + keepSubscriptions=False, + autoResubscribe=True) +``` + +Wrapper over ReadAttribute for a single attribute Returns a +SubscriptionTransaction. See ReadAttribute for more information. + + + +#### InitGroupTestingData + +```python +def InitGroupTestingData() +``` + +Populates the Device Controller's GroupDataProvider with known test group info +and keys. + + + +## ChipDeviceController + +```python +class ChipDeviceController(ChipDeviceControllerBase) +``` + +The ChipDeviceCommissioner binding, named as ChipDeviceController + +TODO: This class contains DEPRECATED functions, we should update the test +scripts to avoid the usage of those functions. + + + +#### Commission + +```python +def Commission(nodeid) -> PyChipError +``` + +Start the auto-commissioning process on a node after establishing a PASE +connection. This function is intended to be used in conjunction with +`EstablishPASESessionBLE` or `EstablishPASESessionIP`. It can be called either +before or after the DevicePairingDelegate receives the OnPairingComplete call. +Commissioners that want to perform simple auto-commissioning should use the +supplied "PairDevice" functions above, which will establish the PASE connection +and commission automatically. + +**Returns**: + +- `bool` - True if successful, False otherwise. + + + +#### CommissionThread + +```python +def CommissionThread(discriminator, setupPinCode, nodeId, + threadOperationalDataset: bytes) -> PyChipError +``` + +Commissions a Thread device over BLE + + + +#### CommissionWiFi + +```python +def CommissionWiFi(discriminator, setupPinCode, nodeId, ssid: str, + credentials: str) -> PyChipError +``` + +Commissions a Wi-Fi device over BLE. + + + +#### SetWiFiCredentials + +```python +def SetWiFiCredentials(ssid: str, credentials: str) +``` + +Set the Wi-Fi credentials to set during commissioning. + + + +#### SetThreadOperationalDataset + +```python +def SetThreadOperationalDataset(threadOperationalDataset) +``` + +Set the Thread operational dataset to set during commissioning. + + + +#### ResetCommissioningParameters + +```python +def ResetCommissioningParameters() +``` + +Sets the commissioning parameters back to the default values. + + + +#### SetTimeZone + +```python +def SetTimeZone(offset: int, validAt: int, name: str = "") +``` + +Set the time zone to set during commissioning. Currently only one time zone +entry is supported + + + +#### SetDSTOffset + +```python +def SetDSTOffset(offset: int, validStarting: int, validUntil: int) +``` + +Set the DST offset to set during commissioning. Currently only one DST entry is +supported + + + +#### SetDefaultNTP + +```python +def SetDefaultNTP(defaultNTP: str) +``` + +Set the DefaultNTP to set during commissioning + + + +#### SetTrustedTimeSource + +```python +def SetTrustedTimeSource(nodeId: int, endpoint: int) +``` + +Set the trusted time source nodeId to set during commissioning. This must be a +node on the commissioner fabric. + + + +#### SetCheckMatchingFabric + +```python +def SetCheckMatchingFabric(check: bool) +``` + +Instructs the auto-commissioner to perform a matching fabric check before +commissioning. + + + +#### GetFabricCheckResult + +```python +def GetFabricCheckResult() -> int +``` + +Returns the fabric check result if SetCheckMatchingFabric was used. + + + +#### CommissionOnNetwork + +```python +def CommissionOnNetwork( + nodeId: int, + setupPinCode: int, + filterType: DiscoveryFilterType = DiscoveryFilterType.NONE, + filter: typing.Any = None, + discoveryTimeoutMsec: int = 30000) -> PyChipError +``` + +Does the routine for OnNetworkCommissioning, with a filter for mDNS discovery. +Supported filters are: + + DiscoveryFilterType.NONE + DiscoveryFilterType.SHORT_DISCRIMINATOR + DiscoveryFilterType.LONG_DISCRIMINATOR + DiscoveryFilterType.VENDOR_ID + DiscoveryFilterType.DEVICE_TYPE + DiscoveryFilterType.COMMISSIONING_MODE + DiscoveryFilterType.INSTANCE_NAME + DiscoveryFilterType.COMMISSIONER + DiscoveryFilterType.COMPRESSED_FABRIC_ID + +The filter can be an integer, a string or None depending on the actual type of +selected filter. + + + +#### CommissionWithCode + +```python +def CommissionWithCode( + setupPayload: str, + nodeid: int, + discoveryType: DiscoveryType = DiscoveryType.DISCOVERY_ALL +) -> PyChipError +``` + +Commission with the given nodeid from the setupPayload. setupPayload may be a QR +or manual code. + + + +#### CommissionIP + +```python +def CommissionIP(ipaddr: str, setupPinCode: int, nodeid: int) -> PyChipError +``` + +DEPRECATED, DO NOT USE! Use `CommissionOnNetwork` or `CommissionWithCode` + + + +#### IssueNOCChain + +```python +def IssueNOCChain(csr: Clusters.OperationalCredentials.Commands.CSRResponse, + nodeId: int) +``` + +Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC +chain will be provided in TLV cert format. + + + +## BareChipDeviceController + +```python +class BareChipDeviceController(ChipDeviceControllerBase) +``` + +A bare device controller without AutoCommissioner support. + + + +#### \_\_init\_\_ + +```python +def __init__(operationalKey: p256keypair.P256Keypair, + noc: bytes, + icac: typing.Union[bytes, None], + rcac: bytes, + ipk: typing.Union[bytes, None], + adminVendorId: int, + name: str = None) +``` + +Creates a controller without AutoCommissioner. + +The allocated controller uses the noc, icac, rcac and ipk instead of the +default, random generated certificates / keys. Which is suitable for creating a +controller for manually signing certificates for testing. + +**Arguments**: + +- `operationalKey` - A P256Keypair object for the operational key of the + controller. +- `noc` - The NOC for the controller, in bytes. +- `icac` - The optional ICAC for the controller. +- `rcac` - The RCAC for the controller. +- `ipk` - The optional IPK for the controller, when None is provided, the + defaultIpk will be used. +- `adminVendorId` - The adminVendorId of the controller. +- `name` - The name of the controller, for debugging use only. diff --git a/docs/testing/GenerateChipDeviceCtrlDoc.sh b/docs/testing/GenerateChipDeviceCtrlDoc.sh new file mode 100755 index 00000000000000..f1d3f323c7a45c --- /dev/null +++ b/docs/testing/GenerateChipDeviceCtrlDoc.sh @@ -0,0 +1,26 @@ +# +# 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. +# + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) + +pydoc-markdown -m chip.ChipDeviceCtrl '{ + renderer: { + type: markdown, + descriptive_class_title: false, + render_toc: true, + insert_header_anchors: true + } + }' >"$SCRIPT_DIR"/ChipDeviceCtrlAPI.md diff --git a/docs/testing/python.md b/docs/testing/python.md index 3af81e2394fe85..1f946a38333ecd 100644 --- a/docs/testing/python.md +++ b/docs/testing/python.md @@ -1,6 +1,500 @@ # Python framework tests -This file is a placeholder for python framework test information. +The python test framework is built on top of the ChipDeviceCtrl.py python +controller API and the Mobly test framework. Python tests are interaction tests, +and can be used for certification testing, and / or integration testing in the +CI. -NOTE: be sure to include information about how you need to commission with the -python controller, not chip-tool and how to do that in the scripts +Python tests located in src/python_testing + +## Resources for getting started + +- [src/python_testing/hello_test.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/hello_test.py) - + sample test showing test setup and test harness integration +- [https://github.com/google/mobly/blob/master/docs/tutorial.md](https://github.com/google/mobly/blob/master/docs/tutorial.md) +- [ChipDeviceCtrl.py](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/chip/ChipDeviceCtrl.py) - + Controller implementation - [API documentation](./ChipDeviceCtrlAPI.md) +- [scripts/tests/run_python_test.py](https://github.com/project-chip/connectedhomeip/blob/master/scripts/tests/run_python_test.py) + to easily set up app and script for testing - used in CI + +## Writing Python tests + +- 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 + found in [Test Harness helpers](#test-harness-helpers) section + - any tests that use async function (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 Mobly assertions for failing tests +- self.step() along with a steps\_ function to mark test plan steps for cert + tests +- + +### A simple test + +``` +class TC_MYTEST_1_1(MatterBaseTest): + + @async_test_body + async def test_TC_MYTEST_1_1(self): + + vendor_name = await self.read_single_attribute_check_success( + dev_ctrl=self.default_controller, # defaults to +self.default_controlller + node_id = self.dut_node_id, # defaults to +self.dut_node_id + cluster=Clusters.BasicInformation, + attribute=Clusters.BasicInformation.Attributes.VendorName, + endpoint = 0, #defaults to 0 + ) + asserts.assert_equal(vendor_name, “Test vendor name”, “Unexpected vendor name”) + +if __name__ == "__main__": +default_matter_test_main() +``` + +--- + +In this test, asserts.assert_equal is used to fail the test on condition 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 +`@async_test_body` decorator + +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. + +## Cluster Codegen + +- [Objects.py](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/chip/clusters/Objects.py) + for codegen, +- [ClusterObjects.py](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/chip/clusters/ClusterObjects.py) + for classes + +Common import used in test files: `import chip.clusters as Clusters` + +Each cluster is defined in the `Clusters.` namespace and contains +always: + +- id +- descriptor + +Each `Clusters.` will include the appropriate sub-classes (if +defined for the cluster): + +- Enums +- Bitmaps +- Structs +- Attributes +- Commands +- Events + +### Attributes + +Attributes derive from ClusterAttributeDescriptor + +Each `Clusters..Attributes.` class has: + +- cluster_id +- attribute_id +- attribute_type +- value + +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 + +### Commands + +Commands derive from ClusterCommand + +Each `Clusters..Commands.` class has: + +- 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 + +### Events + +Events derive from ClusterEvent + +Each `Clusters..Events.` class has: + +- cluster_id +- event_id +- descriptor +- data members if required + +Example: + +- Clusters.AccessControl.Events.AccessControlEntryChanged.adminNodeID + +### Enums + +Enums derive from MatterIntEnum + +Each `Clusters..Enum.` has + +- k +- kUnknownEnumValue (used for testing, do not transmit) + +Example: + +- Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister + +### Bitmaps + +Bitmaps derive from IntFlag + +Each `Clusters..Bitmaps.` has: - k + +Special class: + +- class Feature(IntFlag) - contains the feature map bitmaps + +Example: + +- Clusters.LaundryWasherControls.Bitmaps.Feature.kSpin + +### Structs + +Structs derive from ClusterObject + +Each `Clusters..Structs.` has: + +- descriptor +- data members + +Example + +- Clusters.BasicInformation.Structs.ProductAppearanceStruct( +- finish=Clusters.BasicInformation.Enums.ProductFinishEnum.kFabric, +- primaryColor=Clusters.BasicInformation.Enums.ColorEnum.kBlack) + +## Accessing Clusters and Cluster Elements by ID + +[ClusterObjects.py](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/chip/clusters/ClusterObjects.py) +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] + +`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] + +`chip.clusters.ClusterObjects.ALL_ACCEPTED_COMMANDS/ALL_GENERATED_COMMANDS` + +- dict[int, dict[int, ClusterCommand]] +- cmd = chip.clusters.ClusterObjects.ALL_ACCEPTED_COMMANDS[cluster_id][cmd_id] + +## ChipDeviceCtrl API + +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 +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 + +### [Read](./ChipDeviceCtrlAPI.md#read) + +- Read both attributes and events +- Can handle wildcard or concrete path + +### [ReadAttribute](./ChipDeviceCtrlAPI.md#readattribute) + +- convenience wrapper for Read for attributes + +Examples: Wildcard read (all clusters, all endpoints): + +`await dev_ctrl.ReadAttribute(node_id, [()])` + +Wildcard read (single endpoint 0) + +`await dev_ctrl.ReadAttribute(node_id, [(0)])` + +Wildcard read (single cluster from single endpoint 0) + +`await dev_ctrl.ReadAttribute(node_id, [(1, Clusters.OnOff)])` + +Single attribute + +`await dev_ctrl.ReadAttribute(node_id, [(1, Clusters.OnOff.Attributes.OnTime)])` + +Multi-path + +`await dev_ctrl.ReadAttribute(node_id, [(1, Clusters.OnOff.Attributes.OnTime),(1, Clusters.OnOff.Attributes.OnOff)])` + +### [ReadEvent](./ChipDeviceCtrlAPI.md#readevent) + +- convenience wrapper for Read +- Similar to ReadAttribute, but the tuple includes urgency as the last number + +Example: + +``` +urgent = 1 + +await dev_ctrl ReadEvent(node_id, [(1, +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. + +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 + - Callable[[TypedAttributePath, SubscriptionTransaction], None] +- SetEventUpdateCallback + - Callable[[EventReadResult, SubscriptionTransaction], None] +- await changes in the main loop using a trigger mechanism from the callback. + +Example for setting callbacks: + +``` +q = queue.Queue() +cb = SimpleEventCallback("cb", cluster_id, event_id, q) + +urgent = 1 +subscription = await dev_ctrl.ReadEvent(nodeid=1, events=[(1, event, urgent)], reportInterval=[1, 3]) +subscription.SetEventUpdateCallback(callback=cb) + +try: + q.get(block=True, timeout=timeout) +except queue.Empty: + asserts.assert_fail(“Timeout on event”) +``` + +### [WriteAttribute](./ChipDeviceCtrlAPI.md#writeattribute) + +Handles concrete paths only (per spec), can handle lists. Returns list of +PyChipError + +- Instantiate the `ClusterAttributeDescriptor` class with the value you want + to send, tuple is (endpoint, attribute) + - use timedRequestTimeoutMs for timed request actions + +Example: + +``` +res = await devCtrl.WriteAttribute(nodeid=0, attributes=[(0,Clusters.BasicInformation.Attributes.NodeLabel("Test"))]) +asserts.assert_equal(ret[0].status, Status.Success, “write failed”) +``` + +### [SendCommand](./ChipDeviceCtrlAPI.md#sendcommand) + +- Instantiate the command 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 + +Example: + +``` +pai = await dev_ctrl.SendCommand(nodeid, 0, Clusters.OperationalCredentials.Commands.CertificateChainRequest(2)) +``` + +## MatterBaseTest helpers + +- 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 + integration +- 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 + +- default_matter_test_main + - Sets up commissioning and finds all tests, parses command arguments + +use as: + +``` +if __name__ == "__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 + +## Test harness helpers + +The python testing system also includes several functions 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 +through your tests. + +All of these functions 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 + 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 + 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 + +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 +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: + +- 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. + +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. +See +[Device Basic Composition tests](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/TC_DeviceBasicComposition.py) + +## Command line arguments + +- Use help to get a full list +- --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) + +## PICS and PIXITS + +- PICS + - use --PICS on the command line to specify the PICS file + - use check_pics to gate steps in a file +- have_whatever = check_pics(“PICS.S.WHATEVER”) +- PIXITs + - use --int-arg, --bool-arg etc on the command line to specify PIXITs + - Warn users if they don’t set required values, add instructions in the + comments +- pixit_value = self.user_params.get("pixit_name", default) + +## Support functions + +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) + +TH2 = new_fabric_admin.NewController(nodeId=112233) +``` + +Open a commissioning window (ECW): + +``` +params = self.OpenCommissioningWindow(dev_ctrl=self.default_controller, node_id=self.dut_node_id) +``` + +To create a new controller on the SAME fabric, allocate a new controller from +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) +``` + +## other support functions + +- basic_composition_support + - wildcard read, whole device analysis +- CommissioningFlowBlocks + - various commissioning support for core tests +- spec_parsing_support + - parsing data model XML into python readable format + +# Running tests locally + +You can run the python script as-is for local testing against an already-running +DUT + +`./scripts/tests/run_python_test.py` is a convenient script to fire up an +example DUT on the host, with factory reset support + +`./scripts/tests/run_python_test.py --factoryreset --app --app-args "whatever" --script --script-args "whatever"` + +Note that devices must be commissioned by the python test harness to run tests. +chip-tool and the python test harness DO NOT share a fabric. + +# 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 + checks), gate them on the PICS_SDK_CI_ONLY + - is_ci = self.check_pics('PICS_SDK_CI_ONLY') diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap b/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap index b868916264f4ba..516cb763153e1f 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 99, + "featureLevel": 100, "creator": "zap", "keyValuePairs": [ { @@ -1581,10 +1581,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1597,10 +1597,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x0002", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -2903,7 +2903,6 @@ "define": "FAN_CONTROL_CLUSTER", "side": "server", "enabled": 1, - "apiMaturity": "provisional", "commands": [ { "name": "Step", @@ -7610,7 +7609,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x0", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -7626,7 +7625,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -7641,7 +7640,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7657,7 +7656,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7673,7 +7672,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7689,7 +7688,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7747,7 +7746,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7763,8 +7762,8 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", - "reportable": 0, + "defaultValue": null, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -7779,8 +7778,8 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", - "reportable": 0, + "defaultValue": null, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -7795,8 +7794,8 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", - "reportable": 0, + "defaultValue": null, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -7811,7 +7810,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7827,7 +7826,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7843,7 +7842,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7859,7 +7858,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7875,7 +7874,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7891,7 +7890,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -8039,7 +8038,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -8055,7 +8054,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -8071,7 +8070,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -8087,7 +8086,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -8136,43 +8135,48 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 2, "profileId": 259, "endpointId": 2, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 3, "profileId": 259, "endpointId": 3, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 4, "profileId": 259, "endpointId": 4, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 5, "profileId": 259, "endpointId": 5, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null } - ], - "log": [] + ] } \ No newline at end of file diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter index 1f165eecdcc27a..48db2c71b380bb 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter @@ -829,7 +829,7 @@ cluster SoftwareDiagnostics = 52 { /** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ cluster ThreadNetworkDiagnostics = 53 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum ConnectionStatusEnum : enum8 { kConnected = 0; @@ -2203,7 +2203,7 @@ endpoint 0 { callback attribute operationalDatasetComponents; callback attribute activeNetworkFaultsList; ram attribute featureMap default = 0x000F; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; handle command ResetCounts; } diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.zap b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.zap index 06db369cc4e3b6..1ba46389e28a9e 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.zap +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 99, + "featureLevel": 100, "creator": "zap", "keyValuePairs": [ { @@ -1529,10 +1529,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -1545,10 +1545,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x0002", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -2733,7 +2733,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6054,14 +6054,16 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null } ] } \ No newline at end of file diff --git a/examples/air-quality-sensor-app/linux/AirQualitySensorAppAttrUpdateDelegate.cpp b/examples/air-quality-sensor-app/linux/AirQualitySensorAppAttrUpdateDelegate.cpp index 8be44e55cc9e17..41a53d4fd94c7d 100644 --- a/examples/air-quality-sensor-app/linux/AirQualitySensorAppAttrUpdateDelegate.cpp +++ b/examples/air-quality-sensor-app/linux/AirQualitySensorAppAttrUpdateDelegate.cpp @@ -19,11 +19,11 @@ #include "AirQualitySensorAppAttrUpdateDelegate.h" #include -#include #include #include #include #include +#include #include #include diff --git a/examples/air-quality-sensor-app/linux/README.md b/examples/air-quality-sensor-app/linux/README.md index 73139ef4aeeacb..38a0adfb2fe7bf 100644 --- a/examples/air-quality-sensor-app/linux/README.md +++ b/examples/air-quality-sensor-app/linux/README.md @@ -165,3 +165,21 @@ value. ``` $ echo '{"Name":"NitrogenDioxideConcentrationMeasurement","NewValue":1}' > /tmp/chip_air_quality_fifo_ ``` + +Generate event `Pm1ConcentrationMeasurement`, to change the PM1 value. + +``` +echo '{"Name":"Pm1ConcentrationMeasurement","NewValue":1}' > /tmp/chip_air_quality_fifo_ +``` + +Generate event `Pm25ConcentrationMeasurement`, to change the PM2.5 value. + +``` +echo '{"Name":"Pm25ConcentrationMeasurement","NewValue":2.5}' > /tmp/chip_air_quality_fifo_ +``` + +Generate event `Pm10ConcentrationMeasurement`, to change the PM10 value. + +``` +echo '{"Name":"Pm10ConcentrationMeasurement","NewValue":10}' > /tmp/chip_air_quality_fifo_ +``` diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 5a7b510b05b0c8..2c54d75c7e6b06 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -1814,7 +1814,7 @@ cluster SoftwareDiagnostics = 52 { /** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ cluster ThreadNetworkDiagnostics = 53 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum ConnectionStatusEnum : enum8 { kConnected = 0; @@ -5869,7 +5869,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 3; + revision 4; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -7538,7 +7538,7 @@ endpoint 0 { callback attribute operationalDatasetComponents; callback attribute activeNetworkFaultsList; ram attribute featureMap default = 0x000F; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; handle command ResetCounts; } @@ -7761,7 +7761,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0001; - ram attribute clusterRevision default = 5; + ram attribute clusterRevision default = 6; handle command Off; handle command On; @@ -8740,7 +8740,7 @@ endpoint 1 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 4; } server cluster CarbonMonoxideConcentrationMeasurement { @@ -9134,7 +9134,7 @@ endpoint 2 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0001; - ram attribute clusterRevision default = 5; + ram attribute clusterRevision default = 6; handle command Off; handle command On; @@ -9207,7 +9207,7 @@ endpoint 2 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 4; } } endpoint 65534 { diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 21bcfee37b5e0d..683f2dd75658ba 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 99, + "featureLevel": 100, "creator": "zap", "keyValuePairs": [ { @@ -17,12 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json", @@ -30,6 +24,12 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data with some extensions" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" } ], "endpointTypes": [ @@ -4331,7 +4331,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6659,7 +6659,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "5", + "defaultValue": "6", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6895,7 +6895,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "5", + "defaultValue": "6", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -8312,7 +8312,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14241,15 +14241,16 @@ ] }, { - "name": "Power Topology", - "code": 156, + "name": "Energy Preference", + "code": 155, "mfgCode": null, - "define": "POWER_TOPOLOGY_CLUSTER", + "define": "ENERGY_PREFERENCE_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "provisional", "attributes": [ { - "name": "AvailableEndpoints", + "name": "EnergyBalances", "code": 0, "mfgCode": null, "side": "server", @@ -14265,10 +14266,26 @@ "reportableChange": 0 }, { - "name": "ActiveEndpoints", + "name": "CurrentEnergyBalance", "code": 1, "mfgCode": null, "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EnergyPriorities", + "code": 2, + "mfgCode": null, + "side": "server", "type": "array", "included": 1, "storageOption": "External", @@ -14280,6 +14297,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "LowPowerModeSensitivities", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentLowPowerModeSensitivity", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -14351,10 +14400,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14372,41 +14421,23 @@ "bounded": 0, "defaultValue": "1", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 } ] }, { - "name": "Energy EVSE Mode", - "code": 157, + "name": "Power Topology", + "code": 156, "mfgCode": null, - "define": "ENERGY_EVSE_MODE_CLUSTER", + "define": "POWER_TOPOLOGY_CLUSTER", "side": "server", "enabled": 1, "apiMaturity": "provisional", - "commands": [ - { - "name": "ChangeToMode", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ChangeToModeResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], "attributes": [ { - "name": "SupportedModes", + "name": "AvailableEndpoints", "code": 0, "mfgCode": null, "side": "server", @@ -14422,11 +14453,11 @@ "reportableChange": 0 }, { - "name": "CurrentMode", + "name": "ActiveEndpoints", "code": 1, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -14536,10 +14567,10 @@ ] }, { - "name": "Device Energy Management Mode", - "code": 159, + "name": "Energy EVSE Mode", + "code": 157, "mfgCode": null, - "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", + "define": "ENERGY_EVSE_MODE_CLUSTER", "side": "server", "enabled": 1, "apiMaturity": "provisional", @@ -14693,48 +14724,35 @@ ] }, { - "name": "Energy Preference", - "code": 155, + "name": "Device Energy Management Mode", + "code": 159, "mfgCode": null, - "define": "ENERGY_PREFERENCE_CLUSTER", + "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", "side": "server", "enabled": 1, - "attributes": [ + "apiMaturity": "provisional", + "commands": [ { - "name": "EnergyBalances", + "name": "ChangeToMode", "code": 0, "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 + "source": "client", + "isIncoming": 1, + "isEnabled": 1 }, { - "name": "CurrentEnergyBalance", + "name": "ChangeToModeResponse", "code": 1, "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ { - "name": "EnergyPriorities", - "code": 2, + "name": "SupportedModes", + "code": 0, "mfgCode": null, "side": "server", "type": "array", @@ -14749,11 +14767,11 @@ "reportableChange": 0 }, { - "name": "LowPowerModeSensitivities", - "code": 3, + "name": "CurrentMode", + "code": 1, "mfgCode": null, "side": "server", - "type": "array", + "type": "int8u", "included": 1, "storageOption": "External", "singleton": 0, @@ -14764,22 +14782,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "CurrentLowPowerModeSensitivity", - "code": 4, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, @@ -14851,10 +14853,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14872,8 +14874,8 @@ "bounded": 0, "defaultValue": "1", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 } ] @@ -16468,7 +16470,6 @@ "define": "FAN_CONTROL_CLUSTER", "side": "server", "enabled": 1, - "apiMaturity": "provisional", "commands": [ { "name": "Step", @@ -18751,7 +18752,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -23993,7 +23994,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "5", + "defaultValue": "6", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -24764,7 +24765,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -25288,28 +25289,32 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "MA-onofflight", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "MA-onofflight", "endpointTypeIndex": 2, "profileId": 259, "endpointId": 2, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 3, "profileId": 259, "endpointId": 65534, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null } ] } \ No newline at end of file diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake index c4572063508ac0..2afdd4e8d70942 100755 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -153,6 +153,8 @@ endif (matter_enable_ota_requestor) list( APPEND ${list_chip_main_sources} + ${chip_dir}/src/app/clusters/microwave-oven-control-server/microwave-oven-control-server.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp @@ -161,6 +163,7 @@ list( ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-delegates.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp @@ -169,6 +172,10 @@ list( ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp + ${chip_dir}/examples/all-clusters-app/ameba/main/chipinterface.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/BindingHandler.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp @@ -178,6 +185,8 @@ list( ${chip_dir}/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp + ${chip_dir}/examples/microwave-oven-app/microwave-oven-common/src/microwave-oven-device.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp @@ -228,6 +237,8 @@ target_include_directories( ${chip_dir}/zzz_generated/app-common ${chip_dir}/examples/all-clusters-app/all-clusters-common ${chip_dir}/examples/all-clusters-app/all-clusters-common/include + ${chip_dir}/examples/microwave-oven-app/microwave-oven-common + ${chip_dir}/examples/microwave-oven-app/microwave-oven-common/include ${chip_dir}/examples/energy-management-app/energy-management-common/include ${chip_dir}/examples/all-clusters-app/ameba/main/include ${chip_dir}/examples/platform/ameba diff --git a/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp b/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp index feb346b892f6bb..d03dbcd42ae0bd 100644 --- a/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp +++ b/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp @@ -79,6 +79,7 @@ static void RegisterManualOperationCommands() { &ManualRVCCommandHandler, "rvc", " Usage: manual rvc " }, { &ManualRefrigeratorAlarmCommandHandler, "refalm", " Usage: manual refalm " }, { &ManualDishWasherAlarmCommandHandler, "dishalm", " Usage: manual dishalm " }, + { &ManualOvenCavityOperationalStateCommandHandler, "oven-opstate", " Usage: manual dishalm " }, }; static const shell_command_t sManualOperationalStateSubCommands[] = { @@ -123,6 +124,14 @@ static void RegisterManualOperationCommands() { &ManualDishWasherAlarmSetLowerCommandHandler, "lower", "lower Usage: manual dishalm lower" }, }; + static const shell_command_t sManualOvenCavityOperationalStateSubCommands[] = { + { &ManualOvenCavityOperationalStateCommandHelpHandler, "help", "Usage: manual oven-opstate " }, + { &ManualOvenCavityOperationalStateSetStateCommandHandler, "set-state", + "set-state Usage: manual oven-opstate set-state " }, + { &ManualOvenCavityOperationalStateSetErrorCommandHandler, "set-error", + "set-error Usage: manual oven-opstate set-error " }, + }; + static const shell_command_t sManualOperationCommand = { &ManualOperationCommandHandler, "manual", "Manual Operation commands. Usage: manual " }; @@ -139,6 +148,8 @@ static void RegisterManualOperationCommands() ArraySize(sManualRefrigeratorAlarmStateSubCommands)); sShellManualDishWasherAlarmStateSubCommands.RegisterCommands(sManualDishWasherAlarmSubCommands, ArraySize(sManualDishWasherAlarmSubCommands)); + sShellManualOvenCavityOperationalStateSubCommands.RegisterCommands(sManualOvenCavityOperationalStateSubCommands, + ArraySize(sManualOvenCavityOperationalStateSubCommands)); Engine::Root().RegisterCommands(&sManualOperationCommand, 1); } diff --git a/examples/all-clusters-app/ameba/main/chipinterface.cpp b/examples/all-clusters-app/ameba/main/chipinterface.cpp index 20de9cd1ff0124..c9547136035f81 100644 --- a/examples/all-clusters-app/ameba/main/chipinterface.cpp +++ b/examples/all-clusters-app/ameba/main/chipinterface.cpp @@ -17,6 +17,7 @@ #include +#include "AmebaObserver.h" #include "BindingHandler.h" #include "CHIPDeviceManager.h" #include "DeviceCallbacks.h" @@ -28,13 +29,16 @@ #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -43,6 +47,7 @@ #include #include #if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER +#include #include #endif @@ -140,11 +145,11 @@ static void InitServer(intptr_t context) static chip::CommonCaseDeviceServerInitParams initParams; #if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER - // TODO(#31723): Show to customers that they can do `Server::GetInstance().GetTestEventTriggerDelegate().AddHandler(xxx)` - // to add custom handlers during their app init, after InitServer. static AmebaTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; #endif + static AmebaObserver sAmebaObserver; + initParams.appDelegate = &sAmebaObserver; initParams.InitializeStaticResourcesBeforeServerInit(); @@ -166,6 +171,12 @@ static void InitServer(intptr_t context) InitManualOperation(); #endif app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); + MatterMicrowaveOvenServerInit(); +#if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER + static SmokeCOTestEventTriggerHandler sSmokeCOTestEventTriggerHandler; + Server::GetInstance().GetTestEventTriggerDelegate()->AddHandler(&sSmokeCOTestEventTriggerHandler); +#endif + chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAmebaObserver); } extern "C" void ChipTest(void) @@ -213,3 +224,9 @@ void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) { LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); } + +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} diff --git a/examples/all-clusters-app/ameba/main/include/AmebaObserver.h b/examples/all-clusters-app/ameba/main/include/AmebaObserver.h new file mode 100644 index 00000000000000..a19c9c99954def --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/AmebaObserver.h @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace chip { + +class AmebaObserver : public AppDelegate, public FabricTable::Delegate +{ +public: + // Commissioning Observer + void OnCommissioningSessionEstablishmentError(CHIP_ERROR err) override + { + ChipLogProgress(DeviceLayer, "Ameba Observer: Commissioning error (0x%x)", err); + // Handle commissioning errror here + } + // Fabric Observer + void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override + { + ChipLogProgress(DeviceLayer, "Ameba Observer: Fabric 0x%x has been Removed", fabricIndex); + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + // Customer code + } + } +}; + +} // namespace chip diff --git a/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h b/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h index fc2825576e6b72..31e186ae77d2a8 100644 --- a/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h +++ b/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h @@ -19,6 +19,7 @@ #include "controller/InvokeInteraction.h" #include "controller/ReadInteraction.h" #include "operational-state-delegate-impl.h" +#include "oven-operational-state-delegate.h" #include "rvc-operational-state-delegate-impl.h" #if CONFIG_ENABLE_CHIP_SHELL @@ -39,6 +40,7 @@ using Shell::streamer_printf; Engine sShellManualOperationalStateSubCommands; Engine sShellManualRVCOperationalStateSubCommands; +Engine sShellManualOvenCavityOperationalStateSubCommands; #endif // defined(ENABLE_CHIP_SHELL) #if CONFIG_ENABLE_CHIP_SHELL @@ -183,4 +185,71 @@ CHIP_ERROR ManualRVCOperationalStateSetErrorCommandHandler(int argc, char ** arg return CHIP_NO_ERROR; } + +/******************************************************** + * Oven Cavity Operational State Functions + *********************************************************/ + +CHIP_ERROR ManualOvenCavityOperationalStateCommandHelpHandler(int argc, char ** argv) +{ + sShellManualOvenCavityOperationalStateSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualOvenCavityOperationalStateCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualOvenCavityOperationalStateCommandHelpHandler(argc, argv); + } + + return sShellManualOvenCavityOperationalStateSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualOvenCavityOperationalStateSetStateCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualOvenCavityOperationalStateCommandHelpHandler(argc, argv); + } + uint32_t state = atoi(argv[0]); + + CHIP_ERROR err; + err = OvenCavityOperationalState::GetOperationalStateInstance()->SetOperationalState(state); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualOvenCavityOperationalStateSetStateCommandHandler Failed!\r\n"); + } + + return err; +} + +CHIP_ERROR ManualOvenCavityOperationalStateSetErrorCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualOvenCavityOperationalStateCommandHelpHandler(argc, argv); + } + + GenericOperationalError err(to_underlying(ErrorStateEnum::kNoError)); + uint32_t error = atoi(argv[0]); + + switch (error) + { + case to_underlying(OvenCavityOperationalState::ErrorStateEnum::kNoError): // 0x00, 0 + case to_underlying(OvenCavityOperationalState::ErrorStateEnum::kUnableToStartOrResume): // 0x01, 1 + case to_underlying(OvenCavityOperationalState::ErrorStateEnum::kUnableToCompleteOperation): // 0x02, 2 + case to_underlying(OvenCavityOperationalState::ErrorStateEnum::kCommandInvalidInState): // 0x03, 3 + err.errorStateID = error; + break; + default: + err.errorStateID = to_underlying(OvenCavityOperationalState::ErrorStateEnum::kUnknownEnumValue); // 0x04, 4 + break; + } + + OvenCavityOperationalState::GetOperationalStateInstance()->OnOperationalErrorDetected(err); + + return CHIP_NO_ERROR; +} #endif // CONFIG_ENABLE_CHIP_SHELL diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index b2fe3a90b59f3f..d1bab3649f0b67 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -19,12 +19,12 @@ #include "AllClustersCommandDelegate.h" #include -#include #include #include #include #include #include +#include #include #include diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index 775f4a1c0f324c..8760bcb92d456c 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -50,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index dbb244cf6265b3..0c9569504c7846 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -1694,7 +1694,7 @@ cluster SoftwareDiagnostics = 52 { /** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ cluster ThreadNetworkDiagnostics = 53 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum ConnectionStatusEnum : enum8 { kConnected = 0; @@ -4428,7 +4428,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 3; + revision 4; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -6120,7 +6120,7 @@ endpoint 0 { callback attribute operationalDatasetComponents; callback attribute activeNetworkFaultsList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster WiFiNetworkDiagnostics { @@ -6571,7 +6571,7 @@ endpoint 1 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 4; } server cluster WakeOnLan { @@ -6916,7 +6916,7 @@ endpoint 2 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 4; } } endpoint 65534 { diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap index 2d64015215a5ce..3294f430a3e337 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 99, + "featureLevel": 100, "creator": "zap", "keyValuePairs": [ { @@ -2618,10 +2618,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2634,10 +2634,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x0002", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -2993,7 +2993,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -6999,7 +6999,6 @@ "define": "FAN_CONTROL_CLUSTER", "side": "server", "enabled": 1, - "apiMaturity": "provisional", "attributes": [ { "name": "FanMode", @@ -7998,7 +7997,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -11824,7 +11823,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -12348,28 +12347,32 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "MA-onofflight", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "MA-onofflight", "endpointTypeIndex": 2, "profileId": 259, "endpointId": 2, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null }, { "endpointTypeName": "Anonymous Endpoint Type", "endpointTypeIndex": 3, "profileId": 259, "endpointId": 65534, - "networkId": 0 + "networkId": 0, + "parentEndpointIdentifier": null } ] } \ No newline at end of file diff --git a/examples/all-clusters-minimal-app/linux/main-common.cpp b/examples/all-clusters-minimal-app/linux/main-common.cpp index a6fd0a9866220e..d9f0a51cd747cf 100644 --- a/examples/all-clusters-minimal-app/linux/main-common.cpp +++ b/examples/all-clusters-minimal-app/linux/main-common.cpp @@ -19,10 +19,10 @@ #include "include/tv-callbacks.h" #include #include -#include #include #include #include +#include #include #include #include diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt index 5b49a6d9ab05ab..2ffbec50c746a2 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt @@ -16,7 +16,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipDeviceController import chip.devicecontroller.ChipIdLookup -import chip.devicecontroller.InvokeCallback +import chip.devicecontroller.ExtendableInvokeCallback import chip.devicecontroller.ReportCallback import chip.devicecontroller.ResubscriptionAttemptCallback import chip.devicecontroller.SubscriptionEstablishedCallback @@ -26,6 +26,8 @@ import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.ChipPathId import chip.devicecontroller.model.InvokeElement +import chip.devicecontroller.model.InvokeResponseData +import chip.devicecontroller.model.NoInvokeResponseData import chip.devicecontroller.model.NodeState import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient @@ -57,6 +59,8 @@ class WildcardFragment : Fragment() { private val attributePath = ArrayList() private val eventPath = ArrayList() + private val writePath = ArrayList() + private val invokePath = ArrayList() private val subscribeIdList = ArrayList() private val reportCallback = @@ -89,29 +93,47 @@ class WildcardFragment : Fragment() { private val writeAttributeCallback = object : WriteAttributesCallback { + var viewText = "" + override fun onError(attributePath: ChipAttributePath?, ex: Exception?) { Log.e(TAG, "Report error for $attributePath: $ex") + viewText += "onError : $attributePath - $ex\n" } override fun onResponse(attributePath: ChipAttributePath, status: Status) { - val text = "$attributePath : Write response: $status" - requireActivity().runOnUiThread { binding.outputTv.text = text } + viewText += "$attributePath : Write response: $status\n" } override fun onDone() { - Log.i(TAG, "write attribute Done") + requireActivity().runOnUiThread { + binding.outputTv.text = viewText + viewText = "" + } } } - private val invokeCallback = - object : InvokeCallback { + private val extendableInvokeCallback = + object : ExtendableInvokeCallback { + var viewText = "" + override fun onError(e: java.lang.Exception?) { + viewText += "Invoke onError : $e\n" Log.e(TAG, "Report error", e) } - override fun onResponse(invokeElement: InvokeElement?, successCode: Long) { - val text = "Invoke Response : $invokeElement, $successCode" - requireActivity().runOnUiThread { binding.outputTv.text = text } + override fun onResponse(invokeResponseData: InvokeResponseData?) { + viewText += "Invoke Response : $invokeResponseData\n" + } + + override fun onNoResponse(noInvokeResponseData: NoInvokeResponseData?) { + viewText += "Invoke onNoResponse : $noInvokeResponseData\n" + } + + override fun onDone() { + requireActivity().runOnUiThread { + binding.outputTv.text = viewText + viewText = "" + } } } @@ -123,41 +145,27 @@ class WildcardFragment : Fragment() { _binding = WildcardFragmentBinding.inflate(inflater, container, false) scope = viewLifecycleOwner.lifecycleScope - binding.selectTypeRadioGroup.setOnCheckedChangeListener { _, i -> - val readBtnOn = (i == R.id.readRadioBtn) - val subscribeBtnOn = (i == R.id.subscribeRadioBtn) - val writeBtnOn = (i == R.id.writeRadioBtn) - val invokeBtnOn = (i == R.id.invokeRadioBtn) - - binding.addLayout.visibility = getVisibility(readBtnOn || subscribeBtnOn) - binding.attributeIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn) - binding.attributeIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn) - binding.eventIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn) - binding.eventIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn) - binding.commandIdLabel.visibility = getVisibility(invokeBtnOn) - binding.commandIdEd.visibility = getVisibility(invokeBtnOn) - binding.isUrgentLabel.visibility = getVisibility(subscribeBtnOn) - binding.isUrgentSp.visibility = getVisibility(subscribeBtnOn) - binding.shutdownSubscriptionBtn.visibility = getVisibility(subscribeBtnOn) - } + val writeTypeSpinnerAdapter = + ArrayAdapter( + requireActivity(), + android.R.layout.simple_spinner_dropdown_item, + TLV_MAP.keys.toList() + ) + binding.writeValueTypeSp.adapter = writeTypeSpinnerAdapter - binding.sendBtn.setOnClickListener { - if (binding.readRadioBtn.isChecked) { - showReadDialog() - } else if (binding.subscribeRadioBtn.isChecked) { - showSubscribeDialog() - } else if (binding.writeRadioBtn.isChecked) { - showWriteDialog() - } else if (binding.invokeRadioBtn.isChecked) { - showInvokeDialog() - } + binding.selectTypeRadioGroup.setOnCheckedChangeListener { _, radioBtnId -> + setVisibilityEachView(radioBtnId) } + binding.sendBtn.setOnClickListener { showDialog() } + binding.shutdownSubscriptionBtn.setOnClickListener { showShutdownSubscriptionDialog() } - binding.addAttributeBtn.setOnClickListener { addPathList(ATTRIBUTE) } - binding.addEventBtn.setOnClickListener { addPathList(EVENT) } + binding.addAttributeBtn.setOnClickListener { addPathList(SendType.ATTRIBUTE) } + binding.addEventBtn.setOnClickListener { addPathList(SendType.EVENT) } + binding.addListBtn.setOnClickListener { addRequest() } binding.resetBtn.setOnClickListener { resetPath() } + binding.writeInvokeresetBtn.setOnClickListener { resetPath() } addressUpdateFragment = childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment @@ -165,6 +173,58 @@ class WildcardFragment : Fragment() { return binding.root } + private fun setVisibilityEachView(radioBtnId: Int) { + val readBtnOn = (radioBtnId == R.id.readRadioBtn) + val subscribeBtnOn = (radioBtnId == R.id.subscribeRadioBtn) + val writeBtnOn = (radioBtnId == R.id.writeRadioBtn) + val invokeBtnOn = (radioBtnId == R.id.invokeRadioBtn) + + binding.addAttributeBtn.visibility = getVisibility(readBtnOn || subscribeBtnOn) + binding.addEventBtn.visibility = getVisibility(readBtnOn || subscribeBtnOn) + binding.resetBtn.visibility = getVisibility(readBtnOn || subscribeBtnOn) + binding.attributeIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn) + binding.attributeIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn) + binding.eventIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn) + binding.eventIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn) + binding.addListBtn.visibility = getVisibility(writeBtnOn || invokeBtnOn) + binding.commandIdLabel.visibility = getVisibility(invokeBtnOn) + binding.commandIdEd.visibility = getVisibility(invokeBtnOn) + binding.isUrgentLabel.visibility = getVisibility(subscribeBtnOn) + binding.isUrgentSp.visibility = getVisibility(subscribeBtnOn) + binding.writeValueLabel.visibility = getVisibility(writeBtnOn) + binding.writeValueEd.visibility = getVisibility(writeBtnOn) + binding.writeValueTypeLabel.visibility = getVisibility(writeBtnOn) + binding.writeValueTypeSp.visibility = getVisibility(writeBtnOn) + binding.dataVersionLabel.visibility = getVisibility(writeBtnOn) + binding.dataVersionEd.visibility = getVisibility(writeBtnOn) + binding.invokeValueLabel.visibility = getVisibility(invokeBtnOn) + binding.invokeValueEd.visibility = getVisibility(invokeBtnOn) + binding.shutdownSubscriptionBtn.visibility = getVisibility(subscribeBtnOn) + binding.writeInvokeresetBtn.visibility = getVisibility(writeBtnOn || invokeBtnOn) + + resetPath() + } + + private fun showDialog() { + if (binding.readRadioBtn.isChecked) { + showReadDialog() + } else if (binding.subscribeRadioBtn.isChecked) { + showSubscribeDialog() + } else if (binding.writeRadioBtn.isChecked) { + showWriteDialog() + } else if (binding.invokeRadioBtn.isChecked) { + showInvokeDialog() + } + } + + private fun addRequest() { + if (binding.writeRadioBtn.isChecked) { + addWriteRequest() + } else { + addInvokeRequest() + } + } + private fun getVisibility(isShowing: Boolean): Int { return if (isShowing) { View.VISIBLE @@ -173,7 +233,7 @@ class WildcardFragment : Fragment() { } } - private fun addPathList(type: Int) { + private fun addPathList(type: SendType) { val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString()) val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString()) val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString()) @@ -183,9 +243,9 @@ class WildcardFragment : Fragment() { (binding.subscribeRadioBtn.isChecked) && (binding.isUrgentSp.selectedItem.toString().toBoolean()) - if (type == ATTRIBUTE) { + if (type == SendType.ATTRIBUTE) { attributePath.add(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)) - } else if (type == EVENT) { + } else if (type == SendType.EVENT) { eventPath.add(ChipEventPath.newInstance(endpointId, clusterId, eventId, isUrgent)) } updateAddListView() @@ -194,6 +254,8 @@ class WildcardFragment : Fragment() { private fun resetPath() { attributePath.clear() eventPath.clear() + writePath.clear() + invokePath.clear() updateAddListView() } @@ -205,6 +267,12 @@ class WildcardFragment : Fragment() { for (event in eventPath) { builder.append("event($event)\n") } + for (write in writePath) { + builder.append("WritePath($write)\n") + } + for (invoke in invokePath) { + builder.append("InvokePath($invoke)\n") + } binding.sendListView.text = builder.toString() } @@ -312,13 +380,11 @@ class WildcardFragment : Fragment() { ) } - private suspend fun write( - writeValueType: String, - writeValue: String, - dataVersion: Int?, - timedRequestTimeoutMs: Int, - imTimeoutMs: Int - ) { + private fun addWriteRequest() { + val writeValue = binding.writeValueEd.text.toString() + val writeValueType = binding.writeValueTypeSp.selectedItem.toString() + val dataVersion = binding.dataVersionEd.text.toString() + val endpointId = if (!addressUpdateFragment.isGroupId()) { getChipPathIdForText(binding.endpointIdEd.text.toString()) @@ -329,10 +395,10 @@ class WildcardFragment : Fragment() { val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString()) val version = - if (dataVersion == null) { + if (dataVersion.isEmpty()) { Optional.empty() } else { - Optional.of(dataVersion) + Optional.of(dataVersion.toInt()) } lateinit var writeRequest: AttributeWriteRequest @@ -364,26 +430,15 @@ class WildcardFragment : Fragment() { version ) } - val devicePtr = - try { - addressUpdateFragment.getDevicePointer(requireContext()) - } catch (e: IllegalStateException) { - Log.d(TAG, "getDevicePointer exception", e) - return - } - deviceController.write( - writeAttributeCallback, - devicePtr, - listOf(writeRequest), - timedRequestTimeoutMs, - imTimeoutMs - ) + writePath.add(writeRequest) + updateAddListView() } - private suspend fun invoke(invokeJson: String, timedRequestTimeoutMs: Int, imTimeoutMs: Int) { + private fun addInvokeRequest() { val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString()) val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString()) val commandId = getChipPathIdForText(binding.commandIdEd.text.toString()) + val invokeJson = binding.invokeValueEd.text.toString() val jsonString = invokeJson.ifEmpty { "{}" } val invokeElement = @@ -398,6 +453,28 @@ class WildcardFragment : Fragment() { } else { InvokeElement.newInstance(endpointId, clusterId, commandId, null, jsonString) } + invokePath.add(invokeElement) + updateAddListView() + } + + private suspend fun write(timedRequestTimeoutMs: Int, imTimeoutMs: Int) { + val devicePtr = + try { + addressUpdateFragment.getDevicePointer(requireContext()) + } catch (e: IllegalStateException) { + Log.d(TAG, "getDevicePointer exception", e) + return + } + deviceController.write( + writeAttributeCallback, + devicePtr, + writePath, + timedRequestTimeoutMs, + imTimeoutMs + ) + } + + private suspend fun invoke(timedRequestTimeoutMs: Int, imTimeoutMs: Int) { val devicePtr = try { addressUpdateFragment.getDevicePointer(requireContext()) @@ -405,10 +482,10 @@ class WildcardFragment : Fragment() { Log.d(TAG, "getDevicePointer exception", e) return } - deviceController.invoke( - invokeCallback, + deviceController.extendableInvoke( + extendableInvokeCallback, devicePtr, - invokeElement, + invokePath, timedRequestTimeoutMs, imTimeoutMs ) @@ -453,31 +530,14 @@ class WildcardFragment : Fragment() { private fun showWriteDialog() { binding.outputTv.text = "" val dialogView = requireActivity().layoutInflater.inflate(R.layout.write_dialog, null) - val writeValueTypeSp = dialogView.findViewById(R.id.writeValueTypeSp) - val spinnerAdapter = - ArrayAdapter( - requireActivity(), - android.R.layout.simple_spinner_dropdown_item, - TLV_MAP.keys.toList() - ) - writeValueTypeSp.adapter = spinnerAdapter val dialog = AlertDialog.Builder(requireContext()).apply { setView(dialogView) }.create() dialogView.findViewById