diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 94ad9314b9a56c..4d5be76434e8f8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,7 +14,7 @@ "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], - "initializeCommand": ".devcontainer/build.sh --tag matter-dev-environment:local --version 22", + "initializeCommand": "bash .devcontainer/build.sh --tag matter-dev-environment:local --version 22", "image": "matter-dev-environment:local", "remoteUser": "vscode", "customizations": { diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 58a06086679e06..d92158e3277bc1 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -14,29 +14,19 @@ abfb ABI ABIs ables -AccessControl -AccessControlEntry +accesscontrol accessor Accessors -AccountLogin acdbc ack ACKed ACL ACLs actdiag -AdapterAddress -AdapterName adb AddNOC -AddOrUpdateThreadNetwork -AddOrUpdateWiFiNetwork addr -AddResponse -AddThreadNetwork -AddStatus adk -AdministratorCommissioning adoc adr AdvAutonomous @@ -48,7 +38,6 @@ AE aef AES AIDL -AlarmCode algs alloc Ameba @@ -61,15 +50,12 @@ AnnounceOTAProvider AnnounceOTAProviderRequest APIs apk -AppConfig AppImpl AppleTV appliable -ApplianceControl applianceeventsandalert ApplianceIdentification appliancestatistics -ApplicationBasic ApplicationId ApplicationIdentifier ApplicationLauncher @@ -171,7 +157,6 @@ BRD breakpoint bredr BridgedDeviceBasicInformation -bridgedLightEndpoint bringup BroadcastReceiver BromateConcentrationMeasurement @@ -259,9 +244,6 @@ CLIs cloudbuild CLRF clusterAttrs -clusterId -clusterList -clusterListName ClusterName ClusterObjectTests ClusterRevision @@ -315,7 +297,6 @@ ContentApp's ContentAppPlatform ContentLaunch ContentLauncher -continuousHinting contrib controllee conv @@ -382,7 +363,6 @@ DefaultOTARequestor DefaultOTARequestorDriver DefaultOTARequestorStorage DefaultSuccess -defaultValue definedValue DehumidificationControl DelayedActionTime @@ -415,9 +395,7 @@ DeviceLayer DeviceNetworkProvisioningDelegate DeviceNetworkProvisioningDelegateImpl DevicePairingDelegate -deviceSoftwareVersionModel DeviceTemperatureConfiguration -deviceType DevKitC DevKitM devtype @@ -511,8 +489,6 @@ EnableNetwork EnableWiFiNetwork endian EndpointId -endpointName -endsWith eno entrypoint enum @@ -523,6 +499,7 @@ epochStartTime eq errorValue esd +espcoredump ESPPORT Espressif esptool @@ -579,7 +556,6 @@ FlowMeasurement FluorideConcentrationMeasurement focusable forkpty -formatOnSave FOTA FreeRTOS FreeRTOSConfig @@ -613,7 +589,6 @@ GetIP getManualTests GetSafeAttributePersistenceProvider getstarted -getTests GH ghcr ghp @@ -638,8 +613,6 @@ graphviz Groupcast GroupId GroupKeyManagement -groupKeySecurityPolicy -groupKeySetID groupsettings gsdk gtk @@ -693,8 +666,6 @@ ifconfig ifdef ifdefs IGMP -ignoreApplyUpdate -ignoreQueryImage ihex IlluminanceMeasurement IM @@ -1621,4 +1592,4 @@ zephyrproject zhengyaohan Zigbee zigbeealliance -zigbeethread \ No newline at end of file +zigbeethread diff --git a/.github/workflows/cherry-picks.yaml b/.github/workflows/cherry-picks.yaml index 6d9b5339b40b9e..a062aa5fcf9b87 100644 --- a/.github/workflows/cherry-picks.yaml +++ b/.github/workflows/cherry-picks.yaml @@ -14,7 +14,6 @@ jobs: (github.event.pull_request.merged == true) && ( (contains(github.event.pull_request.labels.*.name, 'sve')) - || (contains(github.event.pull_request.labels.*.name, 'spec')) || (contains(github.event.pull_request.labels.*.name, 'request sve')) || (contains(github.event.pull_request.labels.*.name, 'cert blocker')) ) @@ -27,11 +26,12 @@ jobs: uses: carloscastrojumo/github-cherry-pick-action@v1.0.9 with: token: ${{ secrets.MATTER_PAT }} - branch: sve-2 + branch: 1.3-sve labels: | sve cherry pick reviewers: | woody-apple andy31415 + raju-apple env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/darwin-tests.yaml b/.github/workflows/darwin-tests.yaml index 05943be5b0e155..e6e14ec4929a11 100644 --- a/.github/workflows/darwin-tests.yaml +++ b/.github/workflows/darwin-tests.yaml @@ -100,6 +100,7 @@ jobs: --target darwin-x64-bridge-${BUILD_VARIANT} \ --target darwin-x64-lit-icd-${BUILD_VARIANT} \ --target darwin-x64-microwave-oven-${BUILD_VARIANT} \ + --target darwin-x64-rvc-${BUILD_VARIANT} \ build \ --copy-artifacts-to objdir-clone \ " @@ -120,6 +121,7 @@ jobs: --tv-app ./out/darwin-x64-tv-app-${BUILD_VARIANT}/chip-tv-app \ --bridge-app ./out/darwin-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \ --microwave-oven-app ./out/darwin-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ + --rvc-app ./out/darwin-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ " - name: Run OTA Test run: | diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 189f63837c841e..69613217033e8b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -93,35 +93,20 @@ jobs: --known-failure app/AttributeAccessInterface.h \ --known-failure app/AttributeAccessToken.h \ --known-failure app/att-storage.h \ - --known-failure app/BufferedReadCallback.h \ --known-failure app/CommandHandler.h \ --known-failure app/CommandHandlerInterface.h \ - --known-failure app/CommandPathParams.h \ - --known-failure app/CommandPathRegistry.h \ - --known-failure app/CommandResponseSender.h \ - --known-failure app/CommandSender.h \ --known-failure app/CommandSenderLegacyCallback.h \ --known-failure app/CompatEnumNames.h \ - --known-failure app/ConcreteAttributePath.h \ - --known-failure app/ConcreteCommandPath.h \ --known-failure app/data-model/ListLargeSystemExtensions.h \ --known-failure app/EventHeader.h \ - --known-failure app/EventLoggingDelegate.h \ - --known-failure app/EventLogging.h \ --known-failure app/EventLoggingTypes.h \ - --known-failure app/EventManagement.h \ - --known-failure app/InteractionModelHelper.h \ - --known-failure app/ObjectList.h \ - --known-failure app/ReadClient.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/server/AppDelegate.h \ --known-failure app/TestEventTriggerDelegate.h \ --known-failure app/util/af.h \ --known-failure app/util/af-types.h \ - --known-failure app/util/attribute-metadata.h \ --known-failure app/util/attribute-storage.cpp \ --known-failure app/util/attribute-storage.h \ --known-failure app/util/attribute-storage-null-handling.h \ @@ -141,14 +126,9 @@ jobs: --known-failure app/util/im-client-callbacks.h \ --known-failure app/util/MatterCallbacks.h \ --known-failure app/util/message.cpp \ - --known-failure app/util/mock/Constants.h \ - --known-failure app/util/mock/Functions.h \ - --known-failure app/util/mock/MockNodeConfig.h \ --known-failure app/util/odd-sized-integers.h \ - --known-failure app/util/types_stub.h \ --known-failure app/util/util.cpp \ --known-failure app/util/util.h \ - --known-failure app/WriteClient.h \ --known-failure app/WriteHandler.h \ --known-failure lib/core/CHIPVendorIdentifiers.hpp \ --known-failure platform/DeviceSafeQueue.cpp \ diff --git a/.github/workflows/spell.yml b/.github/workflows/spell.yml index 57593372543079..1e8194a9a2075f 100644 --- a/.github/workflows/spell.yml +++ b/.github/workflows/spell.yml @@ -25,19 +25,20 @@ on: - ".github/.wordlist.txt" jobs: - check-reviewdog: - name: Check Spelling - reviewdog - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - uses: reviewdog/action-misspell@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} +# Seems redundant; removed as pyspelling is customized while this is not +# check-reviewdog: +# name: Check Spelling - reviewdog +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# - uses: reviewdog/action-misspell@v1 +# with: +# github_token: ${{ secrets.GITHUB_TOKEN }} check-spellcheck: name: Check Spelling - pyspelling runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - uses: igsekor/pyspelling-any@v1.0.4 + - uses: rojopolis/spellcheck-github-actions@0.36.0 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 05d2670edd665e..83d921c2fa4188 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -213,6 +213,7 @@ jobs: --target linux-x64-bridge-${BUILD_VARIANT} \ --target linux-x64-lit-icd-${BUILD_VARIANT} \ --target linux-x64-microwave-oven-${BUILD_VARIANT} \ + --target linux-x64-rvc-${BUILD_VARIANT} \ build \ --copy-artifacts-to objdir-clone \ " @@ -234,6 +235,7 @@ jobs: --bridge-app ./out/linux-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \ --lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ + --rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ " - name: Run purposeful failure tests using the python parser sending commands to chip-tool @@ -274,6 +276,7 @@ jobs: --bridge-app ./out/linux-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \ --lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ + --rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ " - name: Run Tests using chip-repl (including slow) if: github.event_name == 'push' @@ -292,6 +295,7 @@ jobs: --bridge-app ./out/linux-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \ --lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ + --rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ " - name: Uploading core files uses: actions/upload-artifact@v4 @@ -359,6 +363,7 @@ jobs: --target darwin-x64-bridge-${BUILD_VARIANT} \ --target darwin-x64-lit-icd-${BUILD_VARIANT} \ --target darwin-x64-microwave-oven-${BUILD_VARIANT} \ + --target darwin-x64-rvc-${BUILD_VARIANT} \ build \ --copy-artifacts-to objdir-clone \ " @@ -381,6 +386,7 @@ jobs: --bridge-app ./out/darwin-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \ --lit-icd-app ./out/darwin-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/darwin-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ + --rvc-app ./out/darwin-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ " - name: Run purposeful failure tests using the python parser sending commands to chip-tool @@ -460,6 +466,7 @@ jobs: --target linux-x64-lit-icd-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-energy-management-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test \ + --target linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-python-bindings \ build \ --copy-artifacts-to objdir-clone \ @@ -502,9 +509,8 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_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_RVCCLEANM_1_2.py" --script-args "--int-arg PIXIT_ENDPOINT:1 --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_RVCRUNM_1_2.py" --script-args "--int-arg PIXIT_ENDPOINT:1 --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"' 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_TIMESYNC_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_TIMESYNC_2_10.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"' @@ -542,6 +548,15 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_MWOCTRL_2_3.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-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_MWOCTRL_2_4.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-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_MWOM_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-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCRUNM_1_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCRUNM_2_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto --int-arg PIXIT.RVCRUNM.MODE_CHANGE_OK:0 PIXIT.RVCRUNM.MODE_CHANGE_FAIL:2"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCRUNM_2_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto --int-arg PIXIT.RVCRUNM.MODE_A:1 PIXIT.RVCRUNM.MODE_B:2"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCCLEANM_1_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCCLEANM_2_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto --int-arg PIXIT.RVCCLEANM.MODE_CHANGE_FAIL:1 PIXIT.RVCCLEANM.MODE_CHANGE_OK:2"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCCLEANM_2_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCOPSTATE_2_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCOPSTATE_2_3.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCOPSTATE_2_4.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' - name: Uploading core files uses: actions/upload-artifact@v4 if: ${{ failure() && !env.ACT }} diff --git a/.spellcheck.yml b/.spellcheck.yml index c04880827addba..27a48c7de8e174 100644 --- a/.spellcheck.yml +++ b/.spellcheck.yml @@ -68,3 +68,4 @@ matrix: - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md' aspell: ignore-case: true + camel-case: true diff --git a/BUILD.gn b/BUILD.gn index 838ea743f348c8..0992c61b0510c6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -182,7 +182,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { deps += [ "${chip_root}/src/app/server/java", "${chip_root}/src/controller/java", + "${chip_root}/src/controller/java:jsontlv", "${chip_root}/src/controller/java:onboarding_payload", + "${chip_root}/src/controller/java:tlv", "${chip_root}/src/platform/android:java", ] } @@ -363,6 +365,10 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { enable_linux_lit_icd_app_build = enable_default_builds && (host_os == "linux" || host_os == "mac") + # Build the Linux RVC app example. + enable_linux_rvc_app_build = + enable_default_builds && (host_os == "linux" || host_os == "mac") + # Build the cc13x2x7_26x2x7 lock app example. enable_cc13x2x7_26x2x7_lock_app_build = enable_ti_simplelink_builds @@ -744,6 +750,14 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { extra_build_deps += [ ":genio_shell_app" ] } + if (enable_linux_rvc_app_build) { + group("linux_rvc_app") { + deps = [ "${chip_root}/examples/rvc-app/linux(${standalone_toolchain})" ] + } + + extra_build_deps += [ ":linux_rvc_app" ] + } + group("default") { deps = extra_build_deps + builds } diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 9d2f17d1acf86e..01626726e0b9af 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -127,7 +127,9 @@ if (_chip_defaults.custom_toolchain != "") { "Unsupported target_cpu: ${current_cpu}. Shall be arm for webOS") } } else { - assert(false, "No toolchain specified, please specify custom_toolchain") + assert( + false, + "No toolchain specified, please specify custom_toolchain for host_os='${host_os}', target_os='${target_os}', host_cpu='${host_cpu}', target_cpu='${target_cpu}'") } set_default_toolchain(_default_toolchain) diff --git a/data_model/README.md b/data_model/README.md index 36f38cae0ff1f8..a26b1c4ff65558 100644 --- a/data_model/README.md +++ b/data_model/README.md @@ -17,7 +17,7 @@ update the spec XML files, however this is not done automatically. You will require access to the following tools locally: - `scraper`. A binary copy generally available - [here](https://github.com/csa-data-model/projects/tree/main/DM-Editor/bin/1.2.0/scrape) + [here](https://github.com/csa-data-model/projects/tree/main/DM-Editor/bin/scrape) - Specification repository checkout from https://github.com/CHIP-Specifications/connectedhomeip-spec diff --git a/data_model/clusters/ACL-Cluster.xml b/data_model/clusters/ACL-Cluster.xml index 9ef2f500e96e01..b965eb84234e0d 100644 --- a/data_model/clusters/ACL-Cluster.xml +++ b/data_model/clusters/ACL-Cluster.xml @@ -55,10 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + + + @@ -112,25 +115,27 @@ Davis, CA 95616, USA - + + - + - + + - + - + - + @@ -150,12 +155,14 @@ Davis, CA 95616, USA - + + - + + diff --git a/data_model/clusters/AccountLogin.xml b/data_model/clusters/AccountLogin.xml index 91f675eaba693b..db87d05dc74902 100644 --- a/data_model/clusters/AccountLogin.xml +++ b/data_model/clusters/AccountLogin.xml @@ -54,14 +54,20 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + - + @@ -70,14 +76,14 @@ Davis, CA 95616, USA - + - + @@ -86,12 +92,27 @@ Davis, CA 95616, USA - + + + + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/AdminCommissioningCluster.xml b/data_model/clusters/AdminCommissioningCluster.xml index b94b25ec5520c2..eea41bc65b6e2c 100644 --- a/data_model/clusters/AdminCommissioningCluster.xml +++ b/data_model/clusters/AdminCommissioningCluster.xml @@ -1,7 +1,5 @@ + + + diff --git a/data_model/clusters/AlarmBase.xml b/data_model/clusters/AlarmBase.xml index 9ba73c14ab6e63..f4ffc6344a8b90 100644 --- a/data_model/clusters/AlarmBase.xml +++ b/data_model/clusters/AlarmBase.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -91,7 +96,7 @@ Davis, CA 95616, USA - + @@ -100,7 +105,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ApplicationBasic.xml b/data_model/clusters/ApplicationBasic.xml index 086839a2338cfc..fa197a8d1e5cca 100644 --- a/data_model/clusters/ApplicationBasic.xml +++ b/data_model/clusters/ApplicationBasic.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/ApplicationLauncher.xml b/data_model/clusters/ApplicationLauncher.xml index 5d716981a55d38..6b84436e73d42d 100644 --- a/data_model/clusters/ApplicationLauncher.xml +++ b/data_model/clusters/ApplicationLauncher.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -111,7 +116,7 @@ Davis, CA 95616, USA - + @@ -124,7 +129,7 @@ Davis, CA 95616, USA - + @@ -134,7 +139,7 @@ Davis, CA 95616, USA - + @@ -145,7 +150,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/AudioOutput.xml b/data_model/clusters/AudioOutput.xml index 176e75b16c19c9..468ba2750152a6 100644 --- a/data_model/clusters/AudioOutput.xml +++ b/data_model/clusters/AudioOutput.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -111,14 +116,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/BallastConfiguration.xml b/data_model/clusters/BallastConfiguration.xml index 416b8cd7014beb..f25bef22cb4b6c 100644 --- a/data_model/clusters/BallastConfiguration.xml +++ b/data_model/clusters/BallastConfiguration.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/BasicInformationCluster.xml b/data_model/clusters/BasicInformationCluster.xml index 87fa765f65b2f5..82b9283b0d21d6 100644 --- a/data_model/clusters/BasicInformationCluster.xml +++ b/data_model/clusters/BasicInformationCluster.xml @@ -59,8 +59,11 @@ Davis, CA 95616, USA - + + + + @@ -175,50 +178,50 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + @@ -226,41 +229,41 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + @@ -271,11 +274,11 @@ Davis, CA 95616, USA - + - + @@ -293,6 +296,12 @@ Davis, CA 95616, USA + + + + + + diff --git a/data_model/clusters/Binding-Cluster.xml b/data_model/clusters/Binding-Cluster.xml index 95f68f1d6ff995..eca291a7d895ff 100644 --- a/data_model/clusters/Binding-Cluster.xml +++ b/data_model/clusters/Binding-Cluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/BooleanState.xml b/data_model/clusters/BooleanState.xml index 5b298075fbaefc..9205310c58f2be 100644 --- a/data_model/clusters/BooleanState.xml +++ b/data_model/clusters/BooleanState.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/BooleanStateConfiguration.xml b/data_model/clusters/BooleanStateConfiguration.xml index 160cb7fadb7a93..dc17f93a7295f0 100644 --- a/data_model/clusters/BooleanStateConfiguration.xml +++ b/data_model/clusters/BooleanStateConfiguration.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -164,7 +169,7 @@ Davis, CA 95616, USA - + @@ -173,7 +178,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Channel.xml b/data_model/clusters/Channel.xml index 9ace62ca720a53..1809f5262e7166 100644 --- a/data_model/clusters/Channel.xml +++ b/data_model/clusters/Channel.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -67,8 +73,28 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + @@ -85,6 +111,17 @@ Davis, CA 95616, USA + + + + + + + + + + + @@ -101,6 +138,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + @@ -117,6 +170,132 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -142,7 +321,7 @@ Davis, CA 95616, USA - + @@ -155,7 +334,6 @@ Davis, CA 95616, USA - @@ -170,7 +348,7 @@ Davis, CA 95616, USA - + @@ -180,12 +358,108 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ColorControl.xml b/data_model/clusters/ColorControl.xml index c0b0655261b10b..b913009f852761 100644 --- a/data_model/clusters/ColorControl.xml +++ b/data_model/clusters/ColorControl.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -64,6 +66,9 @@ Davis, CA 95616, USA + + + @@ -123,19 +128,19 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -158,13 +163,13 @@ Davis, CA 95616, USA - + - + - + @@ -356,16 +361,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -434,7 +439,7 @@ Davis, CA 95616, USA - + @@ -449,7 +454,7 @@ Davis, CA 95616, USA - + @@ -460,16 +465,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -489,23 +494,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -524,23 +529,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -562,7 +567,7 @@ Davis, CA 95616, USA - + @@ -584,23 +589,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -619,23 +624,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -657,7 +662,7 @@ Davis, CA 95616, USA - + @@ -683,7 +688,7 @@ Davis, CA 95616, USA - + @@ -709,7 +714,7 @@ Davis, CA 95616, USA - + @@ -729,7 +734,7 @@ Davis, CA 95616, USA - + @@ -753,7 +758,7 @@ Davis, CA 95616, USA - + @@ -775,7 +780,7 @@ Davis, CA 95616, USA - + @@ -800,7 +805,7 @@ Davis, CA 95616, USA - + @@ -821,7 +826,7 @@ Davis, CA 95616, USA - + @@ -846,7 +851,7 @@ Davis, CA 95616, USA - + @@ -871,7 +876,7 @@ Davis, CA 95616, USA - + @@ -899,13 +904,13 @@ Davis, CA 95616, USA - + - + - + @@ -914,10 +919,10 @@ Davis, CA 95616, USA - + - + @@ -939,7 +944,7 @@ Davis, CA 95616, USA - + @@ -957,7 +962,7 @@ Davis, CA 95616, USA - + @@ -986,7 +991,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ContentAppObserver.xml b/data_model/clusters/ContentAppObserver.xml index b426daa5ec3379..184cce14924cda 100644 --- a/data_model/clusters/ContentAppObserver.xml +++ b/data_model/clusters/ContentAppObserver.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -71,7 +76,7 @@ Davis, CA 95616, USA - + @@ -84,7 +89,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/ContentControl.xml b/data_model/clusters/ContentControl.xml index b51bdff9397448..14996a7c28011a 100644 --- a/data_model/clusters/ContentControl.xml +++ b/data_model/clusters/ContentControl.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + @@ -255,7 +258,7 @@ Davis, CA 95616, USA - + @@ -269,14 +272,13 @@ Davis, CA 95616, USA - + - @@ -285,15 +287,15 @@ Davis, CA 95616, USA - + - + - + @@ -307,7 +309,7 @@ Davis, CA 95616, USA - + @@ -317,19 +319,19 @@ Davis, CA 95616, USA - + - + - + @@ -339,7 +341,7 @@ Davis, CA 95616, USA - + @@ -349,7 +351,7 @@ Davis, CA 95616, USA - + @@ -359,7 +361,7 @@ Davis, CA 95616, USA - + @@ -369,7 +371,7 @@ Davis, CA 95616, USA - + @@ -379,7 +381,7 @@ Davis, CA 95616, USA - + @@ -389,7 +391,7 @@ Davis, CA 95616, USA - + @@ -398,7 +400,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ContentLauncher.xml b/data_model/clusters/ContentLauncher.xml index 2c310c6f2ccb3d..b8f80de2e51ea7 100644 --- a/data_model/clusters/ContentLauncher.xml +++ b/data_model/clusters/ContentLauncher.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -67,6 +73,15 @@ Davis, CA 95616, USA + + + + + + + + + @@ -119,12 +134,21 @@ Davis, CA 95616, USA - + + + + + + + + + + @@ -136,6 +160,16 @@ Davis, CA 95616, USA + + + + + + + + + + @@ -206,6 +240,27 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + @@ -220,6 +275,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + @@ -242,7 +314,7 @@ Davis, CA 95616, USA - + @@ -258,8 +330,15 @@ Davis, CA 95616, USA + + + + + + + - + @@ -273,9 +352,11 @@ Davis, CA 95616, USA + + + - diff --git a/data_model/clusters/DemandResponseLoadControl.xml b/data_model/clusters/DemandResponseLoadControl.xml index a5322bfb4f7206..206201b347612c 100644 --- a/data_model/clusters/DemandResponseLoadControl.xml +++ b/data_model/clusters/DemandResponseLoadControl.xml @@ -55,13 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + + + @@ -192,6 +195,59 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -222,6 +278,41 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -361,14 +452,14 @@ Davis, CA 95616, USA - + - + @@ -376,14 +467,14 @@ Davis, CA 95616, USA - + - + @@ -394,7 +485,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Descriptor-Cluster.xml b/data_model/clusters/Descriptor-Cluster.xml index 9944d8a3f6ea4c..1b17fb4fdfdaea 100644 --- a/data_model/clusters/Descriptor-Cluster.xml +++ b/data_model/clusters/Descriptor-Cluster.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/DeviceEnergyManagement.xml b/data_model/clusters/DeviceEnergyManagement.xml index 21f74a737d52cb..e493c5b332182e 100644 --- a/data_model/clusters/DeviceEnergyManagement.xml +++ b/data_model/clusters/DeviceEnergyManagement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + + @@ -487,13 +492,13 @@ Davis, CA 95616, USA - + - + @@ -507,7 +512,7 @@ Davis, CA 95616, USA - + @@ -521,13 +526,13 @@ Davis, CA 95616, USA - + - + @@ -545,7 +550,7 @@ Davis, CA 95616, USA - + @@ -560,7 +565,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/DiagnosticLogsCluster.xml b/data_model/clusters/DiagnosticLogsCluster.xml index 14f995ca1855a6..5b67564b18f298 100644 --- a/data_model/clusters/DiagnosticLogsCluster.xml +++ b/data_model/clusters/DiagnosticLogsCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -138,11 +139,11 @@ Davis, CA 95616, USA - + - + @@ -221,7 +222,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/DishwasherAlarm.xml b/data_model/clusters/DishwasherAlarm.xml index 7fda78ad163116..b3b67e2bffb500 100644 --- a/data_model/clusters/DishwasherAlarm.xml +++ b/data_model/clusters/DishwasherAlarm.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA + +:xrefstyle: short --> + + + diff --git a/data_model/clusters/DoorLock.xml b/data_model/clusters/DoorLock.xml index 4f84afca85ff1e..6284b973eb63e1 100644 --- a/data_model/clusters/DoorLock.xml +++ b/data_model/clusters/DoorLock.xml @@ -54,8 +54,10 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + @@ -64,7 +66,11 @@ Davis, CA 95616, USA + + + + @@ -98,14 +104,19 @@ Davis, CA 95616, USA - - - - - - - - + + + + + + + + + + + + + @@ -119,6 +130,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -201,6 +220,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + @@ -334,6 +370,21 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + @@ -482,6 +533,11 @@ Davis, CA 95616, USA + + + + + @@ -1053,9 +1109,84 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1067,7 +1198,7 @@ Davis, CA 95616, USA - + @@ -1079,11 +1210,11 @@ Davis, CA 95616, USA - + - + @@ -1098,7 +1229,7 @@ Davis, CA 95616, USA - + @@ -1109,7 +1240,6 @@ Davis, CA 95616, USA - @@ -1138,7 +1268,7 @@ Davis, CA 95616, USA - + @@ -1165,7 +1295,7 @@ Davis, CA 95616, USA - + @@ -1181,7 +1311,6 @@ Davis, CA 95616, USA - @@ -1209,7 +1338,7 @@ Davis, CA 95616, USA - + @@ -1225,7 +1354,7 @@ Davis, CA 95616, USA - + @@ -1236,7 +1365,7 @@ Davis, CA 95616, USA - + @@ -1259,7 +1388,7 @@ Davis, CA 95616, USA - + @@ -1279,7 +1408,6 @@ Davis, CA 95616, USA - @@ -1293,7 +1421,7 @@ Davis, CA 95616, USA - + @@ -1326,7 +1454,7 @@ Davis, CA 95616, USA - + @@ -1341,7 +1469,6 @@ Davis, CA 95616, USA - @@ -1377,7 +1504,7 @@ Davis, CA 95616, USA - + @@ -1392,7 +1519,7 @@ Davis, CA 95616, USA - + @@ -1412,7 +1539,7 @@ Davis, CA 95616, USA - + @@ -1427,7 +1554,6 @@ Davis, CA 95616, USA - @@ -1450,7 +1576,7 @@ Davis, CA 95616, USA - + @@ -1465,7 +1591,7 @@ Davis, CA 95616, USA - + @@ -1484,7 +1610,7 @@ Davis, CA 95616, USA - + @@ -1495,7 +1621,6 @@ Davis, CA 95616, USA - @@ -1520,7 +1645,7 @@ Davis, CA 95616, USA - + @@ -1531,7 +1656,7 @@ Davis, CA 95616, USA - + @@ -1553,7 +1678,7 @@ Davis, CA 95616, USA - + @@ -1573,7 +1698,6 @@ Davis, CA 95616, USA - @@ -1587,7 +1711,7 @@ Davis, CA 95616, USA - + @@ -1615,7 +1739,7 @@ Davis, CA 95616, USA - + @@ -1631,7 +1755,6 @@ Davis, CA 95616, USA - @@ -1659,7 +1782,7 @@ Davis, CA 95616, USA - + @@ -1675,7 +1798,7 @@ Davis, CA 95616, USA - + @@ -1686,7 +1809,7 @@ Davis, CA 95616, USA - + @@ -1731,7 +1854,7 @@ Davis, CA 95616, USA - + @@ -1742,7 +1865,6 @@ Davis, CA 95616, USA - @@ -1792,7 +1914,7 @@ Davis, CA 95616, USA - + @@ -1844,7 +1966,7 @@ Davis, CA 95616, USA - + @@ -1885,7 +2007,6 @@ Davis, CA 95616, USA - @@ -1904,7 +2025,7 @@ Davis, CA 95616, USA - + @@ -1914,7 +2035,6 @@ Davis, CA 95616, USA - @@ -1939,8 +2059,15 @@ Davis, CA 95616, USA + + + + + + + - + @@ -1951,7 +2078,7 @@ Davis, CA 95616, USA - + @@ -1965,6 +2092,36 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/EVSE-Attributes.xml b/data_model/clusters/EVSE-Attributes.xml deleted file mode 100644 index 2d492a27c4c0a1..00000000000000 --- a/data_model/clusters/EVSE-Attributes.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Classification.xml b/data_model/clusters/EVSE-Classification.xml deleted file mode 100644 index 22df357be3e9d0..00000000000000 --- a/data_model/clusters/EVSE-Classification.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-ClusterID.xml b/data_model/clusters/EVSE-ClusterID.xml deleted file mode 100644 index 6f84afeb8d04bc..00000000000000 --- a/data_model/clusters/EVSE-ClusterID.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Commands.xml b/data_model/clusters/EVSE-Commands.xml deleted file mode 100644 index 030565e20f8f96..00000000000000 --- a/data_model/clusters/EVSE-Commands.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-DataTypes.xml b/data_model/clusters/EVSE-DataTypes.xml deleted file mode 100644 index 790d66143c7025..00000000000000 --- a/data_model/clusters/EVSE-DataTypes.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Definitions.xml b/data_model/clusters/EVSE-Definitions.xml deleted file mode 100644 index 7ff6135a3d2976..00000000000000 --- a/data_model/clusters/EVSE-Definitions.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Dependencies.xml b/data_model/clusters/EVSE-Dependencies.xml deleted file mode 100644 index a87cb67a4623ae..00000000000000 --- a/data_model/clusters/EVSE-Dependencies.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Events.xml b/data_model/clusters/EVSE-Events.xml deleted file mode 100644 index 51401775a6fe59..00000000000000 --- a/data_model/clusters/EVSE-Events.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Features.xml b/data_model/clusters/EVSE-Features.xml deleted file mode 100644 index a8b48a53b401e9..00000000000000 --- a/data_model/clusters/EVSE-Features.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-RevisionHistory.xml b/data_model/clusters/EVSE-RevisionHistory.xml deleted file mode 100644 index 89ca30f749e5e1..00000000000000 --- a/data_model/clusters/EVSE-RevisionHistory.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/ElectricalEnergyMeasurement.xml b/data_model/clusters/ElectricalEnergyMeasurement.xml index c6bf8e73863c41..98020764397116 100644 --- a/data_model/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/clusters/ElectricalEnergyMeasurement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -74,7 +79,59 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/ElectricalPowerMeasurement.xml b/data_model/clusters/ElectricalPowerMeasurement.xml index aa5baeaf368cbb..c695e8db031790 100644 --- a/data_model/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/clusters/ElectricalPowerMeasurement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -95,6 +100,68 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/EnergyCalendar.xml b/data_model/clusters/EnergyCalendar.xml index a21845d92c47c4..8d3f1b343bb4a7 100644 --- a/data_model/clusters/EnergyCalendar.xml +++ b/data_model/clusters/EnergyCalendar.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/EnergyEVSE.xml b/data_model/clusters/EnergyEVSE.xml index f59d41807d43e6..fa15692e78896d 100644 --- a/data_model/clusters/EnergyEVSE.xml +++ b/data_model/clusters/EnergyEVSE.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -395,7 +400,6 @@ Davis, CA 95616, USA - @@ -405,11 +409,11 @@ Davis, CA 95616, USA - + - + @@ -425,7 +429,7 @@ Davis, CA 95616, USA - + @@ -439,11 +443,11 @@ Davis, CA 95616, USA - + - + @@ -454,13 +458,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/EnergyPreference.xml b/data_model/clusters/EnergyPreference.xml index 7156be8eafe025..c3676520ed6d01 100644 --- a/data_model/clusters/EnergyPreference.xml +++ b/data_model/clusters/EnergyPreference.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/EnergyPrice.xml b/data_model/clusters/EnergyPrice.xml index 23072a6a99ead5..1683fe1bbc13cf 100644 --- a/data_model/clusters/EnergyPrice.xml +++ b/data_model/clusters/EnergyPrice.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -173,7 +178,7 @@ Davis, CA 95616, USA - + @@ -188,7 +193,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/FanControl.xml b/data_model/clusters/FanControl.xml index acf1d59e54d91e..756a7bd27466b3 100644 --- a/data_model/clusters/FanControl.xml +++ b/data_model/clusters/FanControl.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -277,7 +282,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/FlowMeasurement.xml b/data_model/clusters/FlowMeasurement.xml index 66ad022c2c64ef..29f9d9d7ae58f9 100644 --- a/data_model/clusters/FlowMeasurement.xml +++ b/data_model/clusters/FlowMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/GeneralCommissioningCluster.xml b/data_model/clusters/GeneralCommissioningCluster.xml index a25cdfc6ac934e..635a6635990654 100644 --- a/data_model/clusters/GeneralCommissioningCluster.xml +++ b/data_model/clusters/GeneralCommissioningCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -86,21 +89,22 @@ Davis, CA 95616, USA - + - + + - + - + - + - + @@ -117,35 +121,35 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -160,13 +164,15 @@ Davis, CA 95616, USA - + + - + + @@ -184,14 +190,14 @@ Davis, CA 95616, USA - + - + @@ -199,20 +205,19 @@ Davis, CA 95616, USA - - + - + @@ -220,7 +225,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/Groups.xml b/data_model/clusters/Groups.xml index 175c9caf26a435..72902e878cbe9f 100644 --- a/data_model/clusters/Groups.xml +++ b/data_model/clusters/Groups.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -84,7 +89,7 @@ Davis, CA 95616, USA - + @@ -97,7 +102,6 @@ Davis, CA 95616, USA - @@ -108,7 +112,7 @@ Davis, CA 95616, USA - + @@ -117,7 +121,6 @@ Davis, CA 95616, USA - @@ -132,7 +135,7 @@ Davis, CA 95616, USA - + @@ -143,7 +146,6 @@ Davis, CA 95616, USA - @@ -156,7 +158,7 @@ Davis, CA 95616, USA - + @@ -165,7 +167,6 @@ Davis, CA 95616, USA - @@ -176,11 +177,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/ICDManagement.xml b/data_model/clusters/ICDManagement.xml index 3cc6c9bfab4416..2a770a4f97f2b4 100644 --- a/data_model/clusters/ICDManagement.xml +++ b/data_model/clusters/ICDManagement.xml @@ -54,21 +54,41 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +// Update Name --> - + + + + + - + + + + + + + + + + + + + + + @@ -133,9 +153,28 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + - + @@ -156,7 +195,6 @@ Davis, CA 95616, USA - @@ -164,7 +202,7 @@ Davis, CA 95616, USA - + @@ -177,7 +215,7 @@ Davis, CA 95616, USA - + @@ -190,7 +228,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/Identify.xml b/data_model/clusters/Identify.xml index 379e684e51297d..1cdc33aa0df727 100644 --- a/data_model/clusters/Identify.xml +++ b/data_model/clusters/Identify.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -127,14 +132,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/IlluminanceMeasurement.xml b/data_model/clusters/IlluminanceMeasurement.xml index c9be9fa6879293..c39daa0e6bdc4d 100644 --- a/data_model/clusters/IlluminanceMeasurement.xml +++ b/data_model/clusters/IlluminanceMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/KeypadInput.xml b/data_model/clusters/KeypadInput.xml index f0459e6b1bff1a..4cfb509b06d0be 100644 --- a/data_model/clusters/KeypadInput.xml +++ b/data_model/clusters/KeypadInput.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -345,7 +350,7 @@ Davis, CA 95616, USA - + @@ -353,7 +358,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/Label-Cluster-FixedLabel.xml b/data_model/clusters/Label-Cluster-FixedLabelCluster.xml similarity index 96% rename from data_model/clusters/Label-Cluster-FixedLabel.xml rename to data_model/clusters/Label-Cluster-FixedLabelCluster.xml index 558664a5d69f72..e73bfc274a9da4 100644 --- a/data_model/clusters/Label-Cluster-FixedLabel.xml +++ b/data_model/clusters/Label-Cluster-FixedLabelCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Label-Cluster-Label.xml b/data_model/clusters/Label-Cluster-LabelCluster.xml similarity index 96% rename from data_model/clusters/Label-Cluster-Label.xml rename to data_model/clusters/Label-Cluster-LabelCluster.xml index ee64da775b05cd..f107a0a7b3f12b 100644 --- a/data_model/clusters/Label-Cluster-Label.xml +++ b/data_model/clusters/Label-Cluster-LabelCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Label-Cluster-UserLabel.xml b/data_model/clusters/Label-Cluster-UserLabelCluster.xml similarity index 96% rename from data_model/clusters/Label-Cluster-UserLabel.xml rename to data_model/clusters/Label-Cluster-UserLabelCluster.xml index bca4b1453f22de..f7e809ab785c00 100644 --- a/data_model/clusters/Label-Cluster-UserLabel.xml +++ b/data_model/clusters/Label-Cluster-UserLabelCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/LaundryDryerControls.xml b/data_model/clusters/LaundryDryerControls.xml index 461f08666093b8..a3f7b911fc9e9c 100644 --- a/data_model/clusters/LaundryDryerControls.xml +++ b/data_model/clusters/LaundryDryerControls.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/LaundryWasherControls.xml b/data_model/clusters/LaundryWasherControls.xml index 5a9d108ccc1b01..16879842721473 100644 --- a/data_model/clusters/LaundryWasherControls.xml +++ b/data_model/clusters/LaundryWasherControls.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/LevelControl.xml b/data_model/clusters/LevelControl.xml index 8a348a2dc05cbd..6b2b3cace52ec3 100644 --- a/data_model/clusters/LevelControl.xml +++ b/data_model/clusters/LevelControl.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -65,6 +67,7 @@ Davis, CA 95616, USA + @@ -210,7 +213,7 @@ Davis, CA 95616, USA - + @@ -230,7 +233,7 @@ Davis, CA 95616, USA - + @@ -250,7 +253,7 @@ Davis, CA 95616, USA - + @@ -273,7 +276,7 @@ Davis, CA 95616, USA - + @@ -285,23 +288,23 @@ Davis, CA 95616, USA - + - + - + - + - + diff --git a/data_model/clusters/LocalizationConfiguration.xml b/data_model/clusters/LocalizationConfiguration.xml index b264698b6d5393..f3c2d5b2d7662b 100644 --- a/data_model/clusters/LocalizationConfiguration.xml +++ b/data_model/clusters/LocalizationConfiguration.xml @@ -59,18 +59,25 @@ Davis, CA 95616, USA + + + - + - + - + + + + + \ No newline at end of file diff --git a/data_model/clusters/LocalizationTimeFormat.xml b/data_model/clusters/LocalizationTimeFormat.xml index 204f145f9c8b07..fb8ceea3ee17a8 100644 --- a/data_model/clusters/LocalizationTimeFormat.xml +++ b/data_model/clusters/LocalizationTimeFormat.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + @@ -132,7 +135,8 @@ Davis, CA 95616, USA - + + diff --git a/data_model/clusters/LocalizationUnit.xml b/data_model/clusters/LocalizationUnit.xml index 24c54638b4ffd7..be7ea6a0aa2d78 100644 --- a/data_model/clusters/LocalizationUnit.xml +++ b/data_model/clusters/LocalizationUnit.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/LowPower.xml b/data_model/clusters/LowPower.xml index f8ee432eef58a7..4c228d3154dfa1 100644 --- a/data_model/clusters/LowPower.xml +++ b/data_model/clusters/LowPower.xml @@ -54,14 +54,19 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + - + diff --git a/data_model/clusters/MediaInput.xml b/data_model/clusters/MediaInput.xml index 9ca0f351d1f59f..b7d9d2ef017035 100644 --- a/data_model/clusters/MediaInput.xml +++ b/data_model/clusters/MediaInput.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -132,22 +137,22 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/clusters/MediaPlayback.xml b/data_model/clusters/MediaPlayback.xml index f2cdf5c4a7c851..0a457a446208dd 100644 --- a/data_model/clusters/MediaPlayback.xml +++ b/data_model/clusters/MediaPlayback.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -67,8 +73,73 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -118,6 +189,30 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + @@ -172,52 +267,96 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + + + + + + - + + + + + + - + - + @@ -225,7 +364,6 @@ Davis, CA 95616, USA - @@ -235,7 +373,7 @@ Davis, CA 95616, USA - + @@ -244,5 +382,92 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/Messages.xml b/data_model/clusters/Messages.xml index 9dd223d9a63f46..cea28ac15f54c9 100644 --- a/data_model/clusters/Messages.xml +++ b/data_model/clusters/Messages.xml @@ -55,6 +55,8 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA +:xrefstyle: short + Copyright (C) Connectivity Standards Alliance (2021). All rights reserved. This information within this document is the property of the Connectivity Standards Alliance and its use and disclosure are restricted. @@ -91,6 +93,8 @@ are made. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -98,6 +102,9 @@ Davis, CA 95616, USA + + + @@ -245,7 +252,7 @@ Davis, CA 95616, USA - + @@ -275,7 +282,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/MicrowaveOvenControl.xml b/data_model/clusters/MicrowaveOvenControl.xml index c95d713714854f..d7c6f72f740d3d 100644 --- a/data_model/clusters/MicrowaveOvenControl.xml +++ b/data_model/clusters/MicrowaveOvenControl.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -114,7 +119,7 @@ Davis, CA 95616, USA - + @@ -139,7 +144,7 @@ Davis, CA 95616, USA - + @@ -166,7 +171,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ModeBase.xml b/data_model/clusters/ModeBase.xml index 5774a7fec0c5a5..2a11f85d343b39 100644 --- a/data_model/clusters/ModeBase.xml +++ b/data_model/clusters/ModeBase.xml @@ -61,6 +61,9 @@ Davis, CA 95616, USA + + + @@ -122,7 +125,7 @@ Require at least one standard mode tag. Define reserved ranges for base/derived - + diff --git a/data_model/clusters/ModeSelect.xml b/data_model/clusters/ModeSelect.xml index 19fe502c1fcfe2..a30a5b9bf8eca5 100644 --- a/data_model/clusters/ModeSelect.xml +++ b/data_model/clusters/ModeSelect.xml @@ -60,6 +60,9 @@ Davis, CA 95616, USA + + + @@ -133,7 +136,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Mode_DeviceEnergyManagement.xml b/data_model/clusters/Mode_DeviceEnergyManagement.xml index 4181b9b60ead42..592c7d4290a342 100644 --- a/data_model/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/clusters/Mode_DeviceEnergyManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_Dishwasher.xml b/data_model/clusters/Mode_Dishwasher.xml index 22d0fab7897696..4ff6e78714f648 100644 --- a/data_model/clusters/Mode_Dishwasher.xml +++ b/data_model/clusters/Mode_Dishwasher.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_EVSE.xml b/data_model/clusters/Mode_EVSE.xml index 2a600e3e381325..de88cb3717c8bf 100644 --- a/data_model/clusters/Mode_EVSE.xml +++ b/data_model/clusters/Mode_EVSE.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/Mode_LaundryWasher.xml b/data_model/clusters/Mode_LaundryWasher.xml index e89778fa9ea579..c59b2c3fef9051 100644 --- a/data_model/clusters/Mode_LaundryWasher.xml +++ b/data_model/clusters/Mode_LaundryWasher.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_MicrowaveOven.xml b/data_model/clusters/Mode_MicrowaveOven.xml index cd98c189c12844..6e8a129444b9fd 100644 --- a/data_model/clusters/Mode_MicrowaveOven.xml +++ b/data_model/clusters/Mode_MicrowaveOven.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -75,12 +80,10 @@ Davis, CA 95616, USA - - + - - + diff --git a/data_model/clusters/Mode_Oven.xml b/data_model/clusters/Mode_Oven.xml index 56a369dd425572..f6c7111bb844cd 100644 --- a/data_model/clusters/Mode_Oven.xml +++ b/data_model/clusters/Mode_Oven.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/Mode_RVCClean.xml b/data_model/clusters/Mode_RVCClean.xml index 64118517a03c1b..d1b2272fc7e756 100644 --- a/data_model/clusters/Mode_RVCClean.xml +++ b/data_model/clusters/Mode_RVCClean.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_RVCRun.xml b/data_model/clusters/Mode_RVCRun.xml index 8f49741f7cfeb8..8e19b45a8385fc 100644 --- a/data_model/clusters/Mode_RVCRun.xml +++ b/data_model/clusters/Mode_RVCRun.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_Refrigerator.xml b/data_model/clusters/Mode_Refrigerator.xml index cf6a65721e0efd..d51e30b68d1320 100644 --- a/data_model/clusters/Mode_Refrigerator.xml +++ b/data_model/clusters/Mode_Refrigerator.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_WaterHeater.xml b/data_model/clusters/Mode_WaterHeater.xml index 69fba08b940293..56f1a1e9a66951 100644 --- a/data_model/clusters/Mode_WaterHeater.xml +++ b/data_model/clusters/Mode_WaterHeater.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/NetworkCommissioningCluster.xml b/data_model/clusters/NetworkCommissioningCluster.xml index 0153146c149d26..86c7a01ce9f951 100644 --- a/data_model/clusters/NetworkCommissioningCluster.xml +++ b/data_model/clusters/NetworkCommissioningCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -73,6 +76,11 @@ Davis, CA 95616, USA + + + + + @@ -169,15 +177,34 @@ Davis, CA 95616, USA + + + - + - + + + + + + + + + + + + + + + + + @@ -191,11 +218,11 @@ Davis, CA 95616, USA - + - + @@ -229,17 +256,17 @@ Davis, CA 95616, USA - + - + - + - + @@ -265,10 +292,11 @@ Davis, CA 95616, USA - + + - + @@ -302,24 +330,25 @@ Davis, CA 95616, USA - + - + - + + - + @@ -337,7 +366,7 @@ Davis, CA 95616, USA - + @@ -345,19 +374,18 @@ Davis, CA 95616, USA - + - + - @@ -368,54 +396,68 @@ Davis, CA 95616, USA - + - + - + + - + + - + - + - + - + - + + + + + + + + + + + + + - + - + - + - + @@ -423,16 +465,15 @@ Davis, CA 95616, USA - + - + - @@ -443,16 +484,28 @@ Davis, CA 95616, USA - + - + - + + + + + + + + + + + + + - + @@ -460,16 +513,15 @@ Davis, CA 95616, USA - + - + - @@ -479,7 +531,7 @@ Davis, CA 95616, USA - + @@ -487,7 +539,7 @@ Davis, CA 95616, USA - + @@ -495,9 +547,9 @@ Davis, CA 95616, USA - + - + @@ -507,5 +559,32 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/clusters/NetworkIdentityManagement.xml b/data_model/clusters/NetworkIdentityManagement.xml index 08bee6af5871ff..8769b68583e4b9 100644 --- a/data_model/clusters/NetworkIdentityManagement.xml +++ b/data_model/clusters/NetworkIdentityManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -119,7 +124,7 @@ Davis, CA 95616, USA - + @@ -130,7 +135,7 @@ Davis, CA 95616, USA - + @@ -141,7 +146,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/OTAProvider.xml b/data_model/clusters/OTAProvider.xml index 73157662cd6f6e..baf3996d3b911f 100644 --- a/data_model/clusters/OTAProvider.xml +++ b/data_model/clusters/OTAProvider.xml @@ -1,7 +1,5 @@ @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/OnOff.xml b/data_model/clusters/OnOff.xml index 0d64837ea57fbb..0b1e32af50cddb 100644 --- a/data_model/clusters/OnOff.xml +++ b/data_model/clusters/OnOff.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -64,6 +66,9 @@ Davis, CA 95616, USA + + + @@ -171,11 +176,11 @@ Davis, CA 95616, USA - + - + @@ -183,7 +188,7 @@ Davis, CA 95616, USA - + @@ -191,7 +196,7 @@ Davis, CA 95616, USA - + @@ -205,13 +210,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/OperationalCredentialCluster.xml b/data_model/clusters/OperationalCredentialCluster.xml index ec523ba33671d1..1a2becd5c478a2 100644 --- a/data_model/clusters/OperationalCredentialCluster.xml +++ b/data_model/clusters/OperationalCredentialCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -98,10 +99,10 @@ Davis, CA 95616, USA - + - + @@ -115,11 +116,11 @@ Davis, CA 95616, USA - + - + - + @@ -136,32 +137,34 @@ Davis, CA 95616, USA - + - + - + - + - + + - + - + + - + @@ -175,10 +178,14 @@ Davis, CA 95616, USA - + + + + + @@ -186,7 +193,7 @@ Davis, CA 95616, USA - + @@ -195,7 +202,6 @@ Davis, CA 95616, USA - @@ -206,7 +212,7 @@ Davis, CA 95616, USA - + @@ -215,14 +221,13 @@ Davis, CA 95616, USA - - + @@ -234,7 +239,6 @@ Davis, CA 95616, USA - @@ -245,29 +249,29 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -280,7 +284,6 @@ Davis, CA 95616, USA - @@ -294,7 +297,7 @@ Davis, CA 95616, USA - + @@ -302,7 +305,7 @@ Davis, CA 95616, USA - + @@ -310,12 +313,12 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/clusters/OperationalState.xml b/data_model/clusters/OperationalState.xml index dcb5753b2c1998..0062b38b4b3981 100644 --- a/data_model/clusters/OperationalState.xml +++ b/data_model/clusters/OperationalState.xml @@ -60,6 +60,9 @@ Davis, CA 95616, USA + + + @@ -143,6 +146,53 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/OperationalState_Oven.xml b/data_model/clusters/OperationalState_Oven.xml index 947e93f8ec2348..c44ac37b7ccac9 100644 --- a/data_model/clusters/OperationalState_Oven.xml +++ b/data_model/clusters/OperationalState_Oven.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/OperationalState_RVC.xml b/data_model/clusters/OperationalState_RVC.xml index bc4e5505e45d6d..6426e2639a7b83 100644 --- a/data_model/clusters/OperationalState_RVC.xml +++ b/data_model/clusters/OperationalState_RVC.xml @@ -54,32 +54,29 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA + +:xrefstyle: basic --> + + + - - - - - + + - - + - - - - - - - + + + diff --git a/data_model/clusters/PowerSourceCluster.xml b/data_model/clusters/PowerSourceCluster.xml index 16d6f0ac98cad5..ffd628de6686b8 100644 --- a/data_model/clusters/PowerSourceCluster.xml +++ b/data_model/clusters/PowerSourceCluster.xml @@ -61,6 +61,9 @@ Davis, CA 95616, USA + + + @@ -911,13 +914,13 @@ Davis, CA 95616, USA - + - + @@ -928,12 +931,14 @@ Davis, CA 95616, USA + + - + @@ -944,9 +949,10 @@ Davis, CA 95616, USA + - + @@ -957,13 +963,15 @@ Davis, CA 95616, USA - + + - + - + + - + @@ -971,13 +979,15 @@ Davis, CA 95616, USA - + + - + - + + - + @@ -985,13 +995,15 @@ Davis, CA 95616, USA - + + - + - + + - + diff --git a/data_model/clusters/PowerSourceConfigurationCluster.xml b/data_model/clusters/PowerSourceConfigurationCluster.xml index 5548bf6ad8e6b5..11e3bd47dd9186 100644 --- a/data_model/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/clusters/PowerSourceConfigurationCluster.xml @@ -59,10 +59,13 @@ Davis, CA 95616, USA + + + - + diff --git a/data_model/clusters/PowerTopology.xml b/data_model/clusters/PowerTopology.xml index c8d90baeeded19..d8c8a50d22a3a6 100644 --- a/data_model/clusters/PowerTopology.xml +++ b/data_model/clusters/PowerTopology.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> + + + diff --git a/data_model/clusters/PressureMeasurement.xml b/data_model/clusters/PressureMeasurement.xml index 70093485639090..d9c4a4584404fe 100644 --- a/data_model/clusters/PressureMeasurement.xml +++ b/data_model/clusters/PressureMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/PumpConfigurationControl.xml b/data_model/clusters/PumpConfigurationControl.xml index f3fc98a52cee9e..cfd2971a395ecb 100644 --- a/data_model/clusters/PumpConfigurationControl.xml +++ b/data_model/clusters/PumpConfigurationControl.xml @@ -62,6 +62,9 @@ Davis, CA 95616, USA + + + @@ -169,7 +172,206 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/RefrigeratorAlarm.xml b/data_model/clusters/RefrigeratorAlarm.xml index c987c3860a4f52..caad94da1f6fad 100644 --- a/data_model/clusters/RefrigeratorAlarm.xml +++ b/data_model/clusters/RefrigeratorAlarm.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> + + + @@ -73,8 +78,7 @@ Davis, CA 95616, USA - - + diff --git a/data_model/clusters/ResourceMonitoring.xml b/data_model/clusters/ResourceMonitoring.xml index 17fc7554ac41f0..6b0e8f3a203ded 100644 --- a/data_model/clusters/ResourceMonitoring.xml +++ b/data_model/clusters/ResourceMonitoring.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -164,7 +166,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Scenes.xml b/data_model/clusters/Scenes.xml index 0c4347c4e8be8a..5d9be300d1abbc 100644 --- a/data_model/clusters/Scenes.xml +++ b/data_model/clusters/Scenes.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -116,17 +121,14 @@ Davis, CA 95616, USA - - - @@ -177,7 +179,7 @@ Davis, CA 95616, USA - + @@ -189,7 +191,7 @@ Davis, CA 95616, USA - + @@ -202,7 +204,6 @@ Davis, CA 95616, USA - @@ -216,7 +217,7 @@ Davis, CA 95616, USA - + @@ -228,7 +229,6 @@ Davis, CA 95616, USA - @@ -242,7 +242,7 @@ Davis, CA 95616, USA - + @@ -251,7 +251,7 @@ Davis, CA 95616, USA - + @@ -263,7 +263,6 @@ Davis, CA 95616, USA - @@ -277,7 +276,7 @@ Davis, CA 95616, USA - + @@ -285,7 +284,6 @@ Davis, CA 95616, USA - @@ -295,7 +293,7 @@ Davis, CA 95616, USA - + @@ -307,7 +305,6 @@ Davis, CA 95616, USA - @@ -321,7 +318,7 @@ Davis, CA 95616, USA - + @@ -337,7 +334,7 @@ Davis, CA 95616, USA - + @@ -345,7 +342,6 @@ Davis, CA 95616, USA - @@ -362,7 +358,7 @@ Davis, CA 95616, USA - + @@ -383,9 +379,8 @@ Davis, CA 95616, USA - - + diff --git a/data_model/clusters/SmokeCOAlarm.xml b/data_model/clusters/SmokeCOAlarm.xml index 0db5c78f4e947f..d3d35f13f15f25 100644 --- a/data_model/clusters/SmokeCOAlarm.xml +++ b/data_model/clusters/SmokeCOAlarm.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -226,7 +231,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Switch.xml b/data_model/clusters/Switch.xml index 30602c35bf794f..e7170049ac051f 100644 --- a/data_model/clusters/Switch.xml +++ b/data_model/clusters/Switch.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/TargetNavigator.xml b/data_model/clusters/TargetNavigator.xml index 343f1427176e41..cfb3a0c17a6f99 100644 --- a/data_model/clusters/TargetNavigator.xml +++ b/data_model/clusters/TargetNavigator.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -95,7 +101,7 @@ Davis, CA 95616, USA - + @@ -106,7 +112,6 @@ Davis, CA 95616, USA - @@ -116,4 +121,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/TemperatureControl.xml b/data_model/clusters/TemperatureControl.xml index f457238bab1d8a..70fc100d83bbab 100644 --- a/data_model/clusters/TemperatureControl.xml +++ b/data_model/clusters/TemperatureControl.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + @@ -73,9 +76,58 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/data_model/clusters/TemperatureMeasurement.xml b/data_model/clusters/TemperatureMeasurement.xml index e1603fd3358bc3..540af82bcedd18 100644 --- a/data_model/clusters/TemperatureMeasurement.xml +++ b/data_model/clusters/TemperatureMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/Thermostat.xml b/data_model/clusters/Thermostat.xml index 400d55a048a116..756e27940c2cba 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,11 @@ Davis, CA 95616, USA + + + + @@ -102,6 +106,17 @@ Davis, CA 95616, USA + + + + + + + + + + + @@ -212,13 +227,36 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + - + + + + @@ -297,7 +335,7 @@ Davis, CA 95616, USA - + @@ -372,6 +410,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -451,6 +497,149 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -823,9 +1012,110 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -837,7 +1127,6 @@ Davis, CA 95616, USA - @@ -858,7 +1147,7 @@ Davis, CA 95616, USA - + @@ -881,9 +1170,8 @@ Davis, CA 95616, USA - - + @@ -909,7 +1197,7 @@ Davis, CA 95616, USA - + @@ -923,17 +1211,79 @@ Davis, CA 95616, USA - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ThermostatUserInterfaceConfiguration.xml b/data_model/clusters/ThermostatUserInterfaceConfiguration.xml index 6c8d1d920e6ef7..63fdba001c67a9 100644 --- a/data_model/clusters/ThermostatUserInterfaceConfiguration.xml +++ b/data_model/clusters/ThermostatUserInterfaceConfiguration.xml @@ -60,6 +60,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/ThreadBorderRouterDiagnostics.xml b/data_model/clusters/ThreadBorderRouterDiagnostics.xml index 29b5da9b8511f0..5527c486a0cc51 100644 --- a/data_model/clusters/ThreadBorderRouterDiagnostics.xml +++ b/data_model/clusters/ThreadBorderRouterDiagnostics.xml @@ -54,19 +54,23 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + - + - @@ -75,12 +79,11 @@ Davis, CA 95616, USA - + - diff --git a/data_model/clusters/TimeSync.xml b/data_model/clusters/TimeSync.xml index 096e0ff2798261..99ec173bc7e6e1 100644 --- a/data_model/clusters/TimeSync.xml +++ b/data_model/clusters/TimeSync.xml @@ -1,7 +1,5 @@ + + + @@ -112,19 +116,19 @@ Davis, CA 95616, USA - + - + - + - + @@ -133,22 +137,22 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -178,9 +182,9 @@ Davis, CA 95616, USA - + - + @@ -192,10 +196,6 @@ Davis, CA 95616, USA - - - - \ No newline at end of file diff --git a/data_model/clusters/ValveConfigurationControl.xml b/data_model/clusters/ValveConfigurationControl.xml index 32620ad9cce97d..548fed7d7357c2 100644 --- a/data_model/clusters/ValveConfigurationControl.xml +++ b/data_model/clusters/ValveConfigurationControl.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -171,7 +176,7 @@ Davis, CA 95616, USA - + @@ -186,7 +191,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/WakeOnLAN.xml b/data_model/clusters/WakeOnLAN.xml index 799c92a03fd9b8..deb5af5a75ac7d 100644 --- a/data_model/clusters/WakeOnLAN.xml +++ b/data_model/clusters/WakeOnLAN.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + diff --git a/data_model/clusters/WaterContentMeasurement.xml b/data_model/clusters/WaterContentMeasurement.xml index 8b1ff6a9a049bc..85d44793c93ae4 100644 --- a/data_model/clusters/WaterContentMeasurement.xml +++ b/data_model/clusters/WaterContentMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/WaterHeaterManagement.xml b/data_model/clusters/WaterHeaterManagement.xml index 073da0094b0b4b..4b6368555bf1d6 100644 --- a/data_model/clusters/WaterHeaterManagement.xml +++ b/data_model/clusters/WaterHeaterManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -129,7 +134,7 @@ Davis, CA 95616, USA - + @@ -151,7 +156,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/WiFiNetworkManagement.xml b/data_model/clusters/WiFiNetworkManagement.xml index 6308eca7e4b184..fbb7a84a4e17b2 100644 --- a/data_model/clusters/WiFiNetworkManagement.xml +++ b/data_model/clusters/WiFiNetworkManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + @@ -69,12 +74,11 @@ Davis, CA 95616, USA - + - diff --git a/data_model/clusters/WindowCovering.xml b/data_model/clusters/WindowCovering.xml index 3ee6d43ded8bce..7b0afd461fcb96 100644 --- a/data_model/clusters/WindowCovering.xml +++ b/data_model/clusters/WindowCovering.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -63,6 +65,9 @@ Davis, CA 95616, USA + + + @@ -608,19 +613,19 @@ Davis, CA 95616, USA - + - + - + - + @@ -633,7 +638,7 @@ Davis, CA 95616, USA - + @@ -655,7 +660,7 @@ Davis, CA 95616, USA - + @@ -668,7 +673,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/bridge-clusters-Actions.xml b/data_model/clusters/bridge-clusters-ActionsCluster.xml similarity index 87% rename from data_model/clusters/bridge-clusters-Actions.xml rename to data_model/clusters/bridge-clusters-ActionsCluster.xml index 51f7ee79bb4bad..e02b12e43d64a4 100644 --- a/data_model/clusters/bridge-clusters-Actions.xml +++ b/data_model/clusters/bridge-clusters-ActionsCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:sectnums: --> + + + @@ -159,7 +164,7 @@ Davis, CA 95616, USA - + @@ -181,7 +186,7 @@ Davis, CA 95616, USA - + @@ -189,32 +194,35 @@ Davis, CA 95616, USA - + + - + - + + - + - + + - + - + - + - + @@ -223,7 +231,7 @@ Davis, CA 95616, USA - + @@ -235,7 +243,7 @@ Davis, CA 95616, USA - + @@ -244,7 +252,7 @@ Davis, CA 95616, USA - + @@ -256,7 +264,7 @@ Davis, CA 95616, USA - + @@ -265,7 +273,7 @@ Davis, CA 95616, USA - + @@ -274,7 +282,7 @@ Davis, CA 95616, USA - + @@ -286,7 +294,7 @@ Davis, CA 95616, USA - + @@ -295,7 +303,7 @@ Davis, CA 95616, USA - + @@ -304,7 +312,7 @@ Davis, CA 95616, USA - + @@ -316,7 +324,7 @@ Davis, CA 95616, USA - + @@ -325,7 +333,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformation.xml b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml similarity index 95% rename from data_model/clusters/bridge-clusters-BridgedDeviceBasicInformation.xml rename to data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 5c4bd86b9ab7e4..1dd336ef3656a3 100644 --- a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformation.xml +++ b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -54,13 +54,18 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:sectnums: --> - + + + + @@ -129,6 +134,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/energy_management.xml b/data_model/clusters/energy_management.xml index 792560796cdd4d..93858d1d1b3c89 100644 --- a/data_model/clusters/energy_management.xml +++ b/data_model/clusters/energy_management.xml @@ -54,5 +54,7 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:toc: --> \ No newline at end of file diff --git a/data_model/clusters/network_infrastructure.xml b/data_model/clusters/network_infrastructure.xml index 181ee350003454..7e75cc0af8229f 100644 --- a/data_model/clusters/network_infrastructure.xml +++ b/data_model/clusters/network_infrastructure.xml @@ -59,4 +59,4 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - \ No newline at end of file + diff --git a/data_model/device_types/BaseDeviceType.xml b/data_model/device_types/BaseDeviceType.xml index a92816ac49d6e1..22cec956aa6061 100644 --- a/data_model/device_types/BaseDeviceType.xml +++ b/data_model/device_types/BaseDeviceType.xml @@ -62,23 +62,4 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/Cooktop.xml b/data_model/device_types/Cooktop.xml index 233c72ed37590a..ea94653008d25a 100644 --- a/data_model/device_types/Cooktop.xml +++ b/data_model/device_types/Cooktop.xml @@ -71,9 +71,6 @@ Davis, CA 95616, USA - - - diff --git a/data_model/clusters/Timer.xml b/data_model/device_types/DeviceEnergyManagement.xml similarity index 55% rename from data_model/clusters/Timer.xml rename to data_model/device_types/DeviceEnergyManagement.xml index ad0d864f016e92..9d993a9454ea15 100644 --- a/data_model/clusters/Timer.xml +++ b/data_model/device_types/DeviceEnergyManagement.xml @@ -55,77 +55,17 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/data_model/device_types/EVSE.xml b/data_model/device_types/EVSE.xml index f15b1db770b454..9e6ce7be28f301 100644 --- a/data_model/device_types/EVSE.xml +++ b/data_model/device_types/EVSE.xml @@ -65,28 +65,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - diff --git a/data_model/device_types/Thermostat.xml b/data_model/device_types/Thermostat.xml index fc154468e97c5f..cbdedb7c039ed5 100644 --- a/data_model/device_types/Thermostat.xml +++ b/data_model/device_types/Thermostat.xml @@ -82,13 +82,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/scraper_version b/data_model/scraper_version index 0495c4a88caed0..e8ea05db81420d 100644 --- a/data_model/scraper_version +++ b/data_model/scraper_version @@ -1 +1 @@ -1.2.3 +1.2.4 diff --git a/data_model/spec_sha b/data_model/spec_sha index ec683a1872fc3e..97f7f06deb9fe9 100644 --- a/data_model/spec_sha +++ b/data_model/spec_sha @@ -1 +1 @@ -72ce960f71810d6ca96125aea54e4fb0a9631e34 +b0310bae0264a29665f23a8f3d4dc4f742be6075 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 62dc0d7d84c3fa..5a7b510b05b0c8 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 @@ -4455,6 +4455,40 @@ provisional cluster EnergyEvse = 153 { timed command ClearTargets(): DefaultSuccess = 7; } +/** This cluster provides an interface to specify preferences for how devices should consume energy. */ +provisional cluster EnergyPreference = 155 { + revision 1; + + enum EnergyPriorityEnum : enum8 { + kComfort = 0; + kSpeed = 1; + kEfficiency = 2; + kWaterConsumption = 3; + } + + bitmap Feature : bitmap32 { + kEnergyBalance = 0x1; + kLowPowerModeSensitivity = 0x2; + } + + struct BalanceStruct { + percent step = 0; + optional char_string<64> label = 1; + } + + readonly attribute optional BalanceStruct energyBalances[] = 0; + attribute optional int8u currentEnergyBalance = 1; + readonly attribute optional EnergyPriorityEnum energyPriorities[] = 2; + readonly attribute optional BalanceStruct lowPowerModeSensitivities[] = 3; + attribute optional int8u currentLowPowerModeSensitivity = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ provisional cluster PowerTopology = 156 { revision 1; @@ -8361,6 +8395,20 @@ endpoint 1 { handle command ClearTargets; } + server cluster EnergyPreference { + callback attribute energyBalances; + ram attribute currentEnergyBalance; + callback attribute energyPriorities; + callback attribute lowPowerModeSensitivities; + ram attribute currentLowPowerModeSensitivity; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + } + server cluster PowerTopology { callback attribute availableEndpoints; callback attribute activeEndpoints; 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 0a2a3faf1b37e8..21bcfee37b5e0d 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 @@ -14692,6 +14692,192 @@ } ] }, + { + "name": "Energy Preference", + "code": 155, + "mfgCode": null, + "define": "ENERGY_PREFERENCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "EnergyBalances", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "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", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "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, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, { "name": "Window Covering", "code": 258, diff --git a/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp b/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp new file mode 100644 index 00000000000000..cd9b47dd7979e6 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp @@ -0,0 +1,137 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +using namespace chip; +using namespace chip::app::Clusters::EnergyPreference; +using namespace chip::app::Clusters::EnergyPreference::Structs; + +static BalanceStruct::Type gsEnergyBalances[] = { + { .step = 0, .label = Optional("Efficient"_span) }, + { .step = 50, .label = Optional() }, + { .step = 100, .label = Optional("Comfort"_span) }, +}; + +static BalanceStruct::Type gsPowerBalances[] = { + { .step = 0, .label = Optional("1 Minute"_span) }, + { .step = 12, .label = Optional("5 Minutes"_span) }, + { .step = 24, .label = Optional("10 Minutes"_span) }, + { .step = 36, .label = Optional("15 Minutes"_span) }, + { .step = 48, .label = Optional("20 Minutes"_span) }, + { .step = 60, .label = Optional("25 Minutes"_span) }, + { .step = 70, .label = Optional("30 Minutes"_span) }, + { .step = 80, .label = Optional("60 Minutes"_span) }, + { .step = 90, .label = Optional("120 Minutes"_span) }, + { .step = 100, .label = Optional("Never"_span) }, +}; + +// assumes it'll be the only delegate for it's lifetime. +struct EPrefDelegate : public Delegate +{ + EPrefDelegate(); + virtual ~EPrefDelegate(); + + CHIP_ERROR GetEnergyBalanceAtIndex(chip::EndpointId aEndpoint, size_t aIndex, chip::Percent & aOutStep, + chip::Optional & aOutLabel) override; + CHIP_ERROR GetEnergyPriorityAtIndex(chip::EndpointId aEndpoint, size_t aIndex, EnergyPriorityEnum & priority) override; + CHIP_ERROR GetLowPowerModeSensitivityAtIndex(chip::EndpointId aEndpoint, size_t aIndex, chip::Percent & aOutStep, + chip::Optional & aOutLabel) override; + + size_t GetNumEnergyBalances(chip::EndpointId aEndpoint) override; + size_t GetNumLowPowerModeSensitivities(chip::EndpointId aEndpoint) override; +}; + +EPrefDelegate::EPrefDelegate() : Delegate() +{ + VerifyOrDie(GetDelegate() == nullptr); + SetDelegate(this); +} + +EPrefDelegate::~EPrefDelegate() +{ + VerifyOrDie(GetDelegate() == this); + SetDelegate(nullptr); +} + +size_t EPrefDelegate::GetNumEnergyBalances(chip::EndpointId aEndpoint) +{ + return (ArraySize(gsEnergyBalances)); +} + +size_t EPrefDelegate::GetNumLowPowerModeSensitivities(chip::EndpointId aEndpoint) +{ + return (ArraySize(gsEnergyBalances)); +} + +CHIP_ERROR +EPrefDelegate::GetEnergyBalanceAtIndex(chip::EndpointId aEndpoint, size_t aIndex, chip::Percent & aOutStep, + chip::Optional & aOutLabel) +{ + if (aIndex < GetNumEnergyBalances(aEndpoint)) + { + aOutStep = gsEnergyBalances[aIndex].step; + if (gsEnergyBalances[aIndex].label.HasValue()) + { + chip::CopyCharSpanToMutableCharSpan(gsEnergyBalances[aIndex].label.Value(), aOutLabel.Value()); + } + else + { + aOutLabel.ClearValue(); + } + return CHIP_NO_ERROR; + } + return CHIP_ERROR_NOT_FOUND; +} + +CHIP_ERROR +EPrefDelegate::GetEnergyPriorityAtIndex(chip::EndpointId aEndpoint, size_t aIndex, EnergyPriorityEnum & priority) +{ + static EnergyPriorityEnum priorities[] = { EnergyPriorityEnum::kEfficiency, EnergyPriorityEnum::kComfort }; + + if (aIndex < ArraySize(priorities)) + { + priority = priorities[aIndex]; + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_NOT_FOUND; +} + +CHIP_ERROR +EPrefDelegate::GetLowPowerModeSensitivityAtIndex(chip::EndpointId aEndpoint, size_t aIndex, chip::Percent & aOutStep, + chip::Optional & aOutLabel) +{ + if (aIndex < GetNumLowPowerModeSensitivities(aEndpoint)) + { + aOutStep = gsPowerBalances[aIndex].step; + if (gsPowerBalances[aIndex].label.HasValue()) + { + chip::CopyCharSpanToMutableCharSpan(gsPowerBalances[aIndex].label.Value(), aOutLabel.Value()); + } + else + { + aOutLabel.ClearValue(); + } + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_NOT_FOUND; +} + +static EPrefDelegate gsDelegate; diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake index 0d8b99c117716e..c4572063508ac0 100755 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -158,6 +158,7 @@ list( ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/device-energy-management-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp + ${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-washer-controls-delegate-impl.cpp diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 238f0e899c340d..63851b1deeb611 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -96,8 +96,11 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/valve-configuration-and-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/dishwasher-alarm-server" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-dryer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/energy-preference-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/electrical-energy-measurement-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/electrical-power-measurement-server" ) diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 998f98a19cd3de..3d52ef748de90d 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -40,6 +40,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/electrical-energy-measurement-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/electrical-power-measurement-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt index 0662ec08dc2146..3ef61298930268 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt @@ -17,6 +17,7 @@ import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -138,7 +139,13 @@ class BasicClientFragment : Fragment() { val attributeId = BasicInformation.Attribute.valueOf(attributeName).id val devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } ChipClient.getDeviceController(requireContext()) .readPath( @@ -181,7 +188,13 @@ class BasicClientFragment : Fragment() { private suspend fun sendWriteAttribute(attribute: BasicInformation.Attribute, tlv: ByteArray) { val clusterId = BasicInformation.ID val devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } ChipClient.getDeviceController(requireContext()) .write( @@ -191,8 +204,8 @@ class BasicClientFragment : Fragment() { Log.e(TAG, "Write ${attribute.name} failure", ex) } - override fun onResponse(attributePath: ChipAttributePath?) { - showMessage("Write ${attribute.name} success") + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + showMessage("Write ${attribute.name} response: $status") } }, devicePtr, diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/GroupSettingFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/GroupSettingFragment.kt index 8943801c080c80..bbaacbd3c997ba 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/GroupSettingFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/GroupSettingFragment.kt @@ -271,11 +271,16 @@ class GroupSettingFragment : Fragment() { private suspend fun sendKeySetWrite( groupKeySetStruct: GroupKeyManagementClusterGroupKeySetStruct ) { - val cluster = - ChipClusters.GroupKeyManagementCluster( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), - 0 - ) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + val cluster = ChipClusters.GroupKeyManagementCluster(devicePtr, 0) + cluster.keySetWrite( object : ChipClusters.DefaultClusterCallback { override fun onError(e: Exception?) { @@ -311,11 +316,15 @@ class GroupSettingFragment : Fragment() { } private suspend fun writeGroupKeyMap(groupId: UInt, groupKeySetId: UInt) { - val cluster = - ChipClusters.GroupKeyManagementCluster( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), - 0 - ) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + val cluster = ChipClusters.GroupKeyManagementCluster(devicePtr, 0) cluster.writeGroupKeyMapAttribute( object : ChipClusters.DefaultClusterCallback { override fun onError(e: Exception?) { @@ -356,11 +365,16 @@ class GroupSettingFragment : Fragment() { } private suspend fun sendAddGroup(groupId: UInt, groupName: String) { - val cluster = - ChipClusters.GroupsCluster( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), - 0 - ) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + val cluster = ChipClusters.GroupsCluster(devicePtr, 0) + cluster.addGroup( object : ChipClusters.GroupsCluster.AddGroupResponseCallback { override fun onError(e: Exception?) { @@ -379,11 +393,15 @@ class GroupSettingFragment : Fragment() { } private suspend fun readAccessControl() { - val cluster = - ChipClusters.AccessControlCluster( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), - 0 - ) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + val cluster = ChipClusters.AccessControlCluster(devicePtr, 0) cluster.readAclAttribute( object : ChipClusters.AccessControlCluster.AclAttributeCallback { override fun onError(e: Exception?) { @@ -437,12 +455,16 @@ class GroupSettingFragment : Fragment() { groupId: UInt, privilege: UInt ) { + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } // If GroupID is already added to AccessControl, do not add it. - val cluster = - ChipClusters.AccessControlCluster( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), - 0 - ) + val cluster = ChipClusters.AccessControlCluster(devicePtr, 0) val sendEntry = ArrayList() for (entry in value) { if ( diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt index a82f0ee60ccf35..08443d6ffb4ffc 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt @@ -121,8 +121,16 @@ class MultiAdminClientFragment : Fragment() { private suspend fun sendBasicCommissioningCommandClick() { val testDuration = binding.timeoutEd.text.toString().toInt() + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } deviceController.openPairingWindowCallback( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, testDuration, object : OpenCommissioningCallback { override fun onError(status: Int, deviceId: Long) { @@ -140,7 +148,13 @@ class MultiAdminClientFragment : Fragment() { val testDuration = binding.timeoutEd.text.toString().toInt() val testIteration = 1000 val devicePointer = - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } var setupPinCode: Long? = null if (!binding.setupPinCodeEd.text.toString().isEmpty()) { @@ -181,6 +195,14 @@ class MultiAdminClientFragment : Fragment() { null ) + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } deviceController.invoke( object : InvokeCallback { override fun onError(ex: Exception?) { @@ -193,7 +215,7 @@ class MultiAdminClientFragment : Fragment() { showMessage("Revoke Commissioning success") } }, - getConnectedDevicePointer(), + devicePointer, invokeElement, timedInvokeTimeout, 0 @@ -208,6 +230,16 @@ class MultiAdminClientFragment : Fragment() { val attributeId = attribute.id val attributeName = attribute.name val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) + + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + deviceController.readAttributePath( object : ReportCallback { override fun onReport(nodeState: NodeState?) { @@ -230,16 +262,12 @@ class MultiAdminClientFragment : Fragment() { showMessage("read $attributeName - error : ${e?.message}") } }, - getConnectedDevicePointer(), + devicePointer, listOf(attributePath), 0 ) } - private suspend fun getConnectedDevicePointer(): Long { - return ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) - } - private fun showMessage(msg: String) { requireActivity().runOnUiThread { binding.multiAdminClusterCommandStatus.text = msg } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt index 7994deb2f07a13..d4b55194147fca 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OnOffClientFragment.kt @@ -105,6 +105,15 @@ class OnOffClientFragment : Fragment() { val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + ChipClient.getDeviceController(requireContext()) .readPath( object : ReportCallback { @@ -128,7 +137,7 @@ class OnOffClientFragment : Fragment() { showMessage("On/Off attribute value: $value") } }, - getConnectedDevicePointer(), + devicePointer, listOf(attributePath), null, false, @@ -181,6 +190,15 @@ class OnOffClientFragment : Fragment() { ) } + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + deviceController.subscribeToPath( subscriptionEstablishedCallback, resubscriptionAttemptCallback, @@ -211,7 +229,7 @@ class OnOffClientFragment : Fragment() { showReportMessage(message) } }, - getConnectedDevicePointer(), + devicePointer, listOf(attributePath), null, minInterval, @@ -265,6 +283,15 @@ class OnOffClientFragment : Fragment() { null ) + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + deviceController.invoke( object : InvokeCallback { override fun onError(ex: Exception?) { @@ -277,7 +304,7 @@ class OnOffClientFragment : Fragment() { showMessage("MoveToLevel command success") } }, - getConnectedDevicePointer(), + devicePointer, invokeElement, 0, 0 @@ -298,6 +325,15 @@ class OnOffClientFragment : Fragment() { null ) + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + deviceController.invoke( object : InvokeCallback { override fun onError(ex: Exception?) { @@ -310,17 +346,13 @@ class OnOffClientFragment : Fragment() { showMessage("${commandId.name} command success") } }, - getConnectedDevicePointer(), + devicePointer, invokeElement, 0, 0 ) } - private suspend fun getConnectedDevicePointer(): Long { - return ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) - } - private fun showMessage(msg: String) { requireActivity().runOnUiThread { binding.commandStatusTv.text = msg } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt index 0314f9d82e652c..1fd8db6c97a13b 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt @@ -100,7 +100,13 @@ class OpCredClientFragment : Fragment() { val attributeId = attribute.id val devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } ChipClient.getDeviceController(requireContext()) .readPath( @@ -137,7 +143,13 @@ class OpCredClientFragment : Fragment() { private suspend fun sendRemoveFabricsBtnClick(fabricIndex: UInt) { val devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } // TODO : Need to be implement poj-to-tlv val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt index 87735856fa4844..5d2d62ee76a690 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt @@ -32,6 +32,7 @@ import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -113,6 +114,14 @@ class OtaProviderClientFragment : Fragment() { val attributeId = ClusterIDMapping.AccessControl.Attribute.Acl.id val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } deviceController.readAttributePath( object : ReportCallback { override fun onError( @@ -135,7 +144,7 @@ class OtaProviderClientFragment : Fragment() { requireActivity().runOnUiThread { showAddAccessControlDialog(tlv) } } }, - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, listOf(attributePath), 0 ) @@ -216,6 +225,15 @@ class OtaProviderClientFragment : Fragment() { newEntry.toTlv(AnonymousTag, tlvWriter) tlvWriter.endArray() + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + deviceController.write( object : WriteAttributesCallback { override fun onError(attributePath: ChipAttributePath?, e: Exception?) { @@ -223,12 +241,12 @@ class OtaProviderClientFragment : Fragment() { showMessage("Error : ${e.toString()}") } - override fun onResponse(attributePath: ChipAttributePath?) { + override fun onResponse(attributePath: ChipAttributePath, status: Status) { Log.d(TAG, "onResponse") - showMessage("write Success") + showMessage("$attributePath : Write response: $status") } }, - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, listOf( AttributeWriteRequest.newInstance( 0, @@ -248,6 +266,14 @@ class OtaProviderClientFragment : Fragment() { val clusterId = ClusterIDMapping.OtaSoftwareUpdateRequestor.ID val attributeId = attribute.id val path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } deviceController.readAttributePath( object : ReportCallback { override fun onError( @@ -278,7 +304,7 @@ class OtaProviderClientFragment : Fragment() { showMessage("OtaSoftwareUpdateRequestor ${attribute.name} value: $value") } }, - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, listOf(path), 0 ) @@ -343,6 +369,15 @@ class OtaProviderClientFragment : Fragment() { val writeRequest = AttributeWriteRequest.newInstance(endpoint, clusterId, attributeId, tlv) + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + deviceController.write( object : WriteAttributesCallback { override fun onError(attributePath: ChipAttributePath?, e: Exception?) { @@ -350,12 +385,12 @@ class OtaProviderClientFragment : Fragment() { showMessage("error : ${e.toString()}") } - override fun onResponse(attributePath: ChipAttributePath?) { + override fun onResponse(attributePath: ChipAttributePath, status: Status) { Log.d(TAG, "onResponse") - showMessage("write success") + showMessage("$attributePath : Write response: $status") } }, - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, listOf(writeRequest), 0, 0 @@ -460,11 +495,17 @@ class OtaProviderClientFragment : Fragment() { private suspend fun sendAnnounceOTAProviderBtnClick() { requireActivity().runOnUiThread { updateOTAStatusBtnClick() } + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return + } + val otaRequestCluster = - ChipClusters.OtaSoftwareUpdateRequestorCluster( - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), - OTA_REQUESTER_ENDPOINT_ID - ) + ChipClusters.OtaSoftwareUpdateRequestorCluster(devicePtr, OTA_REQUESTER_ENDPOINT_ID) otaRequestCluster.announceOTAProvider( object : DefaultClusterCallback { override fun onSuccess() { diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt index cad12a5a54bc98..88d9ed63c4f91e 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/SensorClientFragment.kt @@ -155,7 +155,13 @@ class SensorClientFragment : Fragment() { val clusterName = binding.clusterNameSpinner.selectedItem.toString() val clusterId = CLUSTERS[clusterName]!!["clusterId"] as Long val attributeId = CLUSTERS[clusterName]!!["attributeId"] as Long - val device = ChipClient.getConnectedDevicePointer(requireContext(), deviceId) + val device = + try { + ChipClient.getConnectedDevicePointer(requireContext(), deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + return + } val callback = makeReadCallback(clusterName, false) deviceController.readAttributePath( @@ -177,7 +183,13 @@ class SensorClientFragment : Fragment() { val clusterName = binding.clusterNameSpinner.selectedItem.toString() val clusterId = CLUSTERS[clusterName]!!["clusterId"] as Long val attributeId = CLUSTERS[clusterName]!!["attributeId"] as Long - val device = ChipClient.getConnectedDevicePointer(requireContext(), deviceId) + val device = + try { + ChipClient.getConnectedDevicePointer(requireContext(), deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + return + } val callback = makeReadCallback(clusterName, true) deviceController.subscribeToAttributePath( 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 1978951e02e210..5b49a6d9ab05ab 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 @@ -27,6 +27,7 @@ import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.ChipPathId import chip.devicecontroller.model.InvokeElement import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.R import com.google.chip.chiptool.databinding.WildcardFragmentBinding @@ -92,8 +93,8 @@ class WildcardFragment : Fragment() { Log.e(TAG, "Report error for $attributePath: $ex") } - override fun onResponse(attributePath: ChipAttributePath?) { - val text = "$attributePath : Write Success" + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + val text = "$attributePath : Write response: $status" requireActivity().runOnUiThread { binding.outputTv.text = text } } @@ -269,12 +270,18 @@ class WildcardFragment : Fragment() { "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec" ) } - + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + return + } deviceController.subscribeToPath( subscriptionEstablishedCallback, resubscriptionAttemptCallback, reportCallback, - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, attributePath.ifEmpty { null }, eventPath.ifEmpty { null }, minInterval, @@ -287,9 +294,16 @@ class WildcardFragment : Fragment() { } private suspend fun read(isFabricFiltered: Boolean, eventMin: Long?) { + val devicePtr = + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + return + } deviceController.readPath( reportCallback, - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), + devicePtr, attributePath.ifEmpty { null }, eventPath.ifEmpty { null }, isFabricFiltered, @@ -350,10 +364,16 @@ class WildcardFragment : Fragment() { version ) } - + val devicePtr = + try { + addressUpdateFragment.getDevicePointer(requireContext()) + } catch (e: IllegalStateException) { + Log.d(TAG, "getDevicePointer exception", e) + return + } deviceController.write( writeAttributeCallback, - addressUpdateFragment.getDevicePointer(requireContext()), + devicePtr, listOf(writeRequest), timedRequestTimeoutMs, imTimeoutMs @@ -378,9 +398,16 @@ class WildcardFragment : Fragment() { } else { InvokeElement.newInstance(endpointId, clusterId, commandId, null, jsonString) } + val devicePtr = + try { + addressUpdateFragment.getDevicePointer(requireContext()) + } catch (e: IllegalStateException) { + Log.d(TAG, "getDevicePointer exception", e) + return + } deviceController.invoke( invokeCallback, - addressUpdateFragment.getDevicePointer(requireContext()), + devicePtr, invokeElement, timedRequestTimeoutMs, imTimeoutMs @@ -554,7 +581,13 @@ class WildcardFragment : Fragment() { val clusterId = 62L // OperationalCredentials val attributeId = 5L // CurrentFabricIndex val deviceId = addressUpdateFragment.deviceId - val devicePointer = ChipClient.getConnectedDevicePointer(context, deviceId) + val devicePointer = + try { + ChipClient.getConnectedDevicePointer(context, deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + return 0U + } return suspendCoroutine { cont -> deviceController.readAttributePath( object : ReportCallback { diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterDetailFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterDetailFragment.kt index 50c33bd35c60ba..09270003a41a5e 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterDetailFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterDetailFragment.kt @@ -67,7 +67,15 @@ class ClusterDetailFragment : Fragment() { _binding = ClusterDetailFragmentBinding.inflate(inflater, container, false) scope = viewLifecycleOwner.lifecycleScope deviceId = checkNotNull(requireArguments().getLong(DEVICE_ID)) - scope.launch { devicePtr = getConnectedDevicePointer(requireContext(), deviceId) } + scope.launch { + try { + devicePtr = getConnectedDevicePointer(requireContext(), deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("Get DevicePointer fail!") + return@launch + } + } endpointId = checkNotNull(requireArguments().getInt(ENDPOINT_ID_KEY)) historyCommand = requireArguments().getSerializable(HISTORY_COMMAND) as HistoryCommand? deviceController.setCompletionListener(GenericChipDeviceListener()) @@ -199,10 +207,19 @@ class ClusterDetailFragment : Fragment() { private fun castStringToType(data: String, type: Class<*>, underlyingType: Class<*>): Any? { return when (type) { - Int::class.java -> data.toInt() - Boolean::class.java -> data.toBoolean() + Int::class.java, + java.lang.Integer::class.java -> data.toInt() + Boolean::class.java, + java.lang.Boolean::class.java -> data.toBoolean() ByteArray::class.java -> data.encodeToByteArray() - Long::class.java -> data.toLong() + Long::class.java, + java.lang.Long::class.java -> data.toLong() + Short::class.java, + java.lang.Short::class.java -> data.toShort() + Double::class.java, + java.lang.Double::class.java -> data.toDouble() + Float::class.java, + java.lang.Float::class.java -> data.toFloat() Optional::class.java -> if (data.isEmpty()) Optional.empty() else Optional.of(castStringToType(data, underlyingType, underlyingType)!!) diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterInteractionFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterInteractionFragment.kt index d723a93b674f7f..8847da71b87271 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterInteractionFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterInteractionFragment.kt @@ -1,6 +1,7 @@ package com.google.chip.chiptool.clusterclient.clusterinteraction import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -45,7 +46,13 @@ class ClusterInteractionFragment : Fragment() { binding.getEndpointListBtn.setOnClickListener { scope.launch { devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + try { + ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId) + } catch (e: IllegalStateException) { + Log.d(TAG, "getConnectedDevicePointer exception", e) + showMessage("getConnectedDevicePointer fail!") + return@launch + } showMessage("Retrieving endpoints") binding.endpointList.visibility = View.VISIBLE } diff --git a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp index ab0f2ef3b707a1..9d4eda96e98438 100644 --- a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp +++ b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp @@ -91,12 +91,11 @@ CHIP_ERROR RemoveDeviceEndpoint(SubDevice * dev) { if (gSubDevices[index] == dev) { - EndpointId ep = emberAfClearDynamicEndpoint(index); - gSubDevices[index] = NULL; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); // Silence complaints about unused ep when progress logging // disabled. - UNUSED_VAR(ep); + [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); + gSubDevices[index] = NULL; + ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); return CHIP_NO_ERROR; } } diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index 27cdb3c5e2dab5..07db2ba94a534f 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -201,12 +201,11 @@ CHIP_ERROR RemoveDeviceEndpoint(Device * dev) { if (gDevices[index] == dev) { - EndpointId ep = emberAfClearDynamicEndpoint(index); - gDevices[index] = NULL; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); // Silence complaints about unused ep when progress logging // disabled. - UNUSED_VAR(ep); + [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); + gDevices[index] = NULL; + ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); return CHIP_NO_ERROR; } } diff --git a/examples/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp index 80c8b17b7fbed5..c569e7c06e8b45 100644 --- a/examples/bridge-app/linux/main.cpp +++ b/examples/bridge-app/linux/main.cpp @@ -300,12 +300,11 @@ int RemoveDeviceEndpoint(Device * dev) { // Todo: Update this to schedule the work rather than use this lock DeviceLayer::StackLock lock; - EndpointId ep = emberAfClearDynamicEndpoint(index); - gDevices[index] = nullptr; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); // Silence complaints about unused ep when progress logging // disabled. - UNUSED_VAR(ep); + [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); + gDevices[index] = nullptr; + ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); return index; } index++; diff --git a/examples/bridge-app/telink/src/AppTask.cpp b/examples/bridge-app/telink/src/AppTask.cpp index d21897bd2d36b6..72a997c91e9511 100644 --- a/examples/bridge-app/telink/src/AppTask.cpp +++ b/examples/bridge-app/telink/src/AppTask.cpp @@ -224,12 +224,11 @@ CHIP_ERROR RemoveDeviceEndpoint(Device * dev) { if (gDevices[index] == dev) { - EndpointId ep = emberAfClearDynamicEndpoint(index); - gDevices[index] = NULL; - ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); // Silence complaints about unused ep when progress logging // disabled. - UNUSED_VAR(ep); + [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); + gDevices[index] = NULL; + ChipLogProgress(DeviceLayer, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); return CHIP_NO_ERROR; } } diff --git a/examples/chef/common/chef-air-quality.h b/examples/chef/common/chef-air-quality.h index 2eaf3ef28fdf66..e7589488d41d74 100644 --- a/examples/chef/common/chef-air-quality.h +++ b/examples/chef/common/chef-air-quality.h @@ -22,10 +22,10 @@ #include #ifdef MATTER_DM_PLUGIN_AIR_QUALITY_SERVER -Protocols::InteractionModel::Status chefAirQualityWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer); -Protocols::InteractionModel::Status chefAirQualityReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, - uint16_t maxReadLength); +chip::Protocols::InteractionModel::Status chefAirQualityWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer); +chip::Protocols::InteractionModel::Status chefAirQualityReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength); #endif diff --git a/examples/chef/common/chef-concentration-measurement.h b/examples/chef/common/chef-concentration-measurement.h index 9b8fc571872c6b..887df7d943ee08 100644 --- a/examples/chef/common/chef-concentration-measurement.h +++ b/examples/chef/common/chef-concentration-measurement.h @@ -31,10 +31,11 @@ defined(MATTER_DM_PLUGIN_PM10_CONCENTRATION_MEASUREMENT_SERVER) || \ defined(MATTER_DM_PLUGIN_TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_SERVER) || \ defined(MATTER_DM_PLUGIN_RADON_CONCENTRATION_MEASUREMENT_SERVER) -Protocols::InteractionModel::Status chefConcentrationMeasurementWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer); -Protocols::InteractionModel::Status chefConcentrationMeasurementReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer, uint16_t maxReadLength); +chip::Protocols::InteractionModel::Status +chefConcentrationMeasurementWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer); +chip::Protocols::InteractionModel::Status +chefConcentrationMeasurementReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, + uint16_t maxReadLength); #endif diff --git a/examples/chip-tool/commands/common/DeviceScanner.cpp b/examples/chip-tool/commands/common/DeviceScanner.cpp index 29d31c1fc80565..35d74bd06c844f 100644 --- a/examples/chip-tool/commands/common/DeviceScanner.cpp +++ b/examples/chip-tool/commands/common/DeviceScanner.cpp @@ -218,7 +218,7 @@ void DeviceScanner::Log() const auto resultsCount = mDiscoveredResults.size(); VerifyOrReturn(resultsCount > 0, ChipLogProgress(chipTool, "No device discovered.")); - uint16_t index = 0; + [[maybe_unused]] uint16_t index = 0; for (auto & instance : mDiscoveredResults) { ChipLogProgress(chipTool, "Instance Name: %s ", instance.first.c_str()); diff --git a/examples/chip-tool/commands/discover/DiscoverCommissionersCommand.cpp b/examples/chip-tool/commands/discover/DiscoverCommissionersCommand.cpp index 0d1c9a032de02c..57c7574c4ea2e3 100644 --- a/examples/chip-tool/commands/discover/DiscoverCommissionersCommand.cpp +++ b/examples/chip-tool/commands/discover/DiscoverCommissionersCommand.cpp @@ -29,7 +29,7 @@ CHIP_ERROR DiscoverCommissionersCommand::RunCommand() void DiscoverCommissionersCommand::Shutdown() { - int commissionerCount = 0; + [[maybe_unused]] int commissionerCount = 0; for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; i++) { const Dnssd::DiscoveredNodeData * commissioner = mCommissionableNodeController.GetDiscoveredCommissioner(i); diff --git a/examples/common/websocket-server/WebSocketServer.cpp b/examples/common/websocket-server/WebSocketServer.cpp index 623dda3dc47527..2dba035601ea0e 100644 --- a/examples/common/websocket-server/WebSocketServer.cpp +++ b/examples/common/websocket-server/WebSocketServer.cpp @@ -24,9 +24,9 @@ #include #include -constexpr uint16_t kDefaultWebSocketServerPort = 9002; -constexpr uint16_t kMaxMessageBufferLen = 8192; -constexpr char kWebSocketServerReadyMessage[] = "== WebSocket Server Ready"; +constexpr uint16_t kDefaultWebSocketServerPort = 9002; +constexpr uint16_t kMaxMessageBufferLen = 8192; +[[maybe_unused]] constexpr char kWebSocketServerReadyMessage[] = "== WebSocket Server Ready"; namespace { lws * gWebSocketInstance = nullptr; diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn index cc87b4fc1532d6..c9b50a84ceb770 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn @@ -19,6 +19,7 @@ import("//build_overrides/openthread.gni") import("${k32w0_sdk_build_root}/k32w0_executable.gni") import("${k32w0_sdk_build_root}/k32w0_sdk.gni") +import("${chip_root}/src/app/icd/icd.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/platform/device.gni") @@ -75,6 +76,8 @@ k32w0_sdk("sdk") { k32w0_executable("contact_sensor_app") { output_name = "chip-k32w0x-contact-example" + defines = [] + sources = [ "${k32w0_platform_dir}/util/LEDWidget.cpp", "${k32w0_platform_dir}/util/include/LEDWidget.h", @@ -93,13 +96,12 @@ k32w0_executable("contact_sensor_app") { "${k32w0_platform_dir}/common/CustomFactoryDataProvider.h", ] - defines = [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ] + defines += [ "CHIP_DEVICE_CONFIG_USE_CUSTOM_PROVIDER=1" ] } deps = [ ":sdk", "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/contact-sensor-app/contact-sensor-common", "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", "${chip_root}/src/platform:syscalls_stub", @@ -119,6 +121,15 @@ k32w0_executable("contact_sensor_app") { ] } + #lit and sit are using different zap files + if (chip_enable_icd_lit) { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-lit/" ] + + defines += [ "CHIP_ENABLE_LIT=1" ] + } else { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-sit/" ] + } + cflags = [ "-Wconversion" ] output_dir = root_out_dir diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md index 27ae15b672eb05..c325895886a093 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md @@ -22,6 +22,7 @@ network. - [Building](#building) - [Overwrite board config files](#overwrite-board-config-files) - [Known issues building](#known-issues-building) +- [Long Idle Time ICD Support](#long-idle-time-icd-support) - [Manufacturing data](#manufacturing-data) - [Flashing and debugging](#flashing-and-debugging) - [Pigweed Tokenizer](#pigweed-tokenizer) @@ -95,6 +96,11 @@ be discoverable over Bluetooth LE. For security reasons, you must start Bluetooth LE advertising manually after powering up the device by pressing Button USERINTERFACE. +## LIT ICD Active Mode + +If the device is acting as a LIT ICD and it's already commissioned, then Button +USERINTERFACE can be pressed for forcing the switch to Active Mode. + ### Bluetooth LE Rendezvous In this example, the commissioning procedure (called rendezvous) is done over @@ -258,6 +264,42 @@ pycryptodome 3.9.8 The resulting output file can be found in out/debug/chip-k32w0x-contact-example. +## Long Idle Time ICD Support + +By default, contact-sensor is compiled as SIT ICD (Short Idle Time +Intermittently Connected Device) - see rules from k32w0_sdk.gni: + +``` +chip_ot_idle_interval_ms = 2000 # 2s Idle Intervals +chip_ot_active_interval_ms = 500 # 500ms Active Intervals + +nxp_idle_mode_duration_s = 600 # 10min Idle Mode Interval +nxp_active_mode_duration_ms = 10000 # 10s Active Mode Interval +nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold +nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric +``` + +If LIT ICD support is needed then `chip_enable_icd_lit=true` must be specified +as gn argument and the above parameters can be modified to comply with LIT +requirements (e.g.: LIT devices must configure +`chip_ot_idle_interval_ms > 15000`). Example LIT configuration: + +``` +chip_ot_idle_interval_ms = 15000 # 15s Idle Intervals +chip_ot_active_interval_ms = 500 # 500ms Active Intervals + +nxp_idle_mode_duration_s = 3600 # 60min Idle Mode Interval +nxp_active_mode_duration_ms = 0 # 0 Active Mode Interval +nxp_active_mode_threshold_ms = 30000 # 30s Active Mode Threshold +``` + +ICD parameters that may be disabled once LIT functionality is enabled: + +``` +chip_persist_subscriptions: try to re-establish subscriptions from the server side after reboot +chip_subscription_timeout_resumption: same as above but retries are using a Fibonacci backoff +``` + ### Overwrite board config files The example uses template/reference board configuration files. diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni b/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni index 02a388daab9e1a..6e931d00452fcd 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni @@ -24,5 +24,7 @@ chip_stack_lock_tracking = "fatal" chip_enable_ble = true chip_enable_icd_server = true +chip_enable_icd_lit = false +icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp index a46ea5db28df64..17aea9d5897907 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -71,6 +71,9 @@ static LEDWidget sContactSensorLED; static bool sIsThreadProvisioned = false; static bool sHaveBLEConnections = false; +#if CHIP_ENABLE_LIT +static bool sIsDeviceCommissioned = false; +#endif static uint32_t eventMask = 0; @@ -448,6 +451,12 @@ void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { button_event.Handler = ResetActionEventHandler; } +#endif +#if CHIP_ENABLE_LIT + if (button_action == USER_ACTIVE_MODE_TRIGGER_PUSH) + { + button_event.Handler = UserActiveModeHandler; + } #endif } @@ -486,6 +495,16 @@ void AppTask::HandleKeyboard(void) #if (defined OM15082) ButtonEventHandler(RESET_BUTTON, RESET_BUTTON_PUSH); break; +#elif CHIP_ENABLE_LIT + if (sIsDeviceCommissioned) + { + ButtonEventHandler(BLE_BUTTON, USER_ACTIVE_MODE_TRIGGER_PUSH); + } + else + { + ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); + } + break; #else ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); break; @@ -497,7 +516,15 @@ void AppTask::HandleKeyboard(void) ButtonEventHandler(OTA_BUTTON, OTA_BUTTON_PUSH); break; case gKBD_EventPB4_c: - ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); +#if CHIP_ENABLE_LIT + if (sIsDeviceCommissioned) + { + ButtonEventHandler(BLE_BUTTON, USER_ACTIVE_MODE_TRIGGER_PUSH); + } + else +#endif + + ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); break; #if !(defined OM15082) case gKBD_EventLongPB1_c: @@ -694,6 +721,28 @@ void AppTask::BleStartAdvertising(intptr_t arg) } } +#if CHIP_ENABLE_LIT +void AppTask::UserActiveModeHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + + if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) + return; + + if (sAppTask.mFunction != Function::kNoneSelected) + { + K32W_LOG("Another function is scheduled. Could not request ICD Active Mode!"); + return; + } + PlatformMgr().ScheduleWork(AppTask::UserActiveModeTrigger, 0); +} + +void AppTask::UserActiveModeTrigger(intptr_t arg) +{ + ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); +} +#endif + void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) { if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) @@ -707,6 +756,12 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) sIsThreadProvisioned = FALSE; } } +#if CHIP_ENABLE_LIT + else if (event->Type == DeviceEventType::kCommissioningComplete) + { + sIsDeviceCommissioned = TRUE; + } +#endif #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR if (event->Type == DeviceEventType::kDnssdInitialized) diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h index 867a496de1e56d..c3203d78eb543e 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h @@ -85,6 +85,10 @@ class AppTask static void ContactActionEventHandler(void * aGenericEvent); static void ResetActionEventHandler(void * aGenericEvent); static void InstallEventHandler(void * aGenericEvent); +#if CHIP_ENABLE_LIT + static void UserActiveModeHandler(void * aGenericEvent); + static void UserActiveModeTrigger(intptr_t arg); +#endif static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); static void TimerEventHandler(TimerHandle_t xTimer); diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h index 5343e1e56a3af9..61b9866055c1b5 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h @@ -31,6 +31,7 @@ #define CONTACT_SENSOR_BUTTON_PUSH 2 #define OTA_BUTTON_PUSH 3 #define BLE_BUTTON_PUSH 4 +#define USER_ACTIVE_MODE_TRIGGER_PUSH 5 #define APP_BUTTON_PUSH 1 diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn index ed49c7bdd4f7a3..e44c1a9c71bd40 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/BUILD.gn @@ -23,6 +23,7 @@ import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +import("${chip_root}/src/app/icd/icd.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/platform/device.gni") @@ -74,6 +75,8 @@ k32w1_sdk("sdk") { k32w1_executable("contact_sensor_app") { output_name = "chip-k32w1-contact-example" + defines = [] + sources = [ "${k32w1_platform_dir}/util/LEDWidget.cpp", "${k32w1_platform_dir}/util/include/LEDWidget.h", @@ -89,7 +92,6 @@ k32w1_executable("contact_sensor_app") { deps = [ ":sdk", "${chip_root}/examples/common/QRCode", - "${chip_root}/examples/contact-sensor-app/nxp/zap", "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", "${chip_root}/src/platform:syscalls_stub", @@ -109,6 +111,15 @@ k32w1_executable("contact_sensor_app") { ] } + #lit and sit are using different zap files + if (chip_enable_icd_lit) { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-lit/" ] + + defines += [ "CHIP_ENABLE_LIT=1" ] + } else { + deps += [ "${chip_root}/examples/contact-sensor-app/nxp/zap-sit/" ] + } + cflags = [ "-Wconversion" ] output_dir = root_out_dir diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md b/examples/contact-sensor-app/nxp/k32w/k32w1/README.md index 28983f45c89578..ff3496d7b862ac 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/README.md +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/README.md @@ -19,6 +19,7 @@ into an existing Matter network and can be controlled by this network. - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - [Device UI](#device-ui) - [Building](#building) +- [Long Idle Time ICD Support](#long-idle-time-icd-support) - [Manufacturing data](#manufacturing-data) - [Flashing](#flashing) - [Flashing the NBU image](#flashing-the-nbu-image) @@ -100,13 +101,15 @@ will not work. **RGB LED** shows the state of the simulated contact sensor. when the LED is lit, the sensor is contacted, when not lit, the sensor is non-contacted. -**Button SW2** can be used to start BLE advertising. A SHORT press of the button -will enable Bluetooth LE advertising for a predefined period of time. A LONG -Press Button SW2 initiates a factory reset. After an initial period of 3 -seconds, LED 2 and RGB LED will flash in unison to signal the pending reset. -After 6 seconds will cause the device to reset its persistent configuration and -initiate a reboot. The reset action can be cancelled by press SW2 button at any -point before the 6 second limit. +**Button SW2**. SHORT press function is overloaded depending on the device type +and commissioning state. If the device is not commissioned, a SHORT press of the +button will enable Bluetooth LE advertising for a predefined period of time. If +the device is commissioned and is acting as a LIT ICD then a SHORT press of the +button will enable Active Mode. A LONG Press of Button SW2 initiates a factory +reset. After an initial period of 3 seconds, LED 2 and RGB LED will flash in +unison to signal the pending reset. After 6 seconds will cause the device to +reset its persistent configuration and initiate a reboot. The reset action can +be cancelled by press SW2 button at any point before the 6 second limit. **Button SW3** can be used to change the state of the simulated contact sensor. The button behaves as a toggle, swapping the state every time it is short @@ -141,6 +144,43 @@ After a successful build, the `elf` and `srec` files are found in `out/debug/` - build, the `elf` and `srec` files are found in `out/debug/` - `see the files prefixed with chip-k32w1-contact-example`. +## Long Idle Time ICD Support + +By default, contact-sensor is compiled as SIT ICD (Short Idle Time +Intermittently Connected Device) - see rules from k32w1_sdk.gni: + +``` +chip_ot_idle_interval_ms = 2000 # 2s Idle Intervals +chip_ot_active_interval_ms = 500 # 500ms Active Intervals + +nxp_idle_mode_duration_s = 600 # 10min Idle Mode Interval +nxp_active_mode_duration_ms = 10000 # 10s Active Mode Interval +nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold +nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric +``` + +If LIT ICD support is needed then `chip_enable_icd_lit=true` must be specified +as gn argument and the above parameters can be modified to comply with LIT +requirements (e.g.: LIT devices must configure +`chip_ot_idle_interval_ms > 15000`). Example LIT configuration: + +``` +chip_ot_idle_interval_ms = 15000 # 15s Idle Intervals +chip_ot_active_interval_ms = 500 # 500ms Active Intervals + +nxp_idle_mode_duration_s = 3600 # 60min Idle Mode Interval +nxp_active_mode_duration_ms = 0 # 0 Active Mode Interval +nxp_active_mode_threshold_ms = 30000 # 30s Active Mode Threshold +``` + +ICD parameters that may be disabled once LIT functionality is enabled: + +``` +chip_persist_subscriptions: try once to re-establish subscriptions from the server side after reboot +chip_subscription_timeout_resumption: same as above + try to re-establish timeout out subscriptions +using Fibonacci backoff for retries pacing. +``` + ## Manufacturing data Use `chip_with_factory_data=1` in the gn build command to enable factory data. diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni index 18c41cb457bc86..b25f000cd85d1c 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/args.gni @@ -24,5 +24,7 @@ chip_stack_lock_tracking = "fatal" chip_enable_ble = true chip_enable_icd_server = true +chip_enable_icd_lit = false +icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h index 8846799ed6edc9..808b70aad0cab7 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h @@ -132,11 +132,11 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "03-2022-te8" +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp index 10039bb8c9270e..3e9380254bd428 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/AppTask.cpp @@ -78,6 +78,9 @@ static LEDWidget sContactSensorLED; static bool sIsThreadProvisioned = false; static bool sHaveBLEConnections = false; +#if CHIP_ENABLE_LIT +static bool sIsDeviceCommissioned = false; +#endif static uint32_t eventMask = 0; @@ -398,6 +401,12 @@ void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { button_event.Handler = ResetActionEventHandler; } +#if CHIP_ENABLE_LIT + else if (button_action == USER_ACTIVE_MODE_TRIGGER_PUSH) + { + button_event.Handler = UserActiveModeHandler; + } +#endif } sAppTask.PostEvent(&button_event); @@ -418,6 +427,12 @@ button_status_t AppTask::KBD_Callback(void * buttonHandle, button_callback_messa { ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); } +#if CHIP_ENABLE_LIT + else if (sIsDeviceCommissioned) + { + ButtonEventHandler(BLE_BUTTON, USER_ACTIVE_MODE_TRIGGER_PUSH); + } +#endif else { ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); @@ -616,6 +631,28 @@ void AppTask::BleStartAdvertising(intptr_t arg) } } +#if CHIP_ENABLE_LIT +void AppTask::UserActiveModeHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + + if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) + return; + + if (sAppTask.mFunction != Function::kNoneSelected) + { + K32W_LOG("Another function is scheduled. Could not request ICD Active Mode!"); + return; + } + PlatformMgr().ScheduleWork(AppTask::UserActiveModeTrigger, 0); +} + +void AppTask::UserActiveModeTrigger(intptr_t arg) +{ + ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); +} +#endif + void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) { if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) @@ -629,6 +666,12 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) sIsThreadProvisioned = FALSE; } } +#if CHIP_ENABLE_LIT + else if (event->Type == DeviceEventType::kCommissioningComplete) + { + sIsDeviceCommissioned = TRUE; + } +#endif #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR if (event->Type == DeviceEventType::kDnssdInitialized) diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h index bc19b0a9862ebd..2338131f06c4b0 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/AppTask.h @@ -87,6 +87,10 @@ class AppTask static void ContactActionEventHandler(void * aGenericEvent); static void ResetActionEventHandler(void * aGenericEvent); static void InstallEventHandler(void * aGenericEvent); +#if CHIP_ENABLE_LIT + static void UserActiveModeHandler(void * aGenericEvent); + static void UserActiveModeTrigger(intptr_t arg); +#endif static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); static void TimerEventHandler(TimerHandle_t xTimer); diff --git a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h index fbcf14fe7d88d7..7001f636dbd0d7 100644 --- a/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h +++ b/examples/contact-sensor-app/nxp/k32w/k32w1/main/include/app_config.h @@ -30,6 +30,7 @@ #define CONTACT_SENSOR_BUTTON_PUSH 2 #define SOFT_RESET_BUTTON_PUSH 3 #define BLE_BUTTON_PUSH 4 +#define USER_ACTIVE_MODE_TRIGGER_PUSH 5 #define APP_BUTTON_PUSH 1 diff --git a/examples/contact-sensor-app/nxp/zap/BUILD.gn b/examples/contact-sensor-app/nxp/zap-lit/BUILD.gn similarity index 96% rename from examples/contact-sensor-app/nxp/zap/BUILD.gn rename to examples/contact-sensor-app/nxp/zap-lit/BUILD.gn index be4913cf3552ee..7adfcbb7790a35 100644 --- a/examples/contact-sensor-app/nxp/zap/BUILD.gn +++ b/examples/contact-sensor-app/nxp/zap-lit/BUILD.gn @@ -16,7 +16,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") import("${chip_root}/src/app/chip_data_model.gni") -chip_data_model("zap") { +chip_data_model("zap-lit") { zap_file = "contact-sensor-app.zap" zap_pregenerated_dir = diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter new file mode 100644 index 00000000000000..9a6eeb77ef10f2 --- /dev/null +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -0,0 +1,1687 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 1; // NOTE: Default/not specifically set + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute optional char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** Provides an interface for providing OTA software updates */ +cluster OtaSoftwareUpdateProvider = 41 { + revision 1; // NOTE: Default/not specifically set + + enum ApplyUpdateActionEnum : enum8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum DownloadProtocolEnum : enum8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHTTPS = 2; + kVendorSpecific = 3; + } + + enum StatusEnum : enum8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct QueryImageRequest { + vendor_id vendorID = 0; + int16u productID = 1; + int32u softwareVersion = 2; + DownloadProtocolEnum protocolsSupported[] = 3; + optional int16u hardwareVersion = 4; + optional char_string<2> location = 5; + optional boolean requestorCanConsent = 6; + optional octet_string<512> metadataForProvider = 7; + } + + response struct QueryImageResponse = 1 { + StatusEnum status = 0; + optional int32u delayedActionTime = 1; + optional char_string<256> imageURI = 2; + optional int32u softwareVersion = 3; + optional char_string<64> softwareVersionString = 4; + optional octet_string<32> updateToken = 5; + optional boolean userConsentNeeded = 6; + optional octet_string<512> metadataForRequestor = 7; + } + + request struct ApplyUpdateRequestRequest { + octet_string<32> updateToken = 0; + int32u newVersion = 1; + } + + response struct ApplyUpdateResponse = 3 { + ApplyUpdateActionEnum action = 0; + int32u delayedActionTime = 1; + } + + request struct NotifyUpdateAppliedRequest { + octet_string<32> updateToken = 0; + int32u softwareVersion = 1; + } + + /** Determine availability of a new Software Image */ + command QueryImage(QueryImageRequest): QueryImageResponse = 0; + /** Determine next action to take for a downloaded Software Image */ + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + /** Notify OTA Provider that an update was applied */ + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; +} + +/** Provides an interface for downloading and applying OTA software updates */ +cluster OtaSoftwareUpdateRequestor = 42 { + revision 1; // NOTE: Default/not specifically set + + enum AnnouncementReasonEnum : enum8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum ChangeReasonEnum : enum8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum UpdateStateEnum : enum8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + fabric_scoped struct ProviderLocation { + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + fabric_idx fabricIndex = 254; + } + + info event StateTransition = 0 { + UpdateStateEnum previousState = 0; + UpdateStateEnum newState = 1; + ChangeReasonEnum reason = 2; + nullable int32u targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + int32u softwareVersion = 0; + int16u productID = 1; + } + + info event DownloadError = 2 { + int32u softwareVersion = 0; + int64u bytesDownloaded = 1; + nullable int8u progressPercent = 2; + nullable int64s platformCode = 3; + } + + attribute access(write: administer) ProviderLocation defaultOTAProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute UpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AnnounceOTAProviderRequest { + node_id providerNodeID = 0; + vendor_id vendorID = 1; + AnnouncementReasonEnum announcementReason = 2; + optional octet_string<512> metadataForNode = 3; + endpoint_no endpoint = 4; + } + + /** Announce the presence of an OTA Provider */ + command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Software 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 SoftwareDiagnostics = 52 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kWatermarks = 0x1; + } + + struct ThreadMetricsStruct { + int64u id = 0; + optional char_string<8> name = 1; + optional int32u stackFreeCurrent = 2; + optional int32u stackFreeMinimum = 3; + optional int32u stackSize = 4; + } + + info event SoftwareFault = 0 { + int64u id = 0; + optional char_string name = 1; + optional octet_string faultRecording = 2; + } + + readonly attribute optional ThreadMetricsStruct threadMetrics[] = 0; + readonly attribute optional int64u currentHeapFree = 1; + readonly attribute optional int64u currentHeapUsed = 2; + readonly attribute optional int64u currentHeapHighWatermark = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the values: The StackFreeMinimum field of the ThreadMetrics attribute, CurrentHeapHighWaterMark attribute. */ + command access(invoke: manage) ResetWatermarks(): DefaultSuccess = 0; +} + +/** 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 + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + struct RouteTableStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + int16u flags = 1; + } + + info event ConnectionStatus = 0 { + ConnectionStatusEnum connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRoleEnum routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute NeighborTableStruct neighborTable[] = 7; + readonly attribute RouteTableStruct routeTable[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int16u weighting = 10; + readonly attribute nullable int16u dataVersion = 11; + readonly attribute nullable int16u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute optional int16u detachedRoleCount = 14; + readonly attribute optional int16u childRoleCount = 15; + readonly attribute optional int16u routerRoleCount = 16; + readonly attribute optional int16u leaderRoleCount = 17; + readonly attribute optional int16u attachAttemptCount = 18; + readonly attribute optional int16u partitionIdChangeCount = 19; + readonly attribute optional int16u betterPartitionAttachAttemptCount = 20; + readonly attribute optional int16u parentChangeCount = 21; + readonly attribute optional int32u txTotalCount = 22; + readonly attribute optional int32u txUnicastCount = 23; + readonly attribute optional int32u txBroadcastCount = 24; + readonly attribute optional int32u txAckRequestedCount = 25; + readonly attribute optional int32u txAckedCount = 26; + readonly attribute optional int32u txNoAckRequestedCount = 27; + readonly attribute optional int32u txDataCount = 28; + readonly attribute optional int32u txDataPollCount = 29; + readonly attribute optional int32u txBeaconCount = 30; + readonly attribute optional int32u txBeaconRequestCount = 31; + readonly attribute optional int32u txOtherCount = 32; + readonly attribute optional int32u txRetryCount = 33; + readonly attribute optional int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute optional int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute optional int32u txErrCcaCount = 36; + readonly attribute optional int32u txErrAbortCount = 37; + readonly attribute optional int32u txErrBusyChannelCount = 38; + readonly attribute optional int32u rxTotalCount = 39; + readonly attribute optional int32u rxUnicastCount = 40; + readonly attribute optional int32u rxBroadcastCount = 41; + readonly attribute optional int32u rxDataCount = 42; + readonly attribute optional int32u rxDataPollCount = 43; + readonly attribute optional int32u rxBeaconCount = 44; + readonly attribute optional int32u rxBeaconRequestCount = 45; + readonly attribute optional int32u rxOtherCount = 46; + readonly attribute optional int32u rxAddressFilteredCount = 47; + readonly attribute optional int32u rxDestAddrFilteredCount = 48; + readonly attribute optional int32u rxDuplicatedCount = 49; + readonly attribute optional int32u rxErrNoFrameCount = 50; + readonly attribute optional int32u rxErrUnknownNeighborCount = 51; + readonly attribute optional int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute optional int32u rxErrSecCount = 53; + readonly attribute optional int32u rxErrFcsCount = 54; + readonly attribute optional int32u rxErrOtherCount = 55; + readonly attribute optional nullable int64u activeTimestamp = 56; + readonly attribute optional nullable int64u pendingTimestamp = 57; + readonly attribute optional nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFaultEnum activeNetworkFaultsList[] = 62; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the OverrunCount attributes to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** This cluster provides an interface to a boolean state called StateValue. */ +cluster BooleanState = 69 { + revision 1; + + info event StateChange = 0 { + boolean stateValue = 0; + } + + readonly attribute boolean stateValue = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Allows servers to ensure that listed clients are notified when a server is available for communication. */ +cluster IcdManagement = 70 { + revision 2; + + enum OperatingModeEnum : enum8 { + kSIT = 0; + kLIT = 1; + } + + bitmap Feature : bitmap32 { + kCheckInProtocolSupport = 0x1; + kUserActiveModeTrigger = 0x2; + kLongIdleTimeSupport = 0x4; + } + + bitmap UserActiveModeTriggerBitmap : bitmap32 { + kPowerCycle = 0x1; + kSettingsMenu = 0x2; + kCustomInstruction = 0x4; + kDeviceManual = 0x8; + kActuateSensor = 0x10; + kActuateSensorSeconds = 0x20; + kActuateSensorTimes = 0x40; + kActuateSensorLightsBlink = 0x80; + kResetButton = 0x100; + kResetButtonLightsBlink = 0x200; + kResetButtonSeconds = 0x400; + kResetButtonTimes = 0x800; + kSetupButton = 0x1000; + kSetupButtonSeconds = 0x2000; + kSetupButtonLightsBlink = 0x4000; + kSetupButtonTimes = 0x8000; + kAppDefinedButton = 0x10000; + } + + fabric_scoped struct MonitoringRegistrationStruct { + fabric_sensitive node_id checkInNodeID = 1; + fabric_sensitive int64u monitoredSubject = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute int32u idleModeDuration = 0; + readonly attribute int32u activeModeDuration = 1; + readonly attribute int16u activeModeThreshold = 2; + readonly attribute access(read: administer) optional MonitoringRegistrationStruct registeredClients[] = 3; + readonly attribute access(read: administer) optional int32u ICDCounter = 4; + readonly attribute optional int16u clientsSupportedPerFabric = 5; + readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; + readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; + readonly attribute optional OperatingModeEnum operatingMode = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RegisterClientRequest { + node_id checkInNodeID = 0; + int64u monitoredSubject = 1; + octet_string<16> key = 2; + optional octet_string<16> verificationKey = 3; + } + + response struct RegisterClientResponse = 1 { + int32u ICDCounter = 0; + } + + request struct UnregisterClientRequest { + node_id checkInNodeID = 0; + optional octet_string<16> verificationKey = 1; + } + + response struct StayActiveResponse = 4 { + int32u promisedActiveDuration = 0; + } + + /** Register a client to the end device */ + fabric command access(invoke: manage) RegisterClient(RegisterClientRequest): RegisterClientResponse = 0; + /** Unregister a client from an end device */ + fabric command access(invoke: manage) UnregisterClient(UnregisterClientRequest): DefaultSuccess = 2; + /** Request the end device to stay in Active Mode for an additional ActiveModeThreshold */ + command access(invoke: manage) StayActiveRequest(): StayActiveResponse = 3; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 2; + + binding cluster OtaSoftwareUpdateProvider; + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + } + + server cluster OtaSoftwareUpdateRequestor { + emits event StateTransition; + emits event VersionApplied; + emits event DownloadError; + callback attribute defaultOTAProviders; + ram attribute updatePossible default = 1; + ram attribute updateState default = 0; + ram attribute updateStateProgress default = 0; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AnnounceOTAProvider; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute supportedThreadFeatures; + ram attribute threadVersion; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 2; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster SoftwareDiagnostics { + callback attribute threadMetrics; + callback attribute currentHeapFree; + callback attribute currentHeapUsed; + callback attribute currentHeapHighWatermark; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command ResetWatermarks; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute overrunCount; + callback attribute neighborTable; + callback attribute routeTable; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute detachedRoleCount; + callback attribute childRoleCount; + callback attribute routerRoleCount; + callback attribute leaderRoleCount; + callback attribute attachAttemptCount; + callback attribute partitionIdChangeCount; + callback attribute betterPartitionAttachAttemptCount; + callback attribute parentChangeCount; + callback attribute txTotalCount; + callback attribute txUnicastCount; + callback attribute txBroadcastCount; + callback attribute txAckRequestedCount; + callback attribute txAckedCount; + callback attribute txNoAckRequestedCount; + callback attribute txDataCount; + callback attribute txDataPollCount; + callback attribute txBeaconCount; + callback attribute txBeaconRequestCount; + callback attribute txOtherCount; + callback attribute txRetryCount; + callback attribute txDirectMaxRetryExpiryCount; + callback attribute txIndirectMaxRetryExpiryCount; + callback attribute txErrCcaCount; + callback attribute txErrAbortCount; + callback attribute txErrBusyChannelCount; + callback attribute rxTotalCount; + callback attribute rxUnicastCount; + callback attribute rxBroadcastCount; + callback attribute rxDataCount; + callback attribute rxDataPollCount; + callback attribute rxBeaconCount; + callback attribute rxBeaconRequestCount; + callback attribute rxOtherCount; + callback attribute rxAddressFilteredCount; + callback attribute rxDestAddrFilteredCount; + callback attribute rxDuplicatedCount; + callback attribute rxErrNoFrameCount; + callback attribute rxErrUnknownNeighborCount; + callback attribute rxErrInvalidSrcAddrCount; + callback attribute rxErrSecCount; + callback attribute rxErrFcsCount; + callback attribute rxErrOtherCount; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x000F; + ram attribute clusterRevision default = 2; + + handle command ResetCounts; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command OpenCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } + + server cluster IcdManagement { + callback attribute idleModeDuration; + callback attribute activeModeDuration; + callback attribute activeModeThreshold; + callback attribute registeredClients; + callback attribute ICDCounter; + callback attribute clientsSupportedPerFabric; + ram attribute userActiveModeTriggerHint default = 4096; + ram attribute userActiveModeTriggerInstruction default = "Push setup button for Active Mode"; + ram attribute operatingMode default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0007; + ram attribute clusterRevision default = 2; + + handle command RegisterClient; + handle command RegisterClientResponse; + handle command UnregisterClient; + handle command StayActiveRequest; + handle command StayActiveResponse; + } +} +endpoint 1 { + device type ma_contactsensor = 21, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster BooleanState { + emits event StateChange; + ram attribute stateValue default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } +} + + diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap new file mode 100644 index 00000000000000..3e5035049d7808 --- /dev/null +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap @@ -0,0 +1,4161 @@ +{ + "fileFormat": 2, + "featureLevel": 99, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 2 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AnnounceOTAProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "DefaultOTAProviders", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "UpdateStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "VersionApplied", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DownloadError", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetWatermarks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ThreadMetrics", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapFree", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapUsed", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapHighWatermark", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRoleEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NeighborTable", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouteTable", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DetachedRoleCount", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChildRoleCount", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouterRoleCount", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRoleCount", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AttachAttemptCount", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionIdChangeCount", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BetterPartitionAttachAttemptCount", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ParentChangeCount", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxTotalCount", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxUnicastCount", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBroadcastCount", + "code": 24, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckRequestedCount", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckedCount", + "code": 26, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxNoAckRequestedCount", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataCount", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataPollCount", + "code": 29, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconCount", + "code": 30, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconRequestCount", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxOtherCount", + "code": 32, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxRetryCount", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDirectMaxRetryExpiryCount", + "code": 34, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxIndirectMaxRetryExpiryCount", + "code": 35, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCcaCount", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrAbortCount", + "code": 37, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrBusyChannelCount", + "code": 38, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxTotalCount", + "code": 39, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxUnicastCount", + "code": 40, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBroadcastCount", + "code": 41, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataCount", + "code": 42, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataPollCount", + "code": 43, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconCount", + "code": 44, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconRequestCount", + "code": 45, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxOtherCount", + "code": 46, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxAddressFilteredCount", + "code": 47, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDestAddrFilteredCount", + "code": 48, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDuplicatedCount", + "code": 49, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrNoFrameCount", + "code": 50, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrUnknownNeighborCount", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrInvalidSrcAddrCount", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrSecCount", + "code": 53, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrFcsCount", + "code": 54, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrOtherCount", + "code": 55, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x000F", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "ICD Management", + "code": 70, + "mfgCode": null, + "define": "ICD_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RegisterClient", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RegisterClientResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UnregisterClient", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StayActiveRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StayActiveResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdleModeDuration", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveModeDuration", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveModeThreshold", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RegisteredClients", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ICDCounter", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientsSupportedPerFabric", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UserActiveModeTriggerHint", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "UserActiveModeTriggerBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4096", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UserActiveModeTriggerInstruction", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "Push setup button for Active Mode", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OperatingMode", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "OperatingModeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0007", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "MA-dimmablelight", + "deviceTypeRef": { + "code": 21, + "profileId": 259, + "label": "MA-contactsensor", + "name": "MA-contactsensor" + }, + "deviceTypes": [ + { + "code": 21, + "profileId": 259, + "label": "MA-contactsensor", + "name": "MA-contactsensor" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 21 + ], + "deviceTypeName": "MA-contactsensor", + "deviceTypeCode": 21, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Boolean State", + "code": 69, + "mfgCode": null, + "define": "BOOLEAN_STATE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "StateValue", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateChange", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0 + }, + { + "endpointTypeName": "MA-dimmablelight", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0 + } + ] +} \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/zap-sit/BUILD.gn b/examples/contact-sensor-app/nxp/zap-sit/BUILD.gn new file mode 100644 index 00000000000000..e9a20db41208d3 --- /dev/null +++ b/examples/contact-sensor-app/nxp/zap-sit/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") +import("${chip_root}/src/app/chip_data_model.gni") + +chip_data_model("zap-sit") { + zap_file = "contact-sensor-app.zap" + + zap_pregenerated_dir = + "${chip_root}/zzz_generated/contact-sensor-app/nxp/zap-generated" + is_server = true +} diff --git a/examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter similarity index 97% rename from examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter rename to examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index 03736833bb02d3..479f8baa86284c 100644 --- a/examples/contact-sensor-app/nxp/zap/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -1370,6 +1370,9 @@ endpoint 0 { callback attribute subjectsPerAccessControlEntry; callback attribute targetsPerAccessControlEntry; callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1393,6 +1396,10 @@ endpoint 0 { callback attribute capabilityMinima; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; } @@ -1417,6 +1424,10 @@ endpoint 0 { callback attribute regulatoryConfig; callback attribute locationCapability; callback attribute supportsConcurrentConnection; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1437,8 +1448,14 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + ram attribute supportedThreadFeatures; + ram attribute threadVersion; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 2; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; handle command ScanNetworks; handle command ScanNetworksResponse; @@ -1454,12 +1471,19 @@ endpoint 0 { emits event BootReason; callback attribute networkInterfaces; callback attribute rebootCount; + callback attribute upTime; callback attribute activeNetworkFaults; callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; } server cluster SoftwareDiagnostics { @@ -1534,8 +1558,12 @@ endpoint 0 { callback attribute channelPage0Mask; callback attribute operationalDatasetComponents; callback attribute activeNetworkFaultsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0x000F; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; handle command ResetCounts; } @@ -1637,6 +1665,7 @@ endpoint 1 { ram attribute stateValue default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; + callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap similarity index 88% rename from examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap rename to examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap index bf037957bd2629..d7145e74d9fe0b 100644 --- a/examples/contact-sensor-app/nxp/zap/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap @@ -139,10 +139,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, @@ -238,6 +238,54 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, @@ -514,7 +562,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -530,7 +578,71 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -938,6 +1050,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1174,6 +1350,102 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SupportedThreadFeatures", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "ThreadCapabilitiesBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1200,7 +1472,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -1223,6 +1495,22 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 } ], "attributes": [ @@ -1258,6 +1546,22 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ActiveNetworkFaults", "code": 7, @@ -1290,6 +1594,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1297,10 +1665,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, @@ -1313,10 +1681,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -2427,6 +2795,70 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -2453,7 +2885,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -3411,10 +3843,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, @@ -3494,6 +3926,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, @@ -3571,6 +4019,5 @@ "endpointId": 1, "networkId": 0 } - ], - "log": [] + ] } \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt index e0a95d584130eb..1758fbd868fbfb 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt @@ -67,13 +67,12 @@ class PairOnNetworkLongImReadCommand( } fun checkUnitTestClusterGeneralStatus(status: Status): Boolean = - (status.getStatus() == CLUSTER_ID_TEST_GENERAL_ERROR_STATUS) && - !status.getClusterStatus().isPresent() + (status.getStatus() == Status.Code.InvalidDataType) && !status.getClusterStatus().isPresent() fun checkUnitTestClusterClusterStatus(status: Status): Boolean = - (status.getStatus() == CLUSTER_ID_TEST_CLUSTER_ERROR_STATUS) && + (status.getStatus() == Status.Code.Failure) && status.getClusterStatus().isPresent() && - status.getClusterStatus().get() == CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS + (status.getClusterStatus().get() == CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS) private fun validateResponse(nodeState: NodeState) { val endpointZero = @@ -243,8 +242,6 @@ class PairOnNetworkLongImReadCommand( private const val CLUSTER_ID_BASIC_VERSION = 0L private const val CLUSTER_ID_TEST_GENERAL_ERROR_BOOLEAN = 0x0031L private const val CLUSTER_ID_TEST_CLUSTER_ERROR_BOOLEAN = 0x0032L - private const val CLUSTER_ID_TEST_GENERAL_ERROR_STATUS = 0x8d - private const val CLUSTER_ID_TEST_CLUSTER_ERROR_STATUS = 1 private const val CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS = 17 } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt index 3e90935d22268e..fdb74c5d065b5c 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt @@ -22,6 +22,7 @@ import chip.devicecontroller.GetConnectedDeviceCallbackJni.GetConnectedDeviceCal import chip.devicecontroller.WriteAttributesCallback import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath +import chip.devicecontroller.model.Status import com.matter.controller.commands.common.CredentialsIssuer import java.util.logging.Level import java.util.logging.Logger @@ -51,11 +52,8 @@ class PairOnNetworkLongImWriteCommand( setFailure("write failure") } - override fun onResponse(attributePath: ChipAttributePath?) { - logger.log(Level.INFO, "Write receive OnResponse on ") - if (attributePath != null) { - logger.log(Level.INFO, attributePath.toString()) - } + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + logger.log(Level.INFO, "$attributePath : Write response: $status") setSuccess() } } diff --git a/examples/light-switch-app/genio/src/main.cpp b/examples/light-switch-app/genio/src/main.cpp index 93bb82a21b0735..d545409c706913 100644 --- a/examples/light-switch-app/genio/src/main.cpp +++ b/examples/light-switch-app/genio/src/main.cpp @@ -51,8 +51,6 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -#define UNUSED_PARAMETER(a) (a = a) - volatile int apperror_cnt; /*************************************************************************** diff --git a/examples/lighting-app/genio/src/AppTask.cpp b/examples/lighting-app/genio/src/AppTask.cpp index 6a121673a002a6..d948087833c4dd 100644 --- a/examples/lighting-app/genio/src/AppTask.cpp +++ b/examples/lighting-app/genio/src/AppTask.cpp @@ -66,8 +66,6 @@ #error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" #endif -#define UNUSED_PARAMETER(a) (a = a) - #if defined(ENABLE_CHIP_SHELL) using chip::Shell::Engine; using chip::Shell::PrintCommandHelp; diff --git a/examples/lighting-app/genio/src/main.cpp b/examples/lighting-app/genio/src/main.cpp index ab578f3f2c75bd..22f654eb5f2f50 100644 --- a/examples/lighting-app/genio/src/main.cpp +++ b/examples/lighting-app/genio/src/main.cpp @@ -51,8 +51,6 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -#define UNUSED_PARAMETER(a) (a = a) - volatile int apperror_cnt; /*************************************************************************** diff --git a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h index 536b822d776377..05f8042ed28138 100644 --- a/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nxp/k32w/k32w1/include/CHIPProjectConfig.h @@ -139,11 +139,11 @@ * {MAJOR_VERSION}.0d{MINOR_VERSION} */ #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "03-2022-te8" +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION -#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION #endif #ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME diff --git a/examples/lit-icd-app/nrfconnect/.gitignore b/examples/lit-icd-app/nrfconnect/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/lit-icd-app/nrfconnect/CMakeLists.txt b/examples/lit-icd-app/nrfconnect/CMakeLists.txt new file mode 100644 index 00000000000000..a9b921016670e7 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/CMakeLists.txt @@ -0,0 +1,66 @@ +# +# 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. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(NRFCONNECT_COMMON ${CHIP_ROOT}/examples/platform/nrfconnect REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) + +include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) + +# Set Kconfig root files that will be processed as a first Kconfig for used child images. +set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) +set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) + +if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) +endif() + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) + +project(chip-nrfconnect-lit-icd-app-example) + +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app PRIVATE + main/include + ${GEN_DIR}/app-common + ${GEN_DIR}/lit-icd-app + ${NRFCONNECT_COMMON}/util/include + ${NRFCONNECT_COMMON}/app/include) + +target_sources(app PRIVATE + main/AppTask.cpp + main/main.cpp + ${NRFCONNECT_COMMON}/util/LEDWidget.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lit-icd-common/lit-icd-server-app.zap +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/OTAUtil.cpp) +endif() diff --git a/examples/lit-icd-app/nrfconnect/Kconfig b/examples/lit-icd-app/nrfconnect/Kconfig new file mode 100644 index 00000000000000..4d9501ac5cab90 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/Kconfig @@ -0,0 +1,41 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +mainmenu "Matter nRF Connect LIT ICD Example Application" + +config STATE_LEDS + bool "Use LEDs to indicate the device state" + default y + help + Use LEDs to render the current state of the device such as the progress of commissioning of + the device into a network or the factory reset initiation. Note that setting this option to + 'n' does not disable the LED indicating the state of the simulated bolt. + +# Sample configuration used for Thread networking +if NET_L2_OPENTHREAD + +choice OPENTHREAD_NORDIC_LIBRARY_CONFIGURATION + default OPENTHREAD_NORDIC_LIBRARY_MTD +endchoice + +choice OPENTHREAD_DEVICE_TYPE + default OPENTHREAD_MTD +endchoice + +endif # NET_L2_OPENTHREAD + +rsource "../../../config/nrfconnect/chip-module/Kconfig.features" +rsource "../../../config/nrfconnect/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/lit-icd-app/nrfconnect/README.md b/examples/lit-icd-app/nrfconnect/README.md new file mode 100644 index 00000000000000..704950fdcac63e --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/README.md @@ -0,0 +1,401 @@ +# Matter nRF Connect LIT ICD Example Application + +The nRF Connect LIT ICD Example allows to test the device that utilizes Long +Idle Time feature from the Intermittently Connected Device Management cluster. +It uses buttons to change the device states and LEDs to show the state of these +changes. You can use this example as a reference for creating your own +application. + +Nordic Semiconductor logo +nRF52840 DK + +The example is based on +[Matter](https://github.com/project-chip/connectedhomeip) and Nordic +Semiconductor's nRF Connect SDK, and was created to facilitate testing and +certification of a Matter device communicating over a low-power, 802.15.4 Thread +network. + +The example behaves as a Matter accessory, that is a device that can be paired +into an existing Matter network and can be controlled by this network. + +
+ +## Overview + +This example is running on the nRF Connect platform, which is based on Nordic +Semiconductor's +[nRF Connect SDK](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/index.html) +and [Zephyr RTOS](https://zephyrproject.org/). Visit Matter's +[nRF Connect platform overview](../../../docs/guides/nrfconnect_platform_overview.md) +to read more about the platform structure and dependencies. + +By default, the Matter accessory device has IPv6 networking disabled. You must +pair it with the Matter controller over Bluetooth® LE to get the configuration +from the controller to use the device within a Thread network. You have to make +the device discoverable manually (for security reasons). See +[Bluetooth LE advertising](#bluetooth-le-advertising) to learn how to do this. +The controller must get the commissioning information from the Matter accessory +device and provision the device into the network. + +The sample uses buttons for changing the device states, and LEDs to show the +state of these changes. + +### Bluetooth LE advertising + +In this example, to commission the device onto a Matter network, it must be +discoverable over Bluetooth LE. For security reasons, you must start Bluetooth +LE advertising manually after powering up the device by pressing **Button 4**. + +### Bluetooth LE rendezvous + +In this example, the commissioning procedure is done over Bluetooth LE between a +Matter device and the Matter controller, where the controller has the +commissioner role. + +To start the rendezvous, the controller must get the commissioning information +from the Matter device. The data payload is encoded within a QR code, printed to +the UART console, and shared using an NFC tag. The emulation of the NFC tag +emulation starts automatically when Bluetooth LE advertising is started and +stays enabled until Bluetooth LE advertising timeout expires. + +#### Thread provisioning + +The provisioning operation, which is the Last part of the rendezvous procedure, +involves sending the Thread network credentials from the Matter controller to +the Matter device. As a result, the device joins the Thread network and can +communicate with other devices in the network. + +### Device Firmware Upgrade + +The example supports over-the-air (OTA) device firmware upgrade (DFU) using +Matter OTA mechanism, which is enabled by default. + +The +[MCUboot](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/index.html) +bootloader solution is used to replace the old firmware image with the new one. + +#### Matter Over-the-Air Update + +The Matter over-the-air update distinguishes two types of nodes: OTA Provider +and OTA Requestor. + +An OTA Provider is a node that hosts a new firmware image and is able to respond +on an OTA Requestor's queries regarding availability of new firmware images or +requests to start sending the update packages. + +An OTA Requestor is a node that wants to download a new firmware image and sends +requests to an OTA Provider to start the update process. + +#### Bootloader + +MCUboot is a secure bootloader used for swapping firmware images of different +versions and generating proper build output files that can be used in the device +firmware upgrade process. + +The bootloader solution requires an area of flash memory to swap application +images during the firmware upgrade. Nordic Semiconductor devices use an external +memory chip for this purpose. The memory chip communicates with the +microcontroller through the QSPI bus. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to change MCUboot and flash configuration in this example. + +
+ +## Requirements + +The application requires a specific revision of the nRF Connect SDK to work +correctly. See [Setting up the environment](#setting-up-the-environment) for +more information. + +### Supported devices + +The example supports building and running on the following devices: + +| Hardware platform | Build target | Platform image | +| ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| + +
+ +## Device UI + +This section lists the User Interface elements that you can use to control and +monitor the state of the device. These correspond to PCB components on the +platform image. + +**LED 1** shows the overall state of the device and its connectivity. The +following states are possible: + +- _Short Flash On (50 ms on/950 ms off)_ — The device is in the + unprovisioned (unpaired) state and is waiting for a commissioning + application to connect. + +- _Rapid Even Flashing (100 ms on/100 ms off)_ — The device is in the + unprovisioned state and a commissioning application is connected through + Bluetooth LE. + +- _Short Flash Off (950ms on/50ms off)_ — The device is fully + provisioned, but does not yet have full connectivity for Thread network. + +- _Solid On_ — The device is fully provisioned. + +**LED 2** is used for the Identify feature purpose. The LED starts blinking +evenly (500 ms on/500 ms off) when the Identify command of the Identify cluster +is received on the endpoint 1. The command’s argument can be used to specify the +duration of the effect. + +**Button 1** Pressing the button for more than 3 s initiates the factory reset +of the device. Releasing the button within the 3-second window cancels the +factory reset procedure. + +**Button 3** Represents the User Active Mode Trigger feature from the +Intermittently Connected Devices Management cluster. Pressing it puts the ICD +device in the active mode and makes it responsive. + +**Button 4** Starts the NFC tag emulation, enables Bluetooth LE advertising for +the predefined period of time (15 minutes by default), and makes the device +discoverable over Bluetooth LE. This button is used during the commissioning +procedure. + +**SEGGER J-Link USB port** can be used to get logs from the device or +communicate with it using the +[command line interface](../../../docs/guides/nrfconnect_examples_cli.md). + +**NFC port with antenna attached** can be used to start the +[rendezvous](#bluetooth-le-rendezvous) by providing the commissioning +information from the Matter device in a data payload that can be shared using +NFC. + +
+ +## Setting up the environment + +Before building the example, check out the Matter repository and sync submodules +using the following command: + + $ python3 scripts/checkout_submodules.py --shallow --platform nrfconnect + +> **Note**: +> +> For Linux operating system install +> [SEGGER J-Link Software](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack). + +### Install Command Line Tools + +With admin permissions enabled, download and install the +[nRF Command Line Tools](https://www.nordicsemi.com/Products/Development-tools/nrf-command-line-tools). + +### Install Toolchain Manager + +Toolchain Manager is available from +[nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop), +a cross-platform tool that provides different applications that simplify +installing the nRF Connect SDK. Both the tool and the application are available +for Windows, Linux, and macOS. + +To install the Toolchain Manager app, complete the following steps: + +1. [Download nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop/download#infotabs) + for your operating system. + +2. Install and run the tool on your machine. + +3. In the **APPS** section, click **Install** button on the Toolchain Manager + tab. + +### Install nRF Connect SDK + +Complete the following steps to install the nRF Connect SDK: + +1. Open Toolchain Manager in nRF Connect for Desktop. + +2. Click the **Install** button next to the + [recommended](../../../config/nrfconnect/.nrfconnect-recommended-revision) + version of the nRF Connect SDK. + +3. A pop-up window will inform you about the current installation directory. If + you want to change the directory, click the **Change directory** button. + Otherwise, click the **Continue installation** button. + +4. When the nRF Connect SDK is installed on your machine, the **Install** + button changes to the **Open VS Code** button. + +5. Click the dropdown menu next to the **Open VS Code** button for the + installed nRF Connect SDK version, and select **Open terminal**. + +6. Make sure that the nRF Connect SDK version is compatible with the Matter SDK + version: + + ``` + $ cd {connectedhomeip directory} + $ python3 scripts/setup/nrfconnect/update_ncs.py --update + ``` + +Now you can proceed with the [Building](#building) instruction. + +
+ +## Building + +Complete the following steps to build the sample: + +1. Navigate to the example's directory: + + $ cd examples/lit-icd-app/nrfconnect + +2. Run the following command to build the example, with _build-target_ replaced + with the build target name of the Nordic Semiconductor's kit you own, for + example `nrf52840dk_nrf52840`: + + $ west build -b build-target + + You only need to specify the build target on the first build. See + [Requirements](#requirements) for the build target names of compatible kits. + +The output `zephyr.hex` file will be available in the `build/zephyr/` directory. + +### Removing build artifacts + +If you're planning to build the example for a different kit or make changes to +the configuration, remove all build artifacts before building. To do so, use the +following command: + + $ rm -r build + +### Building with release configuration + +To build the example with release configuration that disables the diagnostic +features like logs and command-line interface, run the following command: + + $ west build -b build-target -- -DCONF_FILE=prj_release.conf + +Remember to replace _build-target_ with the build target name of the Nordic +Semiconductor's kit you own. + +### Building with Device Firmware Upgrade support + +Support for DFU using Matter OTA is enabled by default. + +To completely disable support for DFU, run the following command with +_build-target_ replaced with the build target name of the Nordic Semiconductor +kit you are using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + +> **Note**: +> +> There are two types of Device Firmware Upgrade modes: single-image DFU and +> multi-image DFU. Single-image mode supports upgrading only one firmware image, +> the application image, and should be used for single-core nRF52840 DK devices. +> Multi-image mode allows to upgrade more firmware images and is suitable for +> upgrading the application core and network core firmware in two-core nRF5340 +> DK devices. + +#### Changing bootloader configuration + +To change the default MCUboot configuration, edit the `prj.conf` file located in +the `child_image/mcuboot` directory. + +Make sure to keep the configuration consistent with changes made to the +application configuration. This is necessary for the configuration to work, as +the bootloader image is a separate application from the user application and it +has its own configuration file. + +#### Changing flash memory settings + +In the default configuration, the MCUboot uses the +[Partition Manager](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#partition-manager) +to configure flash partitions used for the bootloader application image slot +purposes. You can change these settings by defining +[static partitions](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#ug-pm-static). +This example uses this option to define using an external flash. + +To modify the flash settings of your board (that is, your _build-target_, for +example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the +`configuration/build-target/` directory. + +
+ +## Configuring the example + +The Zephyr ecosystem is based on Kconfig files and the settings can be modified +using the menuconfig utility. + +To open the menuconfig utility, run the following command from the example +directory: + + $ west build -b build-target -t menuconfig + +Remember to replace _build-target_ with the build target name of the Nordic +Semiconductor's kit you own. + +Changes done with menuconfig will be lost if the `build` directory is deleted. +To make them persistent, save the configuration options in the `prj.conf` file. + +### Example build types + +The example uses different configuration files depending on the supported +features. Configuration files are provided for different build types and they +are located in the application root directory. + +The `prj.conf` file represents a debug build type. Other build types are covered +by dedicated files with the build type added as a suffix to the prj part, as per +the following list. For example, the release build type file name is +`prj_release.conf`. If a board has other configuration files, for example +associated with partition layout or child image configuration, these follow the +same pattern. + +Before you start testing the application, you can select one of the build types +supported by the sample. This sample supports the following build types, +depending on the selected board: + +- debug -- Debug version of the application - can be used to enable additional + features for verifying the application behavior, such as logs or + command-line shell. +- release -- Release version of the application - can be used to enable only + the necessary application functionalities to optimize its performance. +- no_dfu -- Debug version of the application without Device Firmware Upgrade + feature support. + +For more information, see the +[Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) +page. + +
+ +## Flashing and debugging + +To flash the application to the device, use the west tool and run the following +command from the example directory: + + $ west flash --erase + +If you have multiple development kits connected, west will prompt you to pick +the correct one. + +To debug the application on target, run the following command from the example +directory: + + $ west debug + +
+ +## Testing the example + +Check the [CLI tutorial](../../../docs/guides/nrfconnect_examples_cli.md) to +learn how to use command-line interface of the application. + +### Testing using Linux CHIPTool + +Read the [CHIP Tool user guide](../../../docs/guides/chip_tool_guide.md) to see +how to use [CHIP Tool for Linux or mac OS](../../chip-tool/README.md) to +commission and control the application within a Matter-enabled Thread network. + +### Testing Device Firmware Upgrade + +Read the +[DFU tutorial](../../../docs/guides/nrfconnect_examples_software_update.md) to +see how to upgrade your device firmware. diff --git a/examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay b/examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..7babe0424821ba --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,54 @@ +/* + * 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. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; + + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + chosen { + zephyr,entropy = &rng; + }; +}; + +/* Disable unused peripherals to reduce power consumption */ +&adc { + status = "disabled"; +}; +&uart1 { + status = "disabled"; +}; +&i2c0 { + status = "disabled"; +}; +&pwm0 { + status = "disabled"; +}; +&spi1 { + status = "disabled"; +}; +&spi3 { + status = "disabled"; +}; +&usbd { + status = "disabled"; +}; diff --git a/examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..12155ffcd1f509 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + +/* Set IPC thread priority to the highest value to not collide with other threads. */ +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; +}; + +/* Disable unused peripherals to reduce power consumption */ +&adc { + status = "disabled"; +}; +&i2c1 { + status = "disabled"; +}; +&pwm0 { + status = "disabled"; +}; +&spi2 { + status = "disabled"; +}; +&usbd { + status = "disabled"; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..9f9128c6beff60 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay new file mode 100644 index 00000000000000..9f9128c6beff60 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..50069180506973 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay new file mode 100644 index 00000000000000..9f9128c6beff60 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf new file mode 100644 index 00000000000000..3f43b733b4bb96 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.mcuboot.defaults to set options common for all +# samples using mcuboot. This file should contain only options specific for this sample +# mcuboot configuration or overrides of default values. + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Bootloader size optimization +# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding +# in board files. +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf new file mode 100644 index 00000000000000..3f43b733b4bb96 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.mcuboot.defaults to set options common for all +# samples using mcuboot. This file should contain only options specific for this sample +# mcuboot configuration or overrides of default values. + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Bootloader size optimization +# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding +# in board files. +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf new file mode 100644 index 00000000000000..48deaa9fa18135 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all +# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample +# multiprotocol_rpmsg configuration or overrides of default values. + +# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding +# in board files. + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf new file mode 100644 index 00000000000000..48deaa9fa18135 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all +# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample +# multiprotocol_rpmsg configuration or overrides of default values. + +# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding +# in board files. + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf new file mode 100644 index 00000000000000..48deaa9fa18135 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all +# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample +# multiprotocol_rpmsg configuration or overrides of default values. + +# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding +# in board files. + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lit-icd-app/nrfconnect/main/AppTask.cpp b/examples/lit-icd-app/nrfconnect/main/AppTask.cpp new file mode 100644 index 00000000000000..50622d0c88b96e --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/AppTask.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "AppConfig.h" +#include "AppEvent.h" +#include "FabricTableDelegate.h" +#include "LEDUtil.h" + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" +#endif + +#include +#include +#include + +LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +namespace { +constexpr uint32_t kFactoryResetTriggerTimeout = 3000; +constexpr uint32_t kFactoryResetCancelWindowTimeout = 3000; +constexpr size_t kAppEventQueueSize = 10; +constexpr EndpointId kIdentifyEndpointId = 1; + +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); +k_timer sFunctionTimer; + +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + +Identify sIdentify = { kIdentifyEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, + Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator }; + +LEDWidget sStatusLED; +LEDWidget sIdentifyLED; +FactoryResetLEDsWrapper<2> sFactoryResetLEDs{ { FACTORY_RESET_SIGNAL_LED, FACTORY_RESET_SIGNAL_LED1 } }; + +bool sIsNetworkProvisioned = false; +bool sIsNetworkEnabled = false; +bool sHaveBLEConnections = false; + +} // namespace + +namespace LedConsts { +constexpr uint32_t kBlinkRate_ms{ 500 }; +constexpr uint32_t kIdentifyBlinkRate_ms{ 500 }; +namespace StatusLed { +namespace Unprovisioned { +constexpr uint32_t kOn_ms{ 100 }; +constexpr uint32_t kOff_ms{ kOn_ms }; +} // namespace Unprovisioned +namespace Provisioned { +constexpr uint32_t kOn_ms{ 50 }; +constexpr uint32_t kOff_ms{ 950 }; +} // namespace Provisioned + +} // namespace StatusLed +} // namespace LedConsts + +CHIP_ERROR AppTask::Init() +{ + // Initialize CHIP stack + LOG_INF("Init CHIP stack"); + + CHIP_ERROR err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Platform::MemoryInit() failed"); + return err; + } + + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().InitChipStack() failed"); + return err; + } + +#if defined(CONFIG_NET_L2_OPENTHREAD) + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ThreadStackMgr().InitThreadStack() failed"); + return err; + } + +#ifdef CONFIG_OPENTHREAD_MTD_SED + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); +#else + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#endif + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); + return err; + } +#else + return CHIP_ERROR_INTERNAL; +#endif // CONFIG_NET_L2_OPENTHREAD + + // Initialize LEDs + LEDWidget::InitGpio(); + LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); + + sStatusLED.Init(SYSTEM_STATE_LED); + sIdentifyLED.Init(IDENTIFY_STATE_LED); + sIdentifyLED.Set(false); + + UpdateStatusLED(); + + // Initialize buttons + auto ret = dk_buttons_init(ButtonEventHandler); + if (ret) + { + LOG_ERR("dk_buttons_init() failed"); + return chip::System::MapErrorZephyr(ret); + } + + // Initialize timer user data + k_timer_init(&sFunctionTimer, &AppTask::FunctionTimerTimeoutCallback, nullptr); + k_timer_user_data_set(&sFunctionTimer, this); + +#ifdef CONFIG_CHIP_OTA_REQUESTOR + /* OTA image confirmation must be done before the factory data init. */ + OtaConfirmNewImage(); +#endif + + // Initialize CHIP server +#if CONFIG_CHIP_FACTORY_DATA + ReturnErrorOnFailure(mFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&mFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); + SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } +#else + SetDeviceInstanceInfoProvider(&DeviceInstanceInfoProviderMgrImpl()); + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + static CommonCaseDeviceServerInitParams initParams; + static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{}; + static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{}; + VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR); + VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR); + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); + + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + ConfigurationMgr().LogDeviceConfig(); + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); + + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().StartEventLoopTask() failed"); + } + + return err; +} + +CHIP_ERROR AppTask::StartApp() +{ + ReturnErrorOnFailure(Init()); + + AppEvent event{}; + + while (true) + { + k_msgq_get(&sAppEventQueue, &event, K_FOREVER); + DispatchEvent(event); + } + + return CHIP_NO_ERROR; +} + +void AppTask::IdentifyStartHandler(Identify *) +{ + AppEvent event; + event.Type = AppEventType::IdentifyStart; + event.Handler = [](const AppEvent &) { sIdentifyLED.Blink(LedConsts::kIdentifyBlinkRate_ms); }; + PostEvent(event); +} + +void AppTask::IdentifyStopHandler(Identify *) +{ + AppEvent event; + event.Type = AppEventType::IdentifyStop; + event.Handler = [](const AppEvent &) { sIdentifyLED.Set(false); }; + PostEvent(event); +} + +void AppTask::ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged) +{ + AppEvent button_event; + button_event.Type = AppEventType::Button; + + if (BLE_ADVERTISEMENT_START_BUTTON_MASK & buttonState & hasChanged) + { + button_event.ButtonEvent.PinNo = BLE_ADVERTISEMENT_START_BUTTON; + button_event.ButtonEvent.Action = static_cast(AppEventType::ButtonPushed); + button_event.Handler = StartBLEAdvertisementHandler; + PostEvent(button_event); + } + + if (FUNCTION_BUTTON_MASK & hasChanged) + { + button_event.ButtonEvent.PinNo = FUNCTION_BUTTON; + button_event.ButtonEvent.Action = + static_cast((FUNCTION_BUTTON_MASK & buttonState) ? AppEventType::ButtonPushed : AppEventType::ButtonReleased); + button_event.Handler = FunctionHandler; + PostEvent(button_event); + } + + if (ICD_UAT_BUTTON_MASK & hasChanged) + { + button_event.ButtonEvent.PinNo = ICD_UAT_BUTTON; + button_event.ButtonEvent.Action = static_cast(AppEventType::ButtonPushed); + button_event.Handler = IcdUatEventHandler; + PostEvent(button_event); + } +} + +void AppTask::IcdUatEventHandler(const AppEvent &) +{ + Server::GetInstance().GetICDManager().UpdateOperationState(ICDManager::OperationalState::ActiveMode); +} + +void AppTask::FunctionTimerTimeoutCallback(k_timer * timer) +{ + if (!timer) + { + return; + } + + AppEvent event; + event.Type = AppEventType::Timer; + event.TimerEvent.Context = k_timer_user_data_get(timer); + event.Handler = FunctionTimerEventHandler; + PostEvent(event); +} + +void AppTask::FunctionTimerEventHandler(const AppEvent & event) +{ + if (event.Type != AppEventType::Timer || !Instance().mFunctionTimerActive) + { + return; + } + + // If we reached here, the button was held past kFactoryResetTriggerTimeout, initiate factory reset + if (Instance().mFunction == FunctionEvent::SoftwareUpdate) + { + LOG_INF("Factory Reset Triggered. Release button within %ums to cancel.", kFactoryResetTriggerTimeout); + + // Start timer for kFactoryResetCancelWindowTimeout to allow user to cancel, if required. + Instance().StartTimer(kFactoryResetCancelWindowTimeout); + Instance().mFunction = FunctionEvent::FactoryReset; + + // Turn off all LEDs before starting blink to make sure blink is coordinated. + sStatusLED.Set(false); + sFactoryResetLEDs.Set(false); + + sStatusLED.Blink(LedConsts::kBlinkRate_ms); + sFactoryResetLEDs.Blink(LedConsts::kBlinkRate_ms); + } + else if (Instance().mFunction == FunctionEvent::FactoryReset) + { + // Actually trigger Factory Reset + Instance().mFunction = FunctionEvent::NoneSelected; + chip::Server::GetInstance().ScheduleFactoryReset(); + } + else if (Instance().mFunction == FunctionEvent::AdvertisingStart) + { + // The button was held past kAdvertisingTriggerTimeout, start BLE advertisement if we have 2 buttons UI + StartBLEAdvertisementHandler(event); + } +} + +void AppTask::FunctionHandler(const AppEvent & event) +{ + if (event.ButtonEvent.PinNo != FUNCTION_BUTTON) + return; + + // To trigger software update: press the FUNCTION_BUTTON button briefly (< FACTORY_RESET_TRIGGER_TIMEOUT) + // To initiate factory reset: press the FUNCTION_BUTTON for FACTORY_RESET_TRIGGER_TIMEOUT + FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + // All LEDs start blinking after FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated. + // To cancel factory reset: release the FUNCTION_BUTTON once all LEDs start blinking within the + // FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + if (event.ButtonEvent.Action == static_cast(AppEventType::ButtonPushed)) + { + if (!Instance().mFunctionTimerActive && Instance().mFunction == FunctionEvent::NoneSelected) + { + Instance().StartTimer(kFactoryResetTriggerTimeout); + + Instance().mFunction = FunctionEvent::SoftwareUpdate; + } + } + else + { + // If the button was released before factory reset got initiated, trigger a software update. + if (Instance().mFunctionTimerActive && Instance().mFunction == FunctionEvent::SoftwareUpdate) + { + Instance().CancelTimer(); + Instance().mFunction = FunctionEvent::NoneSelected; + } + else if (Instance().mFunctionTimerActive && Instance().mFunction == FunctionEvent::FactoryReset) + { + sFactoryResetLEDs.Set(false); + UpdateStatusLED(); + Instance().CancelTimer(); + Instance().mFunction = FunctionEvent::NoneSelected; + LOG_INF("Factory Reset has been Canceled"); + } + } +} + +void AppTask::StartBLEAdvertisementHandler(const AppEvent &) +{ + if (Server::GetInstance().GetFabricTable().FabricCount() != 0) + { + LOG_INF("Matter service BLE advertising not started - device is already commissioned"); + return; + } + + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + LOG_INF("BLE advertising is already enabled"); + return; + } + + if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + LOG_ERR("OpenBasicCommissioningWindow() failed"); + } +} + +void AppTask::UpdateLedStateEventHandler(const AppEvent & event) +{ + if (event.Type == AppEventType::UpdateLedState) + { + event.UpdateLedStateEvent.LedWidget->UpdateState(); + } +} + +void AppTask::LEDStateUpdateHandler(LEDWidget & ledWidget) +{ + AppEvent event; + event.Type = AppEventType::UpdateLedState; + event.Handler = UpdateLedStateEventHandler; + event.UpdateLedStateEvent.LedWidget = &ledWidget; + PostEvent(event); +} + +void AppTask::UpdateStatusLED() +{ +#ifdef CONFIG_STATE_LEDS + // Update the status LED. + // + // If IPv6 network and service provisioned, keep the LED On constantly. + // + // If the system has BLE connection(s) until the stage above, THEN blink the LED at an even + // rate of 100ms. + // + // Otherwise, blink the LED for a very short time. + if (sIsNetworkProvisioned && sIsNetworkEnabled) + { + sStatusLED.Set(true); + } + else if (sHaveBLEConnections) + { + sStatusLED.Blink(LedConsts::StatusLed::Unprovisioned::kOn_ms, LedConsts::StatusLed::Unprovisioned::kOff_ms); + } + else + { + sStatusLED.Blink(LedConsts::StatusLed::Provisioned::kOn_ms, LedConsts::StatusLed::Provisioned::kOff_ms); + } +#endif +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) + { + if (NFCMgr().IsTagEmulationStarted()) + { + LOG_INF("NFC Tag emulation is already started"); + } + else + { + ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + } + } + else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) + { + NFCMgr().StopTagEmulation(); + } +#endif + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; +#if defined(CONFIG_NET_L2_OPENTHREAD) + case DeviceEventType::kDnssdInitialized: +#if CONFIG_CHIP_OTA_REQUESTOR + InitBasicOTARequestor(); +#endif // CONFIG_CHIP_OTA_REQUESTOR + break; + case DeviceEventType::kThreadStateChange: + sIsNetworkProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsNetworkEnabled = ConnectivityMgr().IsThreadEnabled(); + UpdateStatusLED(); + break; +#endif // CONFIG_NET_L2_OPENTHREAD + default: + break; + } +} + +void AppTask::CancelTimer() +{ + k_timer_stop(&sFunctionTimer); + Instance().mFunctionTimerActive = false; +} + +void AppTask::StartTimer(uint32_t aTimeoutInMs) +{ + k_timer_start(&sFunctionTimer, K_MSEC(aTimeoutInMs), K_NO_WAIT); + Instance().mFunctionTimerActive = true; +} + +void AppTask::PostEvent(const AppEvent & event) +{ + if (k_msgq_put(&sAppEventQueue, &event, K_NO_WAIT) != 0) + { + LOG_INF("Failed to post event to app task event queue"); + } +} + +void AppTask::DispatchEvent(const AppEvent & event) +{ + if (event.Handler) + { + event.Handler(event); + } + else + { + LOG_INF("Event received with no handler. Dropping event."); + } +} diff --git a/examples/lit-icd-app/nrfconnect/main/include/AppConfig.h b/examples/lit-icd-app/nrfconnect/main/include/AppConfig.h new file mode 100644 index 00000000000000..26f63f5ec1fa06 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/AppConfig.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BoardUtil.h" + +// ---- LIT ICD Application example config ---- + +#define FUNCTION_BUTTON DK_BTN1 +#define FUNCTION_BUTTON_MASK DK_BTN1_MSK +#define ICD_UAT_BUTTON DK_BTN3 +#define ICD_UAT_BUTTON_MASK DK_BTN3_MSK +#define BLE_ADVERTISEMENT_START_BUTTON DK_BTN4 +#define BLE_ADVERTISEMENT_START_BUTTON_MASK DK_BTN4_MSK +#define SYSTEM_STATE_LED DK_LED1 +#define IDENTIFY_STATE_LED DK_LED2 +#define FACTORY_RESET_SIGNAL_LED DK_LED3 +#define FACTORY_RESET_SIGNAL_LED1 DK_LED4 diff --git a/examples/lit-icd-app/nrfconnect/main/include/AppEvent.h b/examples/lit-icd-app/nrfconnect/main/include/AppEvent.h new file mode 100644 index 00000000000000..27ae7408f52e08 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/AppEvent.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "EventTypes.h" + +class LEDWidget; + +enum class AppEventType : uint8_t +{ + None = 0, + Button, + ButtonPushed, + ButtonReleased, + Timer, + UpdateLedState, + IdentifyStart, + IdentifyStop, +}; + +enum class FunctionEvent : uint8_t +{ + NoneSelected = 0, + SoftwareUpdate = 0, + FactoryReset, + AdvertisingStart +}; + +struct AppEvent +{ + union + { + struct + { + uint8_t PinNo; + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + int32_t Actor; + } LockEvent; + struct + { + LEDWidget * LedWidget; + } UpdateLedStateEvent; + }; + + AppEventType Type{ AppEventType::None }; + EventHandler Handler; +}; diff --git a/examples/lit-icd-app/nrfconnect/main/include/AppTask.h b/examples/lit-icd-app/nrfconnect/main/include/AppTask.h new file mode 100644 index 00000000000000..f1513b2d1e75cb --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/AppTask.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "AppEvent.h" +#include "LEDWidget.h" + +#if CONFIG_CHIP_FACTORY_DATA +#include +#else +#include +#endif + +struct k_timer; +struct Identify; + +class AppTask +{ +public: + static AppTask & Instance(void) + { + static AppTask sAppTask; + return sAppTask; + }; + CHIP_ERROR StartApp(); + + static void IdentifyStartHandler(Identify *); + static void IdentifyStopHandler(Identify *); + + static void PostEvent(const AppEvent & event); + +private: + CHIP_ERROR Init(); + + static void CancelTimer(); + static void StartTimer(uint32_t timeoutInMs); + + static void DispatchEvent(const AppEvent & event); + static void FunctionTimerEventHandler(const AppEvent & event); + static void FunctionHandler(const AppEvent & event); + static void StartBLEAdvertisementHandler(const AppEvent & event); + static void IcdUatEventHandler(const AppEvent & event); + static void UpdateLedStateEventHandler(const AppEvent & event); + + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged); + static void LEDStateUpdateHandler(LEDWidget & ledWidget); + static void FunctionTimerTimeoutCallback(k_timer * timer); + static void UpdateStatusLED(); + + FunctionEvent mFunction = FunctionEvent::NoneSelected; + bool mFunctionTimerActive = false; + +#if CONFIG_CHIP_FACTORY_DATA + chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; +#endif +}; diff --git a/examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h b/examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..4baa186190f638 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h @@ -0,0 +1,28 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once diff --git a/examples/lit-icd-app/nrfconnect/main/main.cpp b/examples/lit-icd-app/nrfconnect/main/main.cpp new file mode 100644 index 00000000000000..0f9b0451e4284d --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/main.cpp @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = AppTask::Instance().StartApp(); + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/lit-icd-app/nrfconnect/prj.conf b/examples/lit-icd-app/nrfconnect/prj.conf new file mode 100644 index 00000000000000..950be7c8c394e4 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/prj.conf @@ -0,0 +1,46 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_STD_CPP17=y + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Bluetooth Low Energy configuration +CONFIG_BT_DEVICE_NAME="MatterLIT" + +# Other settings +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y +CONFIG_RESET_ON_FATAL_ERROR=n + +# Reduce application size +CONFIG_USE_SEGGER_RTT=n + +# Enable Factory Data feature +CONFIG_CHIP_FACTORY_DATA=y +CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable LIT ICD configuration +CONFIG_CHIP_ENABLE_ICD_SUPPORT=y +CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf b/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf new file mode 100644 index 00000000000000..00607e349a31ab --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf @@ -0,0 +1,48 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_STD_CPP17=y + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Bluetooth Low Energy configuration +CONFIG_BT_DEVICE_NAME="MatterLIT" + +# Other settings +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y +CONFIG_RESET_ON_FATAL_ERROR=n + +# Reduce application size +CONFIG_USE_SEGGER_RTT=n + +# Disable Matter OTA DFU +CONFIG_CHIP_OTA_REQUESTOR=n + +# Disable QSPI NOR +CONFIG_CHIP_QSPI_NOR=n + +# Enable LIT ICD configuration +CONFIG_CHIP_ENABLE_ICD_SUPPORT=y +CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/prj_release.conf b/examples/lit-icd-app/nrfconnect/prj_release.conf new file mode 100644 index 00000000000000..61b6b3dfc6f8f8 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/prj_release.conf @@ -0,0 +1,60 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_STD_CPP17=y + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Bluetooth Low Energy configuration +CONFIG_BT_DEVICE_NAME="MatterLIT" + +# Enable system reset on fatal error +CONFIG_RESET_ON_FATAL_ERROR=y + +# Suspend devices when the CPU goes into sleep +CONFIG_PM_DEVICE=y + +# Disable all debug features +CONFIG_USE_SEGGER_RTT=n +CONFIG_SHELL=n +CONFIG_OPENTHREAD_SHELL=n +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_LOG=n +CONFIG_LOG_MODE_MINIMAL=n +CONFIG_ASSERT_VERBOSE=n +CONFIG_ASSERT_NO_FILE_INFO=y +CONFIG_PRINTK=n +CONFIG_PRINTK_SYNC=n +CONFIG_THREAD_NAME=n +CONFIG_BOOT_BANNER=n + +# Enable Factory Data feature +CONFIG_CHIP_FACTORY_DATA=y +CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable LIT ICD configuration +CONFIG_CHIP_ENABLE_ICD_SUPPORT=y +CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/third_party/connectedhomeip b/examples/lit-icd-app/nrfconnect/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/lock-app/genio/src/AppTask.cpp b/examples/lock-app/genio/src/AppTask.cpp index 7a438dd4974d3d..1c2f0719790196 100644 --- a/examples/lock-app/genio/src/AppTask.cpp +++ b/examples/lock-app/genio/src/AppTask.cpp @@ -60,8 +60,6 @@ #error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" #endif -#define UNUSED_PARAMETER(a) (a = a) - namespace { TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. diff --git a/examples/lock-app/genio/src/main.cpp b/examples/lock-app/genio/src/main.cpp index 416c81c53436d7..92b16a39663ee4 100644 --- a/examples/lock-app/genio/src/main.cpp +++ b/examples/lock-app/genio/src/main.cpp @@ -51,8 +51,6 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -#define UNUSED_PARAMETER(a) (a = a) - volatile int apperror_cnt; /*************************************************************************** diff --git a/examples/ota-requestor-app/genio/src/AppTask.cpp b/examples/ota-requestor-app/genio/src/AppTask.cpp index 43c92cf26adeeb..50d1d080a5b7b4 100644 --- a/examples/ota-requestor-app/genio/src/AppTask.cpp +++ b/examples/ota-requestor-app/genio/src/AppTask.cpp @@ -53,8 +53,6 @@ #error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" #endif -#define UNUSED_PARAMETER(a) (a = a) - namespace { TaskHandle_t sAppTaskHandle; diff --git a/examples/ota-requestor-app/genio/src/main.cpp b/examples/ota-requestor-app/genio/src/main.cpp index dcd85fbb920859..e3676c5c9eacbd 100644 --- a/examples/ota-requestor-app/genio/src/main.cpp +++ b/examples/ota-requestor-app/genio/src/main.cpp @@ -53,8 +53,6 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -#define UNUSED_PARAMETER(a) (a = a) - volatile int apperror_cnt; static void OTAEventsHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index 4216dbb4864452..c98882f30aba96 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -146,6 +146,9 @@ Identify gIdentify = { bool BaseApplication::sIsProvisioned = false; bool BaseApplication::sIsFactoryResetTriggered = false; LEDWidget * BaseApplication::sAppActionLed = nullptr; +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 +BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate(); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 #ifdef DIC_ENABLE namespace { @@ -163,6 +166,28 @@ void AppSpecificConnectivityEventCallback(const ChipDeviceEvent * event, intptr_ } // namespace #endif // DIC_ENABLE +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 +void BaseApplicationDelegate::OnCommissioningSessionStarted() +{ + isComissioningStarted = true; +} +void BaseApplicationDelegate::OnCommissioningSessionStopped() +{ + isComissioningStarted = false; +} +void BaseApplicationDelegate::OnCommissioningWindowClosed() +{ + if (!BaseApplication::GetProvisionStatus() && !isComissioningStarted) + { + int32_t status = wfx_power_save(RSI_SLEEP_MODE_8, STANDBY_POWER_SAVE_WITH_RAM_RETENTION); + if (status != SL_STATUS_OK) + { + ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); + } + } +} +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 + /********************************************************** * AppTask Definitions *********************************************************/ @@ -261,7 +286,6 @@ CHIP_ERROR BaseApplication::Init() #if CHIP_ENABLE_OPENTHREAD BaseApplication::sIsProvisioned = ConnectivityMgr().IsThreadProvisioned(); #endif - return err; } diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index 1714f47024f2c2..1a5c55587d76fe 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -30,6 +30,7 @@ #include "FreeRTOS.h" #include "timers.h" // provides FreeRTOS timer support #include +#include #include #include #include @@ -62,6 +63,17 @@ #define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) #define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 +class BaseApplicationDelegate : public AppDelegate +{ +private: + bool isComissioningStarted; + void OnCommissioningSessionStarted() override; + void OnCommissioningSessionStopped() override; + void OnCommissioningWindowClosed() override; +}; +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 + /********************************************************** * BaseApplication Declaration *********************************************************/ @@ -75,6 +87,9 @@ class BaseApplication static bool sIsProvisioned; static bool sIsFactoryResetTriggered; static LEDWidget * sAppActionLed; +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 + static BaseApplicationDelegate sAppDelegate; +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 /** * @brief Create AppTask task and Event Queue diff --git a/examples/platform/silabs/FreeRTOSConfig.h b/examples/platform/silabs/FreeRTOSConfig.h index 93c7ee36444715..478dfa10be547f 100644 --- a/examples/platform/silabs/FreeRTOSConfig.h +++ b/examples/platform/silabs/FreeRTOSConfig.h @@ -122,7 +122,7 @@ extern uint32_t SystemCoreClock; #include "sl_component_catalog.h" #endif -#if SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT +#ifdef SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT #include "SEGGER_SYSVIEW_FreeRTOS.h" #endif diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index e9fed8d924c3e0..32bf04cf0e0f7b 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -18,6 +18,7 @@ */ #include "AppConfig.h" +#include "BaseApplication.h" #include "OTAConfig.h" #include @@ -254,6 +255,9 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) initParams.endpointNativeParams = static_cast(&nativeParams); #endif +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 + initParams.appDelegate = &BaseApplication::sAppDelegate; +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 // Init Matter Server and Start Event Loop err = chip::Server::GetInstance().Init(initParams); @@ -303,10 +307,6 @@ CHIP_ERROR SilabsMatterConfig::InitWiFi(void) extern "C" void vApplicationIdleHook(void) { #if SIWX_917 && CHIP_CONFIG_ENABLE_ICD_SERVER - if (ConnectivityMgr().IsWiFiStationConnected()) - { - // Let the M4 sleep once commissioning is done and device is in idle state - sl_wfx_host_si91x_sleep_wakeup(); - } + sl_wfx_host_si91x_sleep_wakeup(); #endif } diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c index f78539d9817170..c5044fcf255a8e 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c @@ -44,6 +44,7 @@ #if SL_ICD_ENABLED && SIWX_917 #include "rsi_rom_power_save.h" #include "sl_si91x_button_pin_config.h" +#include "sl_si91x_driver.h" #include "sl_si91x_m4_ps.h" // TODO: should be removed once we are getting the press interrupt for button 0 with sleep @@ -188,8 +189,8 @@ sl_status_t join_callback_handler(sl_wifi_event_t event, char * result, uint32_t SILABS_LOG("F: Join Event received with %u bytes payload\n", result_length); callback_status = *(sl_status_t *) result; wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTED); - wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries++); is_wifi_disconnection_event = true; + wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries++); if (is_wifi_disconnection_event || wfx_rsi.join_retries <= WFX_RSI_CONFIG_MAX_JOIN) { xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN); @@ -256,28 +257,36 @@ void sl_wfx_host_si91x_sleep_wakeup() * @brief * Setting the RS911x in DTIM sleep based mode * - * @param[in] None + * @param[in] sl_si91x_ble_state : State to set for the BLE + sl_si91x_wifi_state : State to set for the WiFi * @return * None *********************************************************************/ -int32_t wfx_rsi_power_save() +int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) { int32_t status; - status = rsi_bt_power_save_profile(2, 0); + + status = rsi_bt_power_save_profile(sl_si91x_ble_state, 0); if (status != RSI_SUCCESS) { SILABS_LOG("BT Powersave Config Failed, Error Code : 0x%lX", status); return status; } - - sl_wifi_performance_profile_t wifi_profile = { .profile = ASSOCIATED_POWER_SAVE }; + sl_wifi_performance_profile_t wifi_profile = { .profile = sl_si91x_wifi_state }; status = sl_wifi_set_performance_profile(&wifi_profile); if (status != RSI_SUCCESS) { SILABS_LOG("Powersave Config Failed, Error Code : 0x%lX", status); return status; } - wfx_rsi.dev_state |= WFX_RSI_ST_SLEEP_READY; + if (sl_si91x_wifi_state == HIGH_PERFORMANCE) + { + wfx_rsi.dev_state &= ~(WFX_RSI_ST_SLEEP_READY); + } + else + { + wfx_rsi.dev_state |= WFX_RSI_ST_SLEEP_READY; + } return status; } #endif /* SL_ICD_ENABLED */ @@ -376,7 +385,7 @@ static sl_status_t wfx_rsi_init(void) } // Initiate and program the key required for TRNG hardware engine - status = sl_si91x_trng_program_key(trngKey, TRNGKEY_SIZE); + status = sl_si91x_trng_program_key((uint32_t *) trngKey, TRNGKEY_SIZE); if (status != SL_STATUS_OK) { SILABS_LOG("TRNG Key Programming Failed"); @@ -569,8 +578,7 @@ static sl_status_t wfx_rsi_do_join(void) } else { - SILABS_LOG("%s: WLAN: connecting to %s==%s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0], - wfx_rsi.sec.security); + SILABS_LOG("%s: WLAN: connecting to %s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], wfx_rsi.sec.security); /* * Join the network @@ -582,10 +590,14 @@ static sl_status_t wfx_rsi_do_join(void) sl_wifi_set_join_callback(join_callback_handler, NULL); +#if SL_ICD_ENABLED // Setting the listen interval to 0 which will set it to DTIM interval sl_wifi_listen_interval_t sleep_interval = { .listen_interval = 0 }; status = sl_wifi_set_listen_interval(SL_WIFI_CLIENT_INTERFACE, sleep_interval); + sl_wifi_advanced_client_configuration_t client_config = { .max_retry_attempts = 5 }; + sl_wifi_set_advanced_client_configuration(SL_WIFI_CLIENT_INTERFACE, &client_config); +#endif // SL_ICD_ENABLED /* Try to connect Wifi with given Credentials * untill there is a success or maximum number of tries allowed */ @@ -630,11 +642,11 @@ static sl_status_t wfx_rsi_do_join(void) wfx_rsi.join_retries); wfx_rsi.join_retries += 1; wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED); + wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries); if (is_wifi_disconnection_event || wfx_rsi.join_retries <= MAX_JOIN_RETRIES_COUNT) { xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN); } - wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries); } } } diff --git a/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi.h b/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi.h index 6721071a1de181..998b3ac1ef5d7a 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi.h +++ b/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi.h @@ -95,7 +95,7 @@ int32_t wfx_rsi_disconnect(); int32_t wfx_wifi_rsi_init(void); #if SL_ICD_ENABLED void sl_wfx_host_si91x_sleep_wakeup(); -int32_t wfx_rsi_power_save(); +int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); #endif /* SL_ICD_ENABLED */ #ifdef __cplusplus diff --git a/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.c b/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.c index 8f1f895f9683f9..85525fc1bc6dd0 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.c +++ b/examples/platform/silabs/SiWx917/SiWx917/wfx_rsi_host.c @@ -178,7 +178,7 @@ sl_status_t wfx_connect_to_ap(void) { if (wfx_rsi.dev_state & WFX_RSI_ST_STA_PROVISIONED) { - SILABS_LOG("%s: connecting to access point -> SSID: %s, PSK:%s", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0]); + SILABS_LOG("%s: connecting to access point -> SSID: %s", __func__, &wfx_rsi.sec.ssid[0]); xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN); } else @@ -194,13 +194,14 @@ sl_status_t wfx_connect_to_ap(void) * @fn sl_status_t wfx_power_save() * @brief * Implements the power save in sleepy application - * @param[in] None + * @param[in] sl_si91x_ble_state : State to set for the BLE + sl_si91x_wifi_state : State to set for the WiFi * @return SL_STATUS_OK if successful, * SL_STATUS_FAIL otherwise ***********************************************************************/ -sl_status_t wfx_power_save() +sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) { - if (wfx_rsi_power_save() != SL_STATUS_OK) + if (wfx_rsi_power_save(sl_si91x_ble_state, sl_si91x_wifi_state) != SL_STATUS_OK) { return SL_STATUS_FAIL; } diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c b/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c index 82976deb6a3b09..9f07d3f8f22c16 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c +++ b/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c @@ -57,11 +57,9 @@ LDMA_TransferCfg_t ldmaRXConfig; static osSemaphoreId_t transfer_done_semaphore = NULL; -static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * userParam) +static bool dma_callback([[maybe_unused]] unsigned int channel, [[maybe_unused]] unsigned int sequenceNo, + [[maybe_unused]] void * userParam) { - UNUSED_PARAMETER(channel); - UNUSED_PARAMETER(sequenceNo); - UNUSED_PARAMETER(userParam); #if defined(SL_CATLOG_POWER_MANAGER_PRESENT) sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); #endif @@ -69,10 +67,8 @@ static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * u return false; } -static void gpio_interrupt(uint8_t interrupt_number) +static void gpio_interrupt([[maybe_unused]] uint8_t interrupt_number) { - UNUSED_PARAMETER(interrupt_number); - if (NULL != init_config.rx_irq) { init_config.rx_irq(); @@ -312,4 +308,4 @@ void sl_si91x_host_disable_bus_interrupt(void) bool sl_si91x_host_is_in_irq_context(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0U; -} \ No newline at end of file +} diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c b/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c index ad6b5ed5e3418d..9097177b73a585 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c +++ b/examples/platform/silabs/efr32/rs911x/hal/efx_spi.c @@ -171,10 +171,7 @@ void sl_wfx_host_reset_chip(void) vTaskDelay(pdMS_TO_TICKS(3)); } -void gpio_interrupt(uint8_t interrupt_number) -{ - UNUSED_PARAMETER(interrupt_number); -} +void gpio_interrupt([[maybe_unused]] uint8_t interrupt_number) {} /***************************************************************** * @fn void rsi_hal_board_init(void) diff --git a/examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration.h b/examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration.h index 4310bf719f8179..5591467580bbc4 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration.h +++ b/examples/platform/silabs/efr32/rs911x/hal/sl_board_configuration.h @@ -48,6 +48,4 @@ typedef struct #define INTERRUPT_PIN PIN(A, 7) #define SLEEP_CONFIRM_PIN PIN(A, 5) /* Exp hdr 7 */ #endif - -#define NETWORK_INTERFACE_VALID(x) (x == SL_NET_DEFAULT_WIFI_CLIENT_INTERFACE) || (x == SL_NET_DEFAULT_WIFI_AP_INTERFACE) #endif /* _RSI_BOARD_CONFIGURATION_H_ */ \ No newline at end of file diff --git a/examples/platform/silabs/efr32/rs911x/rsi_if.c b/examples/platform/silabs/efr32/rs911x/rsi_if.c index c43389761dcdfc..1ba06d0e715c16 100644 --- a/examples/platform/silabs/efr32/rs911x/rsi_if.c +++ b/examples/platform/silabs/efr32/rs911x/rsi_if.c @@ -466,8 +466,7 @@ static void wfx_rsi_save_ap_info() // translation break; } - SILABS_LOG("%s: WLAN: connecting to %s==%s, sec=%d, status=%02x", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0], - wfx_rsi.sec.security, status); + SILABS_LOG("%s: WLAN: connecting to %s, sec=%d, status=%02x", __func__, &wfx_rsi.sec.ssid[0], wfx_rsi.sec.security, status); } /******************************************************************************************** @@ -511,8 +510,7 @@ static void wfx_rsi_do_join(void) return; } - SILABS_LOG("%s: WLAN: connecting to %s==%s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0], - wfx_rsi.sec.security); + SILABS_LOG("%s: WLAN: connecting to %s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], wfx_rsi.sec.security); /* * Join the network diff --git a/examples/platform/silabs/efr32/rs911x/wfx_rsi.h b/examples/platform/silabs/efr32/rs911x/wfx_rsi.h index 4d692064a5768f..07217056cef11b 100644 --- a/examples/platform/silabs/efr32/rs911x/wfx_rsi.h +++ b/examples/platform/silabs/efr32/rs911x/wfx_rsi.h @@ -92,7 +92,11 @@ int32_t wfx_rsi_get_ap_ext(wfx_wifi_scan_ext_t * extra_info); int32_t wfx_rsi_reset_count(); int32_t wfx_rsi_disconnect(); #if SL_ICD_ENABLED +#if SLI_SI917 +int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); +#else int32_t wfx_rsi_power_save(); +#endif /* SLI_SI917 */ #endif /* SL_ICD_ENABLED */ #ifdef __cplusplus diff --git a/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.c b/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.c index 331895bd3e524e..8764c0a9dda8bb 100644 --- a/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.c +++ b/examples/platform/silabs/efr32/rs911x/wfx_rsi_host.c @@ -180,7 +180,7 @@ sl_status_t wfx_connect_to_ap(void) { if (wfx_rsi.dev_state & WFX_RSI_ST_STA_PROVISIONED) { - SILABS_LOG("%s: connecting to access point -> SSID: %s, PSK:%s", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0]); + SILABS_LOG("%s: connecting to access point -> SSID: %s", __func__, &wfx_rsi.sec.ssid[0]); xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN); } else @@ -192,6 +192,21 @@ sl_status_t wfx_connect_to_ap(void) } #if SL_ICD_ENABLED +#if SLI_SI917 +/********************************************************************* + * @fn sl_status_t wfx_power_save() + * @brief + * Implements the power save in sleepy application + * @param[in] sl_si91x_ble_state : State to set for the BLE + sl_si91x_wifi_state : State to set for the WiFi + * @return SL_STATUS_OK if successful, + * SL_STATUS_FAIL otherwise + ***********************************************************************/ +sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) +{ + return (wfx_rsi_power_save(sl_si91x_ble_state, sl_si91x_wifi_state) ? SL_STATUS_FAIL : SL_STATUS_OK); +} +#else // For RS9116 /********************************************************************* * @fn sl_status_t wfx_power_save() * @brief @@ -204,6 +219,7 @@ sl_status_t wfx_power_save() { return (wfx_rsi_power_save() ? SL_STATUS_FAIL : SL_STATUS_OK); } +#endif /* SLI_SI917 */ #endif /* SL_ICD_ENABLED */ /********************************************************************* diff --git a/examples/platform/silabs/main.cpp b/examples/platform/silabs/main.cpp index 3c9829edd1954f..a3155194e8d1dd 100644 --- a/examples/platform/silabs/main.cpp +++ b/examples/platform/silabs/main.cpp @@ -71,8 +71,9 @@ int main(void) void application_start(void * unused) { - if (SilabsMatterConfig::InitMatter(BLE_DEV_NAME) != CHIP_NO_ERROR) - appError(CHIP_ERROR_INTERNAL); + CHIP_ERROR err = SilabsMatterConfig::InitMatter(BLE_DEV_NAME); + if (err != CHIP_NO_ERROR) + appError(err); gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); @@ -83,8 +84,9 @@ void application_start(void * unused) chip::DeviceLayer::PlatformMgr().UnlockChipStack(); SILABS_LOG("Starting App Task"); - if (AppTask::GetAppTask().StartAppTask() != CHIP_NO_ERROR) - appError(CHIP_ERROR_INTERNAL); + err = AppTask::GetAppTask().StartAppTask(); + if (err != CHIP_NO_ERROR) + appError(err); vTaskDelete(main_Task); } diff --git a/examples/platform/silabs/silabs_utils.cpp b/examples/platform/silabs/silabs_utils.cpp index 7231836c15bf7e..c8a068a328955c 100644 --- a/examples/platform/silabs/silabs_utils.cpp +++ b/examples/platform/silabs/silabs_utils.cpp @@ -27,7 +27,7 @@ void appError(int err) snprintf(faultMessage, sizeof faultMessage, "App Critical Error:%d", err); SILABS_LOG("!!!!!!!!!!!! %s !!!!!!!!!!!", faultMessage); chip::DeviceLayer::Silabs::OnSoftwareFaultEventHandler(faultMessage); - vTaskDelay(pdMS_TO_TICKS(1000)); + vTaskSuspendAll(); /* Force an assert. */ chipAbort(); } diff --git a/examples/temperature-measurement-app/esp32/README.md b/examples/temperature-measurement-app/esp32/README.md index 18d07ff639b06a..99347fc6ead9f4 100644 --- a/examples/temperature-measurement-app/esp32/README.md +++ b/examples/temperature-measurement-app/esp32/README.md @@ -51,9 +51,39 @@ chip-tool pairing ble-wifi 1 SSID PASSPHRASE 20202021 3840 chip-tool diagnosticlogs retrieve-logs-request 0 0 1 0 # Read network diagnostic using BDX protocol -chip-tool diagnosticlogs retrieve-logs-request 1 0 1 0 --TransferFileDesignator network-diag.log +chip-tool interactive start +> diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator network-diag.log +# Retrieve crash over BDX +> diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator crash.bin ``` +esp-idf supports storing and retrieving +[core dump in flash](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/core_dump.html#core-dump-to-flash). + +To support that, application needs to add core dump partition's entry in +[partitons.csv](partitions.csv#7) and we need to enable few menuconfig options. + +``` +CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y +CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y +``` + +This example's partition table and sdkconfig.default are already modified + +- Retrieve the core dump using diagnostic logs cluster + + ``` + # Read crash logs over BDX + chip-tool interactive start + > diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator crash.bin + ``` + +- Decode the crash logs, using espcoredump.py + ``` + espcoredump.py --chip (CHIP) info_corefile --core /tmp/crash.bin \ + --core-format elf build/chip-temperature-measurement-app.elf + ``` + ## Optimization Optimization related to WiFi, BLuetooth, Asserts etc are the part of this diff --git a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt index 8953d34869b76a..062266652dc303 100644 --- a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt +++ b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt @@ -55,7 +55,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" ) -set(PRIV_REQUIRES_LIST chip QRCode bt nvs_flash) +set(PRIV_REQUIRES_LIST chip QRCode bt nvs_flash bootloader_support espcoredump) if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build @@ -83,7 +83,7 @@ endif (CONFIG_ENABLE_PW_RPC) idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} PRIV_REQUIRES ${PRIV_REQUIRES_LIST} - EMBED_FILES diagnostic_logs/end_user_support.log diagnostic_logs/network_diag.log diagnostic_logs/crash.log) + EMBED_FILES diagnostic_logs/end_user_support.log diagnostic_logs/network_diag.log) include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") chip_app_component_codegen("${CHIP_ROOT}/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter") diff --git a/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp b/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp index 4bef0fbd86cc19..5034e3f928788f 100644 --- a/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp +++ b/examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp @@ -19,10 +19,19 @@ #include #include +#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) +#include +#include +// Its a bit hackish but we need this in order to pull in the sizeof(core_dump_header_t) +// we can even use the static 20 but, what if that gets chagned? +#include "../include_core_dump/esp_core_dump_types.h" +#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + using namespace chip; using namespace chip::app::Clusters::DiagnosticLogs; LogProvider LogProvider::sInstance; +LogProvider::CrashLogContext LogProvider::sCrashLogContext; namespace { bool IsValidIntent(IntentEnum intent) @@ -30,24 +39,21 @@ bool IsValidIntent(IntentEnum intent) return intent != IntentEnum::kUnknownEnumValue; } -// end_user_support.log, network_diag.log, and crash.log files are embedded in the firmware +// end_user_support.log and network_diag.log files are embedded in the firmware extern const uint8_t endUserSupportLogStart[] asm("_binary_end_user_support_log_start"); extern const uint8_t endUserSupportLogEnd[] asm("_binary_end_user_support_log_end"); extern const uint8_t networkDiagnosticLogStart[] asm("_binary_network_diag_log_start"); extern const uint8_t networkDiagnosticLogEnd[] asm("_binary_network_diag_log_end"); - -extern const uint8_t crashLogStart[] asm("_binary_crash_log_start"); -extern const uint8_t crashLogEnd[] asm("_binary_crash_log_end"); } // namespace LogProvider::~LogProvider() { - for (auto sessionSpan : mSessionSpanMap) + for (auto sessionSpan : mSessionContextMap) { Platform::MemoryFree(sessionSpan.second); } - mSessionSpanMap.clear(); + mSessionContextMap.clear(); } CHIP_ERROR LogProvider::GetLogForIntent(IntentEnum intent, MutableByteSpan & outBuffer, Optional & outTimeStamp, @@ -69,93 +75,233 @@ CHIP_ERROR LogProvider::GetLogForIntent(IntentEnum intent, MutableByteSpan & out return CHIP_NO_ERROR; } -const uint8_t * LogProvider::GetDataStartForIntent(IntentEnum intent) +size_t LogProvider::GetSizeForIntent(IntentEnum intent) { switch (intent) { case IntentEnum::kEndUserSupport: - return &endUserSupportLogStart[0]; + return static_cast(endUserSupportLogEnd - endUserSupportLogStart); case IntentEnum::kNetworkDiag: - return &networkDiagnosticLogStart[0]; + return static_cast(networkDiagnosticLogEnd - networkDiagnosticLogStart); case IntentEnum::kCrashLogs: - return &crashLogStart[0]; + return GetCrashSize(); default: - return nullptr; + return 0; } } -size_t LogProvider::GetSizeForIntent(IntentEnum intent) +size_t LogProvider::GetCrashSize() { + size_t outSize = 0; + +#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + size_t unusedOutAddr; + esp_err_t esp_err = esp_core_dump_image_get(&unusedOutAddr, &outSize); + VerifyOrReturnValue(esp_err == ESP_OK, 0, ChipLogError(DeviceLayer, "Failed to get core dump image, esp_err:%d", esp_err)); +#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + + return outSize; +} + +CHIP_ERROR LogProvider::MapCrashPartition(CrashLogContext * context) +{ +#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + size_t outAddr, outSize; + esp_err_t esp_err = esp_core_dump_image_get(&outAddr, &outSize); + VerifyOrReturnError(esp_err == ESP_OK, CHIP_ERROR(ChipError::Range::kPlatform, esp_err), + ChipLogError(DeviceLayer, "Failed to get core dump image, esp_err:%d", esp_err)); + + /* map the full core dump parition, including the checksum. */ + esp_err = spi_flash_mmap(outAddr, outSize, SPI_FLASH_MMAP_DATA, &context->mappedAddress, &context->mappedHandle); + VerifyOrReturnError(esp_err == ESP_OK, CHIP_ERROR(ChipError::Range::kPlatform, esp_err), + ChipLogError(DeviceLayer, "Failed to mmap the crash partition, esp_err:%d", esp_err)); + + context->crashSize = static_cast(outSize); + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_FOUND; +#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) +} + +CHIP_ERROR LogProvider::PrepareLogContextForIntent(LogContext * context, IntentEnum intent) +{ + context->intent = intent; + switch (intent) { + case IntentEnum::kEndUserSupport: { + context->EndUserSupport.span = + ByteSpan(&endUserSupportLogStart[0], static_cast(endUserSupportLogEnd - endUserSupportLogStart)); + } + break; + + case IntentEnum::kNetworkDiag: { + context->NetworkDiag.span = + ByteSpan(&networkDiagnosticLogStart[0], static_cast(networkDiagnosticLogEnd - networkDiagnosticLogStart)); + } + break; + + case IntentEnum::kCrashLogs: { +#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + sCrashLogContext.Reset(); + context->Crash.logContext = &sCrashLogContext; + + CHIP_ERROR err = MapCrashPartition(context->Crash.logContext); + VerifyOrReturnError(err == CHIP_NO_ERROR, err, context->Crash.logContext = nullptr); + + context->Crash.logContext->readOffset = sizeof(core_dump_header_t); + context->Crash.logContext->isMapped = true; +#else + return CHIP_ERROR_NOT_FOUND; +#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + } + break; + + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + + return CHIP_NO_ERROR; +} + +void LogProvider::CleanupLogContextForIntent(LogContext * context) +{ + switch (context->intent) + { case IntentEnum::kEndUserSupport: - return static_cast(endUserSupportLogEnd - endUserSupportLogStart); + break; + case IntentEnum::kNetworkDiag: - return static_cast(networkDiagnosticLogEnd - networkDiagnosticLogStart); - case IntentEnum::kCrashLogs: - return static_cast(crashLogEnd - crashLogStart); + break; + + case IntentEnum::kCrashLogs: { +#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + CrashLogContext * logContext = context->Crash.logContext; + spi_flash_munmap(logContext->mappedHandle); + logContext->Reset(); +#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + } + break; + default: - return 0; + break; } } +CHIP_ERROR LogProvider::GetDataForIntent(LogContext * context, MutableByteSpan & outBuffer, bool & outIsEndOfLog) +{ + switch (context->intent) + { + case IntentEnum::kEndUserSupport: { + auto dataSize = context->EndUserSupport.span.size(); + auto count = std::min(dataSize, outBuffer.size()); + + VerifyOrReturnError(CanCastTo(count), CHIP_ERROR_INVALID_ARGUMENT, outBuffer.reduce_size(0)); + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(context->EndUserSupport.span.data(), count), outBuffer)); + + outIsEndOfLog = dataSize == count; + if (!outIsEndOfLog) + { + // reduce the span after reading count bytes + context->EndUserSupport.span = context->EndUserSupport.span.SubSpan(count); + } + } + break; + + case IntentEnum::kNetworkDiag: { + auto dataSize = context->NetworkDiag.span.size(); + auto count = std::min(dataSize, outBuffer.size()); + + VerifyOrReturnError(CanCastTo(count), CHIP_ERROR_INVALID_ARGUMENT, outBuffer.reduce_size(0)); + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(context->NetworkDiag.span.data(), count), outBuffer)); + + outIsEndOfLog = dataSize == count; + if (!outIsEndOfLog) + { + // reduce the span after reading count bytes + context->NetworkDiag.span = context->NetworkDiag.span.SubSpan(count); + } + } + break; + + case IntentEnum::kCrashLogs: { +#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + CrashLogContext * logContext = context->Crash.logContext; + size_t dataSize = logContext->crashSize - logContext->readOffset; + auto count = std::min(dataSize, outBuffer.size()); + + VerifyOrReturnError(CanCastTo(count), CHIP_ERROR_INVALID_ARGUMENT, outBuffer.reduce_size(0)); + + const uint8_t * readAddr = reinterpret_cast(logContext->mappedAddress) + logContext->readOffset; + memcpy(outBuffer.data(), readAddr, count); + outBuffer.reduce_size(count); + + logContext->readOffset += count; + outIsEndOfLog = dataSize == count; +#else + outBuffer.reduce_size(0); + return CHIP_ERROR_NOT_FOUND; +#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) + } + break; + + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + + return CHIP_NO_ERROR; +} + CHIP_ERROR LogProvider::StartLogCollection(IntentEnum intent, LogSessionHandle & outHandle, Optional & outTimeStamp, Optional & outTimeSinceBoot) { VerifyOrReturnValue(IsValidIntent(intent), CHIP_ERROR_INVALID_ARGUMENT); - const uint8_t * dataStart = GetDataStartForIntent(intent); - VerifyOrReturnError(dataStart, CHIP_ERROR_NOT_FOUND); - - size_t dataSize = GetSizeForIntent(intent); - VerifyOrReturnError(dataSize, CHIP_ERROR_NOT_FOUND); + // In case of crash logs we can only mmap at max once, so check before doing anything + if (intent == IntentEnum::kCrashLogs) + { + VerifyOrReturnError(sCrashLogContext.isMapped == false, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(DeviceLayer, "Crash partition already mapped")); + } - ByteSpan * span = reinterpret_cast(Platform::MemoryCalloc(1, sizeof(ByteSpan))); - VerifyOrReturnValue(span, CHIP_ERROR_NO_MEMORY); + LogContext * context = reinterpret_cast(Platform::MemoryCalloc(1, sizeof(LogContext))); + VerifyOrReturnValue(context != nullptr, CHIP_ERROR_NO_MEMORY); - *span = ByteSpan(dataStart, dataSize); + CHIP_ERROR err = PrepareLogContextForIntent(context, intent); + VerifyOrReturnError(err == CHIP_NO_ERROR, err, Platform::MemoryFree(context)); mLogSessionHandle++; // If the session handle rolls over to UINT16_MAX which is invalid, reset to 0. VerifyOrDo(mLogSessionHandle != kInvalidLogSessionHandle, mLogSessionHandle = 0); - outHandle = mLogSessionHandle; - mSessionSpanMap[mLogSessionHandle] = span; + outHandle = mLogSessionHandle; + mSessionContextMap[mLogSessionHandle] = context; + return CHIP_NO_ERROR; } CHIP_ERROR LogProvider::EndLogCollection(LogSessionHandle sessionHandle) { VerifyOrReturnValue(sessionHandle != kInvalidLogSessionHandle, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnValue(mSessionSpanMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnValue(mSessionContextMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); - ByteSpan * span = mSessionSpanMap[sessionHandle]; - mSessionSpanMap.erase(sessionHandle); + LogContext * context = mSessionContextMap[sessionHandle]; + VerifyOrReturnError(context, CHIP_ERROR_INCORRECT_STATE); + + CleanupLogContextForIntent(context); + Platform::MemoryFree(context); + mSessionContextMap.erase(sessionHandle); - Platform::MemoryFree(span); return CHIP_NO_ERROR; } CHIP_ERROR LogProvider::CollectLog(LogSessionHandle sessionHandle, MutableByteSpan & outBuffer, bool & outIsEndOfLog) { VerifyOrReturnValue(sessionHandle != kInvalidLogSessionHandle, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnValue(mSessionSpanMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); - - ByteSpan * span = mSessionSpanMap[sessionHandle]; - auto dataSize = span->size(); - auto count = std::min(dataSize, outBuffer.size()); - - VerifyOrReturnError(CanCastTo(count), CHIP_ERROR_INVALID_ARGUMENT, outBuffer.reduce_size(0)); - - ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(span->data(), count), outBuffer)); + VerifyOrReturnValue(mSessionContextMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT); - outIsEndOfLog = dataSize == count; + LogContext * context = mSessionContextMap[sessionHandle]; + VerifyOrReturnError(context, CHIP_ERROR_INCORRECT_STATE); - if (!outIsEndOfLog) - { - // reduce the span after reading count bytes - *span = span->SubSpan(count); - } - - return CHIP_NO_ERROR; + return GetDataForIntent(context, outBuffer, outIsEndOfLog); } diff --git a/examples/temperature-measurement-app/esp32/main/diagnostic_logs/crash.log b/examples/temperature-measurement-app/esp32/main/diagnostic_logs/crash.log deleted file mode 100644 index 04089de8ce7afd..00000000000000 --- a/examples/temperature-measurement-app/esp32/main/diagnostic_logs/crash.log +++ /dev/null @@ -1,21 +0,0 @@ -W (5047Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled. - -Core 0 register dump: -PC : 0x4009579a PS : 0x00060c33 A0 : 0x800941e1 A1 : 0x3fff3630 -0x4009579a: uxListRemove at /opt/espressif/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:195 - -A2 : 0x00000006 A3 : 0x00060c20 A4 : 0x00000000 A5 : 0x00060c23 -A6 : 0xb33fffff A7 : 0xb33fffff A8 : 0x800950f0 A9 : 0x3fff3600 -A10 : 0x00000001 A11 : 0x000000fe A12 : 0x00000000 A13 : 0x00000000 -A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000000a EXCCAUSE: 0x0000001c -EXCVADDR: 0x00000016 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff -0x4000c2e0: memcpy in ROM -0x4000c2f6: memcpy in ROM - -Backtrace: 0x40095797:0x3fff3630 0x400941de:0x3fff3650 0x40154b39:0x3fff3670 0x40154b53:0x3fff3690 0x4013e20d:0x3fff36b0 0x40094fa6:0x3fff36d0 -0x40095797: uxListRemove at /opt/espressif/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:202 -0x400941de: vTaskDelete at /opt/espressif/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:1434 (discriminator 4) -0x40154b39: esp_nimble_disable at /opt/espressif/esp-idf/components/bt/host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c:55 -0x40154b53: nimble_port_freertos_deinit at /opt/espressif/esp-idf/components/bt/host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c:80 -0x4013e20d: chip::DeviceLayer::Internal::BLEManagerImpl::bleprph_host_task(void*) at /home/smart/projects/smp_matter/build/esp-idf/chip/../../../../../../../opt/espressif/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/platform/ESP32/nimble/BLEManagerImpl.cpp:864 -0x40094fa6: vPortTaskWrapper at /opt/espressif/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162 diff --git a/examples/temperature-measurement-app/esp32/main/include/diagnostic-logs-provider-delegate-impl.h b/examples/temperature-measurement-app/esp32/main/include/diagnostic-logs-provider-delegate-impl.h index d47dccafa6079d..c3d1bd389fb39b 100644 --- a/examples/temperature-measurement-app/esp32/main/include/diagnostic-logs-provider-delegate-impl.h +++ b/examples/temperature-measurement-app/esp32/main/include/diagnostic-logs-provider-delegate-impl.h @@ -20,6 +20,7 @@ #include #include +#include namespace chip { namespace app { @@ -54,12 +55,59 @@ class LogProvider : public DiagnosticLogsProviderDelegate LogProvider(const LogProvider &) = delete; LogProvider & operator=(const LogProvider &) = delete; - // This tracks the ByteSpan for each session - std::map mSessionSpanMap; + struct CrashLogContext + { + spi_flash_mmap_handle_t mappedHandle = 0; + const void * mappedAddress = nullptr; + uint32_t crashSize = 0; + uint32_t readOffset = 0; + bool isMapped = 0; + + void Reset() + { + this->mappedHandle = 0; + this->mappedAddress = nullptr; + this->crashSize = 0; + this->readOffset = 0; + this->isMapped = 0; + } + }; + + static CrashLogContext sCrashLogContext; + + struct LogContext + { + IntentEnum intent; + union + { + struct + { + ByteSpan span; + } EndUserSupport; + struct + { + ByteSpan span; + } NetworkDiag; + struct + { + // TODO: This be a ref counted, so that we can serve parallel queries for crash logs + CrashLogContext * logContext; + } Crash; + }; + }; + + // This tracks the ByteSpan for each session, need to change this to void * + std::map mSessionContextMap; LogSessionHandle mLogSessionHandle = kInvalidLogSessionHandle; - const uint8_t * GetDataStartForIntent(IntentEnum intent); + // Helpers for Retrieving Core Dump from flash + size_t GetCrashSize(); + CHIP_ERROR MapCrashPartition(CrashLogContext * crashLogContext); + + CHIP_ERROR PrepareLogContextForIntent(LogContext * context, IntentEnum intent); + void CleanupLogContextForIntent(LogContext * contex); + CHIP_ERROR GetDataForIntent(LogContext * context, MutableByteSpan & outBuffer, bool & outIsEndOfLog); }; } // namespace DiagnosticLogs diff --git a/examples/temperature-measurement-app/esp32/partitions.csv b/examples/temperature-measurement-app/esp32/partitions.csv index 8b0928187b8708..35c776d19e80fa 100644 --- a/examples/temperature-measurement-app/esp32/partitions.csv +++ b/examples/temperature-measurement-app/esp32/partitions.csv @@ -2,5 +2,6 @@ # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap nvs, data, nvs, , 0xC000, phy_init, data, phy, , 0x1000, -# Factory partition size about 1.9MB -factory, app, factory, , 1920K, +# Factory partition size about 1.5MB +factory, app, factory, , 1536K, +coredump, data, coredump,, 64K diff --git a/examples/temperature-measurement-app/esp32/sdkconfig.defaults b/examples/temperature-measurement-app/esp32/sdkconfig.defaults index 6d3243cabfeb8c..3dcab272b297db 100644 --- a/examples/temperature-measurement-app/esp32/sdkconfig.defaults +++ b/examples/temperature-measurement-app/esp32/sdkconfig.defaults @@ -99,3 +99,6 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=6 # Enable the diagnostic logs transfer over BDX protocol CONFIG_CHIP_ENABLE_BDX_LOG_TRANSFER=y + +CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y +CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y diff --git a/examples/thermostat/genio/src/main.cpp b/examples/thermostat/genio/src/main.cpp index 93bb82a21b0735..d545409c706913 100644 --- a/examples/thermostat/genio/src/main.cpp +++ b/examples/thermostat/genio/src/main.cpp @@ -51,8 +51,6 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -#define UNUSED_PARAMETER(a) (a = a) - volatile int apperror_cnt; /*************************************************************************** diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java index 79b02f01386769..540798aae913b7 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java @@ -41,6 +41,7 @@ import com.matter.tv.server.tvapp.LowPowerManagerStub; import com.matter.tv.server.tvapp.MediaInputManagerStub; import com.matter.tv.server.tvapp.MediaPlaybackManagerStub; +import com.matter.tv.server.tvapp.MessagesManagerStub; import com.matter.tv.server.tvapp.OnOffManagerStub; import com.matter.tv.server.tvapp.TvApp; import com.matter.tv.server.tvapp.WakeOnLanManagerStub; @@ -96,6 +97,8 @@ public void init(@NonNull Context context) { app.setMediaPlaybackManager(endpoint, new MediaPlaybackManagerStub(endpoint)); } else if (clusterId == Clusters.ClusterId_Channel) { app.setChannelManager(endpoint, new ChannelManagerStub(endpoint)); + } else if (clusterId == Clusters.ClusterId_Messaging) { + app.setMessagesManager(endpoint, new MessagesManagerStub(endpoint)); } else if (clusterId == Clusters.ClusterId_OnOff) { mOnOffEndpoint = endpoint; app.setOnOffManager(endpoint, new OnOffManagerStub(endpoint)); diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn index 63de5a515b0754..47157a271edfe8 100644 --- a/examples/tv-app/android/BUILD.gn +++ b/examples/tv-app/android/BUILD.gn @@ -69,6 +69,8 @@ shared_library("jni") { "java/MediaInputManager.h", "java/MediaPlaybackManager.cpp", "java/MediaPlaybackManager.h", + "java/MessagesManager.cpp", + "java/MessagesManager.h", "java/MyUserPrompter-JNI.cpp", "java/MyUserPrompter-JNI.h", "java/MyUserPrompterResolver-JNI.cpp", @@ -143,6 +145,10 @@ android_library("java") { "java/src/com/matter/tv/server/tvapp/MediaPlaybackManagerStub.java", "java/src/com/matter/tv/server/tvapp/MediaPlaybackPosition.java", "java/src/com/matter/tv/server/tvapp/MediaTrack.java", + "java/src/com/matter/tv/server/tvapp/Message.java", + "java/src/com/matter/tv/server/tvapp/MessageResponseOption.java", + "java/src/com/matter/tv/server/tvapp/MessagesManager.java", + "java/src/com/matter/tv/server/tvapp/MessagesManagerStub.java", "java/src/com/matter/tv/server/tvapp/OnOffManager.java", "java/src/com/matter/tv/server/tvapp/OnOffManagerStub.java", "java/src/com/matter/tv/server/tvapp/TvApp.java", diff --git a/examples/tv-app/android/java/ChannelManager.cpp b/examples/tv-app/android/java/ChannelManager.cpp index 3c0efcab9f8cdc..c7067132e46e9d 100644 --- a/examples/tv-app/android/java/ChannelManager.cpp +++ b/examples/tv-app/android/java/ChannelManager.cpp @@ -57,6 +57,7 @@ void ChannelManager::NewManager(jint endpoint, jobject manager) CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -66,6 +67,8 @@ CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder VerifyOrExit(mChannelManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetChannelListMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { jobjectArray channelInfoList = (jobjectArray) env->CallObjectMethod(mChannelManagerObject.ObjectRef(), mGetChannelListMethod); @@ -134,6 +137,7 @@ CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type lineupInfo; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -144,6 +148,8 @@ CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder) VerifyOrExit(mChannelManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetLineupMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + { jobject channelLineupObject = env->CallObjectMethod(mChannelManagerObject.ObjectRef(), mGetLineupMethod); if (channelLineupObject != nullptr) @@ -197,6 +203,7 @@ CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder) CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type channelInfo; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -207,6 +214,8 @@ CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEnco VerifyOrExit(mChannelManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetCurrentChannelMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + { jobject channelInfoObject = env->CallObjectMethod(mChannelManagerObject.ObjectRef(), mGetCurrentChannelMethod); if (channelInfoObject != nullptr) @@ -273,6 +282,7 @@ CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEnco void ChannelManager::HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) { + DeviceLayer::StackUnlock unlock; std::string name(match.data(), match.size()); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -282,9 +292,10 @@ void ChannelManager::HandleChangeChannel(CommandResponseHelperExceptionClear(); + { UtfString jniname(env, name.c_str()); - env->ExceptionClear(); jobject channelObject = env->CallObjectMethod(mChannelManagerObject.ObjectRef(), mChangeChannelMethod, jniname.jniValue()); if (env->ExceptionCheck()) { @@ -319,6 +330,7 @@ void ChannelManager::HandleChangeChannel(CommandResponseHelper> & externalIdList, const chip::Optional & data) { + DeviceLayer::StackUnlock unlock; ProgramGuideResponseType response; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -394,6 +408,8 @@ void ChannelManager::HandleGetProgramGuide( VerifyOrExit(mChannelManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetProgramGuideMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + { // NOTE: this example app does not pass the Data, PageToken, ChannelsArray or ExternalIdList through to the Java layer UtfString jData(env, ""); @@ -591,6 +607,7 @@ bool ChannelManager::HandleRecordProgram(const chip::CharSpan & programIdentifie const DataModel::DecodableList & externalIdList, const chip::ByteSpan & data) { + DeviceLayer::StackUnlock unlock; jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnValue(env != nullptr, false, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -628,6 +645,7 @@ bool ChannelManager::HandleCancelRecordProgram(const chip::CharSpan & programIde const DataModel::DecodableList & externalIdList, const chip::ByteSpan & data) { + DeviceLayer::StackUnlock unlock; jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnValue(env != nullptr, false, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp index 84e7d9933ad022..00b4ca7a225b2c 100644 --- a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace chip { @@ -43,6 +44,7 @@ std::string ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttri return ""; } + DeviceLayer::StackUnlock unlock; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index 3963140d1b5e65..2e5dcbe0f3b5e1 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace chip { @@ -50,6 +51,7 @@ void ContentAppCommandDelegate::InvokeCommand(CommandHandlerInterface::HandlerCo { if (handlerContext.mRequestPath.mEndpointId >= FIXED_ENDPOINT_COUNT) { + DeviceLayer::StackUnlock unlock; TLV::TLVReader readerForJson; readerForJson.Init(handlerContext.mPayload); diff --git a/examples/tv-app/android/java/ContentLauncherManager.cpp b/examples/tv-app/android/java/ContentLauncherManager.cpp index caa14b04f9e938..f68e1131fa6fb8 100644 --- a/examples/tv-app/android/java/ContentLauncherManager.cpp +++ b/examples/tv-app/android/java/ContentLauncherManager.cpp @@ -51,6 +51,7 @@ void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper playbackPreferences, bool useCurrentContext) { + DeviceLayer::StackUnlock unlock; Commands::LauncherResponse::Type response; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -61,6 +62,7 @@ void ContentLauncherManager::HandleLaunchContent(CommandResponseHelperExceptionClear(); { UtfString jData(env, data); @@ -106,6 +108,7 @@ void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelperExceptionClear(); + { UtfString jContentUrl(env, contentUrl); UtfString jDisplayString(env, displayString); @@ -160,6 +165,7 @@ void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelper acceptedHeadersList; @@ -170,6 +176,8 @@ CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncod VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetAcceptHeaderMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { jobjectArray acceptedHeadersArray = (jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mGetAcceptHeaderMethod); @@ -203,6 +211,7 @@ CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncod uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols() { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); uint32_t supportedStreamingProtocols = 0; @@ -213,6 +222,8 @@ uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols() VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetSupportedStreamingProtocolsMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + { jlong jSupportedStreamingProtocols = env->CallLongMethod(mContentLauncherManagerObject.ObjectRef(), mGetSupportedStreamingProtocolsMethod); diff --git a/examples/tv-app/android/java/KeypadInputManager.cpp b/examples/tv-app/android/java/KeypadInputManager.cpp index a43a56cb860978..2382397fc351d9 100644 --- a/examples/tv-app/android/java/KeypadInputManager.cpp +++ b/examples/tv-app/android/java/KeypadInputManager.cpp @@ -44,6 +44,7 @@ void KeypadInputManager::NewManager(jint endpoint, jobject manager) void KeypadInputManager::HandleSendKey(CommandResponseHelper & helper, const CECKeyCodeEnum & keyCode) { + DeviceLayer::StackUnlock unlock; Commands::SendKeyResponse::Type response; jint ret = -1; diff --git a/examples/tv-app/android/java/LevelManager.cpp b/examples/tv-app/android/java/LevelManager.cpp index b79f150c7ae20e..f9be7578e830ab 100644 --- a/examples/tv-app/android/java/LevelManager.cpp +++ b/examples/tv-app/android/java/LevelManager.cpp @@ -112,6 +112,7 @@ CHIP_ERROR LevelManager::InitializeWithObjects(jobject managerObject) void LevelManager::HandleLevelChanged(uint8_t value) { + DeviceLayer::StackUnlock unlock; ChipLogProgress(Zcl, "LevelManager::HandleLevelChanged"); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); diff --git a/examples/tv-app/android/java/LowPowerManager.cpp b/examples/tv-app/android/java/LowPowerManager.cpp index 12e234964d4c5e..5c6906fcd1d659 100644 --- a/examples/tv-app/android/java/LowPowerManager.cpp +++ b/examples/tv-app/android/java/LowPowerManager.cpp @@ -64,6 +64,7 @@ void LowPowerManager::InitializeWithObjects(jobject managerObject) bool LowPowerManager::HandleSleep() { + DeviceLayer::StackUnlock unlock; jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); JniLocalReferenceScope scope(env); diff --git a/examples/tv-app/android/java/MediaInputManager.cpp b/examples/tv-app/android/java/MediaInputManager.cpp index bbc575b6eab378..0f1c922243c2be 100644 --- a/examples/tv-app/android/java/MediaInputManager.cpp +++ b/examples/tv-app/android/java/MediaInputManager.cpp @@ -51,6 +51,7 @@ void MediaInputManager::NewManager(jint endpoint, jobject manager) CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NO_ENV, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -60,6 +61,8 @@ CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncode VerifyOrExit(mMediaInputManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetInputListMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { jobjectArray inputArray = (jobjectArray) env->CallObjectMethod(mMediaInputManagerObject.ObjectRef(), mGetInputListMethod); if (env->ExceptionCheck()) @@ -121,6 +124,7 @@ CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncode uint8_t MediaInputManager::HandleGetCurrentInput() { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; jint index = -1; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -130,7 +134,8 @@ uint8_t MediaInputManager::HandleGetCurrentInput() ChipLogProgress(Zcl, "Received MediaInputManager::HandleGetCurrentInput"); VerifyOrExit(mMediaInputManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetCurrentInputMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV); + + env->ExceptionClear(); { index = env->CallIntMethod(mMediaInputManagerObject.ObjectRef(), mGetCurrentInputMethod); @@ -154,6 +159,7 @@ uint8_t MediaInputManager::HandleGetCurrentInput() bool MediaInputManager::HandleSelectInput(const uint8_t index) { + DeviceLayer::StackUnlock unlock; jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnValue(env != nullptr, false, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -179,6 +185,7 @@ bool MediaInputManager::HandleSelectInput(const uint8_t index) bool MediaInputManager::HandleShowInputStatus() { + DeviceLayer::StackUnlock unlock; jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnValue(env != nullptr, false, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -204,6 +211,7 @@ bool MediaInputManager::HandleShowInputStatus() bool MediaInputManager::HandleHideInputStatus() { + DeviceLayer::StackUnlock unlock; jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnValue(env != nullptr, false, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -229,6 +237,7 @@ bool MediaInputManager::HandleHideInputStatus() bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharSpan & name) { + DeviceLayer::StackUnlock unlock; std::string inputname(name.data(), name.size()); jboolean ret = JNI_FALSE; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -239,9 +248,10 @@ bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharS VerifyOrExit(mMediaInputManagerObject.HasValidObjectRef(), ChipLogError(Zcl, "mMediaInputManagerObject is not valid")); VerifyOrExit(mRenameInputMethod != nullptr, ChipLogError(Zcl, "mHideInputStatusMethod null")); + env->ExceptionClear(); + { UtfString jniInputname(env, inputname.data()); - env->ExceptionClear(); ret = env->CallBooleanMethod(mMediaInputManagerObject.ObjectRef(), mRenameInputMethod, static_cast(index), jniInputname.jniValue()); if (env->ExceptionCheck()) diff --git a/examples/tv-app/android/java/MediaPlaybackManager.cpp b/examples/tv-app/android/java/MediaPlaybackManager.cpp index 62abeb12ec30eb..667ab2ec41b382 100644 --- a/examples/tv-app/android/java/MediaPlaybackManager.cpp +++ b/examples/tv-app/android/java/MediaPlaybackManager.cpp @@ -97,6 +97,7 @@ CHIP_ERROR MediaPlaybackManager::HandleGetActiveAudioTrack(AttributeValueEncoder CHIP_ERROR MediaPlaybackManager::HandleGetActiveTrack(bool audio, AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; Structs::TrackStruct::Type response; Structs::TrackAttributesStruct::Type trackAttributes; response.trackAttributes = Nullable(trackAttributes); @@ -170,6 +171,7 @@ CHIP_ERROR MediaPlaybackManager::HandleGetAvailableAudioTracks(AttributeValueEnc CHIP_ERROR MediaPlaybackManager::HandleGetAvailableTracks(bool audio, AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); @@ -179,6 +181,8 @@ CHIP_ERROR MediaPlaybackManager::HandleGetAvailableTracks(bool audio, AttributeV VerifyOrExit(mMediaPlaybackManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetAvailableTracksMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + return aEncoder.EncodeList([this, env, audio](const auto & encoder) -> CHIP_ERROR { jobjectArray trackList = (jobjectArray) env->CallObjectMethod(mMediaPlaybackManagerObject.ObjectRef(), mGetAvailableTracksMethod, static_cast(audio)); @@ -317,6 +321,7 @@ bool MediaPlaybackManager::HandleActivateAudioTrack(const chip::CharSpan & track bool MediaPlaybackManager::HandleActivateTrack(bool audio, const chip::CharSpan & trackId) { + DeviceLayer::StackUnlock unlock; std::string id(trackId.data(), trackId.size()); jint ret = -1; @@ -328,9 +333,11 @@ bool MediaPlaybackManager::HandleActivateTrack(bool audio, const chip::CharSpan ChipLogProgress(Zcl, "MediaPlaybackManager::HandleActivateAudioTrack"); VerifyOrExit(mMediaPlaybackManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mActivateTrackMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + env->ExceptionClear(); + { UtfString jniid(env, id.c_str()); - env->ExceptionClear(); ret = env->CallIntMethod(mMediaPlaybackManagerObject.ObjectRef(), mActivateTrackMethod, static_cast(audio), jniid.jniValue()); if (env->ExceptionCheck()) @@ -351,6 +358,7 @@ bool MediaPlaybackManager::HandleActivateTextTrack(const chip::CharSpan & trackI bool MediaPlaybackManager::HandleDeactivateTextTrack() { + DeviceLayer::StackUnlock unlock; jint ret = -1; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -439,6 +447,7 @@ void MediaPlaybackManager::InitializeWithObjects(jobject managerObject) uint64_t MediaPlaybackManager::HandleMediaRequestGetAttribute(MediaPlaybackRequestAttribute attribute) { + DeviceLayer::StackUnlock unlock; uint64_t ret = std::numeric_limits::max(); jlong jAttributeValue = -1; CHIP_ERROR err = CHIP_NO_ERROR; @@ -450,6 +459,8 @@ uint64_t MediaPlaybackManager::HandleMediaRequestGetAttribute(MediaPlaybackReque VerifyOrExit(mMediaPlaybackManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetAttributeMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + jAttributeValue = env->CallLongMethod(mMediaPlaybackManagerObject.ObjectRef(), mGetAttributeMethod, static_cast(attribute)); if (env->ExceptionCheck()) @@ -480,6 +491,7 @@ uint64_t MediaPlaybackManager::HandleMediaRequestGetAttribute(MediaPlaybackReque long MediaPlaybackManager::HandleMediaRequestGetLongAttribute(MediaPlaybackRequestAttribute attribute) { + DeviceLayer::StackUnlock unlock; long ret = 0; jlong jAttributeValue = -1; CHIP_ERROR err = CHIP_NO_ERROR; @@ -491,6 +503,8 @@ long MediaPlaybackManager::HandleMediaRequestGetLongAttribute(MediaPlaybackReque VerifyOrExit(mMediaPlaybackManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mGetAttributeMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + env->ExceptionClear(); + jAttributeValue = env->CallLongMethod(mMediaPlaybackManagerObject.ObjectRef(), mGetAttributeMethod, static_cast(attribute)); if (env->ExceptionCheck()) @@ -516,6 +530,7 @@ Commands::PlaybackResponse::Type MediaPlaybackManager::HandleMediaRequest(MediaP uint64_t deltaPositionMilliseconds) { + DeviceLayer::StackUnlock unlock; Commands::PlaybackResponse::Type response; jint ret = -1; @@ -553,6 +568,7 @@ Commands::PlaybackResponse::Type MediaPlaybackManager::HandleMediaRequest(MediaP CHIP_ERROR MediaPlaybackManager::HandleGetSampledPosition(AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; Structs::PlaybackPositionStruct::Type response; response.updatedAt = 0; response.position = Nullable(0); diff --git a/examples/tv-app/android/java/MessagesManager.cpp b/examples/tv-app/android/java/MessagesManager.cpp new file mode 100644 index 00000000000000..9203d7b54510f5 --- /dev/null +++ b/examples/tv-app/android/java/MessagesManager.cpp @@ -0,0 +1,454 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MessagesManager.h" +#include "TvApp-JNI.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::Messages; +using namespace chip::Uint8; +using MessageResponseOption = chip::app::Clusters::Messages::Structs::MessageResponseOptionStruct::Type; + +/** @brief Messages Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + */ +void emberAfMessagesClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "------------TV Android App: Messages::PostClusterInit"); + TvAppJNIMgr().PostClusterInit(chip::app::Clusters::Messages::Id, endpoint); +} + +void MessagesManager::NewManager(jint endpoint, jobject manager) +{ + ChipLogProgress(Zcl, "-----TV Android App: Messages::SetDefaultDelegate"); + MessagesManager * mgr = new MessagesManager(); + VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "Failed to create MessagesManager")); + mgr->InitializeWithObjects(manager); + chip::app::Clusters::Messages::SetDefaultDelegate(static_cast(endpoint), mgr); +} + +void MessagesManager::InitializeWithObjects(jobject managerObject) +{ + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for MessagesManager")); + + VerifyOrReturn(mMessagesManagerObject.Init(managerObject) == CHIP_NO_ERROR, + ChipLogError(Zcl, "Failed to init mMessagesManagerObject")); + + jclass managerClass = env->GetObjectClass(managerObject); + VerifyOrReturn(managerClass != nullptr, ChipLogError(Zcl, "Failed to get MessagesManager Java class")); + + mGetMessagesMethod = env->GetMethodID(managerClass, "getMessages", "()[Lcom/matter/tv/server/tvapp/Message;"); + if (mGetMessagesMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access MessagesManager 'getMessages' method"); + env->ExceptionClear(); + } + + mPresentMessagesMethod = + env->GetMethodID(managerClass, "presentMessages", "(Ljava/lang/String;IIJILjava/lang/String;Ljava/util/HashMap;)Z"); + if (mPresentMessagesMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access MessagesManager 'presentMessages' method"); + env->ExceptionClear(); + } + + mCancelMessagesMethod = env->GetMethodID(managerClass, "cancelMessage", "(Ljava/lang/String;)Z"); + if (mCancelMessagesMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access MessagesManager 'cancelMessage' method"); + env->ExceptionClear(); + } +} + +uint32_t MessagesManager::GetFeatureMap(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_CONTENT_LAUNCHER_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return kEndpointFeatureMap; + } + + BitMask FeatureMap; + FeatureMap.Set(Feature::kReceivedConfirmation); + FeatureMap.Set(Feature::kConfirmationResponse); + FeatureMap.Set(Feature::kConfirmationReply); + FeatureMap.Set(Feature::kProtectedMessages); + + uint32_t featureMap = FeatureMap.Raw(); + // forcing to all features since this implementation supports all + // Attributes::FeatureMap::Get(endpoint, &featureMap); + return featureMap; +} + +CHIP_ERROR MessagesManager::HandleGetMessages(AttributeValueEncoder & aEncoder) +{ + DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); + JniLocalReferenceScope scope(env); + + env->ExceptionClear(); + + ChipLogProgress(Zcl, "Received MessagesManager::HandleGetMessages"); + VerifyOrExit(mMessagesManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(mGetMessagesMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { + jobjectArray messagesList = + static_cast(env->CallObjectMethod(mMessagesManagerObject.ObjectRef(), mGetMessagesMethod)); + if (env->ExceptionCheck()) + { + ChipLogError(Zcl, "Java exception in MessagesManager::HandleGetMessages"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return CHIP_ERROR_INCORRECT_STATE; + } + + jint length = env->GetArrayLength(messagesList); + + for (jint i = 0; i < length; i++) + { + std::vector options; + std::vector optionLabels; + uint8_t buf[kMessageIdLength]; + + chip::app::Clusters::Messages::Structs::MessageStruct::Type message; + jobject messageObject = env->GetObjectArrayElement(messagesList, i); + jclass messageClass = env->GetObjectClass(messageObject); + + jfieldID getMessageIdField = env->GetFieldID(messageClass, "messageId", "Ljava/lang/String;"); + jstring jmessageId = static_cast(env->GetObjectField(messageObject, getMessageIdField)); + JniUtfString messageId(env, jmessageId); + if (jmessageId != nullptr) + { + VerifyOrReturnValue(chip::Encoding::HexToBytes(messageId.charSpan().data(), messageId.charSpan().size(), buf, + sizeof(buf)) == sizeof(buf), + CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(Zcl, "HexToBytes failed")); + message.messageID = ByteSpan(buf, sizeof(buf)); + } + + jfieldID getMessageTextField = env->GetFieldID(messageClass, "messageText", "Ljava/lang/String;"); + jstring jmessageText = static_cast(env->GetObjectField(messageObject, getMessageTextField)); + JniUtfString messageText(env, jmessageText); + if (jmessageText != nullptr) + { + message.messageText = messageText.charSpan(); + } + + jfieldID messageControlField = env->GetFieldID(messageClass, "messageControl", "I"); + jint jmessageControl = env->GetIntField(messageObject, messageControlField); + message.messageControl = static_cast>(static_cast(jmessageControl)); + + jfieldID priorityField = env->GetFieldID(messageClass, "priority", "I"); + jint jpriority = env->GetIntField(messageObject, priorityField); + if (jpriority >= 0) + { + message.priority = MessagePriorityEnum(static_cast(jpriority)); + } + + jfieldID startTimeField = env->GetFieldID(messageClass, "startTime", "J"); + jlong jstartTime = env->GetLongField(messageObject, startTimeField); + if (jstartTime >= 0) + { + message.startTime = DataModel::Nullable(static_cast(jstartTime)); + } + + jfieldID durationField = env->GetFieldID(messageClass, "duration", "I"); + jint jduration = env->GetIntField(messageObject, durationField); + if (jduration >= 0) + { + message.duration = DataModel::Nullable(static_cast(jduration)); + } + + jfieldID getResponseOptionsField = + env->GetFieldID(messageClass, "responseOptions", "[Lcom/matter/tv/server/tvapp/MessageResponseOption;"); + + jobjectArray responsesArray = static_cast(env->GetObjectField(messageObject, getResponseOptionsField)); + jint size = env->GetArrayLength(responsesArray); + if (size > 0) + { + for (jint j = 0; j < size; j++) + { + MessageResponseOption option; + + jobject responseOptionObject = env->GetObjectArrayElement(responsesArray, j); + jclass responseOptionClass = env->GetObjectClass(responseOptionObject); + + jfieldID idField = env->GetFieldID(responseOptionClass, "id", "J"); + jlong jid = env->GetLongField(responseOptionObject, idField); + option.messageResponseID = Optional(static_cast(jid)); + + jfieldID getLabelField = env->GetFieldID(responseOptionClass, "label", "Ljava/lang/String;"); + jstring jlabelText = static_cast(env->GetObjectField(responseOptionObject, getLabelField)); + VerifyOrReturnValue(jlabelText != nullptr, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(Zcl, "jlabelText null")); + JniUtfString * label = new JniUtfString(env, jlabelText); + VerifyOrReturnValue(label != nullptr, CHIP_ERROR_NO_MEMORY, ChipLogError(Zcl, "label null")); + + optionLabels.push_back(label); + + option.label = Optional(label->charSpan()); + + options.push_back(option); + } + + message.responses = Optional>( + DataModel::List(options.data(), options.size())); + } + ReturnErrorOnFailure(encoder.Encode(message)); + for (JniUtfString * optionLabel : optionLabels) + { + delete optionLabel; + } + } + + return CHIP_NO_ERROR; + }); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "MessagesManager::HandleGetMessages status error: %s", err.AsString()); + } + return err; +} + +CHIP_ERROR MessagesManager::HandleGetActiveMessageIds(AttributeValueEncoder & aEncoder) +{ + DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); + JniLocalReferenceScope scope(env); + + ChipLogProgress(Zcl, "Received MessagesManager::HandleGetActiveMessageIds"); + VerifyOrExit(mMessagesManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(mGetMessagesMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + env->ExceptionClear(); + + return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { + jobjectArray messagesList = + static_cast(env->CallObjectMethod(mMessagesManagerObject.ObjectRef(), mGetMessagesMethod)); + if (env->ExceptionCheck()) + { + ChipLogError(Zcl, "Java exception in MessagesManager::HandleGetActiveMessageIds"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return CHIP_ERROR_INCORRECT_STATE; + } + + jint length = env->GetArrayLength(messagesList); + + for (jint i = 0; i < length; i++) + { + jobject messageObject = env->GetObjectArrayElement(messagesList, i); + jclass messageClass = env->GetObjectClass(messageObject); + + jfieldID getMessageIdField = env->GetFieldID(messageClass, "messageId", "Ljava/lang/String;"); + jstring jmessageId = static_cast(env->GetObjectField(messageObject, getMessageIdField)); + JniUtfString messageId(env, jmessageId); + if (jmessageId != nullptr) + { + uint8_t buf[kMessageIdLength]; + VerifyOrReturnValue(chip::Encoding::HexToBytes(messageId.charSpan().data(), messageId.charSpan().size(), buf, + sizeof(buf)) == sizeof(buf), + CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(Zcl, "HexToBytes failed")); + + ReturnErrorOnFailure(encoder.Encode(ByteSpan(buf, sizeof(buf)))); + } + } + + return CHIP_NO_ERROR; + }); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "MessagesManager::HandleGetMessages status error: %s", err.AsString()); + } + + return err; +} + +CHIP_ERROR MessagesManager::HandlePresentMessagesRequest( + const ByteSpan & messageId, const MessagePriorityEnum & priority, const BitMask & messageControl, + const DataModel::Nullable & startTime, const DataModel::Nullable & duration, const CharSpan & messageText, + const Optional> & responses) +{ + DeviceLayer::StackUnlock unlock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); + JniLocalReferenceScope scope(env); + + ChipLogProgress(Zcl, "Received MessagesManager::HandlePresentMessagesRequest"); + VerifyOrReturnError(mMessagesManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Zcl, "Invalid mMessagesManagerObject")); + VerifyOrReturnError(mPresentMessagesMethod != nullptr, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Zcl, "mPresentMessagesMethod null")); + + env->ExceptionClear(); + { + char hex_buf[(kMessageIdLength * 2) + 1]; + VerifyOrReturnError( + CHIP_NO_ERROR == + chip::Encoding::BytesToUppercaseHexString(messageId.data(), messageId.size(), hex_buf, sizeof(hex_buf)), + CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "BytesToUppercaseHexString failed")); + + jstring jid = env->NewStringUTF(hex_buf); + if (jid == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + std::string smessageText(messageText.data(), messageText.size()); + jstring jmessageText = env->NewStringUTF(smessageText.c_str()); + if (jmessageText == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + jint jcontrol = static_cast(messageControl.Raw()); + jint jduration = -1; + if (!duration.IsNull()) + { + jduration = static_cast(duration.Value()); + } + jlong jstartTime = -1; + if (!startTime.IsNull()) + { + jstartTime = static_cast(startTime.Value()); + } + + jint jpriority = static_cast(priority); + + jclass hashMapClass = env->FindClass("java/util/HashMap"); + VerifyOrReturnError(hashMapClass != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Could not find class HashMap")); + jmethodID hashMapCtor = env->GetMethodID(hashMapClass, "", "()V"); + VerifyOrReturnError(hashMapCtor != nullptr, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Zcl, "Could not find HashMap constructor")); + jobject joptions = env->NewObject(hashMapClass, hashMapCtor); + VerifyOrReturnError(joptions != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Could not create HashMap")); + + if (responses.HasValue()) + { + jmethodID hashMapPut = + env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + VerifyOrReturnError(hashMapPut != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Could not find HashMap put")); + + jclass longClass = env->FindClass("java/lang/Long"); + VerifyOrReturnError(longClass != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Could not find class Long")); + jmethodID longCtor = env->GetMethodID(longClass, "", "(J)V"); + VerifyOrReturnError(longCtor != nullptr, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Zcl, "Could not find Long constructor")); + + auto iter = responses.Value().begin(); + while (iter.Next()) + { + auto & response = iter.GetValue(); + + std::string label(response.label.Value().data(), response.label.Value().size()); + jstring jlabel = env->NewStringUTF(label.c_str()); + if (jlabel == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + jobject jlong = env->NewObject(longClass, longCtor, response.messageResponseID.Value()); + VerifyOrReturnError(jlong != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Could not create Long")); + + // add to HashMap + env->CallObjectMethod(joptions, hashMapPut, jlong, jlabel); + if (env->ExceptionCheck()) + { + ChipLogError(DeviceLayer, "Java exception in MessagesManager::HandlePresentMessagesRequest"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return CHIP_ERROR_INTERNAL; + } + } + } + + env->CallBooleanMethod(mMessagesManagerObject.ObjectRef(), mPresentMessagesMethod, jid, jpriority, jcontrol, jstartTime, + jduration, jmessageText, joptions); + if (env->ExceptionCheck()) + { + ChipLogError(DeviceLayer, "Java exception in MessagesManager::HandlePresentMessagesRequest"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return CHIP_ERROR_INTERNAL; + } + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR MessagesManager::HandleCancelMessagesRequest(const DataModel::DecodableList & messageIds) +{ + DeviceLayer::StackUnlock unlock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); + JniLocalReferenceScope scope(env); + + ChipLogProgress(Zcl, "Received MessagesManager::HandleCancelMessagesRequest"); + VerifyOrReturnError(mMessagesManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Zcl, "Invalid mMessagesManagerObject")); + VerifyOrReturnError(mCancelMessagesMethod != nullptr, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(Zcl, "mCancelMessagesMethod null")); + + env->ExceptionClear(); + + auto iter = messageIds.begin(); + while (iter.Next()) + { + auto & id = iter.GetValue(); + + char hex_buf[(kMessageIdLength * 2) + 1]; + VerifyOrReturnError(CHIP_NO_ERROR == + chip::Encoding::BytesToUppercaseHexString(id.data(), id.size(), hex_buf, sizeof(hex_buf)), + CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "BytesToUppercaseHexString failed")); + + jstring jid = env->NewStringUTF(hex_buf); + if (jid == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + env->CallBooleanMethod(mMessagesManagerObject.ObjectRef(), mCancelMessagesMethod, jid); + if (env->ExceptionCheck()) + { + ChipLogError(DeviceLayer, "Java exception in MessagesManager::HandleCancelMessagesRequest"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return CHIP_ERROR_INTERNAL; + } + } + return CHIP_NO_ERROR; +} diff --git a/examples/tv-app/android/java/MessagesManager.h b/examples/tv-app/android/java/MessagesManager.h new file mode 100644 index 00000000000000..563192a542bdf6 --- /dev/null +++ b/examples/tv-app/android/java/MessagesManager.h @@ -0,0 +1,63 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include + +#include +#include + +class MessagesManager : public chip::app::Clusters::Messages::Delegate +{ +public: + static void NewManager(jint endpoint, jobject manager); + void InitializeWithObjects(jobject managerObject); + + // Commands + CHIP_ERROR HandlePresentMessagesRequest( + const chip::ByteSpan & messageId, const chip::app::Clusters::Messages::MessagePriorityEnum & priority, + const chip::BitMask & messageControl, + const chip::app::DataModel::Nullable & startTime, const chip::app::DataModel::Nullable & duration, + const chip::CharSpan & messageText, + const chip::Optional< + chip::app::DataModel::DecodableList> & + responses) override; + CHIP_ERROR HandleCancelMessagesRequest(const chip::app::DataModel::DecodableList & messageIds) override; + + // Attributes + CHIP_ERROR HandleGetMessages(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetActiveMessageIds(chip::app::AttributeValueEncoder & aEncoder) override; + + // Global Attributes + uint32_t GetFeatureMap(chip::EndpointId endpoint) override; + // uint16_t GetClusterRevision(chip::EndpointId endpoint) override; + +private: + chip::JniGlobalReference mMessagesManagerObject; + jmethodID mGetMessagesMethod = nullptr; + + jmethodID mPresentMessagesMethod = nullptr; + jmethodID mCancelMessagesMethod = nullptr; + + // TODO: set this based upon meta data from app + static constexpr uint32_t kEndpointFeatureMap = 15; + // static constexpr uint16_t kClusterRevision = 1; +}; diff --git a/examples/tv-app/android/java/MyUserPrompter-JNI.cpp b/examples/tv-app/android/java/MyUserPrompter-JNI.cpp index d2c83b28a1ce8f..82b06e210d7853 100644 --- a/examples/tv-app/android/java/MyUserPrompter-JNI.cpp +++ b/examples/tv-app/android/java/MyUserPrompter-JNI.cpp @@ -78,6 +78,7 @@ JNIMyUserPrompter::JNIMyUserPrompter(jobject provider) */ void JNIMyUserPrompter::PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); std::string stringCommissioneeName(commissioneeName); @@ -119,6 +120,7 @@ void JNIMyUserPrompter::PromptForCommissionOKPermission(uint16_t vendorId, uint1 void JNIMyUserPrompter::PromptForCommissionPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName, uint16_t pairingHint, const char * pairingInstruction) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); std::string stringCommissioneeName(commissioneeName); @@ -198,6 +200,7 @@ void JNIMyUserPrompter::PromptCommissioningStarted(uint16_t vendorId, uint16_t p */ void JNIMyUserPrompter::PromptCommissioningSucceeded(uint16_t vendorId, uint16_t productId, const char * commissioneeName) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); std::string stringCommissioneeName(commissioneeName); @@ -234,6 +237,7 @@ void JNIMyUserPrompter::PromptCommissioningSucceeded(uint16_t vendorId, uint16_t */ void JNIMyUserPrompter::PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); std::string stringCommissioneeName(commissioneeName); diff --git a/examples/tv-app/android/java/OnOffManager.cpp b/examples/tv-app/android/java/OnOffManager.cpp index 9a330754aa4a16..db694748e8a11b 100644 --- a/examples/tv-app/android/java/OnOffManager.cpp +++ b/examples/tv-app/android/java/OnOffManager.cpp @@ -113,6 +113,7 @@ CHIP_ERROR OnOffManager::InitializeWithObjects(jobject managerObject) void OnOffManager::HandleOnOffChanged(bool value) { + DeviceLayer::StackUnlock unlock; ChipLogProgress(Zcl, "OnOffManager::HandleOnOffChanged"); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp index 6bbc35ed297415..72279c49dca9d7 100644 --- a/examples/tv-app/android/java/TVApp-JNI.cpp +++ b/examples/tv-app/android/java/TVApp-JNI.cpp @@ -27,6 +27,7 @@ #include "LowPowerManager.h" #include "MediaInputManager.h" #include "MediaPlaybackManager.h" +#include "MessagesManager.h" #include "MyUserPrompter-JNI.h" #include "OnOffManager.h" #include "WakeOnLanManager.h" @@ -137,6 +138,11 @@ JNI_METHOD(void, setMediaPlaybackManager)(JNIEnv *, jobject, jint endpoint, jobj MediaPlaybackManager::NewManager(endpoint, manager); } +JNI_METHOD(void, setMessagesManager)(JNIEnv *, jobject, jint endpoint, jobject manager) +{ + MessagesManager::NewManager(endpoint, manager); +} + JNI_METHOD(void, setChannelManager)(JNIEnv *, jobject, jint endpoint, jobject manager) { ChannelManager::NewManager(endpoint, manager); diff --git a/examples/tv-app/android/java/WakeOnLanManager.cpp b/examples/tv-app/android/java/WakeOnLanManager.cpp index 5a3093aca53332..a50ddca72bbb3e 100644 --- a/examples/tv-app/android/java/WakeOnLanManager.cpp +++ b/examples/tv-app/android/java/WakeOnLanManager.cpp @@ -51,6 +51,7 @@ void WakeOnLanManager::NewManager(jint endpoint, jobject manager) CHIP_ERROR WakeOnLanManager::HandleGetMacAddress(chip::app::AttributeValueEncoder & aEncoder) { + DeviceLayer::StackUnlock unlock; jobject javaMac; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Clusters.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Clusters.java index d699ca68ea6365..5928c1b10181c7 100644 --- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Clusters.java +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Clusters.java @@ -129,7 +129,7 @@ public class Clusters { public static final long ClusterId_ApplicationBasic = 0x0000050D; public static final long ClusterId_AccountLogin = 0x0000050E; public static final long ClusterId_TestCluster = 0xFFF1FC05; - public static final long ClusterId_Messaging = 0x00000703; + public static final long ClusterId_Messaging = 0x00000097; public static final long ClusterId_ApplianceIdentification = 0x00000B00; public static final long ClusterId_MeterIdentification = 0x00000B01; public static final long ClusterId_ApplianceEventsAndAlert = 0x00000B02; diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Message.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Message.java new file mode 100644 index 00000000000000..c194ffb44f9ee1 --- /dev/null +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Message.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.matter.tv.server.tvapp; + +public class Message { + + public String messageId; + public int priority; + public int messageControl; + public long startTime; + public int duration; + public String messageText; + public MessageResponseOption responseOptions[]; + + public Message( + String messageId, + int priority, + int messageControl, + long startTime, + int duration, + String messageText, + MessageResponseOption responseOptions[]) { + this.messageId = messageId; + this.priority = priority; + this.messageControl = messageControl; + this.startTime = startTime; + this.duration = duration; + this.messageText = messageText; + this.responseOptions = responseOptions; + } +} diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessageResponseOption.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessageResponseOption.java new file mode 100644 index 00000000000000..5d8e77d1e91389 --- /dev/null +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessageResponseOption.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.matter.tv.server.tvapp; + +public class MessageResponseOption { + public long id = -1; + public String label = "na"; + + public MessageResponseOption(long id, String label) { + this.id = id; + this.label = label; + } +} diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessagesManager.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessagesManager.java new file mode 100644 index 00000000000000..0a5680866714c6 --- /dev/null +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessagesManager.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.matter.tv.server.tvapp; + +import java.util.HashMap; + +public interface MessagesManager { + + Message[] getMessages(); + + boolean presentMessages( + String messageId, + int priority, + int messageControl, + long startTime, + int duration, + String messageText, + HashMap responseOptions); + + boolean cancelMessage(String messageId); +} diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessagesManagerStub.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessagesManagerStub.java new file mode 100644 index 00000000000000..63fef69d35c936 --- /dev/null +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/MessagesManagerStub.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.matter.tv.server.tvapp; + +import android.util.Log; +import java.util.HashMap; +import java.util.Map; + +public class MessagesManagerStub implements MessagesManager { + private static final String TAG = MessagesManagerStub.class.getSimpleName(); + + private int endpoint = -1; + + private Map messages = new HashMap(); + + public MessagesManagerStub(int endpoint) { + this.endpoint = endpoint; + Log.d(TAG, "MessagesManagerStub: at " + this.endpoint); + + HashMap responseOptions = new HashMap(); + responseOptions.put(new Long(1), "Yes"); + responseOptions.put(new Long(2), "No"); + presentMessages( + "31323334353637383930313233343536", 1, 1, 30, 60, "TestMessage", responseOptions); + Log.d(TAG, "MessagesManagerStub: added dummy message"); + } + + @Override + public Message[] getMessages() { + Log.d(TAG, "getMessages: at " + this.endpoint); + return messages.values().toArray(new Message[0]); + } + + @Override + public boolean presentMessages( + String messageId, + int priority, + int messageControl, + long startTime, + int duration, + String messageText, + HashMap responseOptions) { + Log.d( + TAG, "presentMessages: at " + this.endpoint + " id:" + messageId + " text:" + messageText); + MessageResponseOption[] options = new MessageResponseOption[responseOptions.size()]; + int i = 0; + + for (Map.Entry set : responseOptions.entrySet()) { + Log.d(TAG, "presentMessages option: key:" + set.getKey() + " value:" + set.getValue()); + options[i] = new MessageResponseOption(set.getKey().longValue(), set.getValue()); + i++; + } + + messages.put( + messageId, + new Message( + messageId, priority, messageControl, startTime, duration, messageText, options)); + return true; + } + + @Override + public boolean cancelMessage(String messageId) { + Log.d(TAG, "cancelMessage: at " + this.endpoint + " messageId:" + messageId); + messages.remove(messageId); + return true; // per spec, succeed unless error + } +} diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java index d8bb564370afa4..eaf207e45f3618 100644 --- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java @@ -57,6 +57,8 @@ private void postClusterInit(long clusterId, int endpoint) { public native void setMediaPlaybackManager(int endpoint, MediaPlaybackManager manager); + public native void setMessagesManager(int endpoint, MessagesManager manager); + public native void setChannelManager(int endpoint, ChannelManager manager); public native void setOnOffManager(int endpoint, OnOffManager manager); diff --git a/examples/tv-casting-app/linux/CastingUtils.cpp b/examples/tv-casting-app/linux/CastingUtils.cpp index 02b9467d884614..d4d71b5dd2c0ae 100644 --- a/examples/tv-casting-app/linux/CastingUtils.cpp +++ b/examples/tv-casting-app/linux/CastingUtils.cpp @@ -105,7 +105,7 @@ void InitCommissioningFlow(intptr_t commandArg) commissioner->LogDetail(); if (associatedConnectableVideoPlayer.HasValue()) { - TargetVideoPlayerInfo * targetVideoPlayerInfo = associatedConnectableVideoPlayer.Value(); + [[maybe_unused]] TargetVideoPlayerInfo * targetVideoPlayerInfo = associatedConnectableVideoPlayer.Value(); ChipLogProgress(AppServer, "Previously connected with nodeId 0x" ChipLogFormatX64 " fabricIndex: %d", ChipLogValueX64(targetVideoPlayerInfo->GetNodeId()), targetVideoPlayerInfo->GetFabricIndex()); } @@ -305,7 +305,7 @@ void PrintFabrics() ChipLogError(AppServer, " -- Not initialized"); continue; } - NodeId myNodeId = fb.GetNodeId(); + [[maybe_unused]] NodeId myNodeId = fb.GetNodeId(); ChipLogProgress(NotSpecified, "---- Current Fabric nodeId=0x" ChipLogFormatX64 " fabricId=0x" ChipLogFormatX64 " fabricIndex=%d", ChipLogValueX64(myNodeId), ChipLogValueX64(fb.GetFabricId()), fabricIndex); diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp index 41d9feb52977eb..f34b6b2ef16c34 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp @@ -257,7 +257,7 @@ void CastingPlayer::LogDetail() const { for (unsigned j = 0; j < mAttributes.numIPs; j++) { - char * ipAddressOut = mAttributes.ipAddresses[j].ToString(buf); + [[maybe_unused]] char * ipAddressOut = mAttributes.ipAddresses[j].ToString(buf); ChipLogDetail(AppServer, "\tIP Address #%d: %s", j + 1, ipAddressOut); } } diff --git a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp index 98f6b197a59e33..a3de0a263c3efe 100644 --- a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp @@ -695,7 +695,7 @@ void CastingServer::SetDefaultFabricIndex(std::function int: + if self._codes.get(key) is not None and self._codes.get(key) == value: + return self._codes.get(key) + + if type(value) is str: + code = self._get_code_by_name(value) + else: + code = self._get_code_by_value(value) + + if code is None: + raise TestStepEnumError(value, self.entries_by_name) + + self._codes[key] = code + return code + + def _get_code_by_name(self, value): + # For readability the name could sometimes be written as "enum_name(enum_code)" instead of "enum_name" + # In this case the enum_code should be checked to ensure that it is correct, unless enum_name is UnknownEnumValue + # in which case only invalid enum_code are allowed. + specified_name, specified_code = self._extract_name_and_code(value) + if specified_name not in self.entries_by_name: + return None + + enum_code = self.entries_by_name.get(specified_name) + if specified_code is None or specified_code == enum_code: + return enum_code + + if specified_name != f'{self.type}.UnknownEnumValue': + raise TestStepEnumSpecifierWrongError( + specified_code, specified_name, enum_code) + + enum_name = self.entries_by_code.get(specified_code) + if enum_name: + raise TestStepEnumSpecifierNotUnknownError(value, enum_name) + + return specified_code + + def _get_code_by_value(self, value): + enum_name = self.entries_by_code.get(value) + if not enum_name: + return None + + if STRICT_ENUM_VALUE_CHECK: + raise TestStepEnumError(value, self.entries_by_name) + + return value + + def _compute_entries(self, enum: Enum): + enum_codes = [] + for enum_entry in enum.entries: + name = f'{self.type}.{enum_entry.name}' + code = enum_entry.code + + self.entries_by_name[name] = code + self.entries_by_code[code] = name + enum_codes.append(code) + + # search for the first invalid entry if any + max_code = 0xFF + 1 + if self.base_type == 'enum16': + max_code = 0xFFFF + 1 + + for code in range(0, max_code): + if code not in enum_codes: + name = f'{self.type}.UnknownEnumValue' + self.entries_by_name[name] = code + self.entries_by_code[code] = name + break + + def _extract_name_and_code(self, enum_name: str): + match = re.match(r"([\w.]+)(?:\((\w+)\))?", enum_name) + if match: + name = match.group(1) + code = int(match.group(2)) if match.group(2) else None + return name, code + + return None, None + + @staticmethod + def is_valid_type(target_type: str): + return target_type == 'enum8' or target_type == 'enum16' + + class _TestStepWithPlaceholders: '''A single YAML test parsed, as is, from YAML. @@ -441,7 +539,11 @@ def _as_mapping(self, definitions, cluster_name, target_name): element = definitions.get_type_by_name(cluster_name, target_name) if hasattr(element, 'base_type'): - target_name = element.base_type.lower() + if EnumType.is_valid_type(element.base_type): + target_name = EnumType(element) + else: + target_name = element.base_type + elif hasattr(element, 'fields'): target_name = {f.name: self._as_mapping( definitions, cluster_name, f.data_type.name) for f in element.fields} @@ -480,7 +582,11 @@ def _update_with_definition(self, container: dict, mapping_type): if key == 'value': value[key] = self._update_value_with_definition( - item_value, mapping) + value, + key, + item_value, + mapping + ) elif key == 'saveAs' and type(item_value) is str and item_value not in self._parsing_config_variable_storage: self._parsing_config_variable_storage[item_value] = None elif key == 'saveDataVersionAs' and type(item_value) is str and item_value not in self._parsing_config_variable_storage: @@ -491,37 +597,80 @@ def _update_with_definition(self, container: dict, mapping_type): # the the value type for the target field. if is_typed_constraint(constraint): value[key][constraint] = self._update_value_with_definition( - constraint_value, mapping) + item_value, + constraint, + constraint_value, + mapping + ) else: # This key, value pair does not rely on cluster specifications. pass - def _update_value_with_definition(self, value, mapping_type): + def _update_value_with_definition(self, container: dict, key: str, value, mapping_type): + """ + Processes a given value based on a specified mapping type and returns the updated value. + This method does not modify the container in place; rather, it returns a new value that should be + used to update or process further as necessary. + + The 'container' and 'key' parameters are primarily used for error tagging. If an error occurs + during the value processing, these parameters allow for the error to be precisely located and + reported, facilitating easier debugging and error tracking. + + Parameters: + - container (dict): A dictionary that serves as a context for the operation. It is used for error + tagging if processing fails, by associating errors with specific locations within the data structure. + - key (str): The key related to the value being processed. It is used alongside 'container' to tag + errors, enabling precise identification of the error source. + - value: The value to be processed according to the mapping type. + - mapping_type: Dictates the processing or mapping logic to be applied to 'value'. + + Returns: + The processed value, which is the result of applying the specified mapping type to the original 'value'. + This method does not update the 'container'; any necessary updates based on the processed value must + be handled outside this method. + + Raises: + - TestStepError: If an error occurs during the processing of the value. The error includes details + from the 'container' and 'key' to facilitate error tracing and debugging. + """ + if not mapping_type: return value if type(value) is dict: rv = {} - for key in value: + for item_key in value: # FabricIndex is a special case where the framework requires it to be passed even # if it is not part of the requested arguments per spec and not part of the XML # definition. - if key == 'FabricIndex' or key == 'fabricIndex': - rv[key] = value[key] # int64u + if item_key == 'FabricIndex' or item_key == 'fabricIndex': + rv[item_key] = value[item_key] # int64u else: - if not mapping_type.get(key): - raise TestStepKeyError(value, key) - mapping = mapping_type[key] - rv[key] = self._update_value_with_definition( - value[key], mapping) + if not mapping_type.get(item_key): + raise TestStepKeyError(value, item_key) + mapping = mapping_type[item_key] + rv[item_key] = self._update_value_with_definition( + value, + item_key, + value[item_key], + mapping + ) return rv + if type(value) is list: - return [self._update_value_with_definition(entry, mapping_type) for entry in value] + return [self._update_value_with_definition(container, key, entry, mapping_type) for entry in value] + # TODO currently unsure if the check of `value not in config` is sufficant. For # example let's say value = 'foo + 1' and map type is 'int64u', we would arguably do # the wrong thing below. if value is not None and value not in self._parsing_config_variable_storage: - if mapping_type == 'int64u' or mapping_type == 'int64s' or mapping_type == 'bitmap64' or mapping_type == 'epoch_us': + if type(mapping_type) is EnumType: + try: + value = mapping_type.translate(key, value) + except (TestStepEnumError, TestStepEnumSpecifierNotUnknownError, TestStepEnumSpecifierWrongError) as e: + e.tag_key_with_error(container, key) + raise e + elif mapping_type == 'int64u' or mapping_type == 'int64s' or mapping_type == 'bitmap64' or mapping_type == 'epoch_us': value = fixes.try_apply_float_to_integer_fix(value) value = fixes.try_apply_yaml_cpp_longlong_limitation_fix(value) value = fixes.try_apply_yaml_unrepresentable_integer_for_javascript_fixes( diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/accessory_server_bridge.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/accessory_server_bridge.py index a8991deb9b7870..15ebdf46428830 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/accessory_server_bridge.py +++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/accessory_server_bridge.py @@ -77,6 +77,9 @@ def _get_start_options(request): elif name == 'crashLogPath': options.append('--crash_log') options.append(str(value)) + elif name == 'traceDecode': + options.append('--trace_decode') + options.append(str(value)) elif name == 'registerKey': pass else: diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py index 77028c39d72a9a..92bab169f7e0c6 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py +++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py @@ -33,6 +33,7 @@ +
diff --git a/scripts/py_matter_yamltests/test_yaml_parser.py b/scripts/py_matter_yamltests/test_yaml_parser.py index 055f949773f9d3..27472572a96d6b 100644 --- a/scripts/py_matter_yamltests/test_yaml_parser.py +++ b/scripts/py_matter_yamltests/test_yaml_parser.py @@ -20,14 +20,22 @@ # is arguably better then no checks at all. import io -import tempfile import unittest +from unittest.mock import mock_open, patch from matter_yamltests.definitions import ParseSource, SpecDefinitions +from matter_yamltests.errors import TestStepEnumError, TestStepEnumSpecifierNotUnknownError, TestStepEnumSpecifierWrongError from matter_yamltests.parser import TestParser, TestParserConfig simple_test_description = ''' + + + + + + + @@ -36,8 +44,11 @@ Test 0x1234 - + test_enum + + + ''' @@ -52,43 +63,145 @@ tests: - label: "Send Test Command" command: "test" +''' + +enum_values_yaml = ''' +name: Test Enum Values + +config: + nodeId: 0x12344321 + cluster: "Test" + endpoint: 1 + +tests: + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: 0 + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.A + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.A(0) + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.UnknownEnumValue + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.UnknownEnumValue(255) + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: 0 + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.A + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.A(0) + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.UnknownEnumValue + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.UnknownEnumValue(255) +''' + +enum_value_read_response_wrong_code_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" + response: + value: 123 +''' + +enum_value_read_response_wrong_name_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" + response: + value: ThisIsWrong +''' - - label: "Send Test Not Handled Command" - command: "testNotHandled" +enum_value_read_response_wrong_code_specified_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" response: - error: INVALID_COMMAND + value: TestEnum.A(123) +''' - - label: "Send Test Specific Command" - command: "testSpecific" +enum_value_read_response_not_unknown_code_specified_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" response: - values: - - name: "returnValue" - value: 7 + value: TestEnum.UnknownEnumValue(0) ''' +def mock_open_with_parameter_content(content): + file_object = mock_open(read_data=content).return_value + file_object.__iter__.return_value = content.splitlines(True) + return file_object + + +@patch('builtins.open', new=mock_open_with_parameter_content) class TestYamlParser(unittest.TestCase): def setUp(self): self._definitions = SpecDefinitions( [ParseSource(source=io.StringIO(simple_test_description), name='simple_test_description')]) - self._temp_file = tempfile.NamedTemporaryFile(suffix='.yaml') - with open(self._temp_file.name, 'w') as f: - f.writelines(simple_test_yaml) def test_able_to_iterate_over_all_parsed_tests(self): # self._yaml_parser.tests implements `__next__`, which does value substitution. We are # simply ensure there is no exceptions raise. parser_config = TestParserConfig(None, self._definitions) - yaml_parser = TestParser(self._temp_file.name, parser_config) + yaml_parser = TestParser(simple_test_yaml, parser_config) count = 0 for idx, test_step in enumerate(yaml_parser.tests): count += 1 pass - self.assertEqual(count, 3) + self.assertEqual(count, 1) def test_config(self): parser_config = TestParserConfig(None, self._definitions) - yaml_parser = TestParser(self._temp_file.name, parser_config) + yaml_parser = TestParser(simple_test_yaml, parser_config) for idx, test_step in enumerate(yaml_parser.tests): self.assertEqual(test_step.node_id, 0x12344321) self.assertEqual(test_step.cluster, 'Test') @@ -99,7 +212,7 @@ def test_config_override(self): 'cluster': 'TestOverride', 'endpoint': 4} parser_config = TestParserConfig( None, self._definitions, config_override) - yaml_parser = TestParser(self._temp_file.name, parser_config) + yaml_parser = TestParser(simple_test_yaml, parser_config) for idx, test_step in enumerate(yaml_parser.tests): self.assertEqual(test_step.node_id, 12345) self.assertEqual(test_step.cluster, 'TestOverride') @@ -109,8 +222,37 @@ def test_config_override_unknown_field(self): config_override = {'unknown_field': 1} parser_config = TestParserConfig( None, self._definitions, config_override) - self.assertRaises(KeyError, TestParser, - self._temp_file.name, parser_config) + + yaml_parser = TestParser(simple_test_yaml, parser_config) + self.assertIsInstance(yaml_parser, TestParser) + + def test_config_valid_enum_values(self): + parser_config = TestParserConfig(None, self._definitions) + yaml_parser = TestParser(enum_values_yaml, parser_config) + self.assertIsInstance(yaml_parser, TestParser) + + for idx, test_step in enumerate(yaml_parser.tests): + pass + + def test_config_read_response_wrong_code(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumError, TestParser, + enum_value_read_response_wrong_code_yaml, parser_config) + + def test_config_read_response_wrong_name(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumError, TestParser, + enum_value_read_response_wrong_name_yaml, parser_config) + + def test_config_read_response_wrong_code_specified(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumSpecifierWrongError, TestParser, + enum_value_read_response_wrong_code_specified_yaml, parser_config) + + def test_config_read_response_not_unknown_code_specified(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumSpecifierNotUnknownError, TestParser, + enum_value_read_response_not_unknown_code_specified_yaml, parser_config) def main(): diff --git a/scripts/spec_xml/generate_spec_xml.py b/scripts/spec_xml/generate_spec_xml.py index f4f30d060096a0..016f92d4b5759a 100755 --- a/scripts/spec_xml/generate_spec_xml.py +++ b/scripts/spec_xml/generate_spec_xml.py @@ -79,7 +79,7 @@ def scrape_clusters(scraper, spec_root, output_dir, dry_run): def scrape_cluster(filename: str) -> None: xml_path = get_xml_path(filename, clusters_output_dir) - cmd = [scraper, 'cluster', '-i', filename, '-o', xml_path, '-nd'] + cmd = [scraper, 'cluster', '-i', filename, '-o', xml_path, '-nd', '--define', 'in-progress'] if dry_run: print(cmd) else: diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index 505a5e163cc5c4..ecfd98be618480 100644 --- a/scripts/tests/chiptest/__init__.py +++ b/scripts/tests/chiptest/__init__.py @@ -313,6 +313,8 @@ def target_for_name(name: str): return TestTarget.LIT_ICD if name.startswith("Test_TC_MWOCTRL_") or name.startswith("Test_TC_MWOM_"): return TestTarget.MWO + if name.startswith("Test_TC_RVCRUNM_") or name.startswith("Test_TC_RVCCLEANM_") or name.startswith("Test_TC_RVCOPSTATE_"): + return TestTarget.RVC return TestTarget.ALL_CLUSTERS diff --git a/scripts/tests/chiptest/linux.py b/scripts/tests/chiptest/linux.py index 1d679ee236a3fd..3dbd851be26b47 100644 --- a/scripts/tests/chiptest/linux.py +++ b/scripts/tests/chiptest/linux.py @@ -183,6 +183,7 @@ def PathsWithNetworkNamespaces(paths: ApplicationPaths) -> ApplicationPaths: tv_app='ip netns exec app'.split() + paths.tv_app, lit_icd_app='ip netns exec app'.split() + paths.lit_icd_app, microwave_oven_app='ip netns exec app'.split() + paths.microwave_oven_app, + rvc_app='ip netns exec app'.split() + paths.rvc_app, bridge_app='ip netns exec app'.split() + paths.bridge_app, chip_repl_yaml_tester_cmd='ip netns exec tool'.split() + paths.chip_repl_yaml_tester_cmd, chip_tool_with_python_cmd='ip netns exec tool'.split() + paths.chip_tool_with_python_cmd, diff --git a/scripts/tests/chiptest/test_definition.py b/scripts/tests/chiptest/test_definition.py index 95f7a631928ba4..12c59cfad0cc41 100644 --- a/scripts/tests/chiptest/test_definition.py +++ b/scripts/tests/chiptest/test_definition.py @@ -176,6 +176,7 @@ class TestTarget(Enum): BRIDGE = auto() LIT_ICD = auto() MWO = auto() + RVC = auto() @dataclass @@ -191,10 +192,11 @@ class ApplicationPaths: microwave_oven_app: typing.List[str] chip_repl_yaml_tester_cmd: typing.List[str] chip_tool_with_python_cmd: typing.List[str] + rvc_app: typing.List[str] def items(self): return [self.chip_tool, self.all_clusters_app, self.lock_app, self.ota_provider_app, self.ota_requestor_app, - self.tv_app, self.bridge_app, self.lit_icd_app, self.microwave_oven_app, self.chip_repl_yaml_tester_cmd, self.chip_tool_with_python_cmd] + self.tv_app, self.bridge_app, self.lit_icd_app, self.microwave_oven_app, self.chip_repl_yaml_tester_cmd, self.chip_tool_with_python_cmd, self.rvc_app] @dataclass @@ -305,6 +307,8 @@ def Run(self, runner, apps_register, paths: ApplicationPaths, pics_file: str, target_app = paths.lit_icd_app elif self.target == TestTarget.MWO: target_app = paths.microwave_oven_app + elif self.target == TestTarget.RVC: + target_app = paths.rvc_app else: raise Exception("Unknown test target - " "don't know which application to run") diff --git a/scripts/tests/run_test_suite.py b/scripts/tests/run_test_suite.py index 9dbe01d9dbcfa0..2df88cd6740653 100755 --- a/scripts/tests/run_test_suite.py +++ b/scripts/tests/run_test_suite.py @@ -257,6 +257,9 @@ def cmd_list(context): @click.option( '--microwave-oven-app', help='what microwave oven app to use') +@click.option( + '--rvc-app', + help='what rvc app to use') @click.option( '--chip-repl-yaml-tester', help='what python script to use for running yaml tests using chip-repl as controller') @@ -288,7 +291,7 @@ def cmd_list(context): help='Number of tests that are expected to fail in each iteration. Overall test will pass if the number of failures matches this. Nonzero values require --keep-going') @click.pass_context def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, ota_requestor_app, - tv_app, bridge_app, lit_icd_app, microwave_oven_app, chip_repl_yaml_tester, chip_tool_with_python, pics_file, keep_going, test_timeout_seconds, expected_failures): + tv_app, bridge_app, lit_icd_app, microwave_oven_app, rvc_app, chip_repl_yaml_tester, chip_tool_with_python, pics_file, keep_going, test_timeout_seconds, expected_failures): if expected_failures != 0 and not keep_going: logging.exception(f"'--expected-failures {expected_failures}' used without '--keep-going'") sys.exit(2) @@ -321,6 +324,9 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o if microwave_oven_app is None: microwave_oven_app = paths_finder.get('chip-microwave-oven-app') + if rvc_app is None: + rvc_app = paths_finder.get('chip-rvc-app') + if chip_repl_yaml_tester is None: chip_repl_yaml_tester = paths_finder.get('yamltest_with_chip_repl_tester.py') @@ -341,6 +347,7 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o bridge_app=[bridge_app], lit_icd_app=[lit_icd_app], microwave_oven_app=[microwave_oven_app], + rvc_app=[rvc_app], chip_repl_yaml_tester_cmd=['python3'] + [chip_repl_yaml_tester], chip_tool_with_python_cmd=['python3'] + [chip_tool_with_python], ) diff --git a/src/app/AttributePathExpandIterator.cpp b/src/app/AttributePathExpandIterator.cpp index 5c1bb50c179f47..784499a41c4d74 100644 --- a/src/app/AttributePathExpandIterator.cpp +++ b/src/app/AttributePathExpandIterator.cpp @@ -52,7 +52,7 @@ extern bool emberAfEndpointIndexIsEnabled(uint16_t index); namespace chip { namespace app { -AttributePathExpandIterator::AttributePathExpandIterator(ObjectList * aAttributePath) +AttributePathExpandIterator::AttributePathExpandIterator(SingleLinkedListNode * aAttributePath) { mpAttributePath = aAttributePath; diff --git a/src/app/AttributePathExpandIterator.h b/src/app/AttributePathExpandIterator.h index dbf8382014ce9c..f11e6793822f84 100644 --- a/src/app/AttributePathExpandIterator.h +++ b/src/app/AttributePathExpandIterator.h @@ -69,7 +69,7 @@ namespace app { class AttributePathExpandIterator { public: - AttributePathExpandIterator(ObjectList * aAttributePath); + AttributePathExpandIterator(SingleLinkedListNode * aAttributePath); /** * Proceed the iterator to the next attribute path in the given cluster info. @@ -105,7 +105,7 @@ class AttributePathExpandIterator inline bool Valid() const { return mpAttributePath != nullptr; } private: - ObjectList * mpAttributePath; + SingleLinkedListNode * mpAttributePath; ConcreteAttributePath mOutputPath; diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index c0f30493824f3a..f714560afc15cb 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -87,7 +87,11 @@ source_set("revision_info") { source_set("paths") { sources = [ "AttributePathParams.h", + "CommandPathParams.h", + "CommandPathRegistry.h", + "ConcreteAttributePath.h", "ConcreteClusterPath.h", + "ConcreteCommandPath.h", "ConcreteEventPath.h", "DataVersionFilter.h", "EventPathParams.h", @@ -96,6 +100,7 @@ source_set("paths") { # This source sets also depends on basic-types.h that is not in any dependency we can use public_deps = [ ":app_config", + "${chip_root}/src/app/util:types", "${chip_root}/src/lib/core", "${chip_root}/src/lib/core:types", ] @@ -135,16 +140,24 @@ static_library("interaction-model") { "CASEClientPool.h", "CASESessionManager.cpp", "CASESessionManager.h", + "CommandSender.cpp", + "CommandSender.h", "DeviceProxy.cpp", "DeviceProxy.h", "InteractionModelDelegatePointers.cpp", "InteractionModelDelegatePointers.h", "InteractionModelEngine.cpp", "InteractionModelEngine.h", + "InteractionModelHelper.h", "InteractionModelTimeout.h", "OperationalSessionSetup.cpp", "OperationalSessionSetup.h", "OperationalSessionSetupPool.h", + "PendingResponseTracker.h", + "PendingResponseTrackerImpl.cpp", + "PendingResponseTrackerImpl.h", + "ReadClient.h", # TODO: cpp is only included conditionally. Needs logic + # fixing "RequiredPrivilege.cpp", "RequiredPrivilege.h", "StatusResponse.cpp", @@ -152,6 +165,10 @@ static_library("interaction-model") { "SubscriptionResumptionStorage.h", "TimedHandler.cpp", "TimedHandler.h", + "TimedRequest.cpp", + "TimedRequest.h", + "WriteClient.cpp", + "WriteClient.h", "reporting/Engine.cpp", "reporting/Engine.h", "reporting/ReportScheduler.h", @@ -179,6 +196,10 @@ static_library("interaction-model") { public_configs = [ "${chip_root}/src:includes" ] + if (chip_enable_read_client) { + sources += [ "ReadClient.cpp" ] + } + if (chip_persist_subscriptions) { sources += [ "SimpleSubscriptionResumptionStorage.cpp", @@ -222,26 +243,35 @@ static_library("app") { "CommandHandler.cpp", "CommandResponseHelper.h", "CommandResponseSender.cpp", - "CommandSender.cpp", + "CommandResponseSender.h", "DefaultAttributePersistenceProvider.cpp", "DefaultAttributePersistenceProvider.h", "DeferredAttributePersistenceProvider.cpp", "DeferredAttributePersistenceProvider.h", + "EventLogging.h", + "EventLoggingDelegate.h", "EventManagement.cpp", + "EventManagement.h", "FailSafeContext.cpp", "FailSafeContext.h", "OTAUserConsentCommon.h", - "PendingResponseTracker.h", - "PendingResponseTrackerImpl.cpp", - "PendingResponseTrackerImpl.h", "ReadHandler.cpp", "SafeAttributePersistenceProvider.h", - "TimedRequest.cpp", - "TimedRequest.h", "TimerDelegates.cpp", "TimerDelegates.h", - "WriteClient.cpp", "WriteHandler.cpp", + + # TODO: the following items cannot be included due to interaction-model circularity + # (app depending on im and im including these headers): + # Name with _ so that linter does not recognize it + # "CommandHandler._h" + # "ReadHandler._h", + # "WriteHandler._h" + + # TODO: the following items cannot be included due to platform includes not being + # able to depend on src/app + # Name with _ so that linter does not recognize it + # "_AttributeAccessInterface._h", ] public_deps = [ @@ -261,9 +291,9 @@ static_library("app") { if (chip_enable_read_client) { sources += [ "BufferedReadCallback.cpp", + "BufferedReadCallback.h", "ClusterStateCache.cpp", "ClusterStateCache.h", - "ReadClient.cpp", ] } diff --git a/src/app/CASESessionManager.h b/src/app/CASESessionManager.h index 92fb7a9ba783c7..3e668fa905cbdf 100644 --- a/src/app/CASESessionManager.h +++ b/src/app/CASESessionManager.h @@ -30,8 +30,6 @@ namespace chip { -class OperationalSessionSetupPoolDelegate; - struct CASESessionManagerConfig { CASEClientInitParams sessionInitParams; diff --git a/src/app/CommandSender.cpp b/src/app/CommandSender.cpp index 03ce2786b93d8d..18f4e755835076 100644 --- a/src/app/CommandSender.cpp +++ b/src/app/CommandSender.cpp @@ -16,15 +16,9 @@ * limitations under the License. */ -/** - * @file - * This file defines objects for a CHIP IM Invoke Command Sender - * - */ - #include "CommandSender.h" -#include "InteractionModelEngine.h" #include "StatusResponse.h" +#include #include #include #include diff --git a/src/app/EventLoggingTypes.h b/src/app/EventLoggingTypes.h index 35fd37a25045ca..04a843ebcfbd60 100644 --- a/src/app/EventLoggingTypes.h +++ b/src/app/EventLoggingTypes.h @@ -19,11 +19,11 @@ #include #include -#include #include #include #include #include +#include #include inline constexpr size_t kNumPriorityLevel = 3; @@ -151,10 +151,10 @@ struct EventLoadOutContext EventNumber mStartingEventNumber = 0; Timestamp mPreviousTime; Timestamp mCurrentTime; - EventNumber mCurrentEventNumber = 0; - size_t mEventCount = 0; - const ObjectList * mpInterestedEventPaths = nullptr; - bool mFirst = true; + EventNumber mCurrentEventNumber = 0; + size_t mEventCount = 0; + const SingleLinkedListNode * mpInterestedEventPaths = nullptr; + bool mFirst = true; Access::SubjectDescriptor mSubjectDescriptor; }; } // namespace app diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp index aa3abd67f828d8..8e6d53c24c9636 100644 --- a/src/app/EventManagement.cpp +++ b/src/app/EventManagement.cpp @@ -639,7 +639,7 @@ CHIP_ERROR EventManagement::CopyEventsSince(const TLVReader & aReader, size_t aD return err; } -CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, const ObjectList * apEventPathList, +CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, const SingleLinkedListNode * apEventPathList, EventNumber & aEventMin, size_t & aEventCount, const Access::SubjectDescriptor & aSubjectDescriptor) { diff --git a/src/app/EventManagement.h b/src/app/EventManagement.h index 228c26cca94a68..950efdc2bae867 100644 --- a/src/app/EventManagement.h +++ b/src/app/EventManagement.h @@ -31,10 +31,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -359,7 +359,7 @@ class EventManagement * available. * */ - CHIP_ERROR FetchEventsSince(chip::TLV::TLVWriter & aWriter, const ObjectList * apEventPathList, + CHIP_ERROR FetchEventsSince(chip::TLV::TLVWriter & aWriter, const SingleLinkedListNode * apEventPathList, EventNumber & aEventMin, size_t & aEventCount, const Access::SubjectDescriptor & aSubjectDescriptor); /** diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index ddc8a984f16b72..8e4b5a80e3df7d 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -450,7 +450,7 @@ CHIP_ERROR InteractionModelEngine::ParseAttributePaths(const Access::SubjectDesc // This avoids the 'parse all paths' approach that is employed in ReadHandler since we want to // avoid allocating out of the path store during this minimal initial processing stage. // - ObjectList paramsList; + SingleLinkedListNode paramsList; ReturnErrorOnFailure(path.Init(pathReader)); ReturnErrorOnFailure(path.ParsePath(paramsList.mValue)); @@ -1513,12 +1513,12 @@ bool InteractionModelEngine::HasConflictWriteRequests(const WriteHandler * apWri return false; } -void InteractionModelEngine::ReleaseAttributePathList(ObjectList *& aAttributePathList) +void InteractionModelEngine::ReleaseAttributePathList(SingleLinkedListNode *& aAttributePathList) { ReleasePool(aAttributePathList, mAttributePathPool); } -CHIP_ERROR InteractionModelEngine::PushFrontAttributePathList(ObjectList *& aAttributePathList, +CHIP_ERROR InteractionModelEngine::PushFrontAttributePathList(SingleLinkedListNode *& aAttributePathList, AttributePathParams & aAttributePath) { CHIP_ERROR err = PushFront(aAttributePathList, aAttributePath, mAttributePathPool); @@ -1530,10 +1530,10 @@ CHIP_ERROR InteractionModelEngine::PushFrontAttributePathList(ObjectList *& aAttributePaths) +void InteractionModelEngine::RemoveDuplicateConcreteAttributePath(SingleLinkedListNode *& aAttributePaths) { - ObjectList * prev = nullptr; - auto * path1 = aAttributePaths; + SingleLinkedListNode * prev = nullptr; + auto * path1 = aAttributePaths; while (path1 != nullptr) { @@ -1585,12 +1585,12 @@ void InteractionModelEngine::RemoveDuplicateConcreteAttributePath(ObjectList *& aEventPathList) +void InteractionModelEngine::ReleaseEventPathList(SingleLinkedListNode *& aEventPathList) { ReleasePool(aEventPathList, mEventPathPool); } -CHIP_ERROR InteractionModelEngine::PushFrontEventPathParamsList(ObjectList *& aEventPathList, +CHIP_ERROR InteractionModelEngine::PushFrontEventPathParamsList(SingleLinkedListNode *& aEventPathList, EventPathParams & aEventPath) { CHIP_ERROR err = PushFront(aEventPathList, aEventPath, mEventPathPool); @@ -1602,12 +1602,12 @@ CHIP_ERROR InteractionModelEngine::PushFrontEventPathParamsList(ObjectList *& aDataVersionFilterList) +void InteractionModelEngine::ReleaseDataVersionFilterList(SingleLinkedListNode *& aDataVersionFilterList) { ReleasePool(aDataVersionFilterList, mDataVersionFilterPool); } -CHIP_ERROR InteractionModelEngine::PushFrontDataVersionFilterList(ObjectList *& aDataVersionFilterList, +CHIP_ERROR InteractionModelEngine::PushFrontDataVersionFilterList(SingleLinkedListNode *& aDataVersionFilterList, DataVersionFilter & aDataVersionFilter) { CHIP_ERROR err = PushFront(aDataVersionFilterList, aDataVersionFilter, mDataVersionFilterPool); @@ -1620,12 +1620,13 @@ CHIP_ERROR InteractionModelEngine::PushFrontDataVersionFilterList(ObjectList -void InteractionModelEngine::ReleasePool(ObjectList *& aObjectList, ObjectPool, N> & aObjectPool) +void InteractionModelEngine::ReleasePool(SingleLinkedListNode *& aObjectList, + ObjectPool, N> & aObjectPool) { - ObjectList * current = aObjectList; + SingleLinkedListNode * current = aObjectList; while (current != nullptr) { - ObjectList * nextObject = current->mpNext; + SingleLinkedListNode * nextObject = current->mpNext; aObjectPool.ReleaseObject(current); current = nextObject; } @@ -1634,9 +1635,10 @@ void InteractionModelEngine::ReleasePool(ObjectList *& aObjectList, ObjectPoo } template -CHIP_ERROR InteractionModelEngine::PushFront(ObjectList *& aObjectList, T & aData, ObjectPool, N> & aObjectPool) +CHIP_ERROR InteractionModelEngine::PushFront(SingleLinkedListNode *& aObjectList, T & aData, + ObjectPool, N> & aObjectPool) { - ObjectList * object = aObjectPool.CreateObject(); + SingleLinkedListNode * object = aObjectPool.CreateObject(); if (object == nullptr) { return CHIP_ERROR_NO_MEMORY; diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index b222087867380f..1c05767299dfbb 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -54,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -187,22 +187,22 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, reporting::ReportScheduler * GetReportScheduler() { return mReportScheduler; } - void ReleaseAttributePathList(ObjectList *& aAttributePathList); + void ReleaseAttributePathList(SingleLinkedListNode *& aAttributePathList); - CHIP_ERROR PushFrontAttributePathList(ObjectList *& aAttributePathList, + CHIP_ERROR PushFrontAttributePathList(SingleLinkedListNode *& aAttributePathList, AttributePathParams & aAttributePath); // If a concrete path indicates an attribute that is also referenced by a wildcard path in the request, // the path SHALL be removed from the list. - void RemoveDuplicateConcreteAttributePath(ObjectList *& aAttributePaths); + void RemoveDuplicateConcreteAttributePath(SingleLinkedListNode *& aAttributePaths); - void ReleaseEventPathList(ObjectList *& aEventPathList); + void ReleaseEventPathList(SingleLinkedListNode *& aEventPathList); - CHIP_ERROR PushFrontEventPathParamsList(ObjectList *& aEventPathList, EventPathParams & aEventPath); + CHIP_ERROR PushFrontEventPathParamsList(SingleLinkedListNode *& aEventPathList, EventPathParams & aEventPath); - void ReleaseDataVersionFilterList(ObjectList *& aDataVersionFilterList); + void ReleaseDataVersionFilterList(SingleLinkedListNode *& aDataVersionFilterList); - CHIP_ERROR PushFrontDataVersionFilterList(ObjectList *& aDataVersionFilterList, + CHIP_ERROR PushFrontDataVersionFilterList(SingleLinkedListNode *& aDataVersionFilterList, DataVersionFilter & aDataVersionFilter); CHIP_ERROR RegisterCommandHandler(CommandHandlerInterface * handler); @@ -576,9 +576,9 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, static void ResumeSubscriptionsTimerCallback(System::Layer * apSystemLayer, void * apAppState); template - void ReleasePool(ObjectList *& aObjectList, ObjectPool, N> & aObjectPool); + void ReleasePool(SingleLinkedListNode *& aObjectList, ObjectPool, N> & aObjectPool); template - CHIP_ERROR PushFront(ObjectList *& aObjectList, T & aData, ObjectPool, N> & aObjectPool); + CHIP_ERROR PushFront(SingleLinkedListNode *& aObjectList, T & aData, ObjectPool, N> & aObjectPool); Messaging::ExchangeManager * mpExchangeMgr = nullptr; @@ -606,13 +606,13 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, "CHIP_IM_MAX_NUM_READS is too small to match the requirements of spec 8.5.1"); #endif - ObjectPool, + ObjectPool, CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS + CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS> mAttributePathPool; - ObjectPool, + ObjectPool, CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS + CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS> mEventPathPool; - ObjectPool, + ObjectPool, CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS + CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS> mDataVersionFilterPool; diff --git a/src/app/OperationalSessionSetupPool.h b/src/app/OperationalSessionSetupPool.h index 583c7e8d4cc64b..30160a1cb572c9 100644 --- a/src/app/OperationalSessionSetupPool.h +++ b/src/app/OperationalSessionSetupPool.h @@ -17,7 +17,6 @@ #pragma once -#include #include #include #include diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp index b5fc34484ea8ff..63da2a53aa7470 100644 --- a/src/app/ReadHandler.cpp +++ b/src/app/ReadHandler.cpp @@ -134,7 +134,7 @@ void ReadHandler::OnSubscriptionResumed(const SessionHandle & sessionHandle, MoveToState(HandlerState::CanStartReporting); - ObjectList * attributePath = mpAttributePathList; + SingleLinkedListNode * attributePath = mpAttributePathList; while (attributePath) { mManagementCallback.GetInteractionModelEngine()->GetReportingEngine().SetDirty(attributePath->mValue); diff --git a/src/app/ReadHandler.h b/src/app/ReadHandler.h index 71070c357147df..c597bac8a58d70 100644 --- a/src/app/ReadHandler.h +++ b/src/app/ReadHandler.h @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -224,9 +224,9 @@ class ReadHandler : public Messaging::ExchangeDelegate ReadHandler(ManagementCallback & apCallback, Observer * observer); #endif - const ObjectList * GetAttributePathList() const { return mpAttributePathList; } - const ObjectList * GetEventPathList() const { return mpEventPathList; } - const ObjectList * GetDataVersionFilterList() const { return mpDataVersionFilterList; } + const SingleLinkedListNode * GetAttributePathList() const { return mpAttributePathList; } + const SingleLinkedListNode * GetEventPathList() const { return mpEventPathList; } + const SingleLinkedListNode * GetDataVersionFilterList() const { return mpDataVersionFilterList; } void GetReportingIntervals(uint16_t & aMinInterval, uint16_t & aMaxInterval) const { @@ -550,9 +550,9 @@ class ReadHandler : public Messaging::ExchangeDelegate Messaging::ExchangeManager * mExchangeMgr = nullptr; #endif // CHIP_CONFIG_UNSAFE_SUBSCRIPTION_EXCHANGE_MANAGER_USE - ObjectList * mpAttributePathList = nullptr; - ObjectList * mpEventPathList = nullptr; - ObjectList * mpDataVersionFilterList = nullptr; + SingleLinkedListNode * mpAttributePathList = nullptr; + SingleLinkedListNode * mpEventPathList = nullptr; + SingleLinkedListNode * mpDataVersionFilterList = nullptr; ManagementCallback & mManagementCallback; diff --git a/src/app/SubscriptionResumptionStorage.h b/src/app/SubscriptionResumptionStorage.h index 316adc3bd3c2e3..19342599f36bbc 100644 --- a/src/app/SubscriptionResumptionStorage.h +++ b/src/app/SubscriptionResumptionStorage.h @@ -78,15 +78,15 @@ class SubscriptionResumptionStorage bool mFabricFiltered; Platform::ScopedMemoryBufferWithSize mAttributePaths; Platform::ScopedMemoryBufferWithSize mEventPaths; - CHIP_ERROR SetAttributePaths(const ObjectList * pAttributePathList) + CHIP_ERROR SetAttributePaths(const SingleLinkedListNode * pAttributePathList) { mAttributePaths.Free(); if (!pAttributePathList) { return CHIP_NO_ERROR; } - const ObjectList * attributePath = pAttributePathList; - size_t attributePathCount = 0; + const SingleLinkedListNode * attributePath = pAttributePathList; + size_t attributePathCount = 0; while (attributePath) { attributePathCount++; @@ -103,15 +103,15 @@ class SubscriptionResumptionStorage } return CHIP_NO_ERROR; } - CHIP_ERROR SetEventPaths(const ObjectList * pEventPathList) + CHIP_ERROR SetEventPaths(const SingleLinkedListNode * pEventPathList) { mEventPaths.Free(); if (!pEventPathList) { return CHIP_NO_ERROR; } - const ObjectList * eventPath = pEventPathList; - size_t eventPathCount = 0; + const SingleLinkedListNode * eventPath = pEventPathList; + size_t eventPathCount = 0; while (eventPath) { eventPathCount++; diff --git a/src/app/app-platform/ContentAppPlatform.cpp b/src/app/app-platform/ContentAppPlatform.cpp index abcaa981843037..09d6c55b14454d 100644 --- a/src/app/app-platform/ContentAppPlatform.cpp +++ b/src/app/app-platform/ContentAppPlatform.cpp @@ -237,13 +237,12 @@ EndpointId ContentAppPlatform::RemoveContentApp(ContentApp * app) if (mContentApps[index] == app) { EndpointId curEndpoint = app->GetEndpointId(); - EndpointId ep = emberAfClearDynamicEndpoint(index); - mContentApps[index] = nullptr; - ChipLogProgress(DeviceLayer, "Removed device %d from dynamic endpoint %d (index=%d)", - app->GetApplicationBasicDelegate()->HandleGetVendorId(), ep, index); // Silence complaints about unused ep when progress logging // disabled. - UNUSED_VAR(ep); + /*[[maybe_unused]]*/ EndpointId ep = emberAfClearDynamicEndpoint(index); + mContentApps[index] = nullptr; + ChipLogProgress(DeviceLayer, "Removed device %d from dynamic endpoint %d (index=%d)", + app->GetApplicationBasicDelegate()->HandleGetVendorId(), ep, index); if (curEndpoint == mCurrentAppEndpointId) { mCurrentAppEndpointId = kNoCurrentEndpointId; diff --git a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp index 95d9a332819ae3..7b1b036ee4857b 100644 --- a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp +++ b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp @@ -115,6 +115,9 @@ void DiagnosticLogsServer::HandleLogRequestForResponsePayload(CommandHandler * c Optional timeStamp; Optional timeSinceBoot; + auto size = delegate->GetSizeForIntent(intent); + VerifyOrReturn(size != 0, AddResponse(commandObj, path, StatusEnum::kNoLogs)); + auto err = delegate->GetLogForIntent(intent, logContent, timeStamp, timeSinceBoot); VerifyOrReturn(CHIP_ERROR_NOT_FOUND != err, AddResponse(commandObj, path, StatusEnum::kNoLogs)); VerifyOrReturn(CHIP_NO_ERROR == err, AddResponse(commandObj, path, StatusEnum::kDenied)); @@ -129,6 +132,8 @@ void DiagnosticLogsServer::HandleLogRequestForBdx(CommandHandler * commandObj, c // INVALID_COMMAND. VerifyOrReturn(transferFileDesignator.HasValue(), commandObj->AddStatus(path, Status::InvalidCommand)); + VerifyOrReturn(transferFileDesignator.Value().size() > 0, commandObj->AddStatus(path, Status::ConstraintError)); + VerifyOrReturn(transferFileDesignator.Value().size() <= kMaxFileDesignatorLen, commandObj->AddStatus(path, Status::ConstraintError)); @@ -136,10 +141,13 @@ void DiagnosticLogsServer::HandleLogRequestForBdx(CommandHandler * commandObj, c auto * delegate = GetDiagnosticLogsProviderDelegate(path.mEndpointId); VerifyOrReturn(nullptr != delegate, AddResponse(commandObj, path, StatusEnum::kNoLogs)); + auto size = delegate->GetSizeForIntent(intent); + // In the case where the size is 0 sets the Status field of the RetrieveLogsResponse to NoLogs and do not start a BDX session. + VerifyOrReturn(size != 0, HandleLogRequestForResponsePayload(commandObj, path, intent, StatusEnum::kNoLogs)); + // In the case where the Node is able to fit the entirety of the requested logs within the LogContent field, the Status field of // the RetrieveLogsResponse SHALL be set to Exhausted and a BDX session SHALL NOT be initiated. - VerifyOrReturn(delegate->GetSizeForIntent(intent) > kMaxLogContentSize, - HandleLogRequestForResponsePayload(commandObj, path, intent, StatusEnum::kExhausted)); + VerifyOrReturn(size > kMaxLogContentSize, HandleLogRequestForResponsePayload(commandObj, path, intent, StatusEnum::kExhausted)); // If the RequestedProtocol is set to BDX and either the Node does not support BDX or it is not possible for the Node // to establish a BDX session, then the Node SHALL utilize the LogContent field of the RetrieveLogsResponse command diff --git a/src/app/clusters/energy-preference-server/energy-preference-server.cpp b/src/app/clusters/energy-preference-server/energy-preference-server.cpp new file mode 100644 index 00000000000000..7cb377a7221ba1 --- /dev/null +++ b/src/app/clusters/energy-preference-server/energy-preference-server.cpp @@ -0,0 +1,235 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "energy-preference-server.h" + +#include // Needed for registerAttributeAccessOverride + +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyPreference; +using namespace chip::app::Clusters::EnergyPreference::Structs; +using namespace chip::app::Clusters::EnergyPreference::Attributes; + +using Status = Protocols::InteractionModel::Status; + +namespace { + +class EnergyPrefAttrAccess : public AttributeAccessInterface +{ +public: + EnergyPrefAttrAccess() : AttributeAccessInterface(Optional::Missing(), EnergyPreference::Id) {} + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; +}; + +EnergyPrefAttrAccess gEnergyPrefAttrAccess; +Delegate * gsDelegate = nullptr; + +CHIP_ERROR EnergyPrefAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == EnergyPreference::Id); + EndpointId endpoint = aPath.mEndpointId; + uint32_t ourFeatureMap = 0; + const bool featureMapIsGood = FeatureMap::Get(aPath.mEndpointId, &ourFeatureMap) == Status::Success; + const bool balanceSupported = featureMapIsGood && ((ourFeatureMap & to_underlying(Feature::kEnergyBalance)) != 0); + const bool lowPowerSupported = featureMapIsGood && ((ourFeatureMap & to_underlying(Feature::kLowPowerModeSensitivity)) != 0); + + switch (aPath.mAttributeId) + { + case EnergyBalances::Id: + if (!balanceSupported) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + + if (gsDelegate != nullptr) + { + return aEncoder.EncodeList([endpoint](const auto & encoder) -> CHIP_ERROR { + size_t index = 0; + CHIP_ERROR err = CHIP_NO_ERROR; + do + { + Percent step; + char buffer[64]; + Optional label{ MutableCharSpan(buffer) }; + if ((err = gsDelegate->GetEnergyBalanceAtIndex(endpoint, index, step, label)) == CHIP_NO_ERROR) + { + BalanceStruct::Type balance = { step, + label.HasValue() ? Optional(label.Value()) + : Optional() }; + ReturnErrorOnFailure(encoder.Encode(balance)); + index++; + } + } while (err == CHIP_NO_ERROR); + + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + return err; + }); + } + return CHIP_ERROR_INCORRECT_STATE; + case EnergyPriorities::Id: + if (balanceSupported == false) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + + if (gsDelegate != nullptr) + { + return aEncoder.EncodeList([endpoint](const auto & encoder) -> CHIP_ERROR { + EnergyPriorityEnum priority; + size_t index = 0; + CHIP_ERROR err = CHIP_NO_ERROR; + while ((err = gsDelegate->GetEnergyPriorityAtIndex(endpoint, index, priority)) == CHIP_NO_ERROR) + { + ReturnErrorOnFailure(encoder.Encode(priority)); + index++; + } + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + return err; + }); + } + return CHIP_ERROR_INCORRECT_STATE; + case LowPowerModeSensitivities::Id: + if (lowPowerSupported == false) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + + if (gsDelegate != nullptr) + { + return aEncoder.EncodeList([endpoint](const auto & encoder) -> CHIP_ERROR { + size_t index = 0; + CHIP_ERROR err = CHIP_NO_ERROR; + do + { + Percent step; + char buffer[64]; + Optional label{ MutableCharSpan(buffer) }; + if ((err = gsDelegate->GetLowPowerModeSensitivityAtIndex(endpoint, index, step, label)) == CHIP_NO_ERROR) + { + BalanceStruct::Type balance = { step, + label.HasValue() ? Optional(label.Value()) + : Optional() }; + ReturnErrorOnFailure(encoder.Encode(balance)); + index++; + } + } while (err == CHIP_NO_ERROR); + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + return err; + }); + } + return CHIP_ERROR_INCORRECT_STATE; + default: // return CHIP_NO_ERROR and just read from the attribute store in default + break; + } + + return CHIP_NO_ERROR; +} + +} // anonymous namespace + +namespace chip::app::Clusters::EnergyPreference { + +void SetDelegate(Delegate * aDelegate) +{ + gsDelegate = aDelegate; +} + +Delegate * GetDelegate() +{ + return gsDelegate; +} + +} // namespace chip::app::Clusters::EnergyPreference + +Status MatterEnergyPreferenceClusterServerPreAttributeChangedCallback(const ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, + uint8_t * value) +{ + EndpointId endpoint = attributePath.mEndpointId; + Delegate * delegate = GetDelegate(); + uint32_t ourFeatureMap; + const bool featureMapIsGood = FeatureMap::Get(attributePath.mEndpointId, &ourFeatureMap) == Status::Success; + const bool balanceSupported = featureMapIsGood && ((ourFeatureMap & to_underlying(Feature::kEnergyBalance)) != 0); + const bool lowPowerSupported = featureMapIsGood && ((ourFeatureMap & to_underlying(Feature::kLowPowerModeSensitivity)) != 0); + + if (delegate == nullptr) + { + return Status::UnsupportedWrite; + } + + switch (attributePath.mAttributeId) + { + case CurrentEnergyBalance::Id: { + if (balanceSupported == false) + { + return Status::UnsupportedAttribute; + } + + uint8_t index = Encoding::Get8(value); + size_t arraySize = delegate->GetNumEnergyBalances(endpoint); + if (index >= arraySize) + { + return Status::ConstraintError; + } + + return Status::Success; + } + + case CurrentLowPowerModeSensitivity::Id: { + if (lowPowerSupported == false) + { + return Status::UnsupportedAttribute; + } + + uint8_t index = Encoding::Get8(value); + size_t arraySize = delegate->GetNumLowPowerModeSensitivities(endpoint); + if (index >= arraySize) + { + return Status::ConstraintError; + } + + return Status::Success; + } + default: + return Status::Success; + } +} + +void MatterEnergyPreferencePluginServerInitCallback() +{ + registerAttributeAccessOverride(&gEnergyPrefAttrAccess); +} diff --git a/src/app/clusters/energy-preference-server/energy-preference-server.h b/src/app/clusters/energy-preference-server/energy-preference-server.h new file mode 100644 index 00000000000000..771057847e372a --- /dev/null +++ b/src/app/clusters/energy-preference-server/energy-preference-server.h @@ -0,0 +1,107 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace chip::app::Clusters::EnergyPreference { + +struct Delegate +{ + // Note: This delegate does not handle the "Current Active" indexes attributes storage. + // eg: Current Energy Balance and Current Low Power Mode Sensitivity. These can be handled using + // ember built in storage, or via the external callbacks as desired by the implementer. + + virtual ~Delegate() {} + + /** + * Get an Energy Balance. + * + * The delegate method is called by the cluster to fill out the + * values for the list in EnergyBalances attribute. Storage for + * both aOutStep and aOutLabel is provided by the caller. + * + * @param aEndpoint The endpoint to query. + * @param aIndex The index of the balance, with 0 representing the first one. + * @param aOutStep The Step value from BalanceStruct + * + * @param aOutLabel The Label value from BalanceStruct. Storage is + * provided by the caller, and is large enough to accomodate the + * longest label (64 chars), on successful return the size of the span must be + * adjusted to reflect the length of the value, or ClearValue() called on the Optional to indicate there is no label. + * + * @return CHIP_ERROR_NOT_FOUND if the index is out of range. + */ + virtual CHIP_ERROR GetEnergyBalanceAtIndex(chip::EndpointId aEndpoint, size_t aIndex, chip::Percent & aOutStep, + chip::Optional & aOutLabel) = 0; + + /** + * Get an Energy Priority. + * @param aEndpoint The endpoint to query. + * @param aIndex The index of the priority, with 0 representing the first one. + * @param aOutPriority The EnergyPriorityEnum to copy the data into. + * @return CHIP_ERROR_NOT_FOUND if the index is out of range. + */ + virtual CHIP_ERROR GetEnergyPriorityAtIndex(chip::EndpointId aEndpoint, size_t aIndex, + chip::app::Clusters::EnergyPreference::EnergyPriorityEnum & aOutPriority) = 0; + + /** + * Get a Power Sensitity Balance Struct data at the specified index. + * + * The delegate method is called by the cluster to fill out the + * values for the list in LowPowerSensitivities attribute. Storage for + * both aOutStep and aOutLabel is provided by the caller. + * + * @param aEndpoint The endpoint to query. + * @param aIndex The index of the priority, with 0 representing the first one. + * @param aOutStep The Step value from BalanceStruct + * + * @param aOutLabel The Label value from BalanceStruct. Storage is + * provided by the caller, and is large enough to accomodate the + * longest label (64 chars), on successful return the size of the span must be + * adjusted to reflect the length of the value, or ClearValue() called on the Optional to indicate there is no label. + * + * @return CHIP_ERROR_NOT_FOUND if the index is out of range. + */ + virtual CHIP_ERROR GetLowPowerModeSensitivityAtIndex(chip::EndpointId aEndpoint, size_t aIndex, chip::Percent & aOutStep, + chip::Optional & aOutLabel) = 0; + + /** + * Get the number of energy balances this endpoint has. + * @param aEndpoint The endpoint to query. + * @return the number of balance structs in the list. + */ + virtual size_t GetNumEnergyBalances(chip::EndpointId aEndpoint) = 0; + + /** + * Get the number of low power mode sensitivities this endpoint has. + * @param aEndpoint The endpoint to query. + * @return the number of balance structs in the list. + */ + virtual size_t GetNumLowPowerModeSensitivities(chip::EndpointId aEndpoint) = 0; +}; + +void SetDelegate(Delegate * aDelegate); +Delegate * GetDelegate(); + +} // namespace chip::app::Clusters::EnergyPreference diff --git a/src/app/common/BUILD.gn b/src/app/common/BUILD.gn index 193d4c362e537e..1af268a477efaf 100644 --- a/src/app/common/BUILD.gn +++ b/src/app/common/BUILD.gn @@ -27,7 +27,9 @@ static_library("cluster-objects") { ] public_deps = [ + "${chip_root}/src/app:paths", "${chip_root}/src/app/data-model", + "${chip_root}/src/app/util:types", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", "${chip_root}/src/protocols/interaction_model", diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 20677184632c6c..875cdbcdbd1514 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -84,5 +84,6 @@ ClustersWithPreAttributeChangeFunctions: - Mode Select - Fan Control - Thermostat + - Energy Preference - Laundry Washer Controls - Laundry Dryer Controls diff --git a/src/app/data-model/BUILD.gn b/src/app/data-model/BUILD.gn index 49a49033f0e9f2..9b04882a60ec9c 100644 --- a/src/app/data-model/BUILD.gn +++ b/src/app/data-model/BUILD.gn @@ -37,8 +37,8 @@ source_set("data-model") { # of this, in part due to zap-generated code dependency. # # - app/util/attribute-storage-null-handling.h - # - app/ConcreteAttributePath.h # + "${chip_root}/src/app:paths", "${chip_root}/src/app/common:enums", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index 80dec7ed6d3cd1..2dd730c358fe0a 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -58,7 +58,7 @@ void Engine::Shutdown() mGlobalDirtySet.ReleaseAll(); } -bool Engine::IsClusterDataVersionMatch(const ObjectList * aDataVersionFilterList, +bool Engine::IsClusterDataVersionMatch(const SingleLinkedListNode * aDataVersionFilterList, const ConcreteReadAttributePath & aPath) { bool existPathMatch = false; diff --git a/src/app/reporting/Engine.h b/src/app/reporting/Engine.h index 47483d9096bfec..fccf9e08ab020f 100644 --- a/src/app/reporting/Engine.h +++ b/src/app/reporting/Engine.h @@ -179,7 +179,7 @@ class Engine // of those will fail to match. This function should return false if either nothing in the list matches the given // endpoint+cluster in the path or there is an entry in the list that matches the endpoint+cluster in the path but does not // match the current data version of that cluster. - bool IsClusterDataVersionMatch(const ObjectList * aDataVersionFilterList, + bool IsClusterDataVersionMatch(const SingleLinkedListNode * aDataVersionFilterList, const ConcreteReadAttributePath & aPath); /** diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index 4d63afda77ad42..7c661464bbaea3 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -30,6 +30,7 @@ static_library("server") { sources = [ "AclStorage.cpp", "AclStorage.h", + "AppDelegate.h", "CommissioningModeProvider.h", "CommissioningWindowManager.cpp", "CommissioningWindowManager.h", diff --git a/src/app/server/DefaultAclStorage.cpp b/src/app/server/DefaultAclStorage.cpp index 58d0d18feedda6..6f40cce2599893 100644 --- a/src/app/server/DefaultAclStorage.cpp +++ b/src/app/server/DefaultAclStorage.cpp @@ -138,7 +138,7 @@ CHIP_ERROR DefaultAclStorage::Init(PersistentStorageDelegate & persistentStorage CHIP_ERROR err; - size_t count = 0; + [[maybe_unused]] size_t count = 0; for (auto it = first; it != last; ++it) { diff --git a/src/app/tests/TestAttributePathExpandIterator.cpp b/src/app/tests/TestAttributePathExpandIterator.cpp index d4da4fc95a2b8c..e5505320193b81 100644 --- a/src/app/tests/TestAttributePathExpandIterator.cpp +++ b/src/app/tests/TestAttributePathExpandIterator.cpp @@ -20,12 +20,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -41,7 +41,7 @@ using P = app::ConcreteAttributePath; void TestAllWildcard(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo; + SingleLinkedListNode clusInfo; app::ConcreteAttributePath path; P paths[] = { @@ -144,7 +144,7 @@ void TestAllWildcard(nlTestSuite * apSuite, void * apContext) void TestWildcardEndpoint(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo; + SingleLinkedListNode clusInfo; clusInfo.mValue.mClusterId = Test::MockClusterId(3); clusInfo.mValue.mAttributeId = Test::MockAttributeId(3); @@ -167,7 +167,7 @@ void TestWildcardEndpoint(nlTestSuite * apSuite, void * apContext) void TestWildcardCluster(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo; + SingleLinkedListNode clusInfo; clusInfo.mValue.mEndpointId = Test::kMockEndpoint3; clusInfo.mValue.mAttributeId = app::Clusters::Globals::Attributes::ClusterRevision::Id; @@ -193,7 +193,7 @@ void TestWildcardCluster(nlTestSuite * apSuite, void * apContext) void TestWildcardClusterGlobalAttributeNotInMetadata(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo; + SingleLinkedListNode clusInfo; clusInfo.mValue.mEndpointId = Test::kMockEndpoint3; clusInfo.mValue.mAttributeId = app::Clusters::Globals::Attributes::AttributeList::Id; @@ -219,7 +219,7 @@ void TestWildcardClusterGlobalAttributeNotInMetadata(nlTestSuite * apSuite, void void TestWildcardAttribute(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo; + SingleLinkedListNode clusInfo; clusInfo.mValue.mEndpointId = Test::kMockEndpoint2; clusInfo.mValue.mClusterId = Test::MockClusterId(3); @@ -252,7 +252,7 @@ void TestWildcardAttribute(nlTestSuite * apSuite, void * apContext) void TestNoWildcard(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo; + SingleLinkedListNode clusInfo; clusInfo.mValue.mEndpointId = Test::kMockEndpoint2; clusInfo.mValue.mClusterId = Test::MockClusterId(3); clusInfo.mValue.mAttributeId = Test::MockAttributeId(3); @@ -277,21 +277,21 @@ void TestNoWildcard(nlTestSuite * apSuite, void * apContext) void TestMultipleClusInfo(nlTestSuite * apSuite, void * apContext) { - app::ObjectList clusInfo1; + SingleLinkedListNode clusInfo1; - app::ObjectList clusInfo2; + SingleLinkedListNode clusInfo2; clusInfo2.mValue.mClusterId = Test::MockClusterId(3); clusInfo2.mValue.mAttributeId = Test::MockAttributeId(3); - app::ObjectList clusInfo3; + SingleLinkedListNode clusInfo3; clusInfo3.mValue.mEndpointId = Test::kMockEndpoint3; clusInfo3.mValue.mAttributeId = app::Clusters::Globals::Attributes::ClusterRevision::Id; - app::ObjectList clusInfo4; + SingleLinkedListNode clusInfo4; clusInfo4.mValue.mEndpointId = Test::kMockEndpoint2; clusInfo4.mValue.mClusterId = Test::MockClusterId(3); - app::ObjectList clusInfo5; + SingleLinkedListNode clusInfo5; clusInfo5.mValue.mEndpointId = Test::kMockEndpoint2; clusInfo5.mValue.mClusterId = Test::MockClusterId(3); clusInfo5.mValue.mAttributeId = Test::MockAttributeId(3); diff --git a/src/app/tests/TestEventLogging.cpp b/src/app/tests/TestEventLogging.cpp index 08f950517acfde..baf43d6b398707 100644 --- a/src/app/tests/TestEventLogging.cpp +++ b/src/app/tests/TestEventLogging.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +133,7 @@ static void CheckLogState(nlTestSuite * apSuite, chip::app::EventManagement & aL } static void CheckLogReadOut(nlTestSuite * apSuite, chip::app::EventManagement & alogMgmt, chip::EventNumber startingEventNumber, - size_t expectedNumEvents, chip::app::ObjectList * clusterInfo) + size_t expectedNumEvents, chip::SingleLinkedListNode * clusterInfo) { CHIP_ERROR err; chip::TLV::TLVReader reader; @@ -236,7 +236,7 @@ static void CheckLogEventWithEvictToNextBuffer(nlTestSuite * apSuite, void * apC NL_TEST_ASSERT(apSuite, (eid4 + 1) == eid5); NL_TEST_ASSERT(apSuite, (eid5 + 1) == eid6); - chip::app::ObjectList paths[2]; + chip::SingleLinkedListNode paths[2]; paths[0].mValue.mEndpointId = kTestEndpointId1; paths[0].mValue.mClusterId = kLivenessClusterId; @@ -257,7 +257,7 @@ static void CheckLogEventWithEvictToNextBuffer(nlTestSuite * apSuite, void * apC // interested paths are path list, expect to retrieve all events for those interested paths CheckLogReadOut(apSuite, logMgmt, 0, 6, paths); - chip::app::ObjectList pathsWithWildcard[2]; + chip::SingleLinkedListNode pathsWithWildcard[2]; paths[0].mValue.mEndpointId = kTestEndpointId1; paths[0].mValue.mClusterId = kLivenessClusterId; diff --git a/src/app/tests/TestEventLoggingNoUTCTime.cpp b/src/app/tests/TestEventLoggingNoUTCTime.cpp index 43df98a790e2ba..8360f9a0813e98 100644 --- a/src/app/tests/TestEventLoggingNoUTCTime.cpp +++ b/src/app/tests/TestEventLoggingNoUTCTime.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -177,7 +177,7 @@ static void CheckLogState(nlTestSuite * apSuite, chip::app::EventManagement & aL } static void CheckLogReadOut(nlTestSuite * apSuite, chip::app::EventManagement & alogMgmt, chip::EventNumber startingEventNumber, - size_t expectedNumEvents, chip::app::ObjectList * clusterInfo) + size_t expectedNumEvents, chip::SingleLinkedListNode * clusterInfo) { CHIP_ERROR err; chip::TLV::TLVReader reader; @@ -279,7 +279,7 @@ static void CheckLogEventWithEvictToNextBuffer(nlTestSuite * apSuite, void * apC NL_TEST_ASSERT(apSuite, (eid4 + 1) == eid5); NL_TEST_ASSERT(apSuite, (eid5 + 1) == eid6); - chip::app::ObjectList paths[2]; + chip::SingleLinkedListNode paths[2]; paths[0].mValue.mEndpointId = kTestEndpointId1; paths[0].mValue.mClusterId = kLivenessClusterId; @@ -300,7 +300,7 @@ static void CheckLogEventWithEvictToNextBuffer(nlTestSuite * apSuite, void * apC // interested paths are path list, expect to retrieve all events for those interested paths CheckLogReadOut(apSuite, logMgmt, 0, 6, paths); - chip::app::ObjectList pathsWithWildcard[2]; + chip::SingleLinkedListNode pathsWithWildcard[2]; paths[0].mValue.mEndpointId = kTestEndpointId1; paths[0].mValue.mClusterId = kLivenessClusterId; diff --git a/src/app/tests/TestFabricScopedEventLogging.cpp b/src/app/tests/TestFabricScopedEventLogging.cpp index f55ac63b687491..d016ad5183e1c0 100644 --- a/src/app/tests/TestFabricScopedEventLogging.cpp +++ b/src/app/tests/TestFabricScopedEventLogging.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -137,7 +137,7 @@ static void CheckLogState(nlTestSuite * apSuite, chip::app::EventManagement & aL } static void CheckLogReadOut(nlTestSuite * apSuite, chip::app::EventManagement & alogMgmt, chip::EventNumber startingEventNumber, - size_t expectedNumEvents, chip::app::ObjectList * clusterInfo, + size_t expectedNumEvents, chip::SingleLinkedListNode * clusterInfo, const chip::Access::SubjectDescriptor & aSubjectDescriptor) { CHIP_ERROR err; @@ -220,7 +220,7 @@ static void CheckLogEventWithEvictToNextBuffer(nlTestSuite * apSuite, void * apC NL_TEST_ASSERT(apSuite, (eid2 + 1) == eid3); NL_TEST_ASSERT(apSuite, (eid3 + 1) == eid4); - chip::app::ObjectList paths[2]; + chip::SingleLinkedListNode paths[2]; paths[0].mValue.mEndpointId = kTestEndpointId1; paths[0].mValue.mClusterId = kLivenessClusterId; @@ -247,7 +247,7 @@ static void CheckLogEventWithEvictToNextBuffer(nlTestSuite * apSuite, void * apC CheckLogReadOut(apSuite, logMgmt, 0, 1, paths, descriptor); // Fabric event + wildcard test, only have one fabric-scoped event with fabric 2 - chip::app::ObjectList pathsWithWildcard[2]; + chip::SingleLinkedListNode pathsWithWildcard[2]; paths[0].mValue.mEndpointId = kTestEndpointId1; paths[0].mValue.mClusterId = kLivenessClusterId; diff --git a/src/app/tests/TestInteractionModelEngine.cpp b/src/app/tests/TestInteractionModelEngine.cpp index f4450635ac0b8f..fcdc7d53e1594f 100644 --- a/src/app/tests/TestInteractionModelEngine.cpp +++ b/src/app/tests/TestInteractionModelEngine.cpp @@ -52,13 +52,13 @@ class TestInteractionModelEngine #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION static void TestSubscriptionResumptionTimer(nlTestSuite * apSuite, void * apContext); #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION - static int GetAttributePathListLength(ObjectList * apattributePathParamsList); + static int GetAttributePathListLength(SingleLinkedListNode * apattributePathParamsList); }; -int TestInteractionModelEngine::GetAttributePathListLength(ObjectList * apAttributePathParamsList) +int TestInteractionModelEngine::GetAttributePathListLength(SingleLinkedListNode * apAttributePathParamsList) { - int length = 0; - ObjectList * runner = apAttributePathParamsList; + int length = 0; + SingleLinkedListNode * runner = apAttributePathParamsList; while (runner != nullptr) { runner = runner->mpNext; @@ -74,7 +74,7 @@ void TestInteractionModelEngine::TestAttributePathParamsPushRelease(nlTestSuite err = InteractionModelEngine::GetInstance()->Init(&ctx.GetExchangeManager(), &ctx.GetFabricTable(), app::reporting::GetDefaultReportScheduler()); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ObjectList * attributePathParamsList = nullptr; + SingleLinkedListNode * attributePathParamsList = nullptr; AttributePathParams attributePathParams1; AttributePathParams attributePathParams2; AttributePathParams attributePathParams3; @@ -112,7 +112,7 @@ void TestInteractionModelEngine::TestRemoveDuplicateConcreteAttribute(nlTestSuit err = InteractionModelEngine::GetInstance()->Init(&ctx.GetExchangeManager(), &ctx.GetFabricTable(), app::reporting::GetDefaultReportScheduler()); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ObjectList * attributePathParamsList = nullptr; + SingleLinkedListNode * attributePathParamsList = nullptr; AttributePathParams attributePathParams1; AttributePathParams attributePathParams2; AttributePathParams attributePathParams3; diff --git a/src/app/tests/suites/DL_UsersAndCredentials.yaml b/src/app/tests/suites/DL_UsersAndCredentials.yaml index 0a344d4883eba6..e86fbbe56dc053 100644 --- a/src/app/tests/suites/DL_UsersAndCredentials.yaml +++ b/src/app/tests/suites/DL_UsersAndCredentials.yaml @@ -562,7 +562,7 @@ tests: - name: "UserUniqueID" value: 0xBABA - name: "UserStatus" - value: 2 + value: UserStatusEnum.UnknownEnumValue(2) - name: "UserType" value: null - name: "CredentialRule" @@ -1031,7 +1031,7 @@ tests: - name: "UserIndex" value: null - name: "UserStatus" - value: 2 + value: UserStatusEnum.UnknownEnumValue(2) - name: "UserType" value: null response: diff --git a/src/app/tests/suites/TestAccessControlConstraints.yaml b/src/app/tests/suites/TestAccessControlConstraints.yaml index 82e66b8d347c10..1a54ea48f92365 100644 --- a/src/app/tests/suites/TestAccessControlConstraints.yaml +++ b/src/app/tests/suites/TestAccessControlConstraints.yaml @@ -130,7 +130,7 @@ tests: { FabricIndex: 0, Privilege: 3, - AuthMode: 4, # INVALID + AuthMode: AccessControlEntryAuthModeEnum.UnknownEnumValue, Subjects: [], Targets: null, }, @@ -231,7 +231,7 @@ tests: }, { FabricIndex: 0, - Privilege: 6, # INVALID + Privilege: AccessControlEntryPrivilegeEnum.UnknownEnumValue, AuthMode: 2, # CASE Subjects: null, Targets: null, diff --git a/src/app/tests/suites/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index d51aea86b777f6..017d6ce6b6daf4 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -1066,7 +1066,7 @@ tests: - name: "arg1" value: 20003 - name: "arg2" - value: 101 + value: SimpleEnum.UnknownEnumValue response: # Attempting to echo back the invalid enum value should fail. error: FAILURE @@ -2814,7 +2814,7 @@ tests: command: "writeAttribute" attribute: "nullable_enum_attr" arguments: - value: 255 + value: SimpleEnum.UnknownEnumValue(255) response: error: CONSTRAINT_ERROR diff --git a/src/app/tests/suites/TestDiagnosticLogs.yaml b/src/app/tests/suites/TestDiagnosticLogs.yaml index 57ab8cb0fa04f8..2e512d962678c3 100644 --- a/src/app/tests/suites/TestDiagnosticLogs.yaml +++ b/src/app/tests/suites/TestDiagnosticLogs.yaml @@ -443,7 +443,7 @@ tests: arguments: values: - name: "Intent" - value: 128 # undefined value + value: IntentEnum.UnknownEnumValue(128) - name: "RequestedProtocol" value: 0 # ResponsePayload response: @@ -456,7 +456,7 @@ tests: - name: "Intent" value: 0 # EndUserSupport - name: "RequestedProtocol" - value: 128 # undefined value + value: TransferProtocolEnum.UnknownEnumValue(128) response: error: "INVALID_COMMAND" diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 068db7f0dfe525..49554c37f4e3b6 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -10160,3 +10160,36 @@ PICS: - label: "Can the mode change be manually controlled?" id: EEVSEM.S.M.CAN_MANUALLY_CONTROLLED + + # + # Power Topology Cluster + # + - label: "Does the device implement the Power Topology Cluster as a server?" + id: PWRTL.S + + # Features + + - label: + "Does the associated endpoint provide or consume power for the entire + node?" + id: PWRTL.S.F00 + + - label: + "Does the associated endpoint provide or consume power for itself and + its child endpoints?" + id: PWRTL.S.F01 + + - label: + "Does the associated endpoint provide or consume power for a provided + set of endpoints?" + id: PWRTL.S.F02 + + - label: "Can the provided set of endpoints change?" + id: PWRTL.S.F03 + + #Server attributes + - label: "Does the device implement the AvailableEndpoints attribute?" + id: PWRTL.S.A0000 + + - label: "Does the device implement the ActiveEndpoints attribute?" + id: PWRTL.S.A0001 diff --git a/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml b/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml index bd173e7eb81427..12a6829c642048 100644 --- a/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml +++ b/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml @@ -1164,7 +1164,7 @@ tests: FabricIndex: CurrentFabricIndexValue, }, { - Privilege: 6, + Privilege: AccessControlEntryPrivilegeEnum.UnknownEnumValue, AuthMode: 2, Subjects: null, Targets: null, @@ -1192,7 +1192,7 @@ tests: }, { Privilege: 3, - AuthMode: 4, + AuthMode: AccessControlEntryAuthModeEnum.UnknownEnumValue, Subjects: null, Targets: null, FabricIndex: CurrentFabricIndexValue, diff --git a/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml b/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml index 22ce1c1451f5a4..d2db93f33b1cd8 100644 --- a/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml +++ b/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml @@ -66,8 +66,8 @@ tests: value: [ { - Privilege: "4", - AuthMode: "2", + Privilege: AccessControlEntryPrivilegeEnum.Manage, + AuthMode: AccessControlEntryAuthModeEnum.CASE, Subjects: [CommissionerNodeId], Targets: null, FabricIndex: CurrentFabricIndexValue, @@ -94,8 +94,8 @@ tests: value: [ { - Privilege: "5", - AuthMode: "2", + Privilege: AccessControlEntryPrivilegeEnum.Administer, + AuthMode: AccessControlEntryAuthModeEnum.CASE, Subjects: [CommissionerNodeId], Targets: null, FabricIndex: CurrentFabricIndexValue, diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_2.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_2.yaml index 4814d35ee82829..514d9375b11251 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_2.yaml @@ -37,9 +37,10 @@ tests: verification: | Verify in DUT(ALL-CLUSTER-APP) start BLE Advertising by specific DUT implementation - Verify in TH (CHIP-TOOL) start commissioning process(need to obtain the Thread dataset first) + Verify in TH (CHIP-TOOL) start commissioning process (either Thread or WiFi) ./chip-tool pairing ble-thread 1 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd27e57b1b1e22d9051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f01021234041061e1206d2c2b46e079eb775f41fc72190c0402a0fff8 20202021 3840 + ./chip-tool pairing ble-wifi 20202021 3840 disabled: true - label: @@ -51,6 +52,38 @@ tests: CHIP:SC: Received PBKDF param response disabled: true + - label: + "Step 2a: Commissioner reads General Commissioning cluster attribute + SupportsConcurrentConnection" + verification: | + Verify in TH(CHIP-TOOL) + CHIP:DMG: AttributeReportIB = + CHIP:DMG: { + CHIP:DMG: AttributeDataIB = + CHIP:DMG: { + CHIP:DMG: DataVersion = 0xb0556660, + CHIP:DMG: AttributePathIB = + CHIP:DMG: { + CHIP:DMG: Endpoint = 0x0, + CHIP:DMG: Cluster = 0x30, + CHIP:DMG: Attribute = 0x0000_0004, + CHIP:DMG: } + CHIP:DMG: + CHIP:DMG: Data = false, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: ], + CHIP:DMG: + CHIP:DMG: SuppressResponse = true, + CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: } + CHIP:CTL: ----- NetworkCommissioning Features: has WiFi. endpointid = 0 + CHIP:SVR: OnReadCommissioningInfo - vendorId=0xFFF1 productId=0x8001 + CHIP:CTL: Successfully finished commissioning step 'ReadCommissioningInfo2' + disabled: true + - label: "Step 3: Commissioner SHALL re-arm Fail-safe timer on Commissionee within 60s (the autonomously Fail-safe timer length set by @@ -76,63 +109,68 @@ tests: OperationalCSRRequest command" verification: | Verify in TH(CHIP-TOOL) - - CHIP:CTL: Sending CSR request to 0xffffa4001730 device + CHIP:CTL: Sending CSR request to 0xffff7fe56480 device CHIP:DMG: ICR moving to [AddingComm] CHIP:DMG: ICR moving to [AddedComma] - CHIP:IN: Prepared secure message 0xffffb9ba6db8 to 0x0000000000000001 (1) of type 0x8 and protocolId (0, 1) on exchange 45042i with MessageCounter:12011388. - CHIP:IN: Sending encrypted msg 0xffffb9ba6db8 with MessageCounter:12011388 to 0x0000000000000001 (1) at monotonic time: 304120 msec - CHIP:DMG: ICR moving to [CommandSen] + CHIP:EM: <<< [E:11057i S:28473 M:98750543] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [BLE] --- Type 0001:08 (IM:InvokeCommandRequest) + CHIP:DMG: ICR moving to [AwaitingRe] CHIP:CTL: Sent CSR request, waiting for the CSR CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DL: Long dispatch time: 118 ms, for event type 16389 CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - CHIP:DL: Indication received, conn = 0xffffb0044210 + CHIP:DL: Indication received, conn = 0xffff81218b30 CHIP:DL: HandlePlatformSpecificBLEEvent 16389 - CHIP:DL: Indication received, conn = 0xffffb0044210 + CHIP:DL: Indication received, conn = 0xffff81218b30 CHIP:DL: HandlePlatformSpecificBLEEvent 16389 - CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:8508040 on exchange 45042i - CHIP:EM: Found matching exchange: 45042i, Delegate: 0xffffb0040000 + CHIP:EM: >>> [E:11057i S:28473 M:31913565] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) + CHIP:EM: Found matching exchange: 11057i, Delegate: 0xffff78c217c8 CHIP:DMG: ICR moving to [ResponseRe] CHIP:DMG: InvokeResponseMessage = CHIP:DMG: { - CHIP:DMG: suppressResponse = false, - CHIP:DMG: InvokeResponseIBs = - CHIP:DMG: [ - CHIP:DMG: InvokeResponseIB = - CHIP:DMG: { - CHIP:DMG: CommandDataIB = - CHIP:DMG: { - CHIP:DMG: CommandPathIB = - CHIP:DMG: { - CHIP:DMG: EndpointId = 0x0, - CHIP:DMG: ClusterId = 0x3e, - CHIP:DMG: CommandId = 0x5, - CHIP:DMG: }, + CHIP:DMG: suppressResponse = false, + CHIP:DMG: InvokeResponseIBs = + CHIP:DMG: [ + CHIP:DMG: InvokeResponseIB = + CHIP:DMG: { + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0x3e, + CHIP:DMG: CommandId = 0x5, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: CommandData = - CHIP:DMG: { - CHIP:DMG: 0x0 = [ - CHIP:DMG: 0x15, 0x30, 0x1, 0xcd, 0x30, 0x81, 0xca, 0x30, 0x70, 0x2, 0x1, 0x0, 0x30, 0xe, 0x31, 0xc, 0x30, 0xa, 0x6, 0x3, 0x55, 0x4, 0xa, 0xc, 0x3, 0x43, 0x53, 0x52, 0x30, 0x59, 0x30, 0x13, 0x6, 0x7, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x2, 0x1, 0x6, 0x8, 0x2a, 0x86 - CHIP:DMG: ] - CHIP:DMG: 0x1 = [ - CHIP:DMG: 0xea, 0xd6, 0x96, 0x53, 0x4d, 0x46, 0x1d, 0xd6, 0xcc, 0x7f, 0x25, 0x50, 0x80, 0x4c, 0x2a, 0xe9, 0xc8, 0xb8, 0x1b, 0x34, 0xca, 0x98, 0x38, 0x42, 0x74, 0xc2, 0x13, 0xf4, 0x10, 0x4d, 0xa2, 0x44, 0x38, 0x98, 0x28, 0xb6, 0xb1, 0x94, 0x6b, 0xd, 0x29, 0x1b - CHIP:DMG: ] - CHIP:DMG: }, - CHIP:DMG: }, + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = [ + CHIP:DMG: 0x15, 0x30, 0x01, 0xca, 0x30, 0x81, 0xc7, 0x30, 0x70, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x03, 0x43, 0x53, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf1, 0xa2, 0x66, 0x01, 0xf7, 0xec, 0x41, 0x11, 0x82, 0x3f, 0xf6, 0x8f, 0x94, 0xe6, 0xeb, 0xe6, 0x6e, 0x6b, 0xbb, 0x2b, 0xad, 0x19, 0x7e, 0xb8, 0x11, 0xbb, 0xc8, 0xc8, 0xf8, 0x59, 0x73, 0x10, 0xd7, 0xff, 0x61, 0x01, 0x0e, 0x7d, 0x50, 0x6e, 0x9d, 0x66, 0xd3, 0x89, 0x83, 0x84, 0xfe, 0xe0, 0xee, 0x7b, 0xbf, 0xaa, 0xa6, 0x3c, 0x60, 0x0a, 0x8e, 0xda, 0xb1, 0xfc, 0xa4, 0xf5, 0xf2, 0xcb, 0xa0, 0x00, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x23, 0x94, 0xd8, 0xc4, 0x00, 0x9a, 0xec, 0x9c, 0x0e, 0x11, 0x26, 0x7f, 0x9e, 0xea, 0x7b, 0xe3, 0x83, 0xde, 0xf8, 0xd3, 0xd3, 0xe7, 0x31, 0xeb, 0x3c, 0xf5, 0x73, 0x65, 0xcd, 0xd8, 0xc0, 0x48, 0x02, 0x20, 0x63, 0x5a, 0x67, 0x85, 0x71, 0xa9, 0x50, 0x30, 0x8e, 0x4c, 0x00, 0x0e, 0x65, 0x1e, 0x59, 0x53, 0x85, 0xb2, 0x6f, 0x5a, 0x01, 0x46, 0xda, 0xb5, 0x27, 0xea, 0x6b, 0x5c, 0x8a, 0x82, 0x48, 0x5e, 0x30, 0x02, 0x20, 0x08, 0x9b, 0x9c, 0xe3, 0xa4, 0xfd, 0xdb, 0xc5, 0xbd, 0x78, 0x36, 0x7c, 0x47, 0xd9, 0xaf, 0x57, 0x22, 0x5a, 0x70, 0xa8, 0x14, 0x86, 0xdd, 0xea, 0x1b, 0x44, 0x80, 0xbd, 0x39, 0x4f, 0xca, 0x76, 0x18, + CHIP:DMG: ] (242 bytes) + CHIP:DMG: 0x1 = [ + CHIP:DMG: 0xc1, 0xa1, 0xf7, 0xba, 0xe4, 0x5f, 0xd5, 0x62, 0x06, 0xb9, 0xe7, 0xf3, 0x64, 0x47, 0x36, 0x6f, 0xcb, 0xf5, 0x74, 0x97, 0x61, 0xf1, 0x54, 0xbc, 0x9a, 0x6c, 0x1b, 0x60, 0xa7, 0xf0, 0xb6, 0x5e, 0x9b, 0x05, 0x06, 0xd8, 0x9f, 0x0e, 0x47, 0xd9, 0x3a, 0xbf, 0x8d, 0x71, 0x61, 0xd4, 0xcf, 0xee, 0x38, 0x64, 0x0d, 0xc0, 0xf8, 0x44, 0xe7, 0x77, 0x08, 0x7d, 0x6b, 0x20, 0x1e, 0x40, 0x1f, 0x94, + CHIP:DMG: ] (64 bytes) + CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: ], + CHIP:DMG: ], CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 1 + CHIP:DMG: InteractionModelRevision = 11 CHIP:DMG: }, CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0005 CHIP:CTL: Received certificate signing request from the device + CHIP:CTL: Successfully finished commissioning step 'SendOpCertSigningRequest' + CHIP:CTL: Commissioning stage next step: 'SendOpCertSigningRequest' -> 'ValidateCSR' + CHIP:CTL: Performing next commissioning step 'ValidateCSR' + CHIP:CTL: Successfully finished commissioning step 'ValidateCSR' + CHIP:CTL: Commissioning stage next step: 'ValidateCSR' -> 'GenerateNOCChain' + CHIP:CTL: Performing next commissioning step 'GenerateNOCChain' CHIP:CTL: Getting certificate chain for the device from the issuer CHIP:CTL: Verifying Certificate Signing Request CHIP:CTL: Generating NOC CHIP:CTL: Providing certificate chain to the commissioner - CHIP:CTL: Received callback from the CA for NOC Chain generation. Status ../../src/controller/ExampleOperationalCredentialsIssuer.cpp:225: Success + CHIP:CTL: Received callback from the CA for NOC Chain generation. Status src/controller/ExampleOperationalCredentialsIssuer.cpp:395: Success disabled: true - label: @@ -141,49 +179,48 @@ tests: verification: | Verify in TH(CHIP-TOOL) - [1651218829.220063][3273:3278] CHIP:CTL: Sending root certificate to the device - [1651218829.220201][3273:3278] CHIP:DMG: ICR moving to [AddingComm] - [1651218829.222415][3273:3278] CHIP:DMG: ICR moving to [AddedComma] - [1651218829.222549][3273:3278] CHIP:IN: Prepared secure message 0xffffb9ba6b98 to 0x0000000000000001 (1) of type 0x8 and protocolId (0, 1) on exchange 45043i with MessageCounter:12011389. - [1651218829.222616][3273:3278] CHIP:IN: Sending encrypted msg 0xffffb9ba6b98 with MessageCounter:12011389 to 0x0000000000000001 (1) at monotonic time: 305872 msec - [1651218829.222746][3273:3278] CHIP:DMG: ICR moving to [CommandSen] - [1651218829.222789][3273:3278] CHIP:CTL: Sent root certificate to the device - [1651218829.223121][3273:3278] CHIP:DMG: ICR moving to [AwaitingDe] - [1651218829.306861][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218829.404144][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218829.454121][3273:3276] CHIP:DL: Indication received, conn = 0xffffb0044210 - [1651218829.454352][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16389 - CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:8508041 on exchange 45043i - CHIP:EM: Found matching exchange: 45043i, Delegate: 0xffffa400def0 + CHIP:CTL: Sending root certificate to the device + CHIP:DMG: ICR moving to [AddingComm] + CHIP:DMG: ICR moving to [AddedComma] + CHIP:EM: <<< [E:11058i S:28473 M:98750544] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [BLE] --- Type 0001:08 (IM:InvokeCommandRequest) + CHIP:DMG: ICR moving to [AwaitingRe] + CHIP:CTL: Sent root certificate to the device + CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: Indication received, conn = 0xffff81218b30 + CHIP:DL: HandlePlatformSpecificBLEEvent 16389 + CHIP:EM: >>> [E:11058i S:28473 M:31913566] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) + CHIP:EM: Found matching exchange: 11058i, Delegate: 0xffff78c20b88 CHIP:DMG: ICR moving to [ResponseRe] CHIP:DMG: InvokeResponseMessage = CHIP:DMG: { - CHIP:DMG: suppressResponse = false, - CHIP:DMG: InvokeResponseIBs = - CHIP:DMG: [ - CHIP:DMG: InvokeResponseIB = - CHIP:DMG: { - CHIP:DMG: CommandStatusIB = - CHIP:DMG: { - CHIP:DMG: CommandPathIB = - CHIP:DMG: { - CHIP:DMG: EndpointId = 0x0, - CHIP:DMG: ClusterId = 0x3e, - CHIP:DMG: CommandId = 0xb, - CHIP:DMG: }, + CHIP:DMG: suppressResponse = false, + CHIP:DMG: InvokeResponseIBs = + CHIP:DMG: [ + CHIP:DMG: InvokeResponseIB = + CHIP:DMG: { + CHIP:DMG: CommandStatusIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0x3e, + CHIP:DMG: CommandId = 0xb, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: StatusIB = - CHIP:DMG: { - CHIP:DMG: status = 0x0, - CHIP:DMG: }, + CHIP:DMG: StatusIB = + CHIP:DMG: { + CHIP:DMG: status = 0x00 (SUCCESS), + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: ], + CHIP:DMG: ], CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 1 + CHIP:DMG: InteractionModelRevision = 11 CHIP:DMG: }, CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_003E Command=0x0000_000B Status=0x0 CHIP:CTL: Device confirmed that it has received the root certificate @@ -195,54 +232,53 @@ tests: verification: | Verify in TH(CHIP-TOOL) - [1651218829.457248][3273:3278] CHIP:CTL: Sending operational certificate chain to the device - [1651218829.457372][3273:3278] CHIP:DMG: ICR moving to [AddingComm] - [1651218829.460013][3273:3278] CHIP:DMG: ICR moving to [AddedComma] - [1651218829.460273][3273:3278] CHIP:IN: Prepared secure message 0xffffb9ba7828 to 0x0000000000000001 (1) of type 0x8 and protocolId (0, 1) on exchange 45044i with MessageCounter:12011390. - [1651218829.460374][3273:3278] CHIP:IN: Sending encrypted msg 0xffffb9ba7828 with MessageCounter:12011390 to 0x0000000000000001 (1) at monotonic time: 306110 msec - [1651218829.460602][3273:3278] CHIP:DMG: ICR moving to [CommandSen] - [1651218829.460684][3273:3278] CHIP:CTL: Sent operational certificate to the device - [1651218829.460778][3273:3278] CHIP:DMG: ICR moving to [AwaitingDe] - [1651218829.550574][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218829.648065][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218829.745594][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218833.988087][3273:3276] CHIP:DL: Indication received, conn = 0xffffb0044210 - [1651218833.988336][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16389 - [1651218833.988598][3273:3278] CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:8508042 on exchange 45044i - CHIP:EM: Found matching exchange: 45044i, Delegate: 0xffffb0040000 + CHIP:CTL: Performing next commissioning step 'SendNOC' + CHIP:DMG: ICR moving to [AddingComm] + CHIP:DMG: ICR moving to [AddedComma] + CHIP:EM: <<< [E:11059i S:28473 M:98750545] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [BLE] --- Type 0001:08 (IM:InvokeCommandRequest) + CHIP:DMG: ICR moving to [AwaitingRe] + CHIP:CTL: Sent operational certificate to the device + CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: Indication received, conn = 0xffff81218b30 + CHIP:DL: HandlePlatformSpecificBLEEvent 16389 + CHIP:EM: >>> [E:11059i S:28473 M:31913567] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) + CHIP:EM: Found matching exchange: 11059i, Delegate: 0xffff78c209c8 CHIP:DMG: ICR moving to [ResponseRe] CHIP:DMG: InvokeResponseMessage = CHIP:DMG: { - CHIP:DMG: suppressResponse = false, - CHIP:DMG: InvokeResponseIBs = - CHIP:DMG: [ - CHIP:DMG: InvokeResponseIB = - CHIP:DMG: { - CHIP:DMG: CommandDataIB = - CHIP:DMG: { - CHIP:DMG: CommandPathIB = - CHIP:DMG: { - CHIP:DMG: EndpointId = 0x0, - CHIP:DMG: ClusterId = 0x3e, - CHIP:DMG: CommandId = 0x8, - CHIP:DMG: }, + CHIP:DMG: suppressResponse = false, + CHIP:DMG: InvokeResponseIBs = + CHIP:DMG: [ + CHIP:DMG: InvokeResponseIB = + CHIP:DMG: { + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0x3e, + CHIP:DMG: CommandId = 0x8, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: CommandData = - CHIP:DMG: { - CHIP:DMG: 0x0 = 0, - CHIP:DMG: 0x1 = 1, - CHIP:DMG: }, - CHIP:DMG: }, + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = 0, + CHIP:DMG: 0x1 = 1, + CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: ], + CHIP:DMG: ], CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 1 + CHIP:DMG: InteractionModelRevision = 11 CHIP:DMG: }, CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 CHIP:CTL: Device returned status 0 on receiving the NOC - CHIP:CTL: Operational credentials provisioned on device 0xffffa4001730 + CHIP:CTL: Operational credentials provisioned on device 0xffff7fe56480 disabled: true - label: @@ -251,50 +287,49 @@ tests: verification: | Verify in TH(CHIP-TOOL) - [1651218833.995054][3273:3278] CHIP:CTL: Adding thread network - [1651218833.995176][3273:3278] CHIP:DMG: ICR moving to [AddingComm] - [1651218833.995253][3273:3278] CHIP:DMG: ICR moving to [AddedComma] - [1651218833.995431][3273:3278] CHIP:IN: Prepared secure message 0xffffb9ba7848 to 0x0000000000000001 (1) of type 0x8 and protocolId (0, 1) on exchange 45045i with MessageCounter:12011391. - [1651218833.995523][3273:3278] CHIP:IN: Sending encrypted msg 0xffffb9ba7848 with MessageCounter:12011391 to 0x0000000000000001 (1) at monotonic time: 310645 msec - [1651218833.995723][3273:3278] CHIP:DMG: ICR moving to [CommandSen] - [1651218833.995823][3273:3278] CHIP:DMG: ICR moving to [AwaitingDe] - [1651218834.084548][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218834.134690][3273:3276] CHIP:DL: Indication received, conn = 0xffffb0044210 - [1651218834.134918][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16389 - CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:8508043 on exchange 45045i - CHIP:EM: Found matching exchange: 45045i, Delegate: 0xffffa400def0 + CHIP:CTL: Performing next commissioning step 'WiFiNetworkSetup' + CHIP:DMG: ICR moving to [AddingComm] + CHIP:DMG: ICR moving to [AddedComma] + CHIP:EM: <<< [E:11060i S:28473 M:98750546] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [BLE] --- Type 0001:08 (IM:InvokeCommandRequest) + CHIP:DMG: ICR moving to [AwaitingRe] + CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: Indication received, conn = 0xffff81218b30 + CHIP:DL: HandlePlatformSpecificBLEEvent 16389 + CHIP:EM: >>> [E:11060i S:28473 M:31913568] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) + CHIP:EM: Found matching exchange: 11060i, Delegate: 0xffff78c20808 CHIP:DMG: ICR moving to [ResponseRe] CHIP:DMG: InvokeResponseMessage = CHIP:DMG: { - CHIP:DMG: suppressResponse = false, - CHIP:DMG: InvokeResponseIBs = - CHIP:DMG: [ - CHIP:DMG: InvokeResponseIB = - CHIP:DMG: { - CHIP:DMG: CommandDataIB = - CHIP:DMG: { - CHIP:DMG: CommandPathIB = - CHIP:DMG: { - CHIP:DMG: EndpointId = 0x0, - CHIP:DMG: ClusterId = 0x31, - CHIP:DMG: CommandId = 0x5, - CHIP:DMG: }, + CHIP:DMG: suppressResponse = false, + CHIP:DMG: InvokeResponseIBs = + CHIP:DMG: [ + CHIP:DMG: InvokeResponseIB = + CHIP:DMG: { + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0x31, + CHIP:DMG: CommandId = 0x5, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: CommandData = - CHIP:DMG: { - CHIP:DMG: 0x0 = 0, - CHIP:DMG: 0x1 = "", - CHIP:DMG: }, - CHIP:DMG: }, + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = 0, + CHIP:DMG: 0x2 = 0, + CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: ], + CHIP:DMG: ], CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 1 + CHIP:DMG: InteractionModelRevision = 11 CHIP:DMG: }, CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0031 Command=0x0000_0005 - CHIP:CTL: Received NetworkConfig response + CHIP:CTL: Received NetworkConfig response, networkingStatus=0 disabled: true - label: @@ -303,118 +338,124 @@ tests: verification: | Verify in TH(CHIP-TOOL) - [1651218834.137891][3273:3278] CHIP:CTL: Enabling thread network - [1651218834.138014][3273:3278] CHIP:DMG: ICR moving to [AddingComm] - [1651218834.138086][3273:3278] CHIP:DMG: ICR moving to [AddedComma] - [1651218834.138236][3273:3278] CHIP:IN: Prepared secure message 0xffffb9ba7938 to 0x0000000000000001 (1) of type 0x8 and protocolId (0, 1) on exchange 45046i with MessageCounter:12011392. - [1651218834.138325][3273:3278] CHIP:IN: Sending encrypted msg 0xffffb9ba7938 with MessageCounter:12011392 to 0x0000000000000001 (1) at monotonic time: 310788 msec - [1651218834.138522][3273:3278] CHIP:DMG: ICR moving to [CommandSen] - [1651218834.138628][3273:3278] CHIP:DMG: ICR moving to [AwaitingDe] - [1651218834.231701][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16387 - [1651218834.426948][3273:3276] CHIP:DL: Indication received, conn = 0xffffb0044210 - [1651218834.427186][3273:3278] CHIP:DL: HandlePlatformSpecificBLEEvent 16389 - [1651218834.427443][3273:3278] CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:8508044 on exchange 45046i - CHIP:EM: Found matching exchange: 45046i, Delegate: 0xffffb0040000 + CHIP:CTL: SendCommand kWiFiNetworkEnable, supportsConcurrentConnection=0 + CHIP:DMG: ICR moving to [AddingComm] + CHIP:DMG: ICR moving to [AddedComma] + CHIP:EM: <<< [E:11062i S:28473 M:98750548] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [BLE] --- Type 0001:08 (IM:InvokeCommandRequest) + CHIP:DMG: ICR moving to [AwaitingRe] + CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DL: Indication received, conn = 0xffff81218b30 + CHIP:DL: HandlePlatformSpecificBLEEvent 16389 + CHIP:EM: >>> [E:11062i S:28473 M:31913570] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) + CHIP:EM: Found matching exchange: 11062i, Delegate: 0xffff78c20488 CHIP:DMG: ICR moving to [ResponseRe] CHIP:DMG: InvokeResponseMessage = CHIP:DMG: { - CHIP:DMG: suppressResponse = false, - CHIP:DMG: InvokeResponseIBs = - CHIP:DMG: [ - CHIP:DMG: InvokeResponseIB = - CHIP:DMG: { - CHIP:DMG: CommandDataIB = - CHIP:DMG: { - CHIP:DMG: CommandPathIB = - CHIP:DMG: { - CHIP:DMG: EndpointId = 0x0, - CHIP:DMG: ClusterId = 0x31, - CHIP:DMG: CommandId = 0x7, - CHIP:DMG: }, + CHIP:DMG: suppressResponse = false, + CHIP:DMG: InvokeResponseIBs = + CHIP:DMG: [ + CHIP:DMG: InvokeResponseIB = + CHIP:DMG: { + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0x31, + CHIP:DMG: CommandId = 0x7, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: CommandData = - CHIP:DMG: { - CHIP:DMG: 0x0 = 0, - CHIP:DMG: 0x1 = "", - CHIP:DMG: 0x2 = 0, - CHIP:DMG: }, - CHIP:DMG: }, + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = 0, + CHIP:DMG: 0x2 = NULL + CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: }, + CHIP:DMG: }, CHIP:DMG: - CHIP:DMG: ], + CHIP:DMG: ], CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 1 + CHIP:DMG: InteractionModelRevision = 11 CHIP:DMG: }, CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0031 Command=0x0000_0007 - CHIP:CTL: Received ConnectNetwork response + CHIP:CTL: Received ConnectNetwork response, networkingStatus=0 disabled: true - label: "Step 10: Commissioning channel between the Commissioner and - Commissionee is terminated." + Commissionee is closed." + verification: | + Cannot be verified in TH(CHIP-TOOL) + disabled: true + + - label: "Step 11: Commissionee starts the operational channel." verification: | - 1. Terminate the connection between the Commissionee and the Commissioner. (i.e. remove network access or terminate commissioning process) + Verify in TH(CHIP-TOOL) + + Inferred by successful completion of Step 12 disabled: true - label: - "Step 11: Commissioner starts discovery of DUT using Operational + "Step 12: Commissioner starts discovery of DUT using Operational Discovery" verification: | Verify in TH(CHIP-TOOL) - CHIP:DL: Avahi resolve found - CHIP:DIS: Node ID resolved for 0x0000000000000001 - CHIP:DIS: Addr 0: [fd11:22::9d96:8fcf:10cf:799e]:5540 - CHIP:CTL: OperationalDiscoveryComplete for device ID 0x0000000000000001 + CHIP:CTL: Performing next commissioning step 'FindOperational' + CHIP:IN: Expiring all sessions for node <00000000000007CE, 1>!! + CHIP:CSM: FindOrEstablishSession: PeerId = [1:00000000000007CE] + CHIP:CSM: FindOrEstablishSession: No existing OperationalSessionSetup instance found + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 1 --> 2 + CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DIS: Checking node lookup status after 200 ms + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DIS: UDP:[fe80::e65f:1ff:fec2:47af%eth0]:5540: new best score: 7 + CHIP:DIS: Lookup clearing interface for non LL address + CHIP:DIS: UDP:172.16.62.113%eth0:5540: new best score: 2 + CHIP:DIS: Checking node lookup status after 7151 ms + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: Updating device address to UDP:[fe80::e65f:1ff:fec2:47af%eth0]:5540 while in state 2 + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 2 --> 3 + CHIP:IN: SecureSession[0xffff7902f2c0]: Allocated Type:2 LSID:28474 disabled: true - label: - "Step 12: Commissioner opens a CASE session with DUT over operational + "Step 13: Commissioner opens a CASE session with DUT over operational network" verification: | Verify in TH(CHIP-TOOL) CHIP:SC: Sent Sigma1 msg - CHIP:CTL: Address resolved for node: 0x0000000000000001 - CHIP:EM: Received message of type 0x31 with protocolId (0, 0) and MessageCounter:1066460336 on exchange 45047i - CHIP:EM: Found matching exchange: 45047i, Delegate: 0xffffa400f7f8 - CHIP:EM: Rxd Ack; Removing MessageCounter:2352378411 from Retrans Table on exchange 45047i - CHIP:EM: Removed CHIP MessageCounter:2352378411 from RetransTable on exchange 45047i + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 3 --> 4 + CHIP:EM: Retransmitting MessageCounter:226454874 on exchange 11063i Send Cnt 1 + CHIP:EM: Retransmitting MessageCounter:226454874 on exchange 11063i Send Cnt 2 + CHIP:EM: Retransmitting MessageCounter:226454874 on exchange 11063i Send Cnt 3 + CHIP:EM: >>> [E:11063i S:0 M:192590746 (Ack:226454874)] (U) Msg RX from 0:0000000000000000 [0000] --- Type 0000:31 (SecureChannel:CASE_Sigma2) + CHIP:EM: Found matching exchange: 11063i, Delegate: 0xffff78207b08 + CHIP:EM: Rxd Ack; Removing MessageCounter:226454874 from Retrans Table on exchange 11063i CHIP:SC: Received Sigma2 msg - CHIP:SC: Peer assigned session session ID 2 - CHIP:SC: The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures. - CHIP:IN: Generating compressed fabric ID using uncompressed fabric ID 0x0000000000000001 and root pubkey - CHIP:IN: 0x04, 0x6e, 0x3e, 0x58, 0x9d, 0x08, 0xd6, 0xae, - CHIP:IN: 0xe9, 0xff, 0x9b, 0x8f, 0xba, 0x6f, 0x57, 0x73, - CHIP:IN: 0x21, 0xc4, 0xe2, 0x7b, 0x09, 0xe4, 0x24, 0x7f, - CHIP:IN: 0x55, 0x44, 0x3b, 0xf2, 0x7c, 0x13, 0x45, 0x3b, - CHIP:IN: 0x82, 0xa8, 0x42, 0x96, 0xb4, 0x36, 0x78, 0x20, - CHIP:IN: 0xa1, 0x37, 0x69, 0xf0, 0x20, 0xc9, 0x20, 0x7e, - CHIP:IN: 0x66, 0x45, 0x84, 0x53, 0x1b, 0x3e, 0xd2, 0x61, - CHIP:IN: 0xb6, 0x89, 0x27, 0xfd, 0xe8, 0x23, 0x69, 0x6d, - CHIP:IN: 0x93, - CHIP:IN: Generated compressed fabric ID - CHIP:IN: 0xa3, 0x54, 0xab, 0x2a, 0xa2, 0x1f, 0x8e, 0x48, + CHIP:SC: Peer assigned session session ID 24240 CHIP:SC: Found MRP parameters in the message CHIP:SC: Sending Sigma3 - CHIP:EM: Piggybacking Ack for MessageCounter:1066460336 on exchange: 45047i - CHIP:IN: Prepared unauthenticated message 0xaaaad7ce1bf8 to 0x0000000000000000 (0) of type 0x32 and protocolId (0, 0) on exchange 45047i with MessageCounter:2352378412. - CHIP:IN: Sending unauthenticated msg 0xaaaad7ce1bf8 with MessageCounter:2352378412 to 0x0000000000000000 at monotonic time: 315803 msec + CHIP:EM: <<< [E:11063i S:0 M:226454875 (Ack:192590746)] (U) Msg TX to 0:0000000000000000 [0000] [UDP:[fe80::e65f:1ff:fec2:47af%eth0]:5540] --- Type 0000:32 (SecureChannel:CASE_Sigma3) CHIP:SC: Sent Sigma3 msg - CHIP:EM: Received message of type 0x40 with protocolId (0, 0) and MessageCounter:1066460337 on exchange 45047i - CHIP:EM: Found matching exchange: 45047i, Delegate: 0xffffa400f7f8 - CHIP:EM: Rxd Ack; Removing MessageCounter:2352378412 from Retrans Table on exchange 45047i - CHIP:EM: Removed CHIP MessageCounter:2352378412 from RetransTable on exchange 45047i + CHIP:EM: >>> [E:11063i S:0 M:192590747 (Ack:226454875)] (U) Msg RX from 0:0000000000000000 [0000] --- Type 0000:40 (SecureChannel:StatusReport) + CHIP:EM: Found matching exchange: 11063i, Delegate: 0xffff78207b08 + CHIP:EM: Rxd Ack; Removing MessageCounter:226454875 from Retrans Table on exchange 11063i CHIP:SC: Success status report received. Session was established - CHIP:IN: New secure session created for device 0x0000000000000001, LSID:2 PSID:2! + CHIP:SC: SecureSession[0xffff7902f2c0, LSID:28474]: State change 'kEstablishing' --> 'kActive' + CHIP:IN: SecureSession[0xffff7902f2c0]: Activated - Type:2 LSID:28474 + CHIP:IN: New secure session activated for device <00000000000007CE, 1>, LSID:28474 PSID:24240! + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 4 --> 5 + CHIP:CTL: Successfully finished commissioning step 'FindOperational' disabled: true - - label: "Step 13: Commissioner sends CommissioningComplete command" + - label: "Step 14: Commissioner sends CommissioningComplete command" verification: | Verify in TH(CHIP-TOOL) - CHIP:CTL: Received CommissioningComplete response - CHIP:CTL: Rendezvous cleanup - CHIP:TOO: Device commissioning completed with success + CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0030 Command=0x0000_0005 + CHIP:CTL: Received CommissioningComplete response, errorCode=0 + CHIP:CTL: Successfully finished commissioning step 'SendComplete' disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_6.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_6.yaml index 674808bfabb520..ad24d09cbbb9f8 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_6.yaml @@ -28,6 +28,7 @@ tests: - label: "Note" verification: | Chip-tool command used below are an example to verify the DUT as commissioner test cases. For certification test, we expect DUT should have a capability or way to run the equivalent command. + Test Harness is a Commissionee device that is not connected to an operational network (i.e. Wi-Fi, or Ethernet) and is configured as a Non-concurrent device. disabled: true - label: "Preconditions" @@ -50,9 +51,11 @@ tests: verification: | Verify in TH (ALL-CLUSTER-APP) start BLE Advertising by specific DUT implementation - Verify in DUT(CHIP-TOOL) start commissioning process(need to obtain the Thread dataset first) + Verify in DUT(CHIP-TOOL) start commissioning process (either Thread or WiFi) ./chip-tool pairing ble-thread 1 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd27e57b1b1e22d9051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f01021234041061e1206d2c2b46e079eb775f41fc72190c0402a0fff8 20202021 3840 + ./chip-tool pairing ble-wifi 20202021 3840 + disabled: true - label: @@ -64,6 +67,30 @@ tests: CHIP:SC: Received PBKDF param response disabled: true + - label: + "Step 3a: Commissioner reads commissioning information, including + SupportsConcurrentConnection attribute from General Commissioining + Cluster" + verification: | + Verify in TH that SupportsConcurrentConnection is false + + CHIP:IM: Received Read request + CHIP:DMG: ReadRequestMessage = + CHIP:DMG: { + CHIP:DMG: AttributePathIBs = + CHIP:DMG: [ + CHIP:DMG: AttributePathIB = + CHIP:DMG: { + CHIP:DMG: Endpoint = 0x0, + CHIP:DMG: Cluster = 0x30, + CHIP:DMG: Attribute = 0x0000_0004, + CHIP:DMG: } + CHIP:DMG: + CHIP:DMG: isFabricFiltered = false, + CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: }, + disabled: true + - label: "Step 4: Commissioner SHALL re-arm Fail-safe timer on Commissionee within 60s (the autonomously Fail-safe timer length set by @@ -370,15 +397,9 @@ tests: - label: "Step 11: Commissioning channel between the Commissioner and - Commissionee is terminated." + Commissionee is closed, operational channel started." verification: | - Verify the channel was terminated on DUT as commissioner side: - [1651271753284] [23287:743790] CHIP: [CTL] Received CommissioningComplete response - [1651271753284] [23287:743790] CHIP: [CTL] Successfully finished commissioning step 'SendComplete' - [1651271753284] [23287:743790] CHIP: [CTL] Commissioning stage next step: 'SendComplete' -> 'Cleanup' - [1651271753284] [23287:743790] CHIP: [CTL] Performing next commissioning step 'Cleanup' - [1651271753284] [23287:743790] CHIP: [CTL] Successfully finished commissioning step 'Cleanup' - [1651271753284] [23287:743790] CHIP: [TOO] Device commissioning completed with success + Inferred by successful completion of Step 12 disabled: true - label: @@ -387,10 +408,21 @@ tests: verification: | Verify in DUT as commissioner side - CHIP:DL: Avahi resolve found - CHIP:DIS: Node ID resolved for 0x0000000000000001 - CHIP:DIS: Addr 0: [fd11:22::9d96:8fcf:10cf:799e]:5540 - CHIP:CTL: OperationalDiscoveryComplete for device ID 0x0000000000000001 + CHIP:CTL: Performing next commissioning step 'FindOperational' + CHIP:IN: Expiring all sessions for node <00000000000007CE, 1>!! + CHIP:CSM: FindOrEstablishSession: PeerId = [1:00000000000007CE] + CHIP:CSM: FindOrEstablishSession: No existing OperationalSessionSetup instance found + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 1 --> 2 + CHIP:DMG: ICR moving to [AwaitingDe] + CHIP:DIS: Checking node lookup status after 200 ms + CHIP:DL: HandlePlatformSpecificBLEEvent 16387 + CHIP:DIS: UDP:[fe80::e65f:1ff:fec2:47af%eth0]:5540: new best score: 7 + CHIP:DIS: Lookup clearing interface for non LL address + CHIP:DIS: UDP:172.16.62.113%eth0:5540: new best score: 2 + CHIP:DIS: Checking node lookup status after 7151 ms + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: Updating device address to UDP:[fe80::e65f:1ff:fec2:47af%eth0]:5540 while in state 2 + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 2 --> 3 + CHIP:IN: SecureSession[0xffff7902f2c0]: Allocated Type:2 LSID:28474 disabled: true - label: @@ -400,45 +432,35 @@ tests: Verify in DUT as commissioner side CHIP:SC: Sent Sigma1 msg - CHIP:CTL: Address resolved for node: 0x0000000000000001 - CHIP:EM: Received message of type 0x31 with protocolId (0, 0) and MessageCounter:1066460336 on exchange 45047i - CHIP:EM: Found matching exchange: 45047i, Delegate: 0xffffa400f7f8 - CHIP:EM: Rxd Ack; Removing MessageCounter:2352378411 from Retrans Table on exchange 45047i - CHIP:EM: Removed CHIP MessageCounter:2352378411 from RetransTable on exchange 45047i + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 3 --> 4 + CHIP:EM: Retransmitting MessageCounter:226454874 on exchange 11063i Send Cnt 1 + CHIP:EM: Retransmitting MessageCounter:226454874 on exchange 11063i Send Cnt 2 + CHIP:EM: Retransmitting MessageCounter:226454874 on exchange 11063i Send Cnt 3 + CHIP:EM: >>> [E:11063i S:0 M:192590746 (Ack:226454874)] (U) Msg RX from 0:0000000000000000 [0000] --- Type 0000:31 (SecureChannel:CASE_Sigma2) + CHIP:EM: Found matching exchange: 11063i, Delegate: 0xffff78207b08 + CHIP:EM: Rxd Ack; Removing MessageCounter:226454874 from Retrans Table on exchange 11063i CHIP:SC: Received Sigma2 msg - CHIP:SC: Peer assigned session session ID 2 - CHIP:SC: The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures. - CHIP:IN: Generating compressed fabric ID using uncompressed fabric ID 0x0000000000000001 and root pubkey - CHIP:IN: 0x04, 0x6e, 0x3e, 0x58, 0x9d, 0x08, 0xd6, 0xae, - CHIP:IN: 0xe9, 0xff, 0x9b, 0x8f, 0xba, 0x6f, 0x57, 0x73, - CHIP:IN: 0x21, 0xc4, 0xe2, 0x7b, 0x09, 0xe4, 0x24, 0x7f, - CHIP:IN: 0x55, 0x44, 0x3b, 0xf2, 0x7c, 0x13, 0x45, 0x3b, - CHIP:IN: 0x82, 0xa8, 0x42, 0x96, 0xb4, 0x36, 0x78, 0x20, - CHIP:IN: 0xa1, 0x37, 0x69, 0xf0, 0x20, 0xc9, 0x20, 0x7e, - CHIP:IN: 0x66, 0x45, 0x84, 0x53, 0x1b, 0x3e, 0xd2, 0x61, - CHIP:IN: 0xb6, 0x89, 0x27, 0xfd, 0xe8, 0x23, 0x69, 0x6d, - CHIP:IN: 0x93, - CHIP:IN: Generated compressed fabric ID - CHIP:IN: 0xa3, 0x54, 0xab, 0x2a, 0xa2, 0x1f, 0x8e, 0x48, + CHIP:SC: Peer assigned session session ID 24240 CHIP:SC: Found MRP parameters in the message CHIP:SC: Sending Sigma3 - CHIP:EM: Piggybacking Ack for MessageCounter:1066460336 on exchange: 45047i - CHIP:IN: Prepared unauthenticated message 0xaaaad7ce1bf8 to 0x0000000000000000 (0) of type 0x32 and protocolId (0, 0) on exchange 45047i with MessageCounter:2352378412. - CHIP:IN: Sending unauthenticated msg 0xaaaad7ce1bf8 with MessageCounter:2352378412 to 0x0000000000000000 at monotonic time: 315803 msec + CHIP:EM: <<< [E:11063i S:0 M:226454875 (Ack:192590746)] (U) Msg TX to 0:0000000000000000 [0000] [UDP:[fe80::e65f:1ff:fec2:47af%eth0]:5540] --- Type 0000:32 (SecureChannel:CASE_Sigma3) CHIP:SC: Sent Sigma3 msg - CHIP:EM: Received message of type 0x40 with protocolId (0, 0) and MessageCounter:1066460337 on exchange 45047i - CHIP:EM: Found matching exchange: 45047i, Delegate: 0xffffa400f7f8 - CHIP:EM: Rxd Ack; Removing MessageCounter:2352378412 from Retrans Table on exchange 45047i - CHIP:EM: Removed CHIP MessageCounter:2352378412 from RetransTable on exchange 45047i + CHIP:EM: >>> [E:11063i S:0 M:192590747 (Ack:226454875)] (U) Msg RX from 0:0000000000000000 [0000] --- Type 0000:40 (SecureChannel:StatusReport) + CHIP:EM: Found matching exchange: 11063i, Delegate: 0xffff78207b08 + CHIP:EM: Rxd Ack; Removing MessageCounter:226454875 from Retrans Table on exchange 11063i CHIP:SC: Success status report received. Session was established - CHIP:IN: New secure session created for device 0x0000000000000001, LSID:2 PSID:2! + CHIP:SC: SecureSession[0xffff7902f2c0, LSID:28474]: State change 'kEstablishing' --> 'kActive' + CHIP:IN: SecureSession[0xffff7902f2c0]: Activated - Type:2 LSID:28474 + CHIP:IN: New secure session activated for device <00000000000007CE, 1>, LSID:28474 PSID:24240! + CHIP:DIS: OperationalSessionSetup[1:00000000000007CE]: State change 4 --> 5 + CHIP:CTL: Successfully finished commissioning step 'FindOperational' disabled: true disabled: true - label: "Step 14: Commissioner sends CommissioningComplete command" verification: | Verify in DUT as commissioner side - CHIP:CTL: Received CommissioningComplete response - CHIP:CTL: Rendezvous cleanup - CHIP:TOO: Device commissioning completed with success + CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0030 Command=0x0000_0005 + CHIP:CTL: Received CommissioningComplete response, errorCode=0 + CHIP:CTL: Successfully finished commissioning step 'SendComplete' disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_8.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_8.yaml index 8410f4c0aab5eb..e9f48c1652e4a0 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_8.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_8.yaml @@ -29,6 +29,7 @@ tests: - label: "Note" verification: | Chip-tool command used below are an example to verify the DUT as commissioner test cases. For certification test, we expect DUT should have a capability or way to run the equivalent command. + Test Harness is a Commissionee device that is not connected to an operational network (i.e. Wi-Fi, or Ethernet) and is configured as a Non-concurrent device. disabled: true - label: "Preconditions" @@ -50,9 +51,10 @@ tests: verification: | Verify in TH as server side: start BLE Advertising by specific DUT implementation - Verify in DUT as client side: start commissioning process(need to obtain the Thread dataset first) + Verify in DUT as client side: start commissioning process (either Thread or WiFi) ./chip-tool pairing ble-thread 1 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd27e57b1b1e22d9051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f01021234041061e1206d2c2b46e079eb775f41fc72190c0402a0fff8 20202021 3840 + ./chip-tool pairing ble-wifi 20202021 3840 disabled: true - label: @@ -64,6 +66,30 @@ tests: CHIP:SC: Received PBKDF param response disabled: true + - label: + "Step 3a: Commissioner reads commissioning information, including + SupportsConcurrentConnection attribute from General Commissioning + Cluster" + verification: | + Verify in TH that SupportsConcurrentConnection is false + + CHIP:IM: Received Read request + CHIP:DMG: ReadRequestMessage = + CHIP:DMG: { + CHIP:DMG: AttributePathIBs = + CHIP:DMG: [ + CHIP:DMG: AttributePathIB = + CHIP:DMG: { + CHIP:DMG: Endpoint = 0x0, + CHIP:DMG: Cluster = 0x30, + CHIP:DMG: Attribute = 0x0000_0004, + CHIP:DMG: } + CHIP:DMG: + CHIP:DMG: isFabricFiltered = false, + CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: }, + disabled: true + - label: "Step 4: Commissioner SHALL re-arm Fail-safe timer on Commissionee within 60s (the autonomously Fail-safe timer length set by @@ -372,18 +398,18 @@ tests: "Step 11: Commissioning channel between the Commissioner and Commissionee is terminated." verification: | - 1. Verify the channel was terminated on DUT=chip-tool - [1651271753284] [23287:743790] CHIP: [CTL] Received CommissioningComplete response - [1651271753284] [23287:743790] CHIP: [CTL] Successfully finished commissioning step 'SendComplete' - [1651271753284] [23287:743790] CHIP: [CTL] Commissioning stage next step: 'SendComplete' -> 'Cleanup' - [1651271753284] [23287:743790] CHIP: [CTL] Performing next commissioning step 'Cleanup' - [1651271753284] [23287:743790] CHIP: [CTL] Successfully finished commissioning step 'Cleanup' - [1651271753284] [23287:743790] CHIP: [TOO] Device commissioning completed with success + Verify in TH + + CHIP:SVR: Received kCloseAllBleConnections:32777 + CHIP:IN: Clearing BLE pending packets. + CHIP:BLE: Releasing end point's BLE connection back to application. + CHIP:BLE: Got notification regarding chip connection closure + CHIP:DL: wpa_supplicant: Start WiFi management disabled: true - label: "Step 12: Reboot TH and prepare for commissioning" verification: | - 1. Using TH=all-clusters-app, exit the app, re-launch app + 1. Using TH=all-clusters-app in non-concurrent mode, exit the app, re-launch app disabled: true - label: diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml index 9f2e34ea6d01ed..0c10f9fa7ba058 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml @@ -167,7 +167,7 @@ tests: - name: "UserIndex" value: null - name: "UserStatus" - value: 5 + value: UserStatusEnum.UnknownEnumValue(5) - name: "UserType" value: 10 response: diff --git a/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml b/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml index 6afdb920658f94..741fc878e8880f 100644 --- a/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml @@ -86,4 +86,4 @@ tests: constraints: type: enum8 minValue: 0 - maxValue: 254 + maxValue: LightSensorTypeEnum.UnknownEnumValue(254) diff --git a/src/app/tests/suites/certification/Test_TC_I_2_3.yaml b/src/app/tests/suites/certification/Test_TC_I_2_3.yaml index 379ed424638c9b..343539ce69e624 100644 --- a/src/app/tests/suites/certification/Test_TC_I_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_2_3.yaml @@ -237,7 +237,7 @@ tests: - name: "EffectIdentifier" value: 0 - name: "EffectVariant" - value: 66 + value: EffectVariantEnum.UnknownEnumValue(66) - label: "Check DUT executes a blink effect." cluster: "LogCommands" diff --git a/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml b/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml index ead4e9b246c853..b011a94ce9cef7 100644 --- a/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml @@ -352,7 +352,7 @@ tests: command: "writeAttribute" attribute: "ActiveCalendarType" arguments: - value: 50 + value: CalendarTypeEnum.UnknownEnumValue(50) response: error: CONSTRAINT_ERROR @@ -361,6 +361,6 @@ tests: command: "writeAttribute" attribute: "HourFormat" arguments: - value: 5 + value: HourFormatEnum.UnknownEnumValue(5) response: error: CONSTRAINT_ERROR diff --git a/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml b/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml index a572f7e143dc43..b67c22a871ced9 100644 --- a/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml @@ -94,6 +94,6 @@ tests: arguments: # Per spec, if [TEMP] feature is enabled, then this attribute can be # one of 0 (Farenheit), 1 (Celsius) or 2 (Kelvin) - value: 5 # INVALID + value: TempUnitEnum.UnknownEnumValue(5) response: error: CONSTRAINT_ERROR diff --git a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml new file mode 100644 index 00000000000000..cfe6fd860be240 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml @@ -0,0 +1,119 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default + +name: 44.1.1. [TC-PWRTL-1.1] Global Attributes with DUT as Server + +PICS: + - PWRTL.S + +config: + nodeId: 0x12344321 + cluster: "Power Topology" + endpoint: 1 + +tests: + - label: "Step 1: Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Step 2: TH reads the ClusterRevision from DUT" + command: "readAttribute" + attribute: "ClusterRevision" + response: + value: 1 + constraints: + type: int16u + + - label: + "Step 3a: Given PWRTL.S.F00(Node) ensure featuremap has the correct + bit set" + PICS: PWRTL.S.F00 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x1] + hasMasksClear: [0x2, 0x4, 0x8] + + - label: + "Step 3b: Given PWRTL.S.F01(Leaf) ensure featuremap has the correct + bit set" + PICS: PWRTL.S.F01 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x2] + hasMasksClear: [0x1, 0x4, 0x8] + + - label: + "Step 3c: Given PWRTL.S.F02(Set) ensure featuremap has the correct bit + set" + PICS: PWRTL.S.F02 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4] + hasMasksClear: [0x1, 0x2] + + - label: + "Step 3d: Given PWRTL.S.F03(Dynamic Power Flow) ensure featuremap has + the correct bit set" + PICS: PWRTL.S.F03 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4, 0x8] + + - label: "Step 4a: TH reads AttributeList from DUT" + PICS: "!PICS_SF_SET && !PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [] + + - label: + "Step 4b: TH reads feature dependent attribute(AvailableEndpoints) + AttributeList from DUT" + PICS: "PICS_SF_SET && !PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0] + + - label: + "Step 4c: TH reads feature dependent attribute(ActiveEndpoints) + AttributeList from DUT" + PICS: "PICS_SF_SET && PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0, 1] diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml index 63aba52fe3f3f6..faf34fdea43e92 100644 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml @@ -468,8 +468,12 @@ tests: response: constraints: type: enum8 - minValue: 0 - maxValue: 9 + anyOf: + [ + ThermostatRunningModeEnum.Off(0), + ThermostatRunningModeEnum.Cool(3), + ThermostatRunningModeEnum.Heat(4), + ] - label: "Step 27: TH reads the StartOfWeek attribute from the DUT" PICS: TSTAT.S.F03 diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index c710f846f0a13a..021f52e6547ec8 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2477,97 +2477,132 @@ REFALM.S.E00=1 REFALM.S.C00.Rsp=1 REFALM.S.C01.Rsp=1 -# RVC CLEAN MODE CLUSTER - +# PICS for the RVC app +# These are required to be here because currently there isn't a way to select a different PICS +# file when running the yaml tests in CI RVCCLEANM.S=1 - -#Server RVCCLEANM.S.A0000=1 RVCCLEANM.S.A0001=1 - -#Feature -RVCCLEANM.S.F00=0 - -#commands RVCCLEANM.S.C00.Rsp=1 RVCCLEANM.S.C01.Tx=1 - +RVCCLEANM.S.F00=0 RVCCLEANM.S.M.CAN_TEST_MODE_FAILURE=1 -#PIXIT -PIXIT.RVCCLEANM.MODE_CHANGE_FAIL=1 -PIXIT.RVCCLEANM.MODE_CHANGE_OK=1 - -# RVC OPERATIONAL STATE CLUSTER RVCOPSTATE.S=1 -RVCOPSTATE.C=1 - -#ManuallyControlled -# These are the PICS supported by the all-clusters-app - -RVCOPSTATE.S.M.ST_STOPPED=1 -RVCOPSTATE.S.M.ST_RUNNING=1 -RVCOPSTATE.S.M.ST_PAUSED=1 -RVCOPSTATE.S.M.ST_ERROR=0 -RVCOPSTATE.S.M.ST_SEEKING_CHARGER=0 -RVCOPSTATE.S.M.ST_CHARGING=0 -RVCOPSTATE.S.M.ST_DOCKED=0 -RVCOPSTATE.S.M.ERR_NO_ERROR=1 -RVCOPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME=0 -RVCOPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION=0 -RVCOPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE=0 -RVCOPSTATE.S.M.ERR_FAILED_TO_FIND_CHARGING_DOCK=0 -RVCOPSTATE.S.M.ERR_STUCK=0 -RVCOPSTATE.S.M.ERR_DUST_BIN_MISSING=0 -RVCOPSTATE.S.M.ERR_DUST_BIN_FULL=0 -RVCOPSTATE.S.M.ERR_WATER_TANK_EMPTY=0 -RVCOPSTATE.S.M.ERR_WATER_TANK_MISSING=0 -RVCOPSTATE.S.M.ERR_WATER_TANK_LID_OPEN=0 -RVCOPSTATE.S.M.ERR_MOP_CLEANING_PAD_MISSING=0 - -#Events -RVCOPSTATE.S.E00=1 -RVCOPSTATE.S.E01=1 - -#Server RVCOPSTATE.S.A0000=1 RVCOPSTATE.S.A0001=1 -RVCOPSTATE.S.A0002=1 +RVCOPSTATE.S.A0002=0 RVCOPSTATE.S.A0003=1 RVCOPSTATE.S.A0004=1 RVCOPSTATE.S.A0005=1 - -#Commands +RVCOPSTATE.S.E00=1 +RVCOPSTATE.S.E01=1 RVCOPSTATE.S.C00.Rsp=1 RVCOPSTATE.S.C01.Rsp=0 RVCOPSTATE.S.C02.Rsp=0 RVCOPSTATE.S.C03.Rsp=1 RVCOPSTATE.S.C04.Tx=1 RVCOPSTATE.S.C128.Rsp=1 -RVCOPSTATE.C.C00.Tx=1 -RVCOPSTATE.C.C01.Tx=1 -RVCOPSTATE.C.C02.Tx=1 -RVCOPSTATE.C.C04.Tx=1 - +RVCOPSTATE.S.M.ST_STOPPED=1 +RVCOPSTATE.S.M.ST_RUNNING=1 +RVCOPSTATE.S.M.ST_PAUSED=1 +RVCOPSTATE.S.M.ST_ERROR=1 +RVCOPSTATE.S.M.ST_SEEKING_CHARGER=1 +RVCOPSTATE.S.M.ST_CHARGING=1 +RVCOPSTATE.S.M.ST_DOCKED=1 +RVCOPSTATE.S.M.ERR_NO_ERROR=1 +RVCOPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME=1 +RVCOPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION=1 +RVCOPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE=1 +RVCOPSTATE.S.M.ERR_FAILED_TO_FIND_CHARGING_DOCK=1 +RVCOPSTATE.S.M.ERR_STUCK=1 +RVCOPSTATE.S.M.ERR_DUST_BIN_MISSING=1 +RVCOPSTATE.S.M.ERR_DUST_BIN_FULL=1 +RVCOPSTATE.S.M.ERR_WATER_TANK_EMPTY=1 +RVCOPSTATE.S.M.ERR_WATER_TANK_MISSING=1 +RVCOPSTATE.S.M.ERR_WATER_TANK_LID_OPEN=1 +RVCOPSTATE.S.M.ERR_MOP_CLEANING_PAD_MISSING=1 +RVCOPSTATE.C=0 +RVCOPSTATE.C.C00.Tx=0 +RVCOPSTATE.C.C01.Tx=0 +RVCOPSTATE.C.C02.Tx=0 +RVCOPSTATE.C.C04.Tx=0 -# RVC RUN MODE CLUSTER RVCRUNM.S=1 -RVCRUNM.S.F00=0 - -#Server RVCRUNM.S.A0000=1 RVCRUNM.S.A0001=1 - -#Commands RVCRUNM.S.C00.Rsp=1 RVCRUNM.S.C01.Tx=1 - +RVCRUNM.S.F00=0 RVCRUNM.S.M.CAN_TEST_MODE_FAILURE=1 RVCRUNM.S.M.CAN_MANUALLY_CONTROLLED=1 -#PIXIT -PIXIT.RVCRUNM.MODE_CHANGE_FAIL=1 -PIXIT.RVCRUNM.MODE_CHANGE_OK=1 +# These are useless as these values are set where the python tests are run. +# They are only here because a list test wants then to be. +PIXIT.RVCCLEANM.MODE_CHANGE_FAIL=0 +PIXIT.RVCCLEANM.MODE_CHANGE_OK=0 +PIXIT.RVCRUNM.MODE_CHANGE_FAIL=0 +PIXIT.RVCRUNM.MODE_CHANGE_OK=0 + +# These are the RVC PICS for the all-clustrs-app. +# These PICS are commented out because the yaml tests are being run against the rvc-app. +# RVCCLEANM.S=1 +# RVCCLEANM.S.A0000=1 +# RVCCLEANM.S.A0001=1 +# RVCCLEANM.S.F00=0 +# RVCCLEANM.S.C00.Rsp=1 +# RVCCLEANM.S.C01.Tx=1 +# RVCCLEANM.S.M.CAN_TEST_MODE_FAILURE=1 + +# RVCOPSTATE.S=1 +# RVCOPSTATE.C=1 +# RVCOPSTATE.S.M.ST_STOPPED=1 +# RVCOPSTATE.S.M.ST_RUNNING=1 +# RVCOPSTATE.S.M.ST_PAUSED=1 +# RVCOPSTATE.S.M.ST_ERROR=0 +# RVCOPSTATE.S.M.ST_SEEKING_CHARGER=0 +# RVCOPSTATE.S.M.ST_CHARGING=0 +# RVCOPSTATE.S.M.ST_DOCKED=0 +# RVCOPSTATE.S.M.ERR_NO_ERROR=1 +# RVCOPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME=0 +# RVCOPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION=0 +# RVCOPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE=0 +# RVCOPSTATE.S.M.ERR_FAILED_TO_FIND_CHARGING_DOCK=0 +# RVCOPSTATE.S.M.ERR_STUCK=0 +# RVCOPSTATE.S.M.ERR_DUST_BIN_MISSING=0 +# RVCOPSTATE.S.M.ERR_DUST_BIN_FULL=0 +# RVCOPSTATE.S.M.ERR_WATER_TANK_EMPTY=0 +# RVCOPSTATE.S.M.ERR_WATER_TANK_MISSING=0 +# RVCOPSTATE.S.M.ERR_WATER_TANK_LID_OPEN=0 +# RVCOPSTATE.S.M.ERR_MOP_CLEANING_PAD_MISSING=0 +# RVCOPSTATE.S.E00=1 +# RVCOPSTATE.S.E01=1 +# RVCOPSTATE.S.A0000=1 +# RVCOPSTATE.S.A0001=1 +# RVCOPSTATE.S.A0002=1 +# RVCOPSTATE.S.A0003=1 +# RVCOPSTATE.S.A0004=1 +# RVCOPSTATE.S.A0005=1 +# RVCOPSTATE.S.C00.Rsp=1 +# RVCOPSTATE.S.C01.Rsp=0 +# RVCOPSTATE.S.C02.Rsp=0 +# RVCOPSTATE.S.C03.Rsp=1 +# RVCOPSTATE.S.C04.Tx=1 +# RVCOPSTATE.S.C128.Rsp=1 +# RVCOPSTATE.C.C00.Tx=1 +# RVCOPSTATE.C.C01.Tx=1 +# RVCOPSTATE.C.C02.Tx=1 +# RVCOPSTATE.C.C04.Tx=1 + +# RVCRUNM.S=1 +# RVCRUNM.S.F00=0 +# RVCRUNM.S.A0000=1 +# RVCRUNM.S.A0001=1 +# RVCRUNM.S.C00.Rsp=1 +# RVCRUNM.S.C01.Tx=1 +# RVCRUNM.S.M.CAN_TEST_MODE_FAILURE=1 +# RVCRUNM.S.M.CAN_MANUALLY_CONTROLLED=1 + #Refrigerator and Temperature Controlled Cabinet Mode Cluster(TCCM) @@ -2939,3 +2974,15 @@ DEMM.S.C01.Tx=1 #Manual controllable DEMM.S.M.CAN_TEST_MODE_FAILURE=1 DEMM.S.M.CAN_MANUALLY_CONTROLLED=1 + +#Power Topology Cluster +# Server +PWRTL.S=1 +PWRTL.S.A0000=1 +PWRTL.S.A0001=1 + +#Features +PWRTL.S.F00=0 +PWRTL.S.F01=0 +PWRTL.S.F02=1 +PWRTL.S.F03=1 \ No newline at end of file diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index ee6b5436451a6f..26efd799ad7efd 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -191,6 +191,7 @@ "Test_TC_OO_2_4" ], "PowerSource": ["Test_TC_PS_1_1", "Test_TC_PS_2_1"], + "PowerTopology": ["Test_TC_PWRTL_1_1"], "PressureMeasurement": [ "Test_TC_PRS_1_1", "Test_TC_PRS_2_1", diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 774b3d8dce35f3..d199a682492150 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -311,6 +311,7 @@ "AccessControlEnforcement": [], "OvenMode": ["Test_TC_OTCCM_1_1", "Test_TC_OTCCM_1_2"], "EnergyEVSE": ["Test_TC_EEVSE_1_1", "Test_TC_EEVSE_2_1"], + "PowerTopology": ["Test_TC_PWRTL_1_1"], "collection": [ "DeviceDiscovery", "Groups", @@ -338,6 +339,7 @@ "ModeSelect", "OTASoftwareUpdate", "PowerSourceConfiguration", + "PowerTopology", "PressureMeasurement", "SecureChannel", "SoftwareDiagnostics", diff --git a/src/app/util/BUILD.gn b/src/app/util/BUILD.gn index 31d6b9e881956a..821ba51a9badcc 100644 --- a/src/app/util/BUILD.gn +++ b/src/app/util/BUILD.gn @@ -14,3 +14,11 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/common_flags.gni") + +source_set("types") { + sources = [ + "attribute-metadata.h", + "basic-types.h", + "types_stub.h", + ] +} diff --git a/src/app/util/mock/BUILD.gn b/src/app/util/mock/BUILD.gn index 5918318107fd35..be56bc69032844 100644 --- a/src/app/util/mock/BUILD.gn +++ b/src/app/util/mock/BUILD.gn @@ -20,7 +20,10 @@ config("mock_include") { source_set("mock_ember") { sources = [ + "Constants.h", + "Functions.h", "MockNodeConfig.cpp", + "MockNodeConfig.h", "attribute-storage.cpp", ] diff --git a/src/app/util/types_stub.h b/src/app/util/types_stub.h index ac26684f850cd7..dbd1ea184169e1 100644 --- a/src/app/util/types_stub.h +++ b/src/app/util/types_stub.h @@ -166,12 +166,6 @@ typedef struct } EmberEventControl; -/** - * @description Useful macro for avoiding compiler warnings related to unused - * function arguments or unused variables. - */ -#define UNUSED_VAR(x) (void) (x) - /** * @brief Returns the value of the bitmask \c bits within * the register or byte \c reg. diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml index ceff9846978e63..32893bd82a68e9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml @@ -22,6 +22,7 @@ limitations under the License. true This cluster provides an interface to specify preferences for how devices should consume energy. + EnergyBalances diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index b3993634639869..2edfb272ad23e1 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -68,7 +68,6 @@ "MESSAGES_CLUSTER": [], "MODE_SELECT_CLUSTER": [], "NETWORK_COMMISSIONING_CLUSTER": [], - "POWER_TOPOLOGY_CLUSTER": [], "SAMPLE_MEI_CLUSTER": [], "NITROGEN_DIOXIDE_CONCENTRATION_MEASUREMENT_CLUSTER": [], "OCCUPANCY_SENSING_CLUSTER": ["occupancy-sensor-server"], @@ -91,6 +90,7 @@ "POWER_PROFILE_CLUSTER": [], "POWER_SOURCE_CLUSTER": [], "POWER_SOURCE_CONFIGURATION_CLUSTER": [], + "POWER_TOPOLOGY_CLUSTER": [], "PRESSURE_MEASUREMENT_CLUSTER": [], "PROXY_CONFIGURATION_CLUSTER": [], "PROXY_DISCOVERY_CLUSTER": [], @@ -192,7 +192,7 @@ "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER": [ "ethernet-network-diagnostics-server" ], - "ENERGY_PREFERENCE_CLUSTER": [""], + "ENERGY_PREFERENCE_CLUSTER": ["energy-preference-server"], "FAN_CONTROL_CLUSTER": ["fan-control-server"], "FAULT_INJECTION_CLUSTER": ["fault-injection-server"], "FIXED_LABEL_CLUSTER": ["fixed-label-server"], diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 89864630b8e85e..235366f4206e78 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -4978,7 +4978,7 @@ provisional cluster EnergyEvse = 153 { /** This cluster provides an interface to specify preferences for how devices should consume energy. */ provisional cluster EnergyPreference = 155 { - revision 1; // NOTE: Default/not specifically set + revision 1; enum EnergyPriorityEnum : enum8 { kComfort = 0; diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index cc6107cae3a431..01ef820f82c6ed 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -138,7 +138,6 @@ jobject GetNodeStateObj(JNIEnv * env, const char * nodeStateClassSignature, jobj JniReferences::GetInstance().FindMethod(env, wrapperCallback, "getNodeState", nodeStateClassSignature, &getNodeStateMethod); VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogError(Controller, "Could not find getNodeState method")); - DeviceLayer::StackUnlock unlock; jobject ret = env->CallObjectMethod(wrapperCallback, getNodeStateMethod); VerifyOrReturnValue(!env->ExceptionCheck(), nullptr, env->ExceptionDescribe()); @@ -270,6 +269,7 @@ CHIP_ERROR ConvertReportTlvToJson(const uint32_t id, TLV::TLVReader & data, std: void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const app::StatusIB & aStatus) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); @@ -281,9 +281,8 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); jobject nodeState = GetNodeStateObj(env, mNodeStateClassSignature, wrapperCallback); - if (aStatus.IsFailure()) + { - ChipLogError(Controller, "Receive bad status %s", ErrorStr(aStatus.ToChipError())); // Add Attribute Status to wrapperCallback jmethodID addAttributeStatusMethod = nullptr; err = JniReferences::GetInstance().FindMethod(env, nodeState, "addAttributeStatus", "(IJJILjava/lang/Integer;)V", @@ -305,8 +304,10 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId), static_cast(aStatus.mStatus), jClusterState); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); - return; } + + VerifyOrReturn(aStatus.IsSuccess(), ChipLogError(Controller, "Receive bad status %s", ErrorStr(aStatus.ToChipError())); + aPath.LogPath()); VerifyOrReturn(apData != nullptr, ChipLogError(Controller, "Receive empty apData"); aPath.LogPath()); TLV::TLVReader readerForJavaTLV; @@ -407,6 +408,7 @@ void ReportCallback::UpdateClusterDataVersion() void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLVReader * apData, const app::StatusIB * apStatus) { + DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); @@ -415,9 +417,8 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV ChipLogError(Controller, "mReportCallbackRef is not valid in %s", __func__)); jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); jobject nodeState = GetNodeStateObj(env, mNodeStateClassSignature, wrapperCallback); - if (apStatus != nullptr && apStatus->IsFailure()) + if (apStatus != nullptr) { - ChipLogError(Controller, "Receive bad status %s", ErrorStr(apStatus->ToChipError())); // Add Event Status to NodeState jmethodID addEventStatusMethod; err = JniReferences::GetInstance().FindMethod(env, nodeState, "addEventStatus", "(IJJILjava/lang/Integer;)V", @@ -642,7 +643,6 @@ void ReportCallback::ReportError(const app::ConcreteAttributePath * attributePat eventClusterId = static_cast(eventPath->mClusterId); eventId = static_cast(eventPath->mEventId); } - env->CallVoidMethod(wrapperCallback, onErrorMethod, isAttributePath, attributeEndpointId, attributeClusterId, attributeId, isEventPath, eventEndpointId, eventClusterId, eventId, exception); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); @@ -669,23 +669,27 @@ void WriteAttributesCallback::OnResponse(const app::WriteClient * apWriteClient, JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); JniLocalReferenceScope scope(env); - - if (aStatus.mStatus != Protocols::InteractionModel::Status::Success) - { - ReportError(&aPath, aStatus.mStatus); - return; - } - jmethodID onResponseMethod; VerifyOrReturn(mWrapperCallbackRef.HasValidObjectRef(), ChipLogError(Controller, "mWrapperCallbackRef is not valid in %s", __func__)); jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); - err = JniReferences::GetInstance().FindMethod(env, wrapperCallback, "onResponse", "(IJJ)V", &onResponseMethod); + err = JniReferences::GetInstance().FindMethod(env, wrapperCallback, "onResponse", "(IJJILjava/lang/Integer;)V", + &onResponseMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to find onError method: %s", ErrorStr(err))); + jobject jClusterState = nullptr; + if (aStatus.mClusterStatus.HasValue()) + { + err = JniReferences::GetInstance().CreateBoxedObject( + "java/lang/Integer", "(I)V", static_cast(aStatus.mClusterStatus.Value()), jClusterState); + VerifyOrReturn(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Could not CreateBoxedObject with error %" CHIP_ERROR_FORMAT, err.Format())); + } + DeviceLayer::StackUnlock unlock; env->CallVoidMethod(wrapperCallback, onResponseMethod, static_cast(aPath.mEndpointId), - static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId), aStatus.mStatus, + jClusterState); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index b2ec93cb67f160..31dbaafc9fb21f 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -67,7 +67,7 @@ shared_library("jni") { "DeviceAttestationDelegateBridge.h", "GroupDeviceProxy.h", "MatterCallbacks-JNI.cpp", - "MatterController-JNI.cpp", + "MatterInteractionClient-JNI.cpp", ] deps = [ @@ -391,6 +391,7 @@ kotlin_library("kotlin_matter_controller") { "src/matter/controller/WriteAttributesCallbackJni.kt", "src/matter/controller/model/Paths.kt", "src/matter/controller/model/States.kt", + "src/matter/controller/model/Status.kt", ] sources += matter_structs_sources @@ -441,8 +442,6 @@ android_library("java") { deps = [ ":chipcluster", ":chipclusterID", - ":jsontlv", - ":tlv", "${chip_root}/third_party/java_deps:annotation", ] @@ -477,6 +476,7 @@ android_library("java") { "src/chip/devicecontroller/ReportCallback.java", "src/chip/devicecontroller/ReportCallbackJni.java", "src/chip/devicecontroller/ResubscriptionAttemptCallback.java", + "src/chip/devicecontroller/StatusException.java", "src/chip/devicecontroller/SubscriptionEstablishedCallback.java", "src/chip/devicecontroller/ThreadScanResult.java", "src/chip/devicecontroller/UnpairDeviceCallback.java", diff --git a/src/controller/java/MatterController-JNI.cpp b/src/controller/java/MatterInteractionClient-JNI.cpp similarity index 100% rename from src/controller/java/MatterController-JNI.cpp rename to src/controller/java/MatterInteractionClient-JNI.cpp diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 6e479c5f37094c..fcc9154511d2b7 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -25,6 +25,7 @@ import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -241,8 +242,15 @@ static class WriteAttributesCallbackImpl implements WriteAttributesCallback { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/src/controller/java/src/chip/devicecontroller/StatusException.java b/src/controller/java/src/chip/devicecontroller/StatusException.java new file mode 100644 index 00000000000000..6a97e5b0e19aeb --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/StatusException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +import chip.devicecontroller.model.Status; + +/** Exception class holding error codes defined by Interaction Model */ +public class StatusException extends Exception { + private static final long serialVersionUID = 1L; + + public Status.Code code = Status.Code.Success; + + public StatusException() {} + + public StatusException(Status.Code code) { + super(String.format("CHIP IM status error: %s", code.name())); + this.code = code; + } +} diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java index 4e469ab0e58245..477f133c81a9c4 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java @@ -18,6 +18,7 @@ package chip.devicecontroller; import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; /** An interface for receiving write response. */ @@ -40,8 +41,9 @@ public interface WriteAttributesCallback { * path. * * @param attributePath The attribute path field in write response. + * @param status The status field in write response. */ - void onResponse(ChipAttributePath attributePath); + void onResponse(ChipAttributePath attributePath, Status status); default void onDone() {} } diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java index fd7f8066c80a73..7b95b30759222f 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java @@ -18,6 +18,8 @@ package chip.devicecontroller; import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.Status; +import javax.annotation.Nullable; /** JNI wrapper callback class for {@link WriteAttributesCallback}. */ public final class WriteAttributesCallbackJni { @@ -45,9 +47,15 @@ private void onError( e); } - private void onResponse(int endpointId, long clusterId, long attributeId) { + private void onResponse( + int endpointId, + long clusterId, + long attributeId, + int status, + @Nullable Integer clusterStatus) { wrappedWriteAttributesCallback.onResponse( - ChipAttributePath.newInstance(endpointId, clusterId, attributeId)); + ChipAttributePath.newInstance(endpointId, clusterId, attributeId), + Status.newInstance(status, clusterStatus)); } private void onDone() { diff --git a/src/controller/java/src/chip/devicecontroller/model/Status.java b/src/controller/java/src/chip/devicecontroller/model/Status.java index c367535f5e8578..d859fae9f189e0 100644 --- a/src/controller/java/src/chip/devicecontroller/model/Status.java +++ b/src/controller/java/src/chip/devicecontroller/model/Status.java @@ -21,17 +21,87 @@ import java.util.Locale; import java.util.Optional; +/** Class for Interaction Model Status * */ public final class Status { - private Integer status; + public enum Code { + Success(0x0), + Failure(0x01), + InvalidSusbscription(0x7d), + UnsupportedAccess(0x7e), + UnsupportedEndPoint(0x7f), + InvalidAction(0x80), + UnsupportedCommand(0x81), + Deprecated82(0x82), + Deprecated83(0x83), + Deprecated84(0x84), + InvalidCommand(0x85), + UnsupportedAttribute(0x86), + ConstraintError(0x87), + UnsupportedWrite(0x88), + ResourceExhausted(0x89), + Deprecated8a(0x8a), + NotFound(0x8b), + UnreportableAttribute(0x8c), + InvalidDataType(0x8d), + Deprecated8e(0x8e), + UnsupportedRead(0x8f), + Deprecated90(0x90), + Deprecated91(0x91), + DataVersionMismatch(0x92), + Deprecated93(0x93), + Timeout(0x94), + Reserved95(0x95), + Reserved96(0x96), + Reserved97(0x97), + Reserved98(0x98), + Reserved99(0x99), + Reserved9a(0x9a), + Busy(0x9c), + Deprecatedc0(0xc0), + Deprecatedc1(0xc1), + Deprecatedc2(0xc2), + UnsupportedCluster(0xc3), + Deprecatedc4(0xc4), + NoUpstreamSubsricption(0xc5), + NeedTimedInteraction(0xc6), + UnsupportedEvent(0xc7), + PathExhausted(0xc8), + TimedRequestMismatch(0xc9), + FailsafeRequired(0xca), + InvalidInState(0xcb), + NoCommandResponse(0xcc), + WriteIgnored(0xf0); + + private int id = 0; + + Code(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static Code fromId(int id) { + for (Code type : values()) { + if (type.getId() == id) { + return type; + } + } + return null; + } + } + + private Code status = Code.Success; private Optional clusterStatus; private Status(int status, Optional clusterStatus) { - this.status = status; + this.status = Code.fromId(status); this.clusterStatus = clusterStatus; } // Getters - public Integer getStatus() { + public Code getStatus() { return status; } @@ -43,7 +113,7 @@ public String toString() { return String.format( Locale.ENGLISH, "status %s, clusterStatus %s", - String.valueOf(status), + status.name(), clusterStatus.isPresent() ? String.valueOf(clusterStatus.get()) : "None"); } @@ -51,7 +121,7 @@ public static Status newInstance(int status) { return new Status(status, Optional.empty()); } - static Status newInstance(int status, Integer clusterStatus) { + public static Status newInstance(int status, Integer clusterStatus) { return new Status(status, Optional.ofNullable(clusterStatus)); } } diff --git a/src/controller/java/src/matter/controller/MatterControllerImpl.kt b/src/controller/java/src/matter/controller/MatterControllerImpl.kt index 202d97a99e1ad0..6ae71f33a0faac 100644 --- a/src/controller/java/src/matter/controller/MatterControllerImpl.kt +++ b/src/controller/java/src/matter/controller/MatterControllerImpl.kt @@ -36,6 +36,7 @@ import matter.controller.model.AttributePath import matter.controller.model.EventPath import matter.controller.model.EventState import matter.controller.model.NodeState +import matter.controller.model.Status /** Controller to interact with the CHIP device. */ class MatterControllerImpl(params: ControllerParams) : MatterController { @@ -340,8 +341,11 @@ class MatterControllerImpl(params: ControllerParams) : MatterController { return suspendCancellableCoroutine { continuation -> val writeCallback = object : WriteAttributesCallback { - override fun onResponse(attributePath: AttributePath) { - logger.log(Level.INFO, "write success for attributePath:%s", attributePath.toString()) + override fun onResponse(attributePath: AttributePath, status: Status) { + logger.log( + Level.INFO, + "Receive write response for attributePath: ${attributePath} and status ${status}" + ) } override fun onError(attributePath: AttributePath?, ex: Exception) { diff --git a/src/controller/java/src/matter/controller/WriteAttributesCallback.kt b/src/controller/java/src/matter/controller/WriteAttributesCallback.kt index b4a3f112a02f83..6b1b3f7056f71e 100644 --- a/src/controller/java/src/matter/controller/WriteAttributesCallback.kt +++ b/src/controller/java/src/matter/controller/WriteAttributesCallback.kt @@ -18,6 +18,7 @@ package matter.controller import matter.controller.model.AttributePath +import matter.controller.model.Status /** An interface for receiving write response. */ interface WriteAttributesCallback { @@ -38,8 +39,9 @@ interface WriteAttributesCallback { * path. * * @param attributePath The attribute path field in write response. + * @param status The attribute status field in write response. */ - fun onResponse(attributePath: AttributePath) + fun onResponse(attributePath: AttributePath, status: Status) fun onDone() {} } diff --git a/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt b/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt index bd0bad3e228dda..fe52a329ff3078 100644 --- a/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt +++ b/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt @@ -18,6 +18,7 @@ package matter.controller import matter.controller.model.AttributePath +import matter.controller.model.Status /** JNI wrapper callback class for [WriteAttributesCallback]. */ class WriteAttributesCallbackJni( @@ -53,9 +54,16 @@ class WriteAttributesCallbackJni( ) } - private fun onResponse(endpointId: Int, clusterId: Long, attributeId: Long) { + private fun onResponse( + endpointId: Int, + clusterId: Long, + attributeId: Long, + status: Int, + clusterStatus: Int? + ) { wrappedWriteAttributesCallback.onResponse( - AttributePath(endpointId.toUShort(), clusterId.toUInt(), attributeId.toUInt()) + AttributePath(endpointId.toUShort(), clusterId.toUInt(), attributeId.toUInt()), + Status(status, clusterStatus) ) } diff --git a/src/controller/java/src/matter/controller/model/States.kt b/src/controller/java/src/matter/controller/model/States.kt index c913b37b9986f4..e7799f1f5a64e1 100644 --- a/src/controller/java/src/matter/controller/model/States.kt +++ b/src/controller/java/src/matter/controller/model/States.kt @@ -273,5 +273,3 @@ data class EventState( return null } } - -data class Status(val status: Int, val clusterStatus: Int?) diff --git a/src/controller/java/src/matter/controller/model/Status.kt b/src/controller/java/src/matter/controller/model/Status.kt new file mode 100644 index 00000000000000..fa12f0b1cb25a5 --- /dev/null +++ b/src/controller/java/src/matter/controller/model/Status.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package matter.controller.model + +/** + * Represents information about a node, including data on all available endpoints. + * + * @param endpoints A mapping of endpoint IDs with the associated cluster data. + */ +data class Status(val status: Int, val clusterStatus: Int?) { + enum class Code(val id: Int) { + SUCCESS(0X0), + FAILURE(0X01), + INVALID_SUSBSCRIPTION(0X7D), + UNSUPPORTED_ACCESS(0X7E), + UNSUPPORTED_ENDPOINT(0X7F), + INVALID_ACTION(0X80), + UNSUPPORTED_COMMAND(0X81), + DEPRECATED82(0X82), + DEPRECATED83(0X83), + DEPRECATED84(0X84), + INVALID_COMMAND(0X85), + UNSUPPORTED_ATTRIBUTE(0X86), + CONSTRAINT_ERROR(0X87), + UNSUPPORTED_WRITE(0X88), + RESOURCE_EXHAUSTED(0X89), + DEPRECATED8A(0X8A), + NOT_FOUND(0X8B), + UNREPORTABLE_ATTRIBUTE(0X8C), + INVALID_DATATYPE(0X8D), + DEPRECATED8E(0X8E), + UNSUPPORTED_READ(0X8F), + DEPRECATED90(0X90), + DEPRECATED91(0X91), + DATA_VERSION_MISMATCH(0X92), + DEPRECATED93(0X93), + TIMEOUT(0X94), + RESERVED95(0X95), + RESERVED96(0X96), + RESERVED97(0X97), + RESERVED98(0X98), + RESERVED99(0X99), + RESERVED9A(0X9A), + BUSY(0X9C), + DEPRECATEDC0(0XC0), + DEPRECATEDC1(0XC1), + DEPRECATEDC2(0XC2), + UNSUPPORTED_CLUSTER(0XC3), + DEPRECATEDC4(0XC4), + NO_UPSTREAM_SUBSRICPTION(0XC5), + NEEDS_TIMED_INTERACTION(0XC6), + UNSUPPORTED_EVENT(0XC7), + PATH_EXHAUSTED(0XC8), + TIMED_REQUEST_MISMATCH(0XC9), + FAILSAFE_REQUIRED(0XCA), + INVALID_IN_STATE(0XCB), + NO_COMMAND_RESPONSE(0XCC), + WRITE_IGNORED(0XF0) + } + + fun getCode(): Code? { + for (code in Code.values()) { + if (code.id == status) { + return code + } + } + return null + } + + override fun toString(): String = "$status/$clusterStatus/" +} diff --git a/src/controller/python/chip/interaction_model/__init__.py b/src/controller/python/chip/interaction_model/__init__.py index 61faa7f7d5d741..ec100846b085a5 100644 --- a/src/controller/python/chip/interaction_model/__init__.py +++ b/src/controller/python/chip/interaction_model/__init__.py @@ -86,6 +86,7 @@ class Status(enum.IntEnum): FailsafeRequired = 0xca InvalidInState = 0xcb NoCommandResponse = 0xcc + WriteIgnored = 0xf0 class InteractionModelError(ChipStackException): diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 917c3a1251e344..fc2cfaf516524b 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -475,7 +475,7 @@ void TestReadInteraction::TestReadSubscribeAttributeResponseWithCache(nlTestSuit // app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&gTestReadInteraction); - int testId = 0; + [[maybe_unused]] int testId = 0; // Read of E2C3A1(dedup), E*C3A1(E1C3A1 not exit, E2C3A1 exist), E2C3A* (5 supported attributes) // Expect no versions would be cached. diff --git a/src/crypto/tests/TestChipCryptoPAL.cpp b/src/crypto/tests/TestChipCryptoPAL.cpp index b2e12568b7c222..db5ee6b74480cd 100644 --- a/src/crypto/tests/TestChipCryptoPAL.cpp +++ b/src/crypto/tests/TestChipCryptoPAL.cpp @@ -2715,7 +2715,7 @@ static void TestVIDPID_StringExtraction(nlTestSuite * inSuite, void * inContext) }; // clang-format on - int caseIdx = 0; + [[maybe_unused]] int caseIdx = 0; for (const auto & testCase : kTestCases) { AttestationCertVidPid vidpid; diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 00f65b25dc000b..2a981cdd860fff 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1976,7 +1976,6 @@ - (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))compl MTR_LOG_DEBUG("Causing failure in subscribers on purpose"); CauseReadClientFailure(self.deviceController, self.nodeID, queue, completion); } -#endif // The following method is for unit testing purpose only + (id)CHIPEncodeAndDecodeNSObject:(id)object @@ -2018,6 +2017,7 @@ + (id)CHIPEncodeAndDecodeNSObject:(id)object } return decodedData.GetDecodedObject(); } +#endif - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID diff --git a/src/darwin/Framework/CHIP/MTRConversion.h b/src/darwin/Framework/CHIP/MTRConversion.h index 543d80968566c6..b14f4c240f9f67 100644 --- a/src/darwin/Framework/CHIP/MTRConversion.h +++ b/src/darwin/Framework/CHIP/MTRConversion.h @@ -46,6 +46,18 @@ inline NSDate * MatterEpochSecondsAsDate(uint32_t matterEpochSeconds) */ bool DateToMatterEpochSeconds(NSDate * date, uint32_t & epoch); +/** + * Returns whether the conversion could be performed. Will return false if the + * passed-in date is our of the range representable as a Matter epoch-s value. + */ +bool DateToMatterEpochMilliseconds(NSDate * date, uint64_t & matterEpochMilliseconds); + +/** + * Returns whether the conversion could be performed. Will return false if the + * passed-in date is our of the range representable as a Matter epoch-s value. + */ +bool DateToMatterEpochMicroseconds(NSDate * date, uint64_t & matterEpochMicroseconds); + /** * Utilities for converting between NSSet and chip::CATValues. */ diff --git a/src/darwin/Framework/CHIP/MTRConversion.mm b/src/darwin/Framework/CHIP/MTRConversion.mm index c6ba6ec52fbf32..5e657b9330a8e5 100644 --- a/src/darwin/Framework/CHIP/MTRConversion.mm +++ b/src/darwin/Framework/CHIP/MTRConversion.mm @@ -63,18 +63,41 @@ CHIP_ERROR SetToCATValues(NSSet * catSet, chip::CATValues & values) bool DateToMatterEpochSeconds(NSDate * date, uint32_t & matterEpochSeconds) { - auto timeSinceUnixEpoch = date.timeIntervalSince1970; - if (timeSinceUnixEpoch < static_cast(chip::kChipEpochSecondsSinceUnixEpoch)) { - // This is a pre-Matter-epoch time, and cannot be represented in epoch-s. + uint64_t matterEpochMicroseconds = 0; + if (!DateToMatterEpochMicroseconds(date, matterEpochMicroseconds)) { + // Could not convert time return false; } - auto timeSinceMatterEpoch = timeSinceUnixEpoch - chip::kChipEpochSecondsSinceUnixEpoch; + uint64_t timeSinceMatterEpoch = matterEpochMicroseconds / chip::kMicrosecondsPerSecond; if (timeSinceMatterEpoch > UINT32_MAX) { // Too far into the future. return false; } - matterEpochSeconds = static_cast(timeSinceMatterEpoch); return true; } + +bool DateToMatterEpochMilliseconds(NSDate * date, uint64_t & matterEpochMilliseconds) +{ + uint64_t matterEpochMicroseconds = 0; + if (!DateToMatterEpochMicroseconds(date, matterEpochMicroseconds)) { + // Could not convert time + return false; + } + + matterEpochMilliseconds = matterEpochMicroseconds / chip::kMicrosecondsPerMillisecond; + return true; +} + +bool DateToMatterEpochMicroseconds(NSDate * date, uint64_t & matterEpochMicroseconds) +{ + uint64_t timeSinceUnixEpoch = static_cast(date.timeIntervalSince1970 * chip::kMicrosecondsPerSecond); + if (timeSinceUnixEpoch < chip::kChipEpochUsSinceUnixEpoch) { + // This is a pre-Matter-epoch time, and cannot be represented as an epoch time value. + return false; + } + + matterEpochMicroseconds = timeSinceUnixEpoch - chip::kChipEpochUsSinceUnixEpoch; + return true; +} diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 2307a25d22361f..1b42caecf80c76 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -20,11 +20,13 @@ #import "MTRAsyncWorkQueue.h" #import "MTRAttributeSpecifiedCheck.h" +#import "MTRBaseClusters.h" #import "MTRBaseDevice_Internal.h" #import "MTRBaseSubscriptionCallback.h" #import "MTRCluster.h" #import "MTRClusterConstants.h" #import "MTRCommandTimedCheck.h" +#import "MTRConversion.h" #import "MTRDefines_Internal.h" #import "MTRDeviceController_Internal.h" #import "MTRDevice_Internal.h" @@ -143,6 +145,9 @@ typedef NS_ENUM(NSUInteger, MTRDeviceWorkItemDuplicateTypeID) { @interface MTRDevice () @property (nonatomic, readonly) os_unfair_lock lock; // protects the caches and device state +// protects against concurrent time updates by guarding timeUpdateScheduled flag which manages time updates scheduling, +// and protects device calls to setUTCTime and setDSTOffset +@property (nonatomic, readonly) os_unfair_lock timeSyncLock; @property (nonatomic) chip::FabricIndex fabricIndex; @property (nonatomic) MTRWeakReference> * weakDelegate; @property (nonatomic) dispatch_queue_t delegateQueue; @@ -190,6 +195,8 @@ @interface MTRDevice () @property (nonatomic) BOOL expirationCheckScheduled; +@property (nonatomic) BOOL timeUpdateScheduled; + @property (nonatomic) NSDate * estimatedStartTimeFromGeneralDiagnosticsUpTime; @property (nonatomic) NSMutableDictionary * temporaryMetaDataCache; @@ -224,6 +231,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle { if (self = [super init]) { _lock = OS_UNFAIR_LOCK_INIT; + _timeSyncLock = OS_UNFAIR_LOCK_INIT; _nodeID = [nodeID copy]; _fabricIndex = controller.fabricIndex; _deviceController = controller; @@ -249,6 +257,226 @@ + (MTRDevice *)deviceWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControll return [controller deviceForNodeID:nodeID]; } +#pragma mark - Time Synchronization + +- (void)_setTimeOnDevice +{ + NSDate * now = [NSDate date]; + // If no date available, error + if (!now) { + MTR_LOG_ERROR("%@ Could not retrieve current date. Unable to setUTCTime on endpoints.", self); + return; + } + + NSTimeZone * localTimeZone = [NSTimeZone localTimeZone]; + BOOL setDST = TRUE; + if (!localTimeZone) { + MTR_LOG_ERROR("%@ Could not retrieve local time zone. Unable to setDSTOffset on endpoints.", self); + setDST = FALSE; + } + + uint64_t matterEpochTimeMicroseconds = 0; + uint64_t nextDSTInMatterEpochTimeMicroseconds = 0; + if (!DateToMatterEpochMicroseconds(now, matterEpochTimeMicroseconds)) { + MTR_LOG_ERROR("%@ Could not convert NSDate (%@) to Matter Epoch Time. Unable to setUTCTime on endpoints.", self, now); + return; + } + + int32_t dstOffset = 0; + if (setDST) { + NSTimeInterval dstOffsetAsInterval = [localTimeZone daylightSavingTimeOffsetForDate:now]; + dstOffset = int32_t(dstOffsetAsInterval); + + // Calculate time to next DST. This is needed when we set the current DST. + NSDate * nextDSTTransitionDate = [localTimeZone nextDaylightSavingTimeTransition]; + if (!DateToMatterEpochMicroseconds(nextDSTTransitionDate, nextDSTInMatterEpochTimeMicroseconds)) { + MTR_LOG_ERROR("%@ Could not convert NSDate (%@) to Matter Epoch Time. Unable to setDSTOffset on endpoints.", self, nextDSTTransitionDate); + setDST = FALSE; + } + } + + // Set Time on each Endpoint with a Time Synchronization Cluster Server + NSArray * endpointsToSync = [self _endpointsWithTimeSyncClusterServer]; + for (NSNumber * endpoint in endpointsToSync) { + MTR_LOG_DEBUG("%@ Setting Time on Endpoint %@", self, endpoint); + [self _setUTCTime:matterEpochTimeMicroseconds withGranularity:MTRTimeSynchronizationGranularityMicrosecondsGranularity forEndpoint:endpoint]; + if (setDST) { + [self _setDSTOffset:dstOffset validStarting:0 validUntil:nextDSTInMatterEpochTimeMicroseconds forEndpoint:endpoint]; + } + } +} + +- (void)_scheduleNextUpdate:(UInt64)nextUpdateInSeconds +{ + MTRWeakReference * weakSelf = [MTRWeakReference weakReferenceWithObject:self]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (nextUpdateInSeconds * NSEC_PER_SEC)), self.queue, ^{ + MTR_LOG_DEBUG("%@ Timer expired, start Device Time Update", self); + MTRDevice * strongSelf = weakSelf.strongObject; + if (strongSelf) { + [strongSelf _performScheduledTimeUpdate]; + } else { + MTR_LOG_DEBUG("%@ MTRDevice no longer valid. No Timer Scheduled will be scheduled for a Device Time Update.", self); + return; + } + }); + self.timeUpdateScheduled = YES; + MTR_LOG_DEBUG("%@ Timer Scheduled for next Device Time Update, in %llu seconds", self, nextUpdateInSeconds); +} + +// Time Updates are a day apart (this can be changed in the future) +#define MTR_DEVICE_TIME_UPDATE_DEFAULT_WAIT_TIME_SEC (24 * 60 * 60) +// assume lock is held +- (void)_updateDeviceTimeAndScheduleNextUpdate +{ + os_unfair_lock_assert_owner(&self->_timeSyncLock); + if (self.timeUpdateScheduled) { + MTR_LOG_DEBUG("%@ Device Time Update already scheduled", self); + return; + } + + [self _setTimeOnDevice]; + [self _scheduleNextUpdate:MTR_DEVICE_TIME_UPDATE_DEFAULT_WAIT_TIME_SEC]; +} + +- (void)_performScheduledTimeUpdate +{ + os_unfair_lock_lock(&self->_timeSyncLock); + // Device needs to still be reachable + if (self.state != MTRDeviceStateReachable) { + MTR_LOG_DEBUG("%@ Device is not reachable, canceling Device Time Updates.", self); + os_unfair_lock_unlock(&self->_timeSyncLock); + return; + } + // Device must not be invalidated + if (!self.timeUpdateScheduled) { + MTR_LOG_DEBUG("%@ Device Time Update is no longer scheduled, MTRDevice may have been invalidated.", self); + os_unfair_lock_unlock(&self->_timeSyncLock); + return; + } + self.timeUpdateScheduled = NO; + [self _updateDeviceTimeAndScheduleNextUpdate]; + os_unfair_lock_unlock(&self->_timeSyncLock); +} + +- (NSArray *)_endpointsWithTimeSyncClusterServer +{ + auto partsList = [self readAttributeWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID) params:nil]; + NSMutableArray * endpointsOnDevice = [self arrayOfNumbersFromAttributeValue:partsList]; + if (!endpointsOnDevice) { + endpointsOnDevice = [[NSMutableArray alloc] init]; + } + // Add Root node! + [endpointsOnDevice addObject:@(0)]; + + NSMutableArray * endpointsWithTimeSyncCluster = [[NSMutableArray alloc] init]; + for (NSNumber * endpoint in endpointsOnDevice) { + // Get list of server clusters on endpoint + auto clusterList = [self readAttributeWithEndpointID:endpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID) params:nil]; + NSArray * clusterArray = [self arrayOfNumbersFromAttributeValue:clusterList]; + + if (clusterArray && [clusterArray containsObject:@(MTRClusterIDTypeTimeSynchronizationID)]) { + [endpointsWithTimeSyncCluster addObject:endpoint]; + } + } + MTR_LOG_DEBUG("%@ Device has following endpoints with Time Sync Cluster Server: %@", self, endpointsWithTimeSyncCluster); + return endpointsWithTimeSyncCluster; +} + +- (void)_setUTCTime:(UInt64)matterEpochTime withGranularity:(uint8_t)granularity forEndpoint:(NSNumber *)endpoint +{ + MTR_LOG_DEBUG(" %@ _setUTCTime with matterEpochTime: %llu, endpoint %@", self, matterEpochTime, endpoint); + MTRTimeSynchronizationClusterSetUTCTimeParams * params = [[MTRTimeSynchronizationClusterSetUTCTimeParams + alloc] init]; + params.utcTime = @(matterEpochTime); + params.granularity = @(granularity); + auto setUTCTimeResponseHandler = ^(id _Nullable response, NSError * _Nullable error) { + if (error) { + MTR_LOG_ERROR("%@ _setUTCTime failed on endpoint %@, with parameters %@, error: %@", self, endpoint, params, error); + } + }; + + [self _invokeKnownCommandWithEndpointID:endpoint + clusterID:@(MTRClusterIDTypeTimeSynchronizationID) + commandID:@(MTRCommandIDTypeClusterTimeSynchronizationCommandSetUTCTimeID) + commandPayload:params + expectedValues:nil + expectedValueInterval:nil + timedInvokeTimeout:nil + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.queue + completion:setUTCTimeResponseHandler]; +} + +- (void)_setDSTOffset:(int32_t)dstOffset validStarting:(uint64_t)validStarting validUntil:(uint64_t)validUntil forEndpoint:(NSNumber *)endpoint +{ + MTR_LOG_DEBUG("%@ _setDSTOffset with offset: %d, validStarting: %llu, validUntil: %llu, endpoint %@", + self, + dstOffset, validStarting, validUntil, endpoint); + + MTRTimeSynchronizationClusterSetDSTOffsetParams * params = [[MTRTimeSynchronizationClusterSetDSTOffsetParams + alloc] init]; + MTRTimeSynchronizationClusterDSTOffsetStruct * dstOffsetStruct = [[MTRTimeSynchronizationClusterDSTOffsetStruct alloc] init]; + dstOffsetStruct.offset = @(dstOffset); + dstOffsetStruct.validStarting = @(validStarting); + dstOffsetStruct.validUntil = @(validUntil); + params.dstOffset = @[ dstOffsetStruct ]; + + auto setDSTOffsetResponseHandler = ^(id _Nullable response, NSError * _Nullable error) { + if (error) { + MTR_LOG_ERROR("%@ _setDSTOffset failed on endpoint %@, with parameters %@, error: %@", self, endpoint, params, error); + } + }; + + [self _invokeKnownCommandWithEndpointID:endpoint + clusterID:@(MTRClusterIDTypeTimeSynchronizationID) + commandID:@(MTRCommandIDTypeClusterTimeSynchronizationCommandSetDSTOffsetID) + commandPayload:params + expectedValues:nil + expectedValueInterval:nil + timedInvokeTimeout:nil + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.queue + completion:setDSTOffsetResponseHandler]; +} + +- (NSMutableArray *)arrayOfNumbersFromAttributeValue:(NSDictionary *)dataDictionary +{ + if (![MTRArrayValueType isEqual:dataDictionary[MTRTypeKey]]) { + return nil; + } + + id value = dataDictionary[MTRValueKey]; + if (![value isKindOfClass:NSArray.class]) { + return nil; + } + + NSArray * valueArray = value; + __auto_type outputArray = [NSMutableArray arrayWithCapacity:valueArray.count]; + + for (id item in valueArray) { + if (![item isKindOfClass:NSDictionary.class]) { + return nil; + } + + NSDictionary * itemDictionary = item; + id data = itemDictionary[MTRDataKey]; + if (![data isKindOfClass:NSDictionary.class]) { + return nil; + } + + NSDictionary * dataDictionary = data; + id dataType = dataDictionary[MTRTypeKey]; + id dataValue = dataDictionary[MTRValueKey]; + if (![dataType isKindOfClass:NSString.class] || ![dataValue isKindOfClass:NSNumber.class]) { + return nil; + } + [outputArray addObject:dataValue]; + } + return outputArray; +} + #pragma mark Subscription and delegate handling // subscription intervals are in seconds @@ -287,6 +515,10 @@ - (void)invalidate [_asyncWorkQueue invalidate]; + os_unfair_lock_lock(&self->_timeSyncLock); + _timeUpdateScheduled = NO; + os_unfair_lock_unlock(&self->_timeSyncLock); + os_unfair_lock_lock(&self->_lock); _state = MTRDeviceStateUnknown; @@ -370,6 +602,8 @@ - (void)_changeState:(MTRDeviceState)state } } +// First Time Sync happens 2 minutes after reachability (this can be changed in the future) +#define MTR_DEVICE_TIME_UPDATE_INITIAL_WAIT_TIME_SEC (60 * 2) - (void)_handleSubscriptionEstablished { os_unfair_lock_lock(&self->_lock); @@ -380,6 +614,14 @@ - (void)_handleSubscriptionEstablished [self _changeState:MTRDeviceStateReachable]; os_unfair_lock_unlock(&self->_lock); + + os_unfair_lock_lock(&self->_timeSyncLock); + + if (!self.timeUpdateScheduled) { + [self _scheduleNextUpdate:MTR_DEVICE_TIME_UPDATE_INITIAL_WAIT_TIME_SEC]; + } + + os_unfair_lock_unlock(&self->_timeSyncLock); } - (void)_handleSubscriptionError:(NSError *)error @@ -893,7 +1135,7 @@ - (void)_setupSubscription return; } - MTR_LOG_DEFAULT("%@ Subscribe with data version list size %lu, reduced by %lu", self, dataVersions.count, dataVersionFilterListSizeReduction); + MTR_LOG_DEFAULT("%@ Subscribe with data version list size %lu, reduced by %lu", self, (unsigned long) dataVersions.count, (unsigned long) dataVersionFilterListSizeReduction); // Callback and ClusterStateCache and ReadClient will be deleted // when OnDone is called. diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 64d70ce647cdb7..edd521845b2415 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -32,6 +32,7 @@ #import "MTRConversion.h" #import "MTRDeviceControllerDelegateBridge.h" #import "MTRDeviceControllerFactory_Internal.h" +#import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceControllerStartupParams.h" #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDevice_Internal.h" @@ -173,12 +174,31 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory return nil; } + id storageDelegateToUse = storageDelegate; +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + if (MTRDeviceControllerLocalTestStorage.localTestStorageEnabled) { + storageDelegateToUse = [[MTRDeviceControllerLocalTestStorage alloc] initWithPassThroughStorage:storageDelegate]; + } +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED _controllerDataStore = [[MTRDeviceControllerDataStore alloc] initWithController:self - storageDelegate:storageDelegate + storageDelegate:storageDelegateToUse storageDelegateQueue:storageDelegateQueue]; if (_controllerDataStore == nil) { return nil; } + } else { +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + if (MTRDeviceControllerLocalTestStorage.localTestStorageEnabled) { + dispatch_queue_t localTestStorageQueue = dispatch_queue_create("org.csa-iot.matter.framework.devicecontroller.localteststorage", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + MTRDeviceControllerLocalTestStorage * localTestStorage = [[MTRDeviceControllerLocalTestStorage alloc] initWithPassThroughStorage:nil]; + _controllerDataStore = [[MTRDeviceControllerDataStore alloc] initWithController:self + storageDelegate:localTestStorage + storageDelegateQueue:localTestStorageQueue]; + if (_controllerDataStore == nil) { + return nil; + } + } +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED } // Ensure the otaProviderDelegate, if any, is valid. diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h new file mode 100644 index 00000000000000..915834ecabd35c --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h @@ -0,0 +1,37 @@ +// +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + +NS_ASSUME_NONNULL_BEGIN + +MTR_EXTERN @interface MTRDeviceControllerLocalTestStorage : NSObject + +// Setting this variable only affects subsequent MTRDeviceController initializations +@property (class, nonatomic, assign) BOOL localTestStorageEnabled; + +// This storage persists items to NSUserDefaults for MTRStorageSharingTypeNotShared data. Items with other sharing types will be droppped, or stored/fetched with the "passthrough storage" if one is specified. +- (instancetype)initWithPassThroughStorage:(id _Nullable)passThroughStorage; + +@end + +NS_ASSUME_NONNULL_END + +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m new file mode 100644 index 00000000000000..4d52e4bf18afb6 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m @@ -0,0 +1,97 @@ +// +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRDeviceControllerLocalTestStorage.h" + +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + +static NSString * const kLocalTestUserDefaultDomain = @"org.csa-iot.matter.darwintest"; +static NSString * const kLocalTestUserDefaultEnabledKey = @"enableTestStorage"; + +@implementation MTRDeviceControllerLocalTestStorage { + id _passThroughStorage; +} + ++ (BOOL)localTestStorageEnabled +{ + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + return [defaults boolForKey:kLocalTestUserDefaultEnabledKey]; +} + ++ (void)setLocalTestStorageEnabled:(BOOL)localTestStorageEnabled +{ + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + [defaults setBool:localTestStorageEnabled forKey:kLocalTestUserDefaultEnabledKey]; +} + +- (instancetype)initWithPassThroughStorage:(id)passThroughStorage +{ + if (self = [super init]) { + _passThroughStorage = passThroughStorage; + } + return self; +} + +- (nullable id)controller:(MTRDeviceController *)controller + valueForKey:(NSString *)key + securityLevel:(MTRStorageSecurityLevel)securityLevel + sharingType:(MTRStorageSharingType)sharingType +{ + if (sharingType == MTRStorageSharingTypeNotShared) { + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + NSData * storedData = [defaults dataForKey:key]; + NSError * error; + id value = [NSKeyedUnarchiver unarchivedObjectOfClasses:MTRDeviceControllerStorageClasses() fromData:storedData error:&error]; + return value; + } else { + return [_passThroughStorage controller:controller valueForKey:key securityLevel:securityLevel sharingType:sharingType]; + } +} + +- (BOOL)controller:(MTRDeviceController *)controller + storeValue:(id)value + forKey:(NSString *)key + securityLevel:(MTRStorageSecurityLevel)securityLevel + sharingType:(MTRStorageSharingType)sharingType +{ + if (sharingType == MTRStorageSharingTypeNotShared) { + NSError * error; + NSData * data = [NSKeyedArchiver archivedDataWithRootObject:value requiringSecureCoding:YES error:&error]; + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + [defaults setObject:data forKey:key]; + return YES; + } else { + return [_passThroughStorage controller:controller storeValue:value forKey:key securityLevel:securityLevel sharingType:sharingType]; + } +} + +- (BOOL)controller:(MTRDeviceController *)controller + removeValueForKey:(NSString *)key + securityLevel:(MTRStorageSecurityLevel)securityLevel + sharingType:(MTRStorageSharingType)sharingType +{ + if (sharingType == MTRStorageSharingTypeNotShared) { + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + [defaults removeObjectForKey:key]; + return YES; + } else { + return [_passThroughStorage controller:controller removeValueForKey:key securityLevel:securityLevel sharingType:sharingType]; + } +} +@end + +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRAccessGrant.h b/src/darwin/Framework/CHIP/ServerEndpoint/MTRAccessGrant.h index e0b25449755f16..e0dc4bd052f0f4 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRAccessGrant.h +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRAccessGrant.h @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN * An access grant, which can be represented as an entry in the Matter Access * Control cluster. */ +NS_SWIFT_SENDABLE MTR_NEWLY_AVAILABLE @interface MTRAccessGrant : NSObject diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h b/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h index 7f4f88b0cfd643..dc95ddcddaeaeb 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN * A representation of a "device type revision" in the sense used in the Matter * specification. This has an identifier and a version number. */ +NS_SWIFT_SENDABLE MTR_NEWLY_AVAILABLE @interface MTRDeviceTypeRevision : NSObject diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.h b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.h index 46e95bfb39a7bd..f9c7e7ca6dfe4b 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.h +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerAttribute.h @@ -24,7 +24,10 @@ NS_ASSUME_NONNULL_BEGIN * A representation of an attribute implemented on a server cluster by an * MTRDeviceController. An attribute has an identifier and a value, and may or * may not be writable. + * + * MTRServerAttribute's API can be accessed from any thread. */ +NS_SWIFT_SENDABLE MTR_NEWLY_AVAILABLE @interface MTRServerAttribute : NSObject @@ -50,13 +53,13 @@ MTR_NEWLY_AVAILABLE */ - (BOOL)setValue:(NSDictionary *)value; -@property (nonatomic, copy, readonly) NSNumber * attributeID; -@property (nonatomic, copy, readonly) NSDictionary * value; +@property (atomic, copy, readonly) NSNumber * attributeID; +@property (atomic, copy, readonly) NSDictionary * value; /** * The privilege level necessary to read this attribute. */ -@property (nonatomic, assign, readonly) MTRAccessControlEntryPrivilege requiredReadPrivilege; -@property (nonatomic, assign, readonly, getter=isWritable) BOOL writable; +@property (atomic, assign, readonly) MTRAccessControlEntryPrivilege requiredReadPrivilege; +@property (atomic, assign, readonly, getter=isWritable) BOOL writable; @end diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.h b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.h index 48604dd2a76797..591d3afec59779 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.h +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.h @@ -23,7 +23,10 @@ NS_ASSUME_NONNULL_BEGIN /** * A representation of a server cluster implemented by an MTRDeviceController. + * + * MTRServerCluster's API can be accessed from any thread. */ +NS_SWIFT_SENDABLE MTR_NEWLY_AVAILABLE @interface MTRServerCluster : NSObject @@ -89,9 +92,9 @@ MTR_NEWLY_AVAILABLE */ + (MTRServerCluster *)newDescriptorCluster; -@property (nonatomic, copy, readonly) NSNumber * clusterID; +@property (atomic, copy, readonly) NSNumber * clusterID; -@property (nonatomic, copy, readonly) NSNumber * clusterRevision; +@property (atomic, copy, readonly) NSNumber * clusterRevision; /** * The list of entities that are allowed to access this cluster instance. This @@ -99,12 +102,12 @@ MTR_NEWLY_AVAILABLE * * Defaults to empty list, which means no additional access grants. */ -@property (nonatomic, copy, readonly) NSArray * accessGrants; +@property (atomic, copy, readonly) NSArray * accessGrants; /** * The list of attributes supported by the cluster. */ -@property (nonatomic, copy, readonly) NSArray * attributes; +@property (atomic, copy, readonly) NSArray * attributes; @end diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm index c0fba9e9bda64d..7439c0ff6a453a 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster.mm @@ -20,11 +20,12 @@ #import "MTRServerAttribute_Internal.h" #import "MTRServerCluster_Internal.h" #import "MTRServerEndpoint_Internal.h" +#import "MTRUnfairLock.h" +#import "NSDataSpanConversion.h" + #import #import -#import "NSDataSpanConversion.h" - #include #include #include @@ -71,11 +72,26 @@ @implementation MTRServerCluster { std::unique_ptr _attributeAccessInterface; // We can't use something like std::unique_ptr // because EmberAfAttributeMetadata does not have a default constructor, so - // we can't alloc and then initializer later. + // we can't alloc and then initialize later. std::vector _matterAttributeMetadata; std::unique_ptr _matterAcceptedCommandList; std::unique_ptr _matterGeneratedCommandList; + + NSSet * _matterAccessGrants; + + chip::EndpointId _parentEndpoint; + + // _acceptedCommands and _generatedCommands are touched directly by our API + // consumer. + NSArray * _acceptedCommands; + NSArray * _generatedCommands; + + /** + * _lock always protects access to all our mutable ivars (the ones that are + * modified after init). + */ + os_unfair_lock _lock; } - (nullable instancetype)initWithClusterID:(NSNumber *)clusterID revision:(NSNumber *)revision @@ -117,6 +133,7 @@ - (instancetype)initInternalWithClusterID:(NSNumber *)clusterID revision:(NSNumb return nil; } + _lock = OS_UNFAIR_LOCK_INIT; _clusterID = [clusterID copy]; _clusterRevision = [revision copy]; _accessGrants = [[NSMutableSet alloc] init]; @@ -141,6 +158,8 @@ - (instancetype)initInternalWithClusterID:(NSNumber *)clusterID revision:(NSNumb - (void)updateMatterAccessGrants { + os_unfair_lock_assert_owner(&_lock); + MTRDeviceController * deviceController = _deviceController; if (deviceController == nil) { // _matterAccessGrants will be updated when we get bound to a controller. @@ -149,6 +168,7 @@ - (void)updateMatterAccessGrants NSSet * grants = [_accessGrants copy]; [deviceController asyncDispatchToMatterQueue:^{ + std::lock_guard lock(self->_lock); self->_matterAccessGrants = grants; } errorHandler:nil]; @@ -156,6 +176,8 @@ - (void)updateMatterAccessGrants - (void)addAccessGrant:(MTRAccessGrant *)accessGrant { + std::lock_guard lock(self->_lock); + [_accessGrants addObject:accessGrant]; [self updateMatterAccessGrants]; @@ -163,13 +185,24 @@ - (void)addAccessGrant:(MTRAccessGrant *)accessGrant - (void)removeAccessGrant:(MTRAccessGrant *)accessGrant; { + std::lock_guard lock(self->_lock); + [_accessGrants removeObject:accessGrant]; [self updateMatterAccessGrants]; } +- (NSArray *)matterAccessGrants +{ + std::lock_guard lock(self->_lock); + + return [_matterAccessGrants allObjects]; +} + - (BOOL)addAttribute:(MTRServerAttribute *)attribute { + std::lock_guard lock(self->_lock); + MTRDeviceController * deviceController = _deviceController; if (deviceController != nil) { MTR_LOG_ERROR("Cannot add attribute on cluster %llx which is already in use", _clusterID.unsignedLongLongValue); @@ -213,6 +246,8 @@ - (BOOL)addAttribute:(MTRServerAttribute *)attribute - (BOOL)associateWithController:(nullable MTRDeviceController *)controller { + std::lock_guard lock(self->_lock); + MTRDeviceController * existingController = _deviceController; if (existingController != nil) { #if MTR_PER_CONTROLLER_STORAGE_ENABLED @@ -313,7 +348,7 @@ - (BOOL)associateWithController:(nullable MTRDeviceController *)controller _deviceController = controller; - MTR_LOG_DEFAULT("Associated %@, attribute count %llu, with controller", self, + MTR_LOG_DEFAULT("Associated %@, attribute count %llu, with controller", [self _descriptionWhileLocked], static_cast(attributeCount)); return YES; @@ -321,6 +356,8 @@ - (BOOL)associateWithController:(nullable MTRDeviceController *)controller - (void)invalidate { + std::lock_guard lock(_lock); + // Undo any work associateWithController did. for (MTRServerAttribute * attr in _attributes) { [attr invalidate]; @@ -342,6 +379,8 @@ - (void)registerMatterCluster { assertChipStackLockedByCurrentThread(); + std::lock_guard lock(_lock); + if (!registerAttributeAccessOverride(_attributeAccessInterface.get())) { // This should only happen if we somehow managed to register an // AttributeAccessInterface for the same (endpoint, cluster) pair. @@ -354,6 +393,8 @@ - (void)unregisterMatterCluster { assertChipStackLockedByCurrentThread(); + std::lock_guard lock(_lock); + if (_attributeAccessInterface != nullptr) { unregisterAttributeAccessOverride(_attributeAccessInterface.get()); } @@ -361,38 +402,84 @@ - (void)unregisterMatterCluster - (NSArray *)accessGrants { + std::lock_guard lock(_lock); + return [_accessGrants allObjects]; } - (NSArray *)attributes { + std::lock_guard lock(_lock); + return [_attributes copy]; } -- (void)setParentEndpoint:(EndpointId)endpoint +- (BOOL)addToEndpoint:(chip::EndpointId)endpoint { + std::lock_guard lock(_lock); + + if (_parentEndpoint != kInvalidEndpointId) { + MTR_LOG_ERROR("Cannot add cluster " ChipLogFormatMEI " to endpoint %" PRIu32 "; already added to endpoint %" PRIu32, + ChipLogValueMEI(_clusterID.unsignedLongLongValue), endpoint, _parentEndpoint); + return NO; + } + _parentEndpoint = endpoint; // Update it on all the attributes, in case the attributes were added to us // before we were added to the endpoint. for (MTRServerAttribute * attr in _attributes) { [attr updateParentCluster:ConcreteClusterPath(endpoint, static_cast(_clusterID.unsignedLongLongValue))]; } + return YES; +} + +- (chip::EndpointId)parentEndpoint +{ + std::lock_guard lock(_lock); + return _parentEndpoint; } - (Span)matterAttributeMetadata { // This is always called after our _matterAttributeMetadata has been set up // by associateWithController. + std::lock_guard lock(_lock); return Span(_matterAttributeMetadata.data(), _matterAttributeMetadata.size()); } +- (void)setAcceptedCommands:(NSArray *)acceptedCommands +{ + std::lock_guard lock(_lock); + _acceptedCommands = [acceptedCommands copy]; +} + +- (NSArray *)acceptedCommands +{ + std::lock_guard lock(_lock); + return [_acceptedCommands copy]; +} + +- (void)setGeneratedCommands:(NSArray *)generatedCommands +{ + std::lock_guard lock(_lock); + _generatedCommands = [generatedCommands copy]; +} + +- (NSArray *)generatedCommands +{ + std::lock_guard lock(_lock); + return [_generatedCommands copy]; +} + - (CommandId *)matterAcceptedCommands { + std::lock_guard lock(_lock); return _matterAcceptedCommandList.get(); } - (CommandId *)matterGeneratedCommands { + std::lock_guard lock(_lock); return _matterGeneratedCommandList.get(); } @@ -413,6 +500,13 @@ - (CommandId *)matterGeneratedCommands - (NSString *)description { + std::lock_guard lock(_lock); + return [self _descriptionWhileLocked]; +} + +- (NSString *)_descriptionWhileLocked +{ + os_unfair_lock_assert_owner(&_lock); return [NSString stringWithFormat:@"", _parentEndpoint, ChipLogValueMEI(_clusterID.unsignedLongLongValue)]; } diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster_Internal.h b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster_Internal.h index 4ae3d0db348533..253885b7d82e98 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster_Internal.h +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerCluster_Internal.h @@ -57,40 +57,46 @@ NS_ASSUME_NONNULL_BEGIN - (void)invalidate; /** - * The access grants the Matter stack can observe. Only modified while in - * Initializing state or on the Matter queue. + * Add the cluster to an endpoint with the given endpoint ID. Will return NO + * if the cluster is already added to an endpoint. */ -@property (nonatomic, strong, readonly) NSSet * matterAccessGrants; +- (BOOL)addToEndpoint:(chip::EndpointId)endpoint; + +/** + * The access grants the Matter stack can observe. Only modified while + * associating with a controller or on the Matter queue. + */ +@property (atomic, copy, readonly) NSArray * matterAccessGrants; /** * parentEndpoint will be kInvalidEndpointId until the cluster is added to an endpoint. */ -@property (nonatomic, assign) chip::EndpointId parentEndpoint; +@property (atomic, assign, readonly) chip::EndpointId parentEndpoint; /** * The attribute metadata for the cluster. Only valid after associateWithController: has succeeded. */ -@property (nonatomic, assign, readonly) chip::Span matterAttributeMetadata; +@property (atomic, assign, readonly) chip::Span matterAttributeMetadata; /** * The list of accepted command IDs. */ -@property (nonatomic, copy, nullable) NSArray * acceptedCommands; +@property (atomic, copy, nullable) NSArray * acceptedCommands; /** * The list of generated command IDs. */ -@property (nonatomic, copy, nullable) NSArray * generatedCommands; +@property (atomic, copy, nullable) NSArray * generatedCommands; /** * The list of accepted commands IDs in the format the Matter stack needs. */ -@property (nonatomic, assign, nullable, readonly) chip::CommandId * matterAcceptedCommands; +@property (atomic, assign, nullable, readonly) chip::CommandId * matterAcceptedCommands; /** * The list of generated commands IDs in the format the Matter stack needs. */ -@property (nonatomic, assign, nullable, readonly) chip::CommandId * matterGeneratedCommands; +@property (atomic, assign, nullable, readonly) chip::CommandId * matterGeneratedCommands; @end diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.h b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.h index 13dbe8454d759e..9716692ea8895d 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.h +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.h @@ -25,6 +25,7 @@ NS_ASSUME_NONNULL_BEGIN /** * A representation of an endpoint implemented by an MTRDeviceController. */ +NS_SWIFT_SENDABLE MTR_NEWLY_AVAILABLE @interface MTRServerEndpoint : NSObject diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm index c58b1ac4fa7744..c7553230f3748e 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm +++ b/src/darwin/Framework/CHIP/ServerEndpoint/MTRServerEndpoint.mm @@ -154,20 +154,18 @@ - (BOOL)addServerCluster:(MTRServerCluster *)serverCluster return NO; } - if (serverCluster.parentEndpoint != kInvalidEndpointId) { - MTR_LOG_ERROR("Cannot add cluster to endpoint %llu; already added to endpoint %" PRIu32, _endpointID.unsignedLongLongValue, serverCluster.parentEndpoint); - return NO; - } - for (MTRServerCluster * existingCluster in _serverClusters) { if ([existingCluster.clusterID isEqual:serverCluster.clusterID]) { - MTR_LOG_ERROR("Cannot add second cluster with ID %llx on endpoint %llu", serverCluster.clusterID.unsignedLongLongValue, _endpointID.unsignedLongLongValue); + MTR_LOG_ERROR("Cannot add second cluster with ID " ChipLogFormatMEI " on endpoint %llu", ChipLogValueMEI(serverCluster.clusterID.unsignedLongLongValue), _endpointID.unsignedLongLongValue); return NO; } } + if (![serverCluster addToEndpoint:static_cast(_endpointID.unsignedLongLongValue)]) { + return NO; + } [_serverClusters addObject:serverCluster]; - serverCluster.parentEndpoint = static_cast(_endpointID.unsignedLongLongValue); + return YES; } @@ -401,7 +399,7 @@ - (void)invalidate NSMutableArray * grants = [[_matterAccessGrants allObjects] mutableCopy]; for (MTRServerCluster * cluster in _serverClusters) { if ([cluster.clusterID isEqual:clusterID]) { - [grants addObjectsFromArray:[cluster.matterAccessGrants allObjects]]; + [grants addObjectsFromArray:cluster.matterAccessGrants]; } } diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 66bca12cc47bfd..e4628bd475b5ae 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -25,8 +25,10 @@ #import #import "MTRCommandPayloadExtensions_Internal.h" +#import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceTestDelegate.h" #import "MTRErrorTestUtils.h" +#import "MTRTestDeclarations.h" #import "MTRTestKeys.h" #import "MTRTestResetCommissioneeHelper.h" #import "MTRTestStorage.h" @@ -74,19 +76,6 @@ static void WaitForCommissionee(XCTestExpectation * expectation) return mConnectedDevice; } -#ifdef DEBUG -@interface MTRBaseDevice (Test) -- (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))completion; - -// Test function for whitebox testing -+ (id)CHIPEncodeAndDecodeNSObject:(id)object; -@end - -@interface MTRDevice (Test) -- (void)unitTestInjectEventReport:(NSArray *> *)eventReport; -@end -#endif - @interface MTRDeviceTestDeviceControllerDelegate : NSObject @property (nonatomic, strong) XCTestExpectation * expectation; @end @@ -129,10 +118,19 @@ @interface MTRDeviceTests : XCTestCase @implementation MTRDeviceTests +#if MTR_PER_CONTROLLER_STORAGE_ENABLED +static BOOL slocalTestStorageEnabledBeforeUnitTest; +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + + (void)setUp { XCTestExpectation * pairingExpectation = [[XCTestExpectation alloc] initWithDescription:@"Pairing Complete"]; +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + slocalTestStorageEnabledBeforeUnitTest = MTRDeviceControllerLocalTestStorage.localTestStorageEnabled; + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = YES; +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); @@ -182,6 +180,14 @@ + (void)tearDown { ResetCommissionee(GetConnectedDevice(), dispatch_get_main_queue(), nil, kTimeoutInSeconds); +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + // Restore testing setting to previous state, and remove all persisted attributes + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = slocalTestStorageEnabledBeforeUnitTest; + [sController.controllerDataStore clearAllStoredAttributes]; + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedAttributesAfterClear.count, 0); +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + MTRDeviceController * controller = sController; XCTAssertNotNil(controller); [controller shutdown]; @@ -1236,7 +1242,7 @@ - (void)test015_FailedSubscribeWithQueueAcrossShutdown __auto_type * params = [[MTRSubscribeParams alloc] init]; params.resubscribeAutomatically = NO; params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not - // affect this subscription erroring out correctly. + // affect this subscription erroring out correctly. [device subscribeWithQueue:queue minInterval:1 maxInterval:2 @@ -1344,6 +1350,11 @@ - (void)test016_FailedSubscribeWithCacheReadDuringFailure - (void)test017_TestMTRDeviceBasics { + // Ensure the test starts with clean slate, even with MTRDeviceControllerLocalTestStorage enabled + [sController.controllerDataStore clearAllStoredAttributes]; + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedAttributesAfterClear.count, 0); + __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; dispatch_queue_t queue = dispatch_get_main_queue(); @@ -1526,6 +1537,7 @@ - (void)test017_TestMTRDeviceBasics // Resubscription test setup XCTestExpectation * subscriptionDroppedExpectation = [self expectationWithDescription:@"Subscription has dropped"]; + delegate.onNotReachable = ^() { [subscriptionDroppedExpectation fulfill]; }; @@ -1600,7 +1612,7 @@ - (void)test018_SubscriptionErrorWhenNotResubscribing MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)]; params.resubscribeAutomatically = NO; params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not - // affect this subscription erroring out correctly. + // affect this subscription erroring out correctly. __block BOOL subscriptionEstablished = NO; [device subscribeToAttributesWithEndpointID:@1 clusterID:@6 @@ -2826,6 +2838,65 @@ - (void)test030_DeviceAndClusterProperties XCTAssertEqualObjects(cluster.endpointID, @(0)); } +#if MTR_PER_CONTROLLER_STORAGE_ENABLED +- (void)test031_MTRDeviceAttributeCacheLocalTestStorage +{ + dispatch_queue_t queue = dispatch_get_main_queue(); + + // First start with clean slate and + __auto_type * device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + [sController removeDevice:device]; + [sController.controllerDataStore clearAllStoredAttributes]; + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedAttributesAfterClear.count, 0); + + // Now recreate device and get subscription primed + device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + XCTestExpectation * gotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received"]; + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + __weak __auto_type weakDelegate = delegate; + delegate.onReportEnd = ^{ + [gotReportsExpectation fulfill]; + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ gotReportsExpectation ] timeout:60]; + + NSUInteger attributesReportedWithFirstSubscription = [device unitTestAttributesReportedSinceLastCheck]; + + NSArray * dataStoreValuesAfterFirstSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertTrue(dataStoreValuesAfterFirstSubscription.count > 0); + + // Now remove device, resubscribe, and see that it succeeds + [sController removeDevice:device]; + device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + + XCTestExpectation * resubGotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received for resubscription"]; + delegate.onReportEnd = ^{ + [resubGotReportsExpectation fulfill]; + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ resubGotReportsExpectation ] timeout:60]; + + NSUInteger attributesReportedWithSecondSubscription = [device unitTestAttributesReportedSinceLastCheck]; + + XCTAssertTrue(attributesReportedWithSecondSubscription < attributesReportedWithFirstSubscription); + + // 1) MTRDevice actually gets some attributes reported more than once + // 2) Some attributes do change on resubscribe + // * With all-clusts-app as of 2024-02-10, out of 1287 persisted attributes, still 450 attributes were reported with filter + // And so conservatively, assert that data version filters save at least 300 entries. + NSArray * dataStoreValuesAfterSecondSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + NSUInteger storedAttributeCountDifferenceFromMTRDeviceReport = dataStoreValuesAfterSecondSubscription.count - attributesReportedWithSecondSubscription; + XCTAssertTrue(storedAttributeCountDifferenceFromMTRDeviceReport > 300); +} +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + @end @interface MTRDeviceEncoderTests : XCTestCase diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 661dbadb9ac445..38795bcc8cef87 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -22,6 +22,7 @@ #import "MTRDeviceTestDelegate.h" #import "MTRErrorTestUtils.h" #import "MTRFabricInfoChecker.h" +#import "MTRTestDeclarations.h" #import "MTRTestKeys.h" #import "MTRTestPerControllerStorage.h" #import "MTRTestResetCommissioneeHelper.h" @@ -33,28 +34,6 @@ static NSString * kOnboardingPayload = @"MT:-24J0AFN00KA0648G00"; static const uint16_t kTestVendorId = 0xFFF1u; -#ifdef DEBUG -// MTRDeviceControllerDataStore.h includes C++ header, and so we need to declare the methods separately -@protocol MTRDeviceControllerDataStoreAttributeStoreMethods -- (nullable NSArray *)getStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID; -- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)clearAllStoredAttributes; -@end - -// Declare internal methods for testing -@interface MTRDeviceController (Test) -+ (void)forceLocalhostAdvertisingOnly; -- (void)removeDevice:(MTRDevice *)device; -@property (nonatomic, readonly, nullable) id controllerDataStore; -@end - -@interface MTRDevice (Test) -- (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; -- (NSUInteger)unitTestAttributesReportedSinceLastCheck; -@end -#endif // DEBUG - @interface MTRPerControllerStorageTestsControllerDelegate : NSObject @property (nonatomic, strong) XCTestExpectation * expectation; @property (nonatomic, strong) NSNumber * deviceID; diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h new file mode 100644 index 00000000000000..5b77d0ec06aad7 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -0,0 +1,60 @@ +// +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Declarations for internal methods + +// MTRDeviceControllerDataStore.h includes C++ header, and so we need to declare the methods separately +@protocol MTRDeviceControllerDataStoreAttributeStoreMethods +- (nullable NSArray *)getStoredAttributesForNodeID:(NSNumber *)nodeID; +- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID; +- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID; +- (void)clearAllStoredAttributes; +@end + +// Declare internal methods for testing +@interface MTRDeviceController (Test) ++ (void)forceLocalhostAdvertisingOnly; +- (void)removeDevice:(MTRDevice *)device; +@property (nonatomic, readonly, nullable) id controllerDataStore; +@end + +@interface MTRDevice (Test) +- (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; +@end + +#pragma mark - Declarations for items compiled only for DEBUG configuration + +#ifdef DEBUG +@interface MTRBaseDevice (TestDebug) +- (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))completion; + +// Test function for whitebox testing ++ (id)CHIPEncodeAndDecodeNSObject:(id)object; +@end + +@interface MTRDevice (TestDebug) +- (void)unitTestInjectEventReport:(NSArray *> *)eventReport; +- (NSUInteger)unitTestAttributesReportedSinceLastCheck; +@end +#endif + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 5e227bc7a8d2b2..a49b33fa3a1ea4 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -240,6 +240,8 @@ 5ACDDD7D27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5ACDDD7C27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm */; }; 5ACDDD7E27CD3F3A00EFD68A /* MTRClusterStateCacheContainer_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5ACDDD7B27CD14AF00EFD68A /* MTRClusterStateCacheContainer_Internal.h */; }; 5AE6D4E427A99041001F2493 /* MTRDeviceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AE6D4E327A99041001F2493 /* MTRDeviceTests.m */; }; + 75139A6F2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m */; }; + 75139A702B7FE68C00E3A919 /* MTRDeviceControllerLocalTestStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */; }; 7534F12928BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7534F12728BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h */; }; 754F3DF427FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 754F3DF327FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h */; }; @@ -633,6 +635,9 @@ 5ACDDD7B27CD14AF00EFD68A /* MTRClusterStateCacheContainer_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRClusterStateCacheContainer_Internal.h; sourceTree = ""; }; 5ACDDD7C27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRClusterStateCacheContainer.mm; sourceTree = ""; }; 5AE6D4E327A99041001F2493 /* MTRDeviceTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceTests.m; sourceTree = ""; }; + 75139A6C2B7FE19100E3A919 /* MTRTestDeclarations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRTestDeclarations.h; sourceTree = ""; }; + 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceControllerLocalTestStorage.h; sourceTree = ""; }; + 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceControllerLocalTestStorage.m; sourceTree = ""; }; 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceAttestationDelegate.mm; sourceTree = ""; }; 7534F12728BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDeviceAttestationDelegate_Internal.h; sourceTree = ""; }; 754F3DF327FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTREventTLVValueDecoder_Internal.h; sourceTree = ""; }; @@ -792,9 +797,6 @@ 039145E02993102B00257B3E /* main.mm */, 03F430A52994100000166449 /* controller */, 039547092992DB02006D42A8 /* editline */, - 039546AD2991E193006D42A8 /* log */, - 039546B12991E194006D42A8 /* system */, - 039546A72991E185006D42A8 /* delay */, 039546A22991E132006D42A8 /* interaction_model */, 039546972991DFC4006D42A8 /* lib_json */, 039546872991C400006D42A8 /* chip-tool */, @@ -815,7 +817,6 @@ 03FB93DA2A46200A0048CB35 /* discover */, 037C3D7C2991BD4F00B7EEE2 /* pairing */, 037C3D852991BD4F00B7EEE2 /* clusters */, - 037C3D8B2991BD4F00B7EEE2 /* tests */, 037C3D8D2991BD4F00B7EEE2 /* provider */, 037C3D932991BD4F00B7EEE2 /* payload */, 037C3D972991BD4F00B7EEE2 /* storage */, @@ -1105,6 +1106,7 @@ 51C984602A61CE2A00B0AD9A /* MTRFabricInfoChecker.m */, 75B0D01C2B71B46F002074DD /* MTRDeviceTestDelegate.h */, 75B0D01D2B71B47F002074DD /* MTRDeviceTestDelegate.m */, + 75139A6C2B7FE19100E3A919 /* MTRTestDeclarations.h */, ); path = TestHelpers; sourceTree = ""; @@ -1238,6 +1240,8 @@ 5136661228067D550025EDAE /* MTRDeviceControllerFactory.h */, 5136661128067D540025EDAE /* MTRDeviceControllerFactory_Internal.h */, 5136661028067D540025EDAE /* MTRDeviceControllerFactory.mm */, + 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */, + 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m */, 5A6FEC8D27B5624E00F25F42 /* MTRDeviceControllerOverXPC.h */, 5A830D6B27CFCF590053B85D /* MTRDeviceControllerOverXPC_Internal.h */, 5A6FEC8F27B563D900F25F42 /* MTRDeviceControllerOverXPC.mm */, @@ -1555,6 +1559,7 @@ 1EC4CE6425CC276600D7304F /* MTRBaseClusters.h in Headers */, 3D843712294977000070D20A /* MTRCallbackBridgeBase.h in Headers */, 3DECCB742934C21B00585AEC /* MTRDefines.h in Headers */, + 75139A702B7FE68C00E3A919 /* MTRDeviceControllerLocalTestStorage.h in Headers */, 2C5EEEF6268A85C400CAE3D3 /* MTRDeviceConnectionBridge.h in Headers */, 2C8C8FC0253E0C2100797F05 /* MTRPersistentStorageDelegateBridge.h in Headers */, 51FE72352ACDB40000437032 /* MTRCommandPayloads_Internal.h in Headers */, @@ -1753,7 +1758,6 @@ B45373EF2A9FEBFE00807602 /* ops-raw-skt.c in Sources */, 516411332B6BF77700E67C05 /* MTRServerAccessControl.mm in Sources */, 037C3DD52991C2E200B7EEE2 /* CHIPCommandBridge.mm in Sources */, - 039546BC2991E1CB006D42A8 /* LogCommands.cpp in Sources */, 516411312B6BF70300E67C05 /* DataModelHandler.cpp in Sources */, B45373E12A9FEB7F00807602 /* ops-h1.c in Sources */, B45373EB2A9FEBDB00807602 /* ops-listen.c in Sources */, @@ -1766,13 +1770,11 @@ B45373E62A9FEBA400807602 /* header.c in Sources */, B45374002A9FEC4F00807602 /* unix-init.c in Sources */, B45373DF2A9FEB6F00807602 /* system.c in Sources */, - 039546BD2991E1CB006D42A8 /* SystemCommands.cpp in Sources */, B45373FC2A9FEC4F00807602 /* unix-caps.c in Sources */, B4E262162AA0CF1C00DBA5BC /* RemoteDataModelLogger.mm in Sources */, B45373ED2A9FEBEC00807602 /* ops-pipe.c in Sources */, B45373C02A9FEA9100807602 /* output.c in Sources */, 0395470F2992DB37006D42A8 /* complete.c in Sources */, - 039546BE2991E1CB006D42A8 /* DelayCommands.cpp in Sources */, B4E2621B2AA0D02000DBA5BC /* SleepCommand.mm in Sources */, B45373FF2A9FEC4F00807602 /* unix-misc.c in Sources */, B45373D92A9FEB3800807602 /* poll.c in Sources */, @@ -1840,6 +1842,7 @@ 75B765C32A1D82D30014719B /* MTRAttributeSpecifiedCheck.mm in Sources */, AF5F90FF2878D351005503FA /* MTROTAProviderDelegateBridge.mm in Sources */, 516415FF2B6B132200D5CE11 /* DataModelHandler.cpp in Sources */, + 75139A6F2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m in Sources */, 51E95DFC2A78443C00A434F0 /* MTRSessionResumptionStorageBridge.mm in Sources */, 514C79ED2B62ADCD00DD6D7B /* ember-compatibility-functions.cpp in Sources */, 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */, diff --git a/src/include/platform/ThreadStackManager.h b/src/include/platform/ThreadStackManager.h index 86d895ec1cfe52..cda3c7acdccbd5 100644 --- a/src/include/platform/ThreadStackManager.h +++ b/src/include/platform/ThreadStackManager.h @@ -121,6 +121,26 @@ class ThreadStackManager CHIP_ERROR RemoveSrpService(const char * aInstanceName, const char * aName); CHIP_ERROR InvalidateAllSrpServices(); ///< Mark all SRP services as invalid CHIP_ERROR RemoveInvalidSrpServices(); ///< Remove SRP services marked as invalid + + /* + * @brief Utility function to clear all thread SRP host and services established between the SRP server and client. + * It is expected that a transaction is done between the SRP server and client so the clear request is applied on both ends + * + * A generic implementation is provided in `GenericThreadStackManagerImpl_OpenThread` with the SoC OT stack + */ + CHIP_ERROR ClearAllSrpHostAndServices(); + + /* + * @brief Used to synchronize on the SRP server response confirming the clearing of the host and service entries + * Should be called in ClearAllSrpHostAndServices once the request is sent. + */ + void WaitOnSrpClearAllComplete(); + + /* + * @brief Notify that the SRP server confirmed the clearing of the host and service entries + * Should be called in the SRP Client set callback in the removal confirmation. + */ + void NotifySrpClearAllComplete(); CHIP_ERROR SetupSrpHost(const char * aHostName); CHIP_ERROR ClearSrpHost(const char * aHostName); CHIP_ERROR SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback, DnsAsyncReturnCallback aErrorCallback, void * aContext); @@ -289,6 +309,21 @@ inline CHIP_ERROR ThreadStackManager::RemoveInvalidSrpServices() return static_cast(this)->_RemoveInvalidSrpServices(); } +inline CHIP_ERROR ThreadStackManager::ClearAllSrpHostAndServices() +{ + return static_cast(this)->_ClearAllSrpHostAndServices(); +} + +inline void ThreadStackManager::WaitOnSrpClearAllComplete() +{ + return static_cast(this)->_WaitOnSrpClearAllComplete(); +} + +inline void ThreadStackManager::NotifySrpClearAllComplete() +{ + return static_cast(this)->_NotifySrpClearAllComplete(); +} + inline CHIP_ERROR ThreadStackManager::SetupSrpHost(const char * aHostName) { return static_cast(this)->_SetupSrpHost(aHostName); diff --git a/src/lib/core/TLVReader.cpp b/src/lib/core/TLVReader.cpp index abef9af1636ca5..8368b9fb0fac04 100644 --- a/src/lib/core/TLVReader.cpp +++ b/src/lib/core/TLVReader.cpp @@ -49,6 +49,12 @@ using namespace chip::Encoding; static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 }; +TLVReader::TLVReader() : + ImplicitProfileId(kProfileIdNotSpecified), AppData(nullptr), mElemLenOrVal(0), mBackingStore(nullptr), mReadPoint(nullptr), + mBufEnd(nullptr), mLenRead(0), mMaxLen(0), mContainerType(kTLVType_NotSpecified), mControlByte(kTLVControlByte_NotSpecified), + mContainerOpen(false) +{} + void TLVReader::Init(const uint8_t * data, size_t dataLen) { // TODO: Maybe we can just make mMaxLen and mLenRead size_t instead? diff --git a/src/lib/core/TLVReader.h b/src/lib/core/TLVReader.h index bfb6b47f14d3f4..e86812cc2dc16b 100644 --- a/src/lib/core/TLVReader.h +++ b/src/lib/core/TLVReader.h @@ -86,6 +86,8 @@ class DLL_EXPORT TLVReader friend class TLVUpdater; public: + TLVReader(); + /** * Initializes a TLVReader object from another TLVReader object. * diff --git a/src/lib/core/tests/TestTLV.cpp b/src/lib/core/tests/TestTLV.cpp index fce0a5d17ae484..f71bce13fbd70b 100644 --- a/src/lib/core/tests/TestTLV.cpp +++ b/src/lib/core/tests/TestTLV.cpp @@ -3832,6 +3832,27 @@ void TestTLVReader_SkipOverContainer(nlTestSuite * inSuite) ForEachElement(inSuite, reader, nullptr, TestTLVReader_SkipOverContainer_ProcessElement); } +/** + * Tests using an uninitialized TLVReader. + */ +void TestTLVReaderUninitialized(nlTestSuite * inSuite) +{ + TLVReader reader; + + NL_TEST_ASSERT(inSuite, reader.GetType() == kTLVType_NotSpecified); + NL_TEST_ASSERT(inSuite, reader.GetLength() == 0); + NL_TEST_ASSERT(inSuite, reader.GetControlByte() == kTLVControlByte_NotSpecified); + NL_TEST_ASSERT(inSuite, reader.GetContainerType() == kTLVType_NotSpecified); + NL_TEST_ASSERT(inSuite, reader.GetLengthRead() == 0); + NL_TEST_ASSERT(inSuite, reader.GetRemainingLength() == 0); + NL_TEST_ASSERT(inSuite, reader.GetTotalLength() == 0); + NL_TEST_ASSERT(inSuite, reader.GetBackingStore() == nullptr); + NL_TEST_ASSERT(inSuite, reader.IsElementDouble() == false); + NL_TEST_ASSERT(inSuite, reader.GetReadPoint() == nullptr); + NL_TEST_ASSERT(inSuite, reader.ImplicitProfileId == kProfileIdNotSpecified); + NL_TEST_ASSERT(inSuite, reader.AppData == nullptr); +} + /** * Test CHIP TLV Reader */ @@ -3852,6 +3873,8 @@ void CheckTLVReader(nlTestSuite * inSuite, void * inContext) TestTLVReader_NextOverContainer(inSuite); TestTLVReader_SkipOverContainer(inSuite); + + TestTLVReaderUninitialized(inSuite); } /** diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index abbc4647ff3805..3369f8c00b3b3b 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -420,8 +420,13 @@ void DiscoveryImplPlatform::HandleDnssdInit(void * context, CHIP_ERROR initError void DiscoveryImplPlatform::HandleDnssdError(void * context, CHIP_ERROR error) { + DiscoveryImplPlatform * publisher = static_cast(context); + if (error == CHIP_ERROR_FORCED_RESET) { + // Restore dnssd state before restart, also needs to call ChipDnssdShutdown() + publisher->Shutdown(); + DeviceLayer::ChipDeviceEvent event; event.Type = DeviceLayer::DeviceEventType::kDnssdRestartNeeded; error = DeviceLayer::PlatformMgr().PostEvent(&event); diff --git a/src/lib/support/BUILD.gn b/src/lib/support/BUILD.gn index 2342b26ae66d70..02ca1eef593def 100644 --- a/src/lib/support/BUILD.gn +++ b/src/lib/support/BUILD.gn @@ -212,6 +212,7 @@ static_library("support") { "Iterators.h", "LambdaBridge.h", "LifetimePersistedCounter.h", + "LinkedList.h", "ObjectLifeCycle.h", "OwnerOf.h", "PersistedCounter.h", diff --git a/src/app/ObjectList.h b/src/lib/support/LinkedList.h similarity index 90% rename from src/app/ObjectList.h rename to src/lib/support/LinkedList.h index 416db0bb70a6b5..d830c2b3a23351 100644 --- a/src/app/ObjectList.h +++ b/src/lib/support/LinkedList.h @@ -22,13 +22,13 @@ #include namespace chip { -namespace app { +/// A very basic single-linked list template -struct ObjectList +struct SingleLinkedListNode { T mValue; - ObjectList * mpNext = nullptr; + SingleLinkedListNode * mpNext = nullptr; size_t Count() const { @@ -41,5 +41,4 @@ struct ObjectList } }; -} // namespace app } // namespace chip diff --git a/src/platform/Darwin/CHIPDevicePlatformConfig.h b/src/platform/Darwin/CHIPDevicePlatformConfig.h index 15fdaa476e3645..7a5140494c22dd 100644 --- a/src/platform/Darwin/CHIPDevicePlatformConfig.h +++ b/src/platform/Darwin/CHIPDevicePlatformConfig.h @@ -25,7 +25,6 @@ // ==================== Platform Adaptations ==================== -#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC 1 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 diff --git a/src/platform/ESP32/ThreadStackManagerImpl.cpp b/src/platform/ESP32/ThreadStackManagerImpl.cpp index eed07af6d68af1..0449607999668b 100644 --- a/src/platform/ESP32/ThreadStackManagerImpl.cpp +++ b/src/platform/ESP32/ThreadStackManagerImpl.cpp @@ -77,6 +77,30 @@ void ThreadStackManagerImpl::_UnlockThreadStack() esp_openthread_lock_release(); } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete() +{ + // Only 1 task can be blocked on a srpClearAll request + if (mSrpClearAllRequester == nullptr) + { + mSrpClearAllRequester = xTaskGetCurrentTaskHandle(); + // Wait on OnSrpClientNotification which confirms the clearing is done. + // It will notify this current task with NotifySrpClearAllComplete. + // However, we won't wait more than 2s. + ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(2000)); + mSrpClearAllRequester = nullptr; + } +} + +void ThreadStackManagerImpl::_NotifySrpClearAllComplete() +{ + if (mSrpClearAllRequester) + { + xTaskNotifyGive(mSrpClearAllRequester); + } +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void ThreadStackManagerImpl::_ProcessThreadActivity() { // Intentionally empty. diff --git a/src/platform/ESP32/ThreadStackManagerImpl.h b/src/platform/ESP32/ThreadStackManagerImpl.h index 46795d658d6535..1287e7a5f3a1ba 100644 --- a/src/platform/ESP32/ThreadStackManagerImpl.h +++ b/src/platform/ESP32/ThreadStackManagerImpl.h @@ -68,10 +68,21 @@ class ThreadStackManagerImpl final : public ThreadStackManager, void _OnCHIPoBLEAdvertisingStart(); void _OnCHIPoBLEAdvertisingStop(); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + // ===== Methods that override the GenericThreadStackMa + private: friend ThreadStackManager & ::chip::DeviceLayer::ThreadStackMgr(void); friend ThreadStackManagerImpl & ::chip::DeviceLayer::ThreadStackMgrImpl(void); static ThreadStackManagerImpl sInstance; + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + TaskHandle_t mSrpClearAllRequester = nullptr; +#endif + ThreadStackManagerImpl() = default; }; diff --git a/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.h b/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.h index 870fcf2ed80657..059b701f6bda05 100644 --- a/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.h +++ b/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.h @@ -64,6 +64,10 @@ class GenericThreadStackManagerImpl_FreeRTOS bool _TryLockThreadStack(void); void _UnlockThreadStack(void); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT // ===== Members available to the implementation subclass. SemaphoreHandle_t mThreadStackLock; @@ -88,6 +92,10 @@ class GenericThreadStackManagerImpl_FreeRTOS #if defined(CHIP_CONFIG_FREERTOS_USE_STATIC_SEMAPHORE) && CHIP_CONFIG_FREERTOS_USE_STATIC_SEMAPHORE StaticSemaphore_t mThreadStackLockMutex; #endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + TaskHandle_t mSrpClearAllRequester = nullptr; +#endif }; // Instruct the compiler to instantiate the template only when explicitly told to do so. diff --git a/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.hpp b/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.hpp index 4dbee81b23af01..9008258989375e 100644 --- a/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.hpp +++ b/src/platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.hpp @@ -101,6 +101,32 @@ void GenericThreadStackManagerImpl_FreeRTOS::_UnlockThreadStack(void) xSemaphoreGive(mThreadStackLock); } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +template +void GenericThreadStackManagerImpl_FreeRTOS::_WaitOnSrpClearAllComplete() +{ + // Only 1 task can be blocked on a srpClearAll request + if (mSrpClearAllRequester == nullptr) + { + mSrpClearAllRequester = xTaskGetCurrentTaskHandle(); + // Wait on OnSrpClientNotification which confirms the slearing is done. + // It will notify this current task with NotifySrpClearAllComplete. + // However, we won't wait more than 2s. + ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(2000)); + mSrpClearAllRequester = nullptr; + } +} + +template +void GenericThreadStackManagerImpl_FreeRTOS::_NotifySrpClearAllComplete() +{ + if (mSrpClearAllRequester) + { + xTaskNotifyGive(mSrpClearAllRequester); + } +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + template void GenericThreadStackManagerImpl_FreeRTOS::SignalThreadActivityPending() { diff --git a/src/platform/GLibTypeDeleter.h b/src/platform/GLibTypeDeleter.h index e6d9bfd0d2c1ed..f217d559e9cc66 100644 --- a/src/platform/GLibTypeDeleter.h +++ b/src/platform/GLibTypeDeleter.h @@ -29,10 +29,10 @@ class UniquePointerReceiver { public: UniquePointerReceiver(std::unique_ptr & target) : mTarget(target) {} - ~UniquePointerReceiver() { mTarget.reset(mValue); } T *& Get() { return mValue; } + T ** operator&() { return &mValue; } private: std::unique_ptr & mTarget; @@ -151,6 +151,14 @@ struct GAutoPtrDeleter }; template -using GAutoPtr = std::unique_ptr::deleter>; +class GAutoPtr : public std::unique_ptr::deleter> +{ +public: + using deleter = typename GAutoPtrDeleter::deleter; + using std::unique_ptr::unique_ptr; + + // Convenience method to get a UniquePointerReceiver for this object. + UniquePointerReceiver GetReceiver() { return MakeUniquePointerReceiver(*this); } +}; } // namespace chip diff --git a/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.cpp b/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.cpp index f0393a795ef63a..21297d75cf5252 100644 --- a/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.cpp +++ b/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.cpp @@ -54,6 +54,14 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() VerifyOrExit(result == WICED_SUCCESS, err = CHIP_ERROR_INTERNAL); otSysInit(0, NULL); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + mSrpClearAllSemaphore = wiced_rtos_create_mutex(); + VerifyOrExit(mSrpClearAllSemaphore != nullptr, err = CHIP_ERROR_NO_MEMORY); + + result = wiced_rtos_init_mutex(mSrpClearAllSemaphore); + VerifyOrExit(result == WICED_SUCCESS, err = CHIP_ERROR_INTERNAL); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + err = GenericThreadStackManagerImpl_OpenThread::DoInit(NULL); exit: @@ -95,6 +103,21 @@ void ThreadStackManagerImpl::_UnlockThreadStack() VerifyOrReturn(result == WICED_SUCCESS || result == WICED_NOT_OWNED, ChipLogError(DeviceLayer, "%s %x", __func__, result)); } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete() +{ + const wiced_result_t result = wiced_rtos_lock_mutex(mSrpClearAllSemaphore); + VerifyOrReturn(result == WICED_SUCCESS, ChipLogError(DeviceLayer, "%s %x", __func__, result)); +} + +void ThreadStackManagerImpl::_NotifySrpClearAllComplete() +{ + const wiced_result_t result = wiced_rtos_unlock_mutex(mSrpClearAllSemaphore); + VerifyOrReturn(result == WICED_SUCCESS || result == WICED_NOT_OWNED, ChipLogError(DeviceLayer, "%s %x", __func__, result)); +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +// ===== Methods that override the GenericThreadStackMa + void ThreadStackManagerImpl::ThreadTaskMain(void) { while (true) diff --git a/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.h b/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.h index cdb2cb8ee65fdc..5cd3fef1c60239 100644 --- a/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.h +++ b/src/platform/Infineon/CYW30739/ThreadStackManagerImpl.h @@ -58,6 +58,11 @@ class ThreadStackManagerImpl final : public ThreadStackManager, bool _TryLockThreadStack(); void _UnlockThreadStack(); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + // ===== Methods that override the GenericThreadStackMa private: // ===== Members for internal use by the following friends. @@ -67,6 +72,9 @@ class ThreadStackManagerImpl final : public ThreadStackManager, wiced_thread_t * mThread; EventFlags mEventFlags; wiced_mutex_t * mMutex; +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + wiced_mutex_t * mSrpClearAllSemaphore; +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT static ThreadStackManagerImpl sInstance; // ===== Private members for use by this class only. diff --git a/src/platform/Linux/CHIPDevicePlatformConfig.h b/src/platform/Linux/CHIPDevicePlatformConfig.h index 70ed39d62899d5..530e2716308842 100644 --- a/src/platform/Linux/CHIPDevicePlatformConfig.h +++ b/src/platform/Linux/CHIPDevicePlatformConfig.h @@ -26,7 +26,6 @@ // ==================== Platform Adaptations ==================== #if CHIP_DEVICE_CONFIG_ENABLE_WIFI -#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC 1 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 1 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 #else diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index d03cefef4f0ef7..2a57a99d507976 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -98,15 +98,6 @@ namespace DeviceLayer { ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; -#if CHIP_DEVICE_CONFIG_ENABLE_WIFI -char ConnectivityManagerImpl::sWiFiIfName[]; -#endif - -WiFiDriver::ScanCallback * ConnectivityManagerImpl::mpScanCallback; -NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * ConnectivityManagerImpl::mpConnectCallback; -uint8_t ConnectivityManagerImpl::sInterestedSSID[Internal::kMaxWiFiSSIDLength]; -uint8_t ConnectivityManagerImpl::sInterestedSSIDLen; - CHIP_ERROR ConnectivityManagerImpl::_Init() { #if CHIP_DEVICE_CONFIG_ENABLE_WPA @@ -166,12 +157,6 @@ void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) #if CHIP_DEVICE_CONFIG_ENABLE_WPA -bool ConnectivityManagerImpl::mAssociationStarted = false; -BitFlags::ConnectivityFlags> - ConnectivityManagerImpl::mConnectivityFlag; -struct GDBusWpaSupplicant ConnectivityManagerImpl::mWpaSupplicant; -std::mutex ConnectivityManagerImpl::mWpaSupplicantMutex; - ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMode() { if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) @@ -281,8 +266,7 @@ void ConnectivityManagerImpl::_ClearWiFiStationProvision() if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) { GAutoPtr err; - wpa_fi_w1_wpa_supplicant1_interface_call_remove_all_networks_sync(mWpaSupplicant.iface, nullptr, - &MakeUniquePointerReceiver(err).Get()); + wpa_fi_w1_wpa_supplicant1_interface_call_remove_all_networks_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); if (err != nullptr) { @@ -313,7 +297,7 @@ CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) ChipLogProgress(DeviceLayer, "WiFi AP mode change: %s -> %s", WiFiAPModeToStr(mWiFiAPMode), WiFiAPModeToStr(val)); mWiFiAPMode = val; - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } exit: @@ -326,7 +310,7 @@ void ConnectivityManagerImpl::_DemandStartWiFiAP() { ChipLogProgress(DeviceLayer, "wpa_supplicant: Demand start WiFi AP"); mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp(); - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } else { @@ -340,7 +324,7 @@ void ConnectivityManagerImpl::_StopOnDemandWiFiAP() { ChipLogProgress(DeviceLayer, "wpa_supplicant: Demand stop WiFi AP"); mLastAPDemandTime = System::Clock::kZero; - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } else { @@ -362,7 +346,7 @@ void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP() void ConnectivityManagerImpl::_SetWiFiAPIdleTimeout(System::Clock::Timeout val) { mWiFiAPIdleTimeout = val; - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } void ConnectivityManagerImpl::UpdateNetworkStatus() @@ -391,12 +375,11 @@ void ConnectivityManagerImpl::UpdateNetworkStatus() MakeOptional(GetDisconnectReason())); } -void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changed_properties, - const gchar * const * invalidated_properties, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changedProperties) { std::lock_guard lock(mWpaSupplicantMutex); - if (g_variant_n_children(changed_properties) > 0) + if (g_variant_n_children(changedProperties) > 0) { GAutoPtr iter; const gchar * key; @@ -404,7 +387,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate(); - g_variant_get(changed_properties, "a{sv}", &MakeUniquePointerReceiver(iter).Get()); + g_variant_get(changedProperties, "a{sv}", &iter.GetReceiver()); while (g_variant_iter_loop(iter.get(), "{&sv}", &key, &value)) { @@ -424,6 +407,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte if (delegate) { + chip::DeviceLayer::StackLock stackLock; delegate->OnDisconnectionDetected(reason); delegate->OnConnectionStatusChanged(static_cast(ConnectionStatusEnum::kConnected)); } @@ -453,7 +437,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte break; } - DeviceLayer::SystemLayer().ScheduleLambda([reason]() { + DeviceLayer::SystemLayer().ScheduleLambda([this, reason]() { if (mpConnectCallback != nullptr) { mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), reason); @@ -463,6 +447,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte if (delegate) { + chip::DeviceLayer::StackLock stackLock; delegate->OnAssociationFailureDetected(associationFailureCause, status); } } @@ -475,6 +460,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte { if (delegate) { + chip::DeviceLayer::StackLock stackLock; delegate->OnConnectionStatusChanged(static_cast(ConnectionStatusEnum::kNotConnected)); } @@ -484,7 +470,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte { if (mAssociationStarted) { - DeviceLayer::SystemLayer().ScheduleLambda([]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { if (mpConnectCallback != nullptr) { mpConnectCallback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0); @@ -500,7 +486,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte } } -void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -510,8 +496,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, std::lock_guard lock(mWpaSupplicantMutex); - WpaFiW1Wpa_supplicant1Interface * iface = - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus_finish(res, &MakeUniquePointerReceiver(err).Get()); + WpaFiW1Wpa_supplicant1Interface * iface = wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus_finish(res, &err.GetReceiver()); if (mWpaSupplicant.iface) { @@ -525,8 +510,17 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, mWpaSupplicant.state = GDBusWpaSupplicant::WPA_INTERFACE_CONNECTED; ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant interface proxy"); - g_signal_connect(mWpaSupplicant.iface, "properties-changed", G_CALLBACK(_OnWpaPropertiesChanged), NULL); - g_signal_connect(mWpaSupplicant.iface, "scan-done", G_CALLBACK(_OnWpaInterfaceScanDone), NULL); + g_signal_connect( + mWpaSupplicant.iface, "properties-changed", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties, ConnectivityManagerImpl * self) { + return self->_OnWpaPropertiesChanged(proxy, properties); + }), + this); + g_signal_connect(mWpaSupplicant.iface, "scan-done", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceScanDone(proxy, success); + }), + this); } else { @@ -537,7 +531,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, } // We need to stop auto scan or it will block our network scan. - DeviceLayer::SystemLayer().ScheduleLambda([]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { CHIP_ERROR errInner = StopAutoScan(); if (errInner != CHIP_NO_ERROR) { @@ -546,7 +540,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, }); } -void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -556,8 +550,7 @@ void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * source_object, GAsyn std::lock_guard lock(mWpaSupplicantMutex); - WpaFiW1Wpa_supplicant1BSS * bss = - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus_finish(res, &MakeUniquePointerReceiver(err).Get()); + WpaFiW1Wpa_supplicant1BSS * bss = wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus_finish(res, &err.GetReceiver()); if (mWpaSupplicant.bss) { @@ -577,7 +570,7 @@ void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * source_object, GAsyn } } -void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -588,18 +581,27 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy std::lock_guard lock(mWpaSupplicantMutex); gboolean result = wpa_fi_w1_wpa_supplicant1_call_get_interface_finish(mWpaSupplicant.proxy, &mWpaSupplicant.interfacePath, res, - &MakeUniquePointerReceiver(err).Get()); + &err.GetReceiver()); if (result) { mWpaSupplicant.state = GDBusWpaSupplicant::WPA_GOT_INTERFACE_PATH; ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface: %s", mWpaSupplicant.interfacePath); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaInterfaceProxyReady, - nullptr); - - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaBssProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceProxyReady(sourceObject_, res_); + }), + this); + + wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaBssProxyReady(sourceObject_, res_); + }), + this); } else { @@ -617,7 +619,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy args = g_variant_builder_end(&builder); result = wpa_fi_w1_wpa_supplicant1_call_create_interface_sync(mWpaSupplicant.proxy, args, &mWpaSupplicant.interfacePath, - nullptr, &MakeUniquePointerReceiver(error).Get()); + nullptr, &error.GetReceiver()); if (result) { @@ -626,12 +628,21 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy Platform::CopyString(sWiFiIfName, CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, - kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, - _OnWpaInterfaceProxyReady, nullptr); - - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaBssProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceProxyReady(sourceObject_, res_); + }), + this); + + wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaBssProxyReady(sourceObject_, res_); + }), + this); } else { @@ -649,8 +660,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy } } -void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, - gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -669,17 +679,25 @@ void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * prox mWpaSupplicant.state = GDBusWpaSupplicant::WPA_GOT_INTERFACE_PATH; ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface added: %s", mWpaSupplicant.interfacePath); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaInterfaceProxyReady, - nullptr); - - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaBssProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceProxyReady(sourceObject_, res_); + }), + this); + + wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaBssProxyReady(sourceObject_, res_); + }), + this); } } -void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, - gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties) { std::lock_guard lock(mWpaSupplicantMutex); @@ -716,7 +734,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * pr } } -void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -726,17 +744,30 @@ void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * source_object, GAsyncRe std::lock_guard lock(mWpaSupplicantMutex); - mWpaSupplicant.proxy = wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus_finish(res, &MakeUniquePointerReceiver(err).Get()); + mWpaSupplicant.proxy = wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus_finish(res, &err.GetReceiver()); if (mWpaSupplicant.proxy != nullptr && err.get() == nullptr) { mWpaSupplicant.state = GDBusWpaSupplicant::WPA_CONNECTED; ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant proxy"); - g_signal_connect(mWpaSupplicant.proxy, "interface-added", G_CALLBACK(_OnWpaInterfaceAdded), NULL); - - g_signal_connect(mWpaSupplicant.proxy, "interface-removed", G_CALLBACK(_OnWpaInterfaceRemoved), NULL); - - wpa_fi_w1_wpa_supplicant1_call_get_interface(mWpaSupplicant.proxy, sWiFiIfName, nullptr, _OnWpaInterfaceReady, nullptr); + g_signal_connect( + mWpaSupplicant.proxy, "interface-added", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties, + ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceAdded(proxy, path, properties); }), + this); + g_signal_connect( + mWpaSupplicant.proxy, "interface-removed", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties, + ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceRemoved(proxy, path, properties); }), + this); + + wpa_fi_w1_wpa_supplicant1_call_get_interface( + mWpaSupplicant.proxy, sWiFiIfName, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceReady(sourceObject_, res_); + }), + this); } else { @@ -753,7 +784,8 @@ void ConnectivityManagerImpl::StartWiFiManagement() mConnectivityFlag.ClearAll(); mWpaSupplicant = GDBusWpaSupplicant{}; - CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(_StartWiFiManagement, this); + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync( + +[](ConnectivityManagerImpl * self) { return self->_StartWiFiManagement(); }, this); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "Failed to start WiFi management")); } @@ -829,7 +861,7 @@ void ConnectivityManagerImpl::DriveAPState() // Compute the amount of idle time before the AP should be deactivated and // arm a timer to fire at that time. System::Clock::Timeout apTimeout = (mLastAPDemandTime + mWiFiAPIdleTimeout) - now; - err = DeviceLayer::SystemLayer().StartTimer(apTimeout, DriveAPState, nullptr); + err = DeviceLayer::SystemLayer().StartTimer(apTimeout, DriveAPState, this); SuccessOrExit(err); ChipLogProgress(DeviceLayer, "Next WiFi AP timeout in %" PRIu32 " s", std::chrono::duration_cast(apTimeout).count()); @@ -863,7 +895,7 @@ void ConnectivityManagerImpl::DriveAPState() GAutoPtr error(nullptr); gboolean result = wpa_fi_w1_wpa_supplicant1_interface_call_remove_network_sync( - mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, &MakeUniquePointerReceiver(error).Get()); + mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, &error.GetReceiver()); if (result) { @@ -916,7 +948,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() // Clean up current network if exists if (mWpaSupplicant.networkPath) { - g_object_unref(mWpaSupplicant.networkPath); + g_free(mWpaSupplicant.networkPath); mWpaSupplicant.networkPath = nullptr; } @@ -928,7 +960,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() args = g_variant_builder_end(&builder); gboolean result = wpa_fi_w1_wpa_supplicant1_interface_call_add_network_sync( - mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, nullptr, &MakeUniquePointerReceiver(err).Get()); + mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, nullptr, &err.GetReceiver()); if (result) { @@ -937,7 +969,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() ChipLogProgress(DeviceLayer, "wpa_supplicant: added network: SSID: %s: %s", ssid, mWpaSupplicant.networkPath); result = wpa_fi_w1_wpa_supplicant1_interface_call_select_network_sync(mWpaSupplicant.iface, mWpaSupplicant.networkPath, - nullptr, &MakeUniquePointerReceiver(error).Get()); + nullptr, &error.GetReceiver()); if (result) { ChipLogProgress(DeviceLayer, "wpa_supplicant: succeeded to start softAP: SSID: %s", ssid); @@ -956,7 +988,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() if (mWpaSupplicant.networkPath) { - g_object_unref(mWpaSupplicant.networkPath); + g_free(mWpaSupplicant.networkPath); mWpaSupplicant.networkPath = nullptr; } @@ -977,7 +1009,7 @@ void ConnectivityManagerImpl::ChangeWiFiAPState(WiFiAPState newState) void ConnectivityManagerImpl::DriveAPState(::chip::System::Layer * aLayer, void * aAppState) { - sInstance.DriveAPState(); + reinterpret_cast(aAppState)->DriveAPState(); } CHIP_ERROR @@ -998,7 +1030,7 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, GAutoPtr error; result = wpa_fi_w1_wpa_supplicant1_interface_call_remove_network_sync(mWpaSupplicant.iface, networkPath, nullptr, - &MakeUniquePointerReceiver(error).Get()); + &error.GetReceiver()); if (result) { @@ -1020,7 +1052,7 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, } result = wpa_fi_w1_wpa_supplicant1_interface_call_add_network_sync(mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, - nullptr, &MakeUniquePointerReceiver(err).Get()); + nullptr, &err.GetReceiver()); if (result) { @@ -1030,8 +1062,14 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, wpa_fi_w1_wpa_supplicant1_interface_call_disconnect_sync(mWpaSupplicant.iface, nullptr, nullptr); ChipLogProgress(DeviceLayer, "wpa_supplicant: added network: %s", mWpaSupplicant.networkPath); - wpa_fi_w1_wpa_supplicant1_interface_call_select_network(mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, - _ConnectWiFiNetworkAsyncCallback, this); + wpa_fi_w1_wpa_supplicant1_interface_call_select_network( + mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_ConnectWiFiNetworkAsyncCallback(sourceObject_, res_); + }), + this); + mpConnectCallback = apCallback; } else @@ -1040,7 +1078,7 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, if (mWpaSupplicant.networkPath) { - g_object_unref(mWpaSupplicant.networkPath); + g_free(mWpaSupplicant.networkPath); mWpaSupplicant.networkPath = nullptr; } @@ -1086,7 +1124,7 @@ static CHIP_ERROR AddOrReplaceBlob(WpaFiW1Wpa_supplicant1Interface * iface, cons const char * name = (strncmp(nameOrRef, refPrefix.data(), refPrefix.size()) == 0) ? nameOrRef + refPrefix.size() : nameOrRef; GAutoPtr err; - if (!wpa_fi_w1_wpa_supplicant1_interface_call_remove_blob_sync(iface, name, nullptr, &MakeUniquePointerReceiver(err).Get())) + if (!wpa_fi_w1_wpa_supplicant1_interface_call_remove_blob_sync(iface, name, nullptr, &err.GetReceiver())) { GAutoPtr remoteError(g_dbus_error_get_remote_error(err.get())); if (!(remoteError && strcmp(remoteError.get(), kWpaSupplicantBlobUnknown) == 0)) @@ -1097,8 +1135,7 @@ static CHIP_ERROR AddOrReplaceBlob(WpaFiW1Wpa_supplicant1Interface * iface, cons err.reset(); } if (!wpa_fi_w1_wpa_supplicant1_interface_call_add_blob_sync( - iface, name, g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, data.data(), data.size(), 1), nullptr, - &MakeUniquePointerReceiver(err).Get())) + iface, name, g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, data.data(), data.size(), 1), nullptr, &err.GetReceiver())) { ChipLogError(DeviceLayer, "wpa_supplicant: failed to add blob: %s", err ? err->message : "unknown error"); return CHIP_ERROR_INTERNAL; @@ -1191,25 +1228,24 @@ CHIP_ERROR ConnectivityManagerImpl::ConnectWiFiNetworkWithPDCAsync( } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC -void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res) { - ConnectivityManagerImpl * this_ = reinterpret_cast(user_data); GAutoPtr err; std::lock_guard lock(mWpaSupplicantMutex); { - gboolean result = wpa_fi_w1_wpa_supplicant1_interface_call_select_network_finish(mWpaSupplicant.iface, res, - &MakeUniquePointerReceiver(err).Get()); + gboolean result = + wpa_fi_w1_wpa_supplicant1_interface_call_select_network_finish(mWpaSupplicant.iface, res, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "Failed to perform connect network: %s", err == nullptr ? "unknown error" : err->message); - DeviceLayer::SystemLayer().ScheduleLambda([this_]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { if (mpConnectCallback != nullptr) { // TODO(#14175): Replace this with actual thread attach result. - this_->mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), 0); - this_->mpConnectCallback = nullptr; + mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), 0); + mpConnectCallback = nullptr; } mpConnectCallback = nullptr; }); @@ -1217,8 +1253,7 @@ void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * source_ return; } - result = wpa_fi_w1_wpa_supplicant1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, - &MakeUniquePointerReceiver(err).Get()); + result = wpa_fi_w1_wpa_supplicant1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); if (result) { ChipLogProgress(DeviceLayer, "wpa_supplicant: save config succeeded!"); @@ -1295,8 +1330,7 @@ CHIP_ERROR ConnectivityManagerImpl::CommitConfig() ChipLogProgress(DeviceLayer, "wpa_supplicant: save config"); - result = wpa_fi_w1_wpa_supplicant1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, - &MakeUniquePointerReceiver(err).Get()); + result = wpa_fi_w1_wpa_supplicant1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); if (!result) { @@ -1446,8 +1480,7 @@ CHIP_ERROR ConnectivityManagerImpl::GetConfiguredNetwork(NetworkCommissioning::N } GAutoPtr networkInfo(wpa_fi_w1_wpa_supplicant1_network_proxy_new_for_bus_sync( - G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, networkPath, nullptr, - &MakeUniquePointerReceiver(err).Get())); + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, networkPath, nullptr, &err.GetReceiver())); if (networkInfo == nullptr) { return CHIP_ERROR_INTERNAL; @@ -1478,7 +1511,7 @@ CHIP_ERROR ConnectivityManagerImpl::StopAutoScan() ChipLogDetail(DeviceLayer, "wpa_supplicant: disabling auto scan"); result = wpa_fi_w1_wpa_supplicant1_interface_call_auto_scan_sync( - mWpaSupplicant.iface, "" /* empty string means disabling auto scan */, nullptr, &MakeUniquePointerReceiver(err).Get()); + mWpaSupplicant.iface, "" /* empty string means disabling auto scan */, nullptr, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "wpa_supplicant: Failed to stop auto network scan: %s", err ? err->message : "unknown"); @@ -1508,8 +1541,7 @@ CHIP_ERROR ConnectivityManagerImpl::StartWiFiScan(ByteSpan ssid, WiFiDriver::Sca g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_string("active")); args = g_variant_builder_end(&builder); - result = wpa_fi_w1_wpa_supplicant1_interface_call_scan_sync(mWpaSupplicant.iface, args, nullptr, - &MakeUniquePointerReceiver(err).Get()); + result = wpa_fi_w1_wpa_supplicant1_interface_call_scan_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); if (result) { @@ -1636,9 +1668,8 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi // with the proxy object. GAutoPtr err; - GAutoPtr bss( - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - bssPath, nullptr, &MakeUniquePointerReceiver(err).Get())); + GAutoPtr bss(wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus_sync( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, bssPath, nullptr, &err.GetReceiver())); if (bss == nullptr) { @@ -1796,7 +1827,7 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi return true; } -void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success) { std::lock_guard lock(mWpaSupplicantMutex); @@ -1806,7 +1837,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, G if (bsss == nullptr) { ChipLogProgress(DeviceLayer, "wpa_supplicant: no network found"); - DeviceLayer::SystemLayer().ScheduleLambda([]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { if (mpScanCallback != nullptr) { mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr); @@ -1833,7 +1864,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, G } } - DeviceLayer::SystemLayer().ScheduleLambda([networkScanned]() { + DeviceLayer::SystemLayer().ScheduleLambda([this, networkScanned]() { // Note: We cannot post a event in ScheduleLambda since std::vector is not trivial copiable. This results in the use of // const_cast but should be fine for almost all cases, since we actually handled the ownership of this element to this // lambda. @@ -1850,15 +1881,19 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, G g_strfreev(oldBsss); } -CHIP_ERROR ConnectivityManagerImpl::_StartWiFiManagement(ConnectivityManagerImpl * self) +CHIP_ERROR ConnectivityManagerImpl::_StartWiFiManagement() { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. VerifyOrDie(g_main_context_get_thread_default() != nullptr); ChipLogProgress(DeviceLayer, "wpa_supplicant: Start WiFi management"); - wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - kWpaSupplicantObjectPath, nullptr, self->_OnWpaProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, kWpaSupplicantObjectPath, nullptr, + reinterpret_cast(+[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaProxyReady(sourceObject_, res_); + }), + this); return CHIP_NO_ERROR; } diff --git a/src/platform/Linux/ConnectivityManagerImpl.h b/src/platform/Linux/ConnectivityManagerImpl.h index 930b84fb4d455b..26d6172ad438eb 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.h +++ b/src/platform/Linux/ConnectivityManagerImpl.h @@ -155,14 +155,14 @@ class ConnectivityManagerImpl final : public ConnectivityManager, CHIP_ERROR _ConnectWiFiNetworkAsync(GVariant * networkArgs, NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback) CHIP_REQUIRES(mWpaSupplicantMutex); - static void _ConnectWiFiNetworkAsyncCallback(GObject * source_object, GAsyncResult * res, gpointer user_data); + void _ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res); #endif public: const char * GetEthernetIfName() { return (mEthIfName[0] == '\0') ? nullptr : mEthIfName; } #if CHIP_DEVICE_CONFIG_ENABLE_WIFI - static const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; } + const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; } #endif private: @@ -205,29 +205,27 @@ class ConnectivityManagerImpl final : public ConnectivityManager, System::Clock::Timeout _GetWiFiAPIdleTimeout(); void _SetWiFiAPIdleTimeout(System::Clock::Timeout val); void UpdateNetworkStatus(); - static CHIP_ERROR StopAutoScan(); - - static void _OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, - gpointer user_data); - static void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, gpointer user_data); - static void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changed_properties, - const gchar * const * invalidated_properties, gpointer user_data); - static void _OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaBssProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaInterfaceScanDone(GObject * source_object, GAsyncResult * res, gpointer user_data); - - static bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result); - - static CHIP_ERROR _StartWiFiManagement(ConnectivityManagerImpl * self); - - static bool mAssociationStarted; - static BitFlags mConnectivityFlag; - static GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex); + CHIP_ERROR StopAutoScan(); + + void _OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res); + void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties); + void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties); + void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties); + void _OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success); + void _OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res); + void _OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res); + void _OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res); + + bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result); + + CHIP_ERROR _StartWiFiManagement(); + + bool mAssociationStarted = false; + BitFlags mConnectivityFlag; + GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex); // Access to mWpaSupplicant has to be protected by a mutex because it is accessed from // the CHIP event loop thread and dedicated D-Bus thread started by platform manager. - static std::mutex mWpaSupplicantMutex; + std::mutex mWpaSupplicantMutex; NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr; #endif @@ -262,13 +260,15 @@ class ConnectivityManagerImpl final : public ConnectivityManager, #endif #if CHIP_DEVICE_CONFIG_ENABLE_WIFI - static char sWiFiIfName[IFNAMSIZ]; + char sWiFiIfName[IFNAMSIZ]; #endif - static uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength]; - static uint8_t sInterestedSSIDLen; - static NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback; - static NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback; +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength]; + uint8_t sInterestedSSIDLen; +#endif + NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback; + NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback; }; #if CHIP_DEVICE_CONFIG_ENABLE_WPA diff --git a/src/platform/Linux/NetworkCommissioningWiFiDriver.cpp b/src/platform/Linux/NetworkCommissioningWiFiDriver.cpp index 4b5b3c0b6b5e7d..16e4b7f0d7fbde 100644 --- a/src/platform/Linux/NetworkCommissioningWiFiDriver.cpp +++ b/src/platform/Linux/NetworkCommissioningWiFiDriver.cpp @@ -44,12 +44,12 @@ constexpr char kWiFiCredentialsKeyName[] = "wifi-pass"; constexpr char kWifiNetworkIdentityKeyName[] = "wifi-ni"; constexpr char kWifiClientIdentityKeyName[] = "wifi-ci"; constexpr char kWifiClientIdentityKeypairKeyName[] = "wifi-cik"; +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC inline CHIP_ERROR IgnoreNotFound(CHIP_ERROR err) { return (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) ? CHIP_NO_ERROR : err; } -#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC } // namespace // NOTE: For WiFiDriver, we uses two network configs, one is mSavedNetwork, and another is mStagingNetwork, during init, it will diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index 0098eb01ae96eb..401d72bbe413bd 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -108,13 +108,13 @@ gboolean WiFiIPChangeListener(GIOChannel * ch, GIOCondition /* condition */, voi continue; } - if (ConnectivityManagerImpl::GetWiFiIfName() == nullptr) + if (ConnectivityMgrImpl().GetWiFiIfName() == nullptr) { ChipLogDetail(DeviceLayer, "No wifi interface name. Ignoring IP update event."); continue; } - if (strcmp(name, ConnectivityManagerImpl::GetWiFiIfName()) != 0) + if (strcmp(name, ConnectivityMgrImpl().GetWiFiIfName()) != 0) { continue; } diff --git a/src/platform/Linux/ThreadStackManagerImpl.cpp b/src/platform/Linux/ThreadStackManagerImpl.cpp index a8f6c23f1e5a24..5fd865df5485ad 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.cpp +++ b/src/platform/Linux/ThreadStackManagerImpl.cpp @@ -85,7 +85,7 @@ CHIP_ERROR ThreadStackManagerImpl::GLibMatterContextInitThreadStack(ThreadStackM GAutoPtr err; self->mProxy.reset(openthread_io_openthread_border_router_proxy_new_for_bus_sync( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kDBusOpenThreadService, kDBusOpenThreadObjectPath, nullptr, - &MakeUniquePointerReceiver(err).Get())); + &err.GetReceiver())); VerifyOrReturnError( self->mProxy != nullptr, CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "openthread: failed to create openthread dbus proxy %s", err ? err->message : "unknown error")); @@ -123,7 +123,7 @@ void ThreadStackManagerImpl::OnDbusPropertiesChanged(OpenthreadIoOpenthreadBorde GVariant * value; GAutoPtr iter; - g_variant_get(changed_properties, "a{sv}", &MakeUniquePointerReceiver(iter).Get()); + g_variant_get(changed_properties, "a{sv}", &iter.GetReceiver()); if (!iter) return; while (g_variant_iter_loop(iter.get(), "{&sv}", &key, &value)) @@ -193,7 +193,7 @@ bool ThreadStackManagerImpl::_HaveRouteToAddress(const Inet::IPAddress & destAdd if (g_variant_n_children(routes.get()) > 0) { GAutoPtr iter; - g_variant_get(routes.get(), "av", &MakeUniquePointerReceiver(iter).Get()); + g_variant_get(routes.get(), "av", &iter.GetReceiver()); if (!iter) return false; @@ -207,14 +207,13 @@ bool ThreadStackManagerImpl::_HaveRouteToAddress(const Inet::IPAddress & destAdd guchar preference; gboolean stable; gboolean nextHopIsThisDevice; - g_variant_get(route, "(&vqybb)", &MakeUniquePointerReceiver(prefix).Get(), &rloc16, &preference, &stable, - &nextHopIsThisDevice); + g_variant_get(route, "(&vqybb)", &prefix.GetReceiver(), &rloc16, &preference, &stable, &nextHopIsThisDevice); if (!prefix) continue; GAutoPtr address; guchar prefixLength; - g_variant_get(prefix.get(), "(&vy)", &MakeUniquePointerReceiver(address).Get(), &prefixLength); + g_variant_get(prefix.get(), "(&vy)", &address.GetReceiver(), &prefixLength); if (!address) continue; @@ -273,8 +272,7 @@ CHIP_ERROR ThreadStackManagerImpl::_GetThreadProvision(Thread::OperationalDatase GAutoPtr err; GAutoPtr response(g_dbus_proxy_call_sync(G_DBUS_PROXY(mProxy.get()), "org.freedesktop.DBus.Properties.Get", g_variant_new("(ss)", "io.openthread.BorderRouter", "ActiveDatasetTlvs"), - G_DBUS_CALL_FLAGS_NONE, -1, nullptr, - &MakeUniquePointerReceiver(err).Get())); + G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &err.GetReceiver())); if (err) { @@ -330,7 +328,7 @@ bool ThreadStackManagerImpl::_IsThreadEnabled() GAutoPtr err; GAutoPtr response(g_dbus_proxy_call_sync(G_DBUS_PROXY(mProxy.get()), "org.freedesktop.DBus.Properties.Get", g_variant_new("(ss)", "io.openthread.BorderRouter", "DeviceRole"), - G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &MakeUniquePointerReceiver(err).Get())); + G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &err.GetReceiver())); if (err) { @@ -390,8 +388,7 @@ CHIP_ERROR ThreadStackManagerImpl::_SetThreadEnabled(bool val) else { GAutoPtr err; - gboolean result = - openthread_io_openthread_border_router_call_reset_sync(mProxy.get(), nullptr, &MakeUniquePointerReceiver(err).Get()); + gboolean result = openthread_io_openthread_border_router_call_reset_sync(mProxy.get(), nullptr, &err.GetReceiver()); if (err) { ChipLogError(DeviceLayer, "openthread: _SetThreadEnabled calling %s failed: %s", "Reset", err->message); @@ -413,8 +410,7 @@ void ThreadStackManagerImpl::_OnThreadBrAttachFinished(GObject * source_object, GAutoPtr attachRes; GAutoPtr err; { - gboolean result = openthread_io_openthread_border_router_call_attach_finish(this_->mProxy.get(), res, - &MakeUniquePointerReceiver(err).Get()); + gboolean result = openthread_io_openthread_border_router_call_attach_finish(this_->mProxy.get(), res, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "Failed to perform finish Thread network scan: %s", @@ -612,8 +608,8 @@ void ThreadStackManagerImpl::_OnNetworkScanFinished(GAsyncResult * res) GAutoPtr scan_result; GAutoPtr err; { - gboolean result = openthread_io_openthread_border_router_call_scan_finish( - mProxy.get(), &MakeUniquePointerReceiver(scan_result).Get(), res, &MakeUniquePointerReceiver(err).Get()); + gboolean result = openthread_io_openthread_border_router_call_scan_finish(mProxy.get(), &scan_result.GetReceiver(), res, + &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "Failed to perform finish Thread network scan: %s", @@ -635,7 +631,7 @@ void ThreadStackManagerImpl::_OnNetworkScanFinished(GAsyncResult * res) if (g_variant_n_children(scan_result.get()) > 0) { GAutoPtr iter; - g_variant_get(scan_result.get(), "a(tstayqqynyybb)", &MakeUniquePointerReceiver(iter).Get()); + g_variant_get(scan_result.get(), "a(tstayqqynyybb)", &iter.GetReceiver()); if (!iter) { delete scanResult; diff --git a/src/platform/Linux/ThreadStackManagerImpl.h b/src/platform/Linux/ThreadStackManagerImpl.h index 977c6b94d0027f..e262837dd84c76 100755 --- a/src/platform/Linux/ThreadStackManagerImpl.h +++ b/src/platform/Linux/ThreadStackManagerImpl.h @@ -57,6 +57,11 @@ class ThreadStackManagerImpl : public ThreadStackManager bool _TryLockThreadStack() { return false; } // Intentionally left blank void _UnlockThreadStack() {} // Intentionally left blank +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete() {} + void _NotifySrpClearAllComplete() {} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + bool _HaveRouteToAddress(const Inet::IPAddress & destAddr); void _OnPlatformEvent(const ChipDeviceEvent * event); diff --git a/src/platform/Linux/bluez/AdapterIterator.cpp b/src/platform/Linux/bluez/AdapterIterator.cpp index 3197be4e73e175..e69c473f52bbfe 100644 --- a/src/platform/Linux/bluez/AdapterIterator.cpp +++ b/src/platform/Linux/bluez/AdapterIterator.cpp @@ -57,7 +57,7 @@ CHIP_ERROR AdapterIterator::Initialize(AdapterIterator * self) self->mManager = g_dbus_object_manager_client_new_for_bus_sync( G_BUS_TYPE_SYSTEM, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, BLUEZ_INTERFACE, "/", bluez_object_manager_client_get_proxy_type, nullptr /* unused user data in the Proxy Type Func */, - nullptr /*destroy notify */, nullptr /* cancellable */, &MakeUniquePointerReceiver(error).Get()); + nullptr /* destroy notify */, nullptr /* cancellable */, &error.GetReceiver()); VerifyOrExit(self->mManager != nullptr, ChipLogError(DeviceLayer, "Failed to get DBUS object manager for listing adapters."); err = CHIP_ERROR_INTERNAL); diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index db74da8bec1ec4..196529816b59ab 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -65,7 +65,7 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() // Bluez to set "BR/EDR Not Supported" flag. Bluez doesn't provide API to do that explicitly // and the flag is necessary to force using LE transport. bluez_leadvertisement1_set_discoverable(adv, TRUE); - bluez_leadvertisement1_set_discoverable_timeout(adv, 0 /* infinite */); + // empty discoverable timeout for infinite discoverability // empty includes bluez_leadvertisement1_set_local_name(adv, mAdvName); @@ -118,7 +118,7 @@ CHIP_ERROR BluezAdvertisement::Init(const BluezEndpoint & aEndpoint, const char mpRoot = reinterpret_cast(g_object_ref(aEndpoint.GetGattApplicationObjectManager())); mpAdapter = reinterpret_cast(g_object_ref(aEndpoint.GetAdapter())); - g_object_get(G_OBJECT(mpRoot), "object-path", &MakeUniquePointerReceiver(rootPath).Get(), nullptr); + g_object_get(G_OBJECT(mpRoot), "object-path", &rootPath.GetReceiver(), nullptr); mpAdvPath = g_strdup_printf("%s/advertising", rootPath.get()); mpAdvUUID = g_strdup(aAdvUUID); @@ -241,8 +241,7 @@ void BluezAdvertisement::StartDone(GObject * aObject, GAsyncResult * aResult) GAutoPtr error; gboolean success = FALSE; - success = - bluez_leadvertising_manager1_call_register_advertisement_finish(advMgr, aResult, &MakeUniquePointerReceiver(error).Get()); + success = bluez_leadvertising_manager1_call_register_advertisement_finish(advMgr, aResult, &error.GetReceiver()); if (success == FALSE) { g_dbus_object_manager_server_unexport(mpRoot, mpAdvPath); @@ -304,8 +303,7 @@ void BluezAdvertisement::StopDone(GObject * aObject, GAsyncResult * aResult) GAutoPtr error; gboolean success = FALSE; - success = - bluez_leadvertising_manager1_call_unregister_advertisement_finish(advMgr, aResult, &MakeUniquePointerReceiver(error).Get()); + success = bluez_leadvertising_manager1_call_unregister_advertisement_finish(advMgr, aResult, &error.GetReceiver()); if (success == FALSE) { diff --git a/src/platform/Linux/bluez/BluezConnection.cpp b/src/platform/Linux/bluez/BluezConnection.cpp index 39b5bb0bdb8ba6..d2d5745a4c37c2 100644 --- a/src/platform/Linux/bluez/BluezConnection.cpp +++ b/src/platform/Linux/bluez/BluezConnection.cpp @@ -180,7 +180,7 @@ CHIP_ERROR BluezConnection::BluezDisconnect(BluezConnection * conn) ChipLogDetail(DeviceLayer, "%s peer=%s", __func__, conn->GetPeerAddress()); - success = bluez_device1_call_disconnect_sync(conn->mpDevice, nullptr, &MakeUniquePointerReceiver(error).Get()); + success = bluez_device1_call_disconnect_sync(conn->mpDevice, nullptr, &error.GetReceiver()); VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: Disconnect: %s", error->message)); exit: @@ -284,7 +284,7 @@ CHIP_ERROR BluezConnection::SendIndicationImpl(ConnectionDataBundle * data) VerifyOrExit(len <= static_cast(std::numeric_limits::max()), ChipLogError(DeviceLayer, "FAIL: buffer too large in %s", __func__)); auto status = g_io_channel_write_chars(data->mConn.mC2Channel.mChannel.get(), buf, static_cast(len), &written, - &MakeUniquePointerReceiver(error).Get()); + &error.GetReceiver()); VerifyOrExit(status == G_IO_STATUS_NORMAL, ChipLogError(DeviceLayer, "FAIL: C2 Indicate: %s", error->message)); } else @@ -311,7 +311,7 @@ void BluezConnection::SendWriteRequestDone(GObject * aObject, GAsyncResult * aRe { BluezGattCharacteristic1 * c1 = BLUEZ_GATT_CHARACTERISTIC1(aObject); GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c1, aResult, &MakeUniquePointerReceiver(error).Get()); + gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c1, aResult, &error.GetReceiver()); VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: SendWriteRequest : %s", error->message)); BLEManagerImpl::HandleWriteComplete(static_cast(apConnection)); @@ -360,7 +360,7 @@ void BluezConnection::SubscribeCharacteristicDone(GObject * aObject, GAsyncResul { BluezGattCharacteristic1 * c2 = BLUEZ_GATT_CHARACTERISTIC1(aObject); GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &MakeUniquePointerReceiver(error).Get()); + gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &error.GetReceiver()); VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: SubscribeCharacteristic : %s", error->message)); @@ -392,7 +392,7 @@ void BluezConnection::UnsubscribeCharacteristicDone(GObject * aObject, GAsyncRes { BluezGattCharacteristic1 * c2 = BLUEZ_GATT_CHARACTERISTIC1(aObject); GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &MakeUniquePointerReceiver(error).Get()); + gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &error.GetReceiver()); VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: UnsubscribeCharacteristic : %s", error->message)); diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 3baca7d127f20a..e68b28b8f421a8 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -264,8 +264,7 @@ void BluezEndpoint::RegisterGattApplicationDone(GObject * aObject, GAsyncResult GAutoPtr error; BluezGattManager1 * gattMgr = BLUEZ_GATT_MANAGER1(aObject); - gboolean success = - bluez_gatt_manager1_call_register_application_finish(gattMgr, aResult, &MakeUniquePointerReceiver(error).Get()); + gboolean success = bluez_gatt_manager1_call_register_application_finish(gattMgr, aResult, &error.GetReceiver()); VerifyOrReturn(success == TRUE, { ChipLogError(DeviceLayer, "FAIL: RegisterApplication : %s", error->message); @@ -614,16 +613,16 @@ void BluezEndpoint::SetupGattServer(GDBusConnection * aConn) CHIP_ERROR BluezEndpoint::StartupEndpointBindings() { GAutoPtr err; - GAutoPtr conn(g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &MakeUniquePointerReceiver(err).Get())); + GAutoPtr conn(g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err.GetReceiver())); VerifyOrReturnError(conn != nullptr, CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "FAIL: get bus sync in %s, error: %s", __func__, err->message)); SetupGattServer(conn.get()); - mpObjMgr = g_dbus_object_manager_client_new_sync( - conn.get(), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, BLUEZ_INTERFACE, "/", bluez_object_manager_client_get_proxy_type, - nullptr /* unused user data in the Proxy Type Func */, nullptr /*destroy notify */, nullptr /* cancellable */, - &MakeUniquePointerReceiver(err).Get()); + mpObjMgr = g_dbus_object_manager_client_new_sync(conn.get(), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, BLUEZ_INTERFACE, "/", + bluez_object_manager_client_get_proxy_type, + nullptr /* unused user data in the Proxy Type Func */, + nullptr /*destroy notify */, nullptr /* cancellable */, &err.GetReceiver()); VerifyOrReturnError(mpObjMgr != nullptr, CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "FAIL: Error getting object manager client: %s", err->message)); @@ -729,7 +728,7 @@ CHIP_ERROR BluezEndpoint::ConnectDeviceImpl(BluezDevice1 & aDevice) for (uint16_t i = 0; i < kMaxConnectRetries; i++) { GAutoPtr error; - if (bluez_device1_call_connect_sync(&aDevice, mConnectCancellable.get(), &MakeUniquePointerReceiver(error).Get())) + if (bluez_device1_call_connect_sync(&aDevice, mConnectCancellable.get(), &error.GetReceiver())) { ChipLogDetail(DeviceLayer, "ConnectDevice complete"); return CHIP_NO_ERROR; diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.cpp b/src/platform/Linux/bluez/ChipDeviceScanner.cpp index 5d9cbf25c9028b..03b26aa08e3dc7 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.cpp +++ b/src/platform/Linux/bluez/ChipDeviceScanner.cpp @@ -72,7 +72,7 @@ CHIP_ERROR ChipDeviceScanner::Init(BluezAdapter1 * adapter, ChipDeviceScannerDel self->mManager = g_dbus_object_manager_client_new_for_bus_sync( G_BUS_TYPE_SYSTEM, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, BLUEZ_INTERFACE, "/", bluez_object_manager_client_get_proxy_type, nullptr /* unused user data in the Proxy Type Func */, - nullptr /* destroy notify */, nullptr /* cancellable */, &MakeUniquePointerReceiver(err).Get()); + nullptr /* destroy notify */, nullptr /* cancellable */, &err.GetReceiver()); VerifyOrReturnError(self->mManager != nullptr, CHIP_ERROR_INTERNAL, ChipLogError(Ble, "Failed to get D-Bus object manager for device scanning: %s", err->message)); return CHIP_NO_ERROR; @@ -205,8 +205,7 @@ CHIP_ERROR ChipDeviceScanner::MainLoopStopScan(ChipDeviceScanner * self) self->mInterfaceChangedSignal = 0; } - if (!bluez_adapter1_call_stop_discovery_sync(self->mAdapter, nullptr /* not cancellable */, - &MakeUniquePointerReceiver(error).Get())) + if (!bluez_adapter1_call_stop_discovery_sync(self->mAdapter, nullptr /* not cancellable */, &error.GetReceiver())) { ChipLogError(Ble, "Failed to stop discovery %s", error->message); return CHIP_ERROR_INTERNAL; @@ -268,7 +267,7 @@ void ChipDeviceScanner::RemoveDevice(BluezDevice1 & device) const auto devicePath = g_dbus_proxy_get_object_path(G_DBUS_PROXY(&device)); GAutoPtr error; - if (!bluez_adapter1_call_remove_device_sync(mAdapter, devicePath, nullptr, &MakeUniquePointerReceiver(error).Get())) + if (!bluez_adapter1_call_remove_device_sync(mAdapter, devicePath, nullptr, &error.GetReceiver())) { ChipLogDetail(Ble, "Failed to remove device %s: %s", StringOrNullMarker(devicePath), error->message); } @@ -303,17 +302,15 @@ CHIP_ERROR ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self) g_variant_builder_add(&filterBuilder, "{sv}", "Transport", g_variant_new_string("le")); GVariant * filter = g_variant_builder_end(&filterBuilder); - if (!bluez_adapter1_call_set_discovery_filter_sync(self->mAdapter, filter, self->mCancellable.get(), - &MakeUniquePointerReceiver(error).Get())) + if (!bluez_adapter1_call_set_discovery_filter_sync(self->mAdapter, filter, self->mCancellable.get(), &error.GetReceiver())) { // Not critical: ignore if fails ChipLogError(Ble, "Failed to set discovery filters: %s", error->message); - g_clear_error(&MakeUniquePointerReceiver(error).Get()); + error.reset(); } ChipLogProgress(Ble, "BLE initiating scan."); - if (!bluez_adapter1_call_start_discovery_sync(self->mAdapter, self->mCancellable.get(), - &MakeUniquePointerReceiver(error).Get())) + if (!bluez_adapter1_call_start_discovery_sync(self->mAdapter, self->mCancellable.get(), &error.GetReceiver())) { ChipLogError(Ble, "Failed to start discovery: %s", error->message); return CHIP_ERROR_INTERNAL; diff --git a/src/platform/Linux/dbus/bluez/DbusBluez.xml b/src/platform/Linux/dbus/bluez/DbusBluez.xml index 00887dc5e147a9..0a42da708d50a9 100644 --- a/src/platform/Linux/dbus/bluez/DbusBluez.xml +++ b/src/platform/Linux/dbus/bluez/DbusBluez.xml @@ -108,6 +108,10 @@ + @@ -115,6 +119,10 @@ + @@ -152,6 +160,10 @@ + @@ -172,6 +184,10 @@ + @@ -183,13 +199,33 @@ + - - - + + + diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h index 161c2b202a8310..8ce0805182dcaa 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h @@ -121,6 +121,7 @@ class GenericThreadStackManagerImpl_OpenThread CHIP_ERROR _RemoveSrpService(const char * aInstanceName, const char * aName); CHIP_ERROR _InvalidateAllSrpServices(); CHIP_ERROR _RemoveInvalidSrpServices(); + CHIP_ERROR _ClearAllSrpHostAndServices(); CHIP_ERROR _SetupSrpHost(const char * aHostName); CHIP_ERROR _ClearSrpHost(const char * aHostName); @@ -203,6 +204,8 @@ class GenericThreadStackManagerImpl_OpenThread SrpClient mSrpClient; + bool mIsSrpClearAllRequested = false; + static void OnSrpClientNotification(otError aError, const otSrpClientHostInfo * aHostInfo, const otSrpClientService * aServices, const otSrpClientService * aRemovedServices, void * aContext); static void OnSrpClientStateChange(const otSockAddr * aServerSockAddr, void * aContext); diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index acc0c78d0c8eb7..21c44dd00279e3 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -1307,6 +1307,12 @@ void GenericThreadStackManagerImpl_OpenThread::OnSrpClientNotificatio ThreadStackMgrImpl().mSrpClient.mIsInitialized = true; ThreadStackMgrImpl().mSrpClient.mInitializedCallback(ThreadStackMgrImpl().mSrpClient.mCallbackContext, CHIP_NO_ERROR); + + if (ThreadStackMgrImpl().mIsSrpClearAllRequested) + { + ThreadStackMgrImpl().NotifySrpClearAllComplete(); + ThreadStackMgrImpl().mIsSrpClearAllRequested = false; + } } } @@ -1618,6 +1624,35 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_RemoveInvalidSr return error; } +/* + * @brief This is a utility function to remove all Thread client srp host and services + * established between the device and the srp server (in most cases the OTBR). + * The calling task is blocked until OnSrpClientNotification which confims the client received the request. + * The blocking mechanism is defined by the platform implementation of `WaitOnSrpClearAllComplete` and `NotifySrpClearAllComplete` + * + * Note: This function is meant to be used during the factory reset sequence. + * + */ +template +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_ClearAllSrpHostAndServices() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + Impl()->LockThreadStack(); + if (!mIsSrpClearAllRequested) + { + error = + MapOpenThreadError(otSrpClientRemoveHostAndServices(mOTInst, true /*aRemoveKeyLease*/, true /*aSendUnregToServer*/)); + mIsSrpClearAllRequested = true; + Impl()->UnlockThreadStack(); + Impl()->WaitOnSrpClearAllComplete(); + } + else + { + Impl()->UnlockThreadStack(); + } + return error; +} + template CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_SetupSrpHost(const char * aHostName) { diff --git a/src/platform/Tizen/BLEManagerImpl.cpp b/src/platform/Tizen/BLEManagerImpl.cpp index 0a1a9468d00b06..4d4c3e77316fc7 100644 --- a/src/platform/Tizen/BLEManagerImpl.cpp +++ b/src/platform/Tizen/BLEManagerImpl.cpp @@ -208,11 +208,11 @@ void BLEManagerImpl::ReadValueRequestedCb(const char * remoteAddress, int reques GAutoPtr uuid; GAutoPtr value; - VerifyOrReturn(__GetAttInfo(gattHandle, &MakeUniquePointerReceiver(uuid).Get(), &type) == BT_ERROR_NONE, + VerifyOrReturn(__GetAttInfo(gattHandle, &uuid.GetReceiver(), &type) == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from GATT handle")); ChipLogProgress(DeviceLayer, "Gatt read requested on %s: uuid=%s", __ConvertAttTypeToStr(type), StringOrNullMarker(uuid.get())); - ret = bt_gatt_get_value(gattHandle, &MakeUniquePointerReceiver(value).Get(), &len); + ret = bt_gatt_get_value(gattHandle, &value.GetReceiver(), &len); VerifyOrReturn(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "bt_gatt_get_value() failed: %s", get_error_message(ret))); ChipLogByteSpan(DeviceLayer, ByteSpan(Uint8::from_const_char(value.get()), len)); @@ -233,7 +233,7 @@ void BLEManagerImpl::WriteValueRequestedCb(const char * remoteAddress, int reque conn = static_cast(g_hash_table_lookup(mConnectionMap, remoteAddress)); VerifyOrReturn(conn != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info")); - VerifyOrReturn(__GetAttInfo(gattHandle, &MakeUniquePointerReceiver(uuid).Get(), &type) == BT_ERROR_NONE, + VerifyOrReturn(__GetAttInfo(gattHandle, &uuid.GetReceiver(), &type) == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from GATT handle")); ChipLogProgress(DeviceLayer, "Gatt write requested on %s: uuid=%s len=%d", __ConvertAttTypeToStr(type), StringOrNullMarker(uuid.get()), len); @@ -268,7 +268,7 @@ void BLEManagerImpl::NotificationStateChangedCb(bool notify, bt_gatt_server_h se VerifyOrReturn(conn != nullptr, ChipLogError(DeviceLayer, "Failed to find connection info")); - int ret = __GetAttInfo(charHandle, &MakeUniquePointerReceiver(uuid).Get(), &type); + int ret = __GetAttInfo(charHandle, &uuid.GetReceiver(), &type); VerifyOrReturn(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from CHAR handle: %s", get_error_message(ret))); @@ -776,7 +776,7 @@ static bool __GattClientForeachCharCb(int total, int index, bt_gatt_h charHandle GAutoPtr uuid; auto conn = static_cast(data); - int ret = __GetAttInfo(charHandle, &MakeUniquePointerReceiver(uuid).Get(), &type); + int ret = __GetAttInfo(charHandle, &uuid.GetReceiver(), &type); VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from CHAR handle: %s", get_error_message(ret))); @@ -803,7 +803,7 @@ static bool __GattClientForeachServiceCb(int total, int index, bt_gatt_h svcHand auto conn = static_cast(data); ChipLogProgress(DeviceLayer, "__GattClientForeachServiceCb"); - int ret = __GetAttInfo(svcHandle, &MakeUniquePointerReceiver(uuid).Get(), &type); + int ret = __GetAttInfo(svcHandle, &uuid.GetReceiver(), &type); VerifyOrExit(ret == BT_ERROR_NONE, ChipLogError(DeviceLayer, "Failed to fetch GATT Attribute from SVC handle: %s", get_error_message(ret))); diff --git a/src/platform/Tizen/BUILD.gn b/src/platform/Tizen/BUILD.gn index 0d0f329be1bd5e..f2f972635a054d 100644 --- a/src/platform/Tizen/BUILD.gn +++ b/src/platform/Tizen/BUILD.gn @@ -31,6 +31,7 @@ static_library("Tizen") { sources = [ "../DeviceSafeQueue.cpp", "../DeviceSafeQueue.h", + "../GLibTypeDeleter.h", "../SingletonConfigurationManager.cpp", "AppPreference.cpp", "AppPreference.h", diff --git a/src/platform/Tizen/DnssdImpl.cpp b/src/platform/Tizen/DnssdImpl.cpp index 8d383ac48f5d13..cc3e5a1e8f76a6 100644 --- a/src/platform/Tizen/DnssdImpl.cpp +++ b/src/platform/Tizen/DnssdImpl.cpp @@ -181,13 +181,13 @@ void OnBrowse(dnssd_service_state_e state, dnssd_service_h service, void * data) chip::GAutoPtr ifaceName; uint32_t interfaceId = 0; - ret = dnssd_service_get_type(service, &MakeUniquePointerReceiver(type).Get()); + ret = dnssd_service_get_type(service, &type.GetReceiver()); VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_type() failed: %s", get_error_message(ret))); - ret = dnssd_service_get_name(service, &MakeUniquePointerReceiver(name).Get()); + ret = dnssd_service_get_name(service, &name.GetReceiver()); VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_name() failed: %s", get_error_message(ret))); - ret = dnssd_service_get_interface(service, &MakeUniquePointerReceiver(ifaceName).Get()); + ret = dnssd_service_get_interface(service, &ifaceName.GetReceiver()); VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_interface() failed: %s", get_error_message(ret))); @@ -305,12 +305,12 @@ void OnResolve(dnssd_error_e result, dnssd_service_h service, void * userData) chip::Inet::IPAddress ipAddr; CHIP_ERROR err = CHIP_NO_ERROR; - int ret = dnssd_service_get_name(service, &MakeUniquePointerReceiver(name).Get()); + int ret = dnssd_service_get_name(service, &name.GetReceiver()); VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_name() failed: %s", get_error_message(ret))); chip::Platform::CopyString(rCtx->mResult.mName, name.get()); - ret = dnssd_service_get_ip(service, &MakeUniquePointerReceiver(ipv4).Get(), &MakeUniquePointerReceiver(ipv6).Get()); + ret = dnssd_service_get_ip(service, &ipv4.GetReceiver(), &ipv6.GetReceiver()); VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_ip() failed: %s", get_error_message(ret))); // If both IPv4 and IPv6 are set, IPv6 address has higher priority. diff --git a/src/platform/Tizen/ThreadStackManagerImpl.cpp b/src/platform/Tizen/ThreadStackManagerImpl.cpp index 47a4548507e332..e6252d92926190 100644 --- a/src/platform/Tizen/ThreadStackManagerImpl.cpp +++ b/src/platform/Tizen/ThreadStackManagerImpl.cpp @@ -646,6 +646,16 @@ CHIP_ERROR ThreadStackManagerImpl::_RemoveInvalidSrpServices() return CHIP_NO_ERROR; } +CHIP_ERROR ThreadStackManagerImpl::_ClearAllSrpHostAndServices() +{ + for (auto it = mSrpClientServices.begin(); it != mSrpClientServices.end();) + { + ReturnErrorOnFailure(_RemoveSrpService(it->mInstanceName, it->mName)); + it = mSrpClientServices.erase(it); + } + return CHIP_NO_ERROR; +} + void ThreadStackManagerImpl::_ThreadIpAddressCb(int index, char * ipAddr, thread_ipaddr_type_e ipAddrType, void * userData) { VerifyOrReturn(ipAddr != nullptr, ChipLogError(DeviceLayer, "FAIL: Invalid argument: Thread ipAddr not found")); diff --git a/src/platform/Tizen/ThreadStackManagerImpl.h b/src/platform/Tizen/ThreadStackManagerImpl.h index 05b300f574114b..07092f43b320eb 100644 --- a/src/platform/Tizen/ThreadStackManagerImpl.h +++ b/src/platform/Tizen/ThreadStackManagerImpl.h @@ -57,6 +57,11 @@ class ThreadStackManagerImpl : public ThreadStackManager bool _TryLockThreadStack() { return false; } // Intentionally left blank void _UnlockThreadStack() {} // Intentionally left blank +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete() {} + void _NotifySrpClearAllComplete() {} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + bool _HaveRouteToAddress(const Inet::IPAddress & destAddr); void _OnPlatformEvent(const ChipDeviceEvent * event); @@ -115,6 +120,7 @@ class ThreadStackManagerImpl : public ThreadStackManager CHIP_ERROR _RemoveSrpService(const char * aInstanceName, const char * aName); CHIP_ERROR _InvalidateAllSrpServices(); CHIP_ERROR _RemoveInvalidSrpServices(); + CHIP_ERROR _ClearAllSrpHostAndServices(); CHIP_ERROR _SetupSrpHost(const char * aHostName); CHIP_ERROR _ClearSrpHost(const char * aHostName); CHIP_ERROR _SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback, DnsAsyncReturnCallback aErrorCallback, void * aContext); diff --git a/src/platform/Tizen/WiFiManager.cpp b/src/platform/Tizen/WiFiManager.cpp index ed43377e5e0142..50e8b9206401d7 100644 --- a/src/platform/Tizen/WiFiManager.cpp +++ b/src/platform/Tizen/WiFiManager.cpp @@ -400,14 +400,14 @@ bool WiFiManager::_FoundAPOnScanCb(wifi_manager_ap_h ap, void * userData) wifi_manager_security_type_e type; WiFiScanResponse scannedAP; - wifiErr = wifi_manager_ap_get_essid(ap, &MakeUniquePointerReceiver(essid).Get()); + wifiErr = wifi_manager_ap_get_essid(ap, &essid.GetReceiver()); VerifyOrExit(wifiErr == WIFI_MANAGER_ERROR_NONE, ChipLogError(DeviceLayer, "FAIL: get AP essid [%s]", get_error_message(wifiErr))); ChipLogProgress(DeviceLayer, "Essid Found: %s\n", essid.get()); scannedAP.ssidLen = static_cast(std::min(strlen(essid.get()), sizeof(scannedAP.ssid))); memcpy(scannedAP.ssid, essid.get(), scannedAP.ssidLen); - wifiErr = wifi_manager_ap_get_bssid(ap, &MakeUniquePointerReceiver(bssid).Get()); + wifiErr = wifi_manager_ap_get_bssid(ap, &bssid.GetReceiver()); VerifyOrExit(wifiErr == WIFI_MANAGER_ERROR_NONE, ChipLogError(DeviceLayer, "Fail: get AP bssid [%s]", get_error_message(wifiErr))); memcpy(scannedAP.bssid, bssid.get(), std::min(strlen(bssid.get()), sizeof(scannedAP.bssid))); @@ -443,7 +443,7 @@ bool WiFiManager::_FoundAPCb(wifi_manager_ap_h ap, void * userData) bool isPassphraseRequired = false; auto clonedAp = reinterpret_cast(userData); - wifiErr = wifi_manager_ap_get_essid(ap, &MakeUniquePointerReceiver(essid).Get()); + wifiErr = wifi_manager_ap_get_essid(ap, &essid.GetReceiver()); VerifyOrExit(wifiErr == WIFI_MANAGER_ERROR_NONE, ChipLogError(DeviceLayer, "FAIL: get AP essid [%s]", get_error_message(wifiErr))); @@ -503,7 +503,7 @@ bool WiFiManager::_ConfigListCb(const wifi_manager_config_h config, void * userD GAutoPtr name; wifi_manager_security_type_e securityType = WIFI_MANAGER_SECURITY_TYPE_NONE; - wifi_manager_config_get_name(config, &MakeUniquePointerReceiver(name).Get()); + wifi_manager_config_get_name(config, &name.GetReceiver()); wifi_manager_config_get_security_type(config, &securityType); wifiErr = wifi_manager_config_remove(sInstance.mWiFiManagerHandle, config); @@ -1155,7 +1155,7 @@ CHIP_ERROR WiFiManager::GetConfiguredNetwork(NetworkCommissioning::Network & net return CHIP_ERROR_INCORRECT_STATE; } GAutoPtr essid; - int wifiErr = wifi_manager_ap_get_essid(connectedAp, &MakeUniquePointerReceiver(essid).Get()); + int wifiErr = wifi_manager_ap_get_essid(connectedAp, &essid.GetReceiver()); VerifyOrReturnError(wifiErr == WIFI_MANAGER_ERROR_NONE, CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "FAIL: get essid [%s]", get_error_message(wifiErr))); network.networkIDLen = static_cast(std::min(strlen(essid.get()), sizeof(network.networkID))); diff --git a/src/platform/Zephyr/ThreadStackManagerImpl.cpp b/src/platform/Zephyr/ThreadStackManagerImpl.cpp index 3cfcfe3b7888b2..95bdfc8ea7044a 100644 --- a/src/platform/Zephyr/ThreadStackManagerImpl.cpp +++ b/src/platform/Zephyr/ThreadStackManagerImpl.cpp @@ -66,6 +66,10 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() return MapOpenThreadError(otError); }); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + k_sem_init(&mSrpClearAllSemaphore, 0, 1); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + return CHIP_NO_ERROR; } @@ -85,5 +89,17 @@ void ThreadStackManagerImpl::_UnlockThreadStack() openthread_api_mutex_unlock(openthread_get_default_context()); } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete() +{ + k_sem_take(&mSrpClearAllSemaphore, K_SECONDS(2)); +} + +void ThreadStackManagerImpl::_NotifySrpClearAllComplete() +{ + k_sem_give(&mSrpClearAllSemaphore); +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Zephyr/ThreadStackManagerImpl.h b/src/platform/Zephyr/ThreadStackManagerImpl.h index c0c66b492c6b1d..ec9feb8b121d3e 100644 --- a/src/platform/Zephyr/ThreadStackManagerImpl.h +++ b/src/platform/Zephyr/ThreadStackManagerImpl.h @@ -71,6 +71,10 @@ class ThreadStackManagerImpl final : public ThreadStackManager, bool _TryLockThreadStack(); void _UnlockThreadStack(); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT // ===== Methods that override the GenericThreadStackManagerImpl_OpenThread abstract interface. void _ProcessThreadActivity() {} @@ -83,6 +87,10 @@ class ThreadStackManagerImpl final : public ThreadStackManager, friend ThreadStackManager & ::chip::DeviceLayer::ThreadStackMgr(void); friend ThreadStackManagerImpl & ::chip::DeviceLayer::ThreadStackMgrImpl(void); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + k_sem mSrpClearAllSemaphore; +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + static ThreadStackManagerImpl sInstance; // ===== Private members for use by this class only. diff --git a/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h b/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h index 830024033fc0e7..8ae71ce32aeae2 100644 --- a/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h +++ b/src/platform/nxp/k32w/k32w0/CHIPPlatformConfig.h @@ -80,11 +80,11 @@ #if NXP_ICD_ENABLED #ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC -#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_INTERVAL +#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_DURATION_SEC #endif // CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC #ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS -#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_INTERVAL +#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_DURATION_MS #endif // CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS #ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS diff --git a/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h b/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h index cacc28dd4a60d6..9d43598ca3583f 100644 --- a/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h +++ b/src/platform/nxp/k32w/k32w1/CHIPPlatformConfig.h @@ -80,11 +80,11 @@ #if NXP_ICD_ENABLED #ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC -#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_INTERVAL +#define CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC NXP_IDLE_MODE_DURATION_SEC #endif // CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC #ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS -#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_INTERVAL +#define CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS NXP_ACTIVE_MODE_DURATION_MS #endif // CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS #ifndef CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS diff --git a/src/platform/silabs/ConfigurationManagerImpl.cpp b/src/platform/silabs/ConfigurationManagerImpl.cpp index a3e1778c11ac3f..8412075de3a914 100644 --- a/src/platform/silabs/ConfigurationManagerImpl.cpp +++ b/src/platform/silabs/ConfigurationManagerImpl.cpp @@ -272,7 +272,7 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - ThreadStackMgrImpl().RemoveAllSrpServices(); + ThreadStackMgr().ClearAllSrpHostAndServices(); #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT ChipLogProgress(DeviceLayer, "Clearing Thread provision"); ThreadStackMgr().ErasePersistentInfo(); diff --git a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp index c1a1a7de4c0ed1..214b0974668fbb 100644 --- a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp +++ b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp @@ -368,7 +368,11 @@ void ConnectivityManagerImpl::OnStationConnected() (void) PlatformMgr().PostEvent(&event); // Setting the rs911x in the power save mode #if (CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI) +#if SLI_SI917 + sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); +#else sl_status_t err = wfx_power_save(); +#endif /* SLI_SI917 */ if (err != SL_STATUS_OK) { ChipLogError(DeviceLayer, "Power save config for Wifi failed"); diff --git a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp index b4755995e36b01..7e581135fde8bd 100644 --- a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp @@ -20,8 +20,8 @@ #include #include +#include "wfx_host_events.h" #include - #ifdef __cplusplus extern "C" { #endif @@ -35,8 +35,7 @@ extern "C" { #define RPS_HEADER 1 #define RPS_DATA 2 -/// No error, operation OK -#define SL_BOOTLOADER_OK 0L + #define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND uint8_t flag = RPS_HEADER; @@ -124,7 +123,7 @@ CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) { - int32_t err = SL_BOOTLOADER_OK; + int32_t status = SL_STATUS_OK; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) @@ -148,15 +147,21 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) imageProcessor->mHeaderParser.Init(); - // Not calling bootloader_eraseStorageSlot(mSlotId) here because we erase during each write + // Setting the device is in high performace - no-sleepy mode while OTA tranfer +#if (CHIP_CONFIG_ENABLE_ICD_SERVER) + status = wfx_power_save(RSI_ACTIVE, HIGH_PERFORMANCE); + if (status != SL_STATUS_OK) + { + ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); + } +#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); } void OTAImageProcessorImpl::HandleFinalize(intptr_t context) { - uint32_t err = SL_BOOTLOADER_OK; - int32_t status = 0; + int32_t status = SL_STATUS_OK; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) { @@ -177,7 +182,7 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) } else { - ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status); + ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk sl_si91x_fwup_load() error %ld", status); imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); return; } @@ -185,12 +190,21 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) } imageProcessor->ReleaseBlock(); + // Setting the device back to power save mode when transfer is completed successfully +#if (CHIP_CONFIG_ENABLE_ICD_SERVER) + sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); + if (err != SL_STATUS_OK) + { + ChipLogError(DeviceLayer, "Power save config for Wifi failed"); + } +#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ + ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully"); } void OTAImageProcessorImpl::HandleApply(intptr_t context) { - uint32_t err = SL_BOOTLOADER_OK; + int32_t status = SL_STATUS_OK; ChipLogProgress(SoftwareUpdate, "OTAImageProcessorImpl::HandleApply()"); @@ -199,6 +213,15 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleApply"); + // Setting the device is in high performace - no-sleepy mode before soft reset as soft reset is not happening in sleep mode +#if (CHIP_CONFIG_ENABLE_ICD_SERVER) + status = wfx_power_save(RSI_ACTIVE, HIGH_PERFORMANCE); + if (status != SL_STATUS_OK) + { + ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); + } +#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ + if (mReset) { ChipLogProgress(SoftwareUpdate, "M4 Firmware update complete"); @@ -217,14 +240,22 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) return; } + // Setting the device back to power save mode when transfer is aborted in the middle +#if (CHIP_CONFIG_ENABLE_ICD_SERVER) + sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); + if (err != SL_STATUS_OK) + { + ChipLogError(DeviceLayer, "Power save config for Wifi failed"); + } +#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ + // Not clearing the image storage area as it is done during each write imageProcessor->ReleaseBlock(); } void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) { - uint32_t err = SL_BOOTLOADER_OK; - int32_t status = 0; + int32_t status = SL_STATUS_OK; int32_t content_block = 0; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) @@ -280,7 +311,7 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) } else { - ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status); + ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock sl_si91x_fwup_load() error %ld", status); imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); return; } diff --git a/src/platform/silabs/SiWx917/wifi/wfx_host_events.h b/src/platform/silabs/SiWx917/wifi/wfx_host_events.h index e153a12c0461ae..455563e1899bb8 100644 --- a/src/platform/silabs/SiWx917/wifi/wfx_host_events.h +++ b/src/platform/silabs/SiWx917/wifi/wfx_host_events.h @@ -32,6 +32,9 @@ #include "sl_status.h" +#include "rsi_common_apis.h" +#include "sl_wifi_device.h" + #define SL_WIFI_ALLOCATE_COMMAND_BUFFER_WAIT_TIME_MS 1000 /* Wi-Fi events*/ #define SL_WFX_STARTUP_IND_ID (1) @@ -246,7 +249,8 @@ sl_status_t sl_si91x_host_process_data_frame(sl_wifi_interface_t interface, sl_w void * sl_si91x_host_get_buffer_data(sl_wifi_buffer_t * buffer, uint16_t offset, uint16_t * data_length); #if SL_ICD_ENABLED -sl_status_t wfx_power_save(); +sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); +void sl_button_on_change(uint8_t btn, uint8_t btnAction); #endif /* SL_ICD_ENABLED */ void wfx_ipv6_notify(int got_ip); diff --git a/src/platform/silabs/SiWx917/wifi/wfx_notify.cpp b/src/platform/silabs/SiWx917/wifi/wfx_notify.cpp index 3d0f56cf14f442..ac5e8c304f5dcf 100644 --- a/src/platform/silabs/SiWx917/wifi/wfx_notify.cpp +++ b/src/platform/silabs/SiWx917/wifi/wfx_notify.cpp @@ -31,6 +31,18 @@ #include "wfx_rsi.h" #endif +#if SL_ICD_ENABLED +#ifdef __cplusplus +extern "C" { +#endif +#include "sl_si91x_m4_ps.h" +extern "C" uint8_t m4_alarm_initialization_done; +extern "C" void set_alarm_interrupt_timer(uint16_t interval); +#ifdef __cplusplus +} +#endif +#endif // SL_ICD_ENABLED + #include // #include #include @@ -191,6 +203,12 @@ void wfx_ip_changed_notify(int got_ip) ********************************************************************************************/ void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin) { +#if SL_ICD_ENABLED + if (m4_alarm_initialization_done == false) + { + initialize_m4_alarm(); + } +#endif // SL_ICD_ENABLED if (!is_wifi_disconnection_event) { /* After the reboot or a commissioning time device failed to connect with AP. @@ -199,7 +217,22 @@ void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retry if (retryJoin < MAX_JOIN_RETRIES_COUNT) { SILABS_LOG("wfx_retry_interval_handler : Next attempt after %d Seconds", CONVERT_MS_TO_SEC(WLAN_RETRY_TIMER_MS)); +#if SL_ICD_ENABLED + // TODO: cleanup the retry logic MATTER-1921 + if (!chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen()) + { + set_alarm_interrupt_timer(WLAN_RETRY_TIMER_MS / 1000); + wfx_rsi_power_save(RSI_SLEEP_MODE_8, STANDBY_POWER_SAVE_WITH_RAM_RETENTION); + // TODO: remove this once TICKLESS_IDLE is applied. MATTER-3134 + sl_wfx_host_si91x_sleep_wakeup(); + } + else + { + vTaskDelay(pdMS_TO_TICKS(WLAN_RETRY_TIMER_MS)); + } +#else vTaskDelay(pdMS_TO_TICKS(WLAN_RETRY_TIMER_MS)); +#endif // SL_ICD_ENABLED } else { @@ -218,7 +251,14 @@ void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retry retryInterval = WLAN_MAX_RETRY_TIMER_MS; } SILABS_LOG("wfx_retry_interval_handler : Next attempt after %d Seconds", CONVERT_MS_TO_SEC(retryInterval)); +#if SL_ICD_ENABLED + set_alarm_interrupt_timer(retryInterval / 1000); + wfx_rsi_power_save(RSI_SLEEP_MODE_8, STANDBY_POWER_SAVE_WITH_RAM_RETENTION); + // TODO: remove this once TICKLESS_IDLE is applied. MATTER-3134 + sl_wfx_host_si91x_sleep_wakeup(); +#else vTaskDelay(pdMS_TO_TICKS(retryInterval)); +#endif // SL_ICD_ENABLED retryInterval += retryInterval; } } diff --git a/src/platform/silabs/ThreadStackManagerImpl.h b/src/platform/silabs/ThreadStackManagerImpl.h index b1436b3b75b27e..c56990fb0d3712 100644 --- a/src/platform/silabs/ThreadStackManagerImpl.h +++ b/src/platform/silabs/ThreadStackManagerImpl.h @@ -72,19 +72,11 @@ class ThreadStackManagerImpl final : public ThreadStackManager, using ThreadStackManager::InitThreadStack; CHIP_ERROR InitThreadStack(otInstance * otInst); -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - void RemoveAllSrpServices(); -#endif private: // ===== Methods that implement the ThreadStackManager abstract interface. CHIP_ERROR _InitThreadStack(void); -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - static void OnSrpClientRemoveCallback(otError aError, const otSrpClientHostInfo * aHostInfo, - const otSrpClientService * aServices, const otSrpClientService * aRemovedServices, - void * aContext); -#endif // ===== Members for internal use by the following friends. friend ThreadStackManager & ::chip::DeviceLayer::ThreadStackMgr(void); @@ -94,9 +86,6 @@ class ThreadStackManagerImpl final : public ThreadStackManager, static ThreadStackManagerImpl sInstance; static bool IsInitialized(); -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - TaskHandle_t srpRemoveRequester = nullptr; -#endif // ===== Private members for use by this class only. diff --git a/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp b/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp index c4556036034e78..83767f9a0e1fb8 100644 --- a/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp +++ b/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp @@ -66,58 +66,6 @@ bool ThreadStackManagerImpl::IsInitialized() return sInstance.mThreadStackLock != NULL; } -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT -/* - * @brief Notifies `RemoveAllSrpServices` that the Srp Client removal has completed - * and unblock the calling task. - * - * No data is processed. - */ -void ThreadStackManagerImpl::OnSrpClientRemoveCallback(otError aError, const otSrpClientHostInfo * aHostInfo, - const otSrpClientService * aServices, - const otSrpClientService * aRemovedServices, void * aContext) -{ - if (ThreadStackMgrImpl().srpRemoveRequester) - { - xTaskNotifyGive(ThreadStackMgrImpl().srpRemoveRequester); - } -} - -/* - * @brief This is a utility function to remove all Thread client Srp services - * established between the device and the srp server (in most cases the OTBR). - * The calling task is blocked until OnSrpClientRemoveCallback. - * - * Note: This function is meant to be used during the factory reset sequence. - * It overrides the generic SrpClient callback `OnSrpClientNotification` with - * OnSrpClientRemoveCallback which doesn't process any of the callback data. - * - * If there is a usecase where this function would be needed in a non-Factory reset context, - * OnSrpClientRemoveCallback should be extended and tied back with the GenericThreadStackManagerImpl_OpenThread - * management of the srp clients. - */ -void ThreadStackManagerImpl::RemoveAllSrpServices() -{ - // This check ensure that only one srp services removal is running - if (ThreadStackMgrImpl().srpRemoveRequester == nullptr) - { - srpRemoveRequester = xTaskGetCurrentTaskHandle(); - otSrpClientSetCallback(OTInstance(), &OnSrpClientRemoveCallback, nullptr); - InvalidateAllSrpServices(); - if (RemoveInvalidSrpServices() == CHIP_NO_ERROR) - { - // Wait for the OnSrpClientRemoveCallback. - ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(2000)); - } - else - { - ChipLogError(DeviceLayer, "Failed to remove srp services"); - } - ThreadStackMgrImpl().srpRemoveRequester = nullptr; - } -} -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/efr32/wifi/wfx_host_events.h b/src/platform/silabs/efr32/wifi/wfx_host_events.h index 4070cf4ea93700..c9f451f8ac063a 100644 --- a/src/platform/silabs/efr32/wifi/wfx_host_events.h +++ b/src/platform/silabs/efr32/wifi/wfx_host_events.h @@ -103,6 +103,9 @@ typedef struct __attribute__((__packed__)) sl_wfx_mib_req_s #include "sl_status.h" #include "sl_wifi_constants.h" +#include "rsi_common_apis.h" +#include "sl_wifi_device.h" + #define SL_WIFI_ALLOCATE_COMMAND_BUFFER_WAIT_TIME_MS 1000 #endif @@ -365,7 +368,11 @@ void * wfx_rsi_alloc_pkt(void); #ifdef RS911X_WIFI /* RSI Power Save */ #if SL_ICD_ENABLED +#if SLI_SI917 +sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); +#else sl_status_t wfx_power_save(); +#endif /* SLI_SI917 */ #endif /* SL_ICD_ENABLED */ /* RSI for LWIP */ void wfx_rsi_pkt_add_data(void * p, uint8_t * buf, uint16_t len, uint16_t off); diff --git a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp index dda1b7e0e19dac..5527fbfe90d73d 100644 --- a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp +++ b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp @@ -49,7 +49,7 @@ extern "C" { #include "uart.h" #endif -#if SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT +#ifdef SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT #include "SEGGER_SYSVIEW.h" #endif } @@ -78,7 +78,7 @@ CHIP_ERROR SilabsPlatform::Init(void) sl_ot_sys_init(); #endif -#if SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT +#ifdef SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT SEGGER_SYSVIEW_Conf(); SEGGER_SYSVIEW_Start(); #endif diff --git a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp index 1015d959ee0825..f57b73f0499d41 100644 --- a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp +++ b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp @@ -55,8 +55,10 @@ CHIP_ERROR SilabsPlatform::Init(void) // TODO: Setting the highest priority for SVCall_IRQn to avoid the HardFault issue NVIC_SetPriority(SVCall_IRQn, CORE_INTERRUPT_HIGHEST_PRIORITY); +#if !CHIP_CONFIG_ENABLE_ICD_SERVER // Configuration the clock rate soc_pll_config(); +#endif #if SILABS_LOG_ENABLED silabsInitLog(); diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp index e66735b1de68f2..13ba8be424563b 100644 --- a/src/platform/telink/ThreadStackManagerImpl.cpp +++ b/src/platform/telink/ThreadStackManagerImpl.cpp @@ -68,6 +68,10 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() return MapOpenThreadError(otError); }); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + k_sem_init(&mSrpClearAllSemaphore, 0, 1); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + return CHIP_NO_ERROR; } @@ -87,6 +91,18 @@ void ThreadStackManagerImpl::_UnlockThreadStack() openthread_api_mutex_unlock(openthread_get_default_context()); } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete() +{ + k_sem_take(&mSrpClearAllSemaphore, K_SECONDS(2)); +} + +void ThreadStackManagerImpl::_NotifySrpClearAllComplete() +{ + k_sem_give(&mSrpClearAllSemaphore); +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + CHIP_ERROR ThreadStackManagerImpl::_AttachToThreadNetwork(const Thread::OperationalDataset & dataset, NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * callback) diff --git a/src/platform/telink/ThreadStackManagerImpl.h b/src/platform/telink/ThreadStackManagerImpl.h index d1040542f3c616..21db9972f62dec 100644 --- a/src/platform/telink/ThreadStackManagerImpl.h +++ b/src/platform/telink/ThreadStackManagerImpl.h @@ -74,6 +74,10 @@ class ThreadStackManagerImpl final : public ThreadStackManager, bool _TryLockThreadStack(); void _UnlockThreadStack(); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT // ===== Methods that override the GenericThreadStackManagerImpl_OpenThread abstract interface. void _ProcessThreadActivity() {} @@ -95,6 +99,10 @@ class ThreadStackManagerImpl final : public ThreadStackManager, bool mRadioBlocked; bool mReadyToAttach; +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + k_sem mSrpClearAllSemaphore; +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + NetworkCommissioning::ThreadDriver::ScanCallback * mpScanCallback; }; diff --git a/src/platform/webos/ThreadStackManagerImpl.h b/src/platform/webos/ThreadStackManagerImpl.h index 876c339cceb6ae..a21d4cbf551251 100644 --- a/src/platform/webos/ThreadStackManagerImpl.h +++ b/src/platform/webos/ThreadStackManagerImpl.h @@ -50,6 +50,11 @@ class ThreadStackManagerImpl : public ThreadStackManager bool _TryLockThreadStack() { return false; } // Intentionally left blank void _UnlockThreadStack() {} // Intentionally left blank +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete() {} + void _NotifySrpClearAllComplete() {} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + bool _HaveRouteToAddress(const Inet::IPAddress & destAddr); void _OnPlatformEvent(const ChipDeviceEvent * event); diff --git a/src/protocols/interaction_model/StatusCodeList.h b/src/protocols/interaction_model/StatusCodeList.h index 3b79e4a698b7b5..5538478d76ce52 100644 --- a/src/protocols/interaction_model/StatusCodeList.h +++ b/src/protocols/interaction_model/StatusCodeList.h @@ -22,7 +22,10 @@ * include this file, then undefine the macro. */ -/// WARNING: If you touch this list, please also update src/controller/python/chip/interaction_model/__init__.py +/// WARNING: If you touch this list, +/// please update src/controller/python/chip/interaction_model/__init__.py +/// please update src/controller/java/src/chip/devicecontroller/model/Status.java +/// please update src/controller/java/src/matter/controller/model/Status.kt // clang-format off CHIP_IM_STATUS_CODE(Success , SUCCESS , 0x0) diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py new file mode 100644 index 00000000000000..bd839cd5f072f4 --- /dev/null +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -0,0 +1,69 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_PWRTL_2_1(MatterBaseTest): + + def pics_TC_PWRTL_2_1(self) -> list[str]: + return ["PWRTL.S"] + + @async_test_body + async def test_TC_PWRTL_2_1(self): + + attributes = Clusters.PowerTopology.Attributes + + endpoint = self.user_params.get("endpoint", 1) + + self.print_step(1, "Commissioning, already done") + + if not self.check_pics("PWRTL.S.A0000"): + logging.info("Test skipped because PICS PWRTL.S.A0000 is not set") + return + + self.print_step(2, "Read AvailableAttributes attribute") + available_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.AvailableEndpoints) + + if available_endpoints == NullValue: + logging.info("AvailableEndpoints is null") + else: + logging.info("AvailableEndpoints: %s" % (available_endpoints)) + + asserts.assert_less_equal(len(available_endpoints), 21, + "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) + + if not self.check_pics("PWRTL.S.A0001"): + logging.info("Test skipped because PICS PWRTL.S.A0001 is not set") + return + + self.print_step(3, "Read ActiveEndpoints attribute") + active_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.ActiveEndpoints) + logging.info("ActiveEndpoints: %s" % (active_endpoints)) + + if available_endpoints == NullValue: + asserts.assert_true(active_endpoints == NullValue, + "ActiveEndpoints should be null when AvailableEndpoints is null: %s" % active_endpoints) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_RVCCLEANM_2_1.py b/src/python_testing/TC_RVCCLEANM_2_1.py index d000f0d5af697d..6ef91d89a06729 100644 --- a/src/python_testing/TC_RVCCLEANM_2_1.py +++ b/src/python_testing/TC_RVCCLEANM_2_1.py @@ -16,6 +16,7 @@ # import logging +from time import sleep import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches @@ -56,6 +57,9 @@ async def send_run_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcRunM def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests are flaky) + # TODO(#31239): centralize pipe write logic and remove the need of sleep + sleep(0.001) def pics_TC_RVCCLEANM_2_1(self) -> list[str]: return ["RVCCLEANM.S"] diff --git a/src/python_testing/TC_RVCCLEANM_2_2.py b/src/python_testing/TC_RVCCLEANM_2_2.py index ae5c268d7a9668..7e1fa6aaf2667e 100644 --- a/src/python_testing/TC_RVCCLEANM_2_2.py +++ b/src/python_testing/TC_RVCCLEANM_2_2.py @@ -15,6 +15,8 @@ # limitations under the License. # +from time import sleep + import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -70,6 +72,9 @@ def pics_TC_RVCCLEANM_2_2(self) -> list[str]: def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests are flaky) + # TODO(#31239): centralize pipe write logic and remove the need of sleep + sleep(0.001) @async_test_body async def test_TC_RVCCLEANM_2_2(self): diff --git a/src/python_testing/TC_RVCOPSTATE_2_1.py b/src/python_testing/TC_RVCOPSTATE_2_1.py index b0d753ad216164..e9dd4659059fa0 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_1.py +++ b/src/python_testing/TC_RVCOPSTATE_2_1.py @@ -16,6 +16,7 @@ # import logging +from time import sleep import chip.clusters as Clusters from chip.clusters.Types import NullValue @@ -63,6 +64,9 @@ async def send_pause_cmd(self) -> Clusters.Objects.RvcOperationalState.Commands. def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) def TC_RVCOPSTATE_2_1(self) -> list[str]: return ["RVCOPSTATE.S"] diff --git a/src/python_testing/TC_RVCOPSTATE_2_3.py b/src/python_testing/TC_RVCOPSTATE_2_3.py index 4d275ac5adc5b9..aa755315fb7d46 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_3.py +++ b/src/python_testing/TC_RVCOPSTATE_2_3.py @@ -130,6 +130,9 @@ async def send_run_change_to_mode_cmd(self, new_mode) -> Clusters.Objects.RvcRun def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests are flaky) + # TODO(#31239): centralize pipe write logic and remove the need of sleep + sleep(0.001) # Prints the instruction and waits for a user input to continue def print_instruction(self, step_number, instruction): diff --git a/src/python_testing/TC_RVCOPSTATE_2_4.py b/src/python_testing/TC_RVCOPSTATE_2_4.py index 3314eaade876bb..7352fbd089f172 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_4.py +++ b/src/python_testing/TC_RVCOPSTATE_2_4.py @@ -16,6 +16,7 @@ # import logging +from time import sleep import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches @@ -81,6 +82,9 @@ async def send_run_change_to_mode_cmd(self, new_mode): def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests are flaky) + # TODO(#31239): centralize pipe write logic and remove the need of sleep + sleep(0.001) def pics_TC_RVCOPSTATE_2_4(self) -> list[str]: return ["RVCOPSTATE.S"] diff --git a/src/python_testing/TC_RVCRUNM_2_1.py b/src/python_testing/TC_RVCRUNM_2_1.py index a9b4c44ba4f88c..1f3bccb528f137 100644 --- a/src/python_testing/TC_RVCRUNM_2_1.py +++ b/src/python_testing/TC_RVCRUNM_2_1.py @@ -16,6 +16,7 @@ # import logging +from time import sleep import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches @@ -51,6 +52,9 @@ async def send_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcRunMode. def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests are flaky) + # TODO(#31239): centralize pipe write logic and remove the need of sleep + sleep(0.001) def pics_TC_RVCRUNM_2_1(self) -> list[str]: return ["RVCRUNM.S"] diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py index 4868865c367d19..d85d1ae53cb928 100644 --- a/src/python_testing/TC_RVCRUNM_2_2.py +++ b/src/python_testing/TC_RVCRUNM_2_2.py @@ -15,6 +15,8 @@ # limitations under the License. # +from time import sleep + import chip.clusters as Clusters from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -91,6 +93,9 @@ async def read_op_state_operational_state(self) -> Clusters.Objects.RvcOperation def write_to_app_pipe(self, command): with open(self.app_pipe, "w") as app_pipe: app_pipe.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests are flaky) + # TODO(#31239): centralize pipe write logic and remove the need of sleep + sleep(0.001) def pics_TC_RVCRUNM_2_2(self) -> list[str]: return ["RVCRUNM.S"] diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 9b65df0d0dcab5..6a9d1f87ae3442 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -354,6 +354,9 @@ def get_command_type(self, element: ElementTree.Element) -> CommandType: return CommandType.GENERATED if element.attrib['direction'].lower() == 'commandtoclient': return CommandType.UNKNOWN + if element.attrib['direction'].lower() == 'commandtoserver': + return CommandType.ACCEPTED + raise Exception(f"Unknown direction: {element.attrib['direction']}") except KeyError: return CommandType.ACCEPTED diff --git a/third_party/libwebsockets/repo b/third_party/libwebsockets/repo index 49bfef2ecd51b8..b71a6621b0b14b 160000 --- a/third_party/libwebsockets/repo +++ b/third_party/libwebsockets/repo @@ -1 +1 @@ -Subproject commit 49bfef2ecd51b854b63e35d913849b6bb518a7f6 +Subproject commit b71a6621b0b14bfc8fcbe804b036a9543af5e910 diff --git a/third_party/mbedtls/repo b/third_party/mbedtls/repo index ede909f99ab6e6..039c903e7b2882 160000 --- a/third_party/mbedtls/repo +++ b/third_party/mbedtls/repo @@ -1 +1 @@ -Subproject commit ede909f99ab6e6a958a41e365251c2a1d2c4ed4d +Subproject commit 039c903e7b2882af8e85ce5e090fd44e6a9d2289 diff --git a/third_party/nxp/k32w0_sdk/k32w0_sdk.gni b/third_party/nxp/k32w0_sdk/k32w0_sdk.gni index ab37141606f19a..754ac91df80875 100644 --- a/third_party/nxp/k32w0_sdk/k32w0_sdk.gni +++ b/third_party/nxp/k32w0_sdk/k32w0_sdk.gni @@ -49,19 +49,18 @@ declare_args() { ota_custom_entry_address = "0x000C1000" use_antenna_diversity = 0 - #ICD Matter Configuration flags + chip_with_ota_encryption = 0 + chip_with_ota_key = "1234567890ABCDEFA1B2C3D4E5F6F1B4" + chip_with_sdk_package = 1 - chip_ot_idle_interval_ms = 2000 # 2s Idle Intervals - chip_ot_active_interval_ms = 500 # 500ms Active Intervals + # ICD Matter Configuration flags + nxp_ot_idle_interval_ms = 2000 # 2s Idle Intervals + nxp_ot_active_interval_ms = 500 # 500ms Active Intervals - nxp_idle_mode_interval_s = 600 # 10min Idle Mode Interval - nxp_active_mode_interval_ms = 10000 # 10s Active Mode Interval + nxp_idle_mode_duration_s = 600 # 10min Idle Mode Interval + nxp_active_mode_duration_ms = 10000 # 10s Active Mode Interval nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric - - chip_with_ota_encryption = 0 - chip_with_ota_key = "1234567890ABCDEFA1B2C3D4E5F6F1B4" - chip_with_sdk_package = 1 } assert(k32w0_sdk_root != "", "k32w0_sdk_root must be specified") @@ -367,12 +366,12 @@ template("k32w0_sdk") { "gResetSystemReset_d=1", # TODO: move these platform specific defines to args.gni - "NXP_OT_IDLE_INTERVAL=${chip_ot_idle_interval_ms}", - "NXP_OT_ACTIVE_INTERVAL=${chip_ot_active_interval_ms}", + "NXP_OT_IDLE_INTERVAL=${nxp_ot_idle_interval_ms}", + "NXP_OT_ACTIVE_INTERVAL=${nxp_ot_active_interval_ms}", "NXP_ICD_ENABLED=1", "NXP_ACTIVE_MODE_THRESHOLD=${nxp_active_mode_threshold_ms}", - "NXP_ACTIVE_MODE_INTERVAL=${nxp_active_mode_interval_ms}", - "NXP_IDLE_MODE_INTERVAL=${nxp_idle_mode_interval_s}", + "NXP_ACTIVE_MODE_DURATION_MS=${nxp_active_mode_duration_ms}", + "NXP_IDLE_MODE_DURATION_SEC=${nxp_idle_mode_duration_s}", "NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${nxp_icd_supported_clients_per_fabric}", ] diff --git a/third_party/nxp/k32w1_sdk/k32w1_sdk.gni b/third_party/nxp/k32w1_sdk/k32w1_sdk.gni index 7a8bf40afe7a04..d6d9f6146086d7 100644 --- a/third_party/nxp/k32w1_sdk/k32w1_sdk.gni +++ b/third_party/nxp/k32w1_sdk/k32w1_sdk.gni @@ -36,15 +36,6 @@ declare_args() { use_smu2_dynamic = false use_hw_sha256 = false use_hw_aes = false - - # ICD Matter Configuration flags - chip_ot_idle_interval_ms = 2000 # 2s Idle Intervals - chip_ot_active_interval_ms = 500 # 500ms Active Intervals - - nxp_idle_mode_interval_s = 600 # 10min Idle Mode Interval - nxp_active_mode_interval_ms = 10000 # 10s Active Mode Interval - nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold - nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric } openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" @@ -270,12 +261,12 @@ template("k32w1_sdk") { "gConnectPowerLeveldBm_c=0", #move these platform specific defines to args.gni - "NXP_OT_IDLE_INTERVAL=${chip_ot_idle_interval_ms}", - "NXP_OT_ACTIVE_INTERVAL=${chip_ot_active_interval_ms}", + "NXP_OT_IDLE_INTERVAL=${nxp_ot_idle_interval_ms}", + "NXP_OT_ACTIVE_INTERVAL=${nxp_ot_active_interval_ms}", "NXP_ICD_ENABLED=1", "NXP_ACTIVE_MODE_THRESHOLD=${nxp_active_mode_threshold_ms}", - "NXP_ACTIVE_MODE_INTERVAL=${nxp_active_mode_interval_ms}", - "NXP_IDLE_MODE_INTERVAL=${nxp_idle_mode_interval_s}", + "NXP_ACTIVE_MODE_DURATION_MS=${nxp_active_mode_duration_ms}", + "NXP_IDLE_MODE_DURATION_SEC=${nxp_idle_mode_duration_s}", "NXP_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${nxp_icd_supported_clients_per_fabric}", ] @@ -358,6 +349,15 @@ template("k32w1_sdk") { defines += [ "USE_HW_AES" ] } + if (nxp_software_version != "") { + defines += + [ "NXP_CONFIG_DEVICE_SOFTWARE_VERSION=${nxp_software_version}" ] + } + + if (nxp_software_version_string != "") { + defines += [ "NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING=\"${nxp_software_version_string}\"" ] + } + if (defined(invoker.defines)) { defines += invoker.defines } diff --git a/third_party/nxp/nxp_sdk.gni b/third_party/nxp/nxp_sdk.gni index d87d99d2911ae2..da66a0d51c5721 100644 --- a/third_party/nxp/nxp_sdk.gni +++ b/third_party/nxp/nxp_sdk.gni @@ -45,7 +45,16 @@ declare_args() { nxp_software_version = 1 # Defines the current software string version - nxp_software_version_string = "1.1" + nxp_software_version_string = "1.3" + + # ICD Matter Configuration flags + nxp_ot_idle_interval_ms = 2000 # 2s Idle Intervals + nxp_ot_active_interval_ms = 500 # 500ms Active Intervals + + nxp_idle_mode_duration_s = 600 # 10min Idle Mode Interval + nxp_active_mode_duration_ms = 10000 # 10s Active Mode Interval + nxp_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold + nxp_icd_supported_clients_per_fabric = 2 # 2 registration slots per fabric } declare_args() { diff --git a/third_party/openthread/repo b/third_party/openthread/repo index b212a0a748070c..33574ad4175ffb 160000 --- a/third_party/openthread/repo +++ b/third_party/openthread/repo @@ -1 +1 @@ -Subproject commit b212a0a748070ccbda765c3ebed2aab8b6b08fce +Subproject commit 33574ad4175ffb088bcca047f4c8d5fb240d1495 diff --git a/third_party/ot-br-posix/repo b/third_party/ot-br-posix/repo index c5a7a35e3bd2f3..9bdaa9101663c2 160000 --- a/third_party/ot-br-posix/repo +++ b/third_party/ot-br-posix/repo @@ -1 +1 @@ -Subproject commit c5a7a35e3bd2f3da8cce1e2e2a3bbe5cdeedb729 +Subproject commit 9bdaa9101663c2ce9016fb5e2b5010442b17ca26 diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 9868b47efb8a8d..8510295bf7c2e0 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -401,7 +401,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/segger/systemview/profiles/freertos_v10/", ] - defines += [ "SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT=1" ] + defines += [ "SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT" ] } defines += board_defines