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 e1dace194762d8..aa4e2f6e5ad2ba 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
@@ -3041,6 +3041,7 @@ cluster RvcRunMode = 84 {
enum ModeTag : enum16 {
kIdle = 16384;
kCleaning = 16385;
+ kMapping = 16386;
}
enum StatusCode : enum8 {
diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter
index fb79f75aa6244a..cea46e31fad3fc 100644
--- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter
+++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter
@@ -1005,6 +1005,7 @@ cluster RvcRunMode = 84 {
enum ModeTag : enum16 {
kIdle = 16384;
kCleaning = 16385;
+ kMapping = 16386;
}
enum StatusCode : enum8 {
diff --git a/examples/platform/qpg/project_include/OpenThreadConfig.h b/examples/platform/qpg/project_include/OpenThreadConfig.h
index 585d10f3d0ea3d..d6955a90a55734 100644
--- a/examples/platform/qpg/project_include/OpenThreadConfig.h
+++ b/examples/platform/qpg/project_include/OpenThreadConfig.h
@@ -74,7 +74,7 @@
#define OPENTHREAD_CONFIG_TCP_ENABLE 0
#define OPENTHREAD_CONFIG_BLE_TCAT_ENABLE 0
#define OPENTHREAD_CONFIG_TLS_ENABLE 0
-#define OPENTHREAD_CONFIG_DTLS_ENABLE 0
+#define OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE 0
#define OPENTHREAD_ENABLE_VENDOR_EXTENSION 0
#define OPENTHREAD_EXAMPLES_SIMULATION 0
diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter
index 682b5ef6f5dd54..6db104d8eac315 100644
--- a/examples/rvc-app/rvc-common/rvc-app.matter
+++ b/examples/rvc-app/rvc-common/rvc-app.matter
@@ -928,6 +928,7 @@ cluster RvcRunMode = 84 {
enum ModeTag : enum16 {
kIdle = 16384;
kCleaning = 16385;
+ kMapping = 16386;
}
enum StatusCode : enum8 {
diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml
index 7e67a7027b7443..16aad6fe3e8d37 100644
--- a/src/app/tests/suites/certification/PICS.yaml
+++ b/src/app/tests/suites/certification/PICS.yaml
@@ -9421,3 +9421,70 @@ PICS:
- label: "Does the device implement the SensorFault event?"
id: BOOLCFG.S.E01
+
+ #
+ #Valve Configuration and Control
+ #
+ - label:
+ "Does the device implement the Valve Configuration and Control cluster
+ as a server?"
+ id: VALCC.S
+
+ #Features
+ - label:
+ "Does the device support the ability to use UTC time is used for time
+ indications?"
+ id: VALCC.S.F00
+
+ - label:
+ "Does the device support the ability to setting the specific position
+ of the valve?"
+ id: VALCC.S.F01
+
+ #Attributes
+ - label: "Does the device implement the OpenDuration attribute?"
+ id: VALCC.S.A0000
+
+ - label: "Does the device implement the DefaultOpenDuration attribute?"
+ id: VALCC.S.A0001
+
+ - label: "Does the device implement the AutoCloseTime attribute?"
+ id: VALCC.S.A0002
+
+ - label: "Does the device implement the RemainingDuration attribute?"
+ id: VALCC.S.A0003
+
+ - label: "Does the device implement the CurrentState attribute?"
+ id: VALCC.S.A0004
+
+ - label: "Does the device implement the TargetState attribute?"
+ id: VALCC.S.A0005
+
+ - label: "Does the device implement the CurrentLevel attribute?"
+ id: VALCC.S.A0006
+
+ - label: "Does the device implement the TargetLevel attribute?"
+ id: VALCC.S.A0007
+
+ - label: "Does the device implement the DefaultOpenLevel attribute?"
+ id: VALCC.S.A0008
+
+ - label: "Does the device implement the ValveFault attribute?"
+ id: VALCC.S.A0009
+
+ - label: "Does the device implement the LevelStep attribute?"
+ id: VALCC.S.A000a
+
+ #Commands received
+ - label: "Does the device implement receiving the Open command?"
+ id: VALCC.S.C00.Rsp
+
+ - label: "Does the device implement receiving the Close command?"
+ id: VALCC.S.C01.Rsp
+
+ #Events
+ - label: "Does the device implement the ValveStateChanged event?"
+ id: VALCC.S.E00
+
+ - label: "Does the device implement the ValveFault event?"
+ id: VALCC.S.E01
diff --git a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_1.yaml b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_1.yaml
deleted file mode 100644
index 8cfa4e8526774c..00000000000000
--- a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_1.yaml
+++ /dev/null
@@ -1,927 +0,0 @@
-# Copyright (c) 2021 Project CHIP Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default
-
-name:
- 15.2.1. [TC-OPCREDS-3.1] Attribute-NOCs, TrustedRootCertificates list
- validation [DUT-Server]
-
-PICS:
- - OPCREDS.S
-
-config:
- nodeId: 0x12344321
- cluster: "Basic Information"
- endpoint: 0
-
-tests:
- - label: "Pre-Conditions"
- verification: |
- 1. PAI, DAC certificates are obtained and validated against externally obtained PAA certificate
- 2. This test case assumes that during Commissioning AddNOC will be sent with ICACValue
- 3. TH2 is set up with at least one valid CASE Authenticated Tag specified in its NOC, saved as CAT_TH2
- 4. Read SupportedFabrics attributes from the DUT and saves as NumSupportedFabrics . Ensure there are NumSupportedFabrics test harness instances that can each commission the DUT
- disabled: true
-
- - label:
- "Step 1: Factory Reset DUT (to ensure NOC list is empty at the
- beginning of the following steps)"
- PICS: OPCREDS.S.A0000
- verification: |
- On both DUT and TH side
- sudo rm -rf /tmp/chip_*
- disabled: true
-
- - label:
- "Step 2: Start the commissioning process of DUT by TH1 on a first
- Fabric"
- verification: |
- DUT side:
- sudo ./chip-all-clusters-app --wifi --trace_decode 1
-
- TH side:
- ./chip-tool pairing ble-wifi 1 zigbeehome matter123 20202021 3841 --trace_decode 1
-
- [1650455358.501816][4366:4371] CHIP:TOO: Device commissioning completed with success
- disabled: true
-
- - label:
- "Step 3: TH1 sends ArmFailSafe command to the DUT with the
- ExpiryLengthSeconds field set to 900"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
- ./chip-tool generalcommissioning arm-fail-safe 900 600 1 0
-
-
- Verify the ErrorCode as 'OK'(0) in TH log
- [1659676500.031926][2475:2480] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0030 Command=0x0000_0001
- [1659676500.047646][2475:2480] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0030 Command 0x0000_0001
- [1659676500.055459][2475:2480] CHIP:TOO: ArmFailSafeResponse: {
- [1659676500.055613][2475:2480] CHIP:TOO: errorCode: 0
- [1659676500.055669][2475:2480] CHIP:TOO: debugText:
- [1659676500.055719][2475:2480] CHIP:TOO: }
- [1659676500.055806][2475:2480] CHIP:DMG: ICR moving to [AwaitingDe]
- [1659676500.055920][2475:2480] CHIP:EM: Sending Standalone Ack for MessageCounter:225116044 on exchange 37810i
- disabled: true
-
- - label: "Step 4: TH1 sends SetRegulatoryConfig command to the DUT"
- PICS: CGEN.S.C02.Rsp && CGEN.S.C03.Tx
- verification: |
- ./chip-tool generalcommissioning set-regulatory-config 0 new 0 1 0
-
- Verify the ErrorCode as SUCCESS in TH Log
-
- [1658223287.237009][5570:5575] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0030 Command=0x0000_0003
- [1658223287.237060][5570:5575] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0030 Command 0x0000_0003
- [1658223287.237122][5570:5575] CHIP:TOO: SetRegulatoryConfigResponse: {
- [1658223287.237159][5570:5575] CHIP:TOO: errorCode: 0
- [1658223287.237183][5570:5575] CHIP:TOO: debugText:
- [1658223287.237205][5570:5575] CHIP:TOO: }
- disabled: true
-
- - label: "Step 5: TH1 sends AttestationRequest command to DUT"
- PICS: OPCREDS.S.C00.Rsp && OPCREDS.S.C01.Tx
- verification: |
- To get attestation nonce give below command Raspi platform on TH
- echo hex:$(hexdump -vn32 -e'4/4 "%08X" ' /dev/urandom)
-
-
- ./chip-tool operationalcredentials attestation-request hex:3577CA6EFFFC560E287604663AE5BE2F11D1B1CF99BE326AF5B3B114A2E91395 1 0
-
- Verify attestation response in TH Log
-
- [1658223434.718871][5712:5717] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0001
- [1658223434.718921][5712:5717] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0001
- [1658223434.718981][5712:5717] CHIP:TOO: AttestationResponse: {
- [1658223434.719026][5712:5717] CHIP:TOO: attestationElements: 1531011D023082021906092A864886F70D010702A082020A30820206020103310D300B06096086480165030402013082017106092A864886F70D010701A08201620482015E152400012501F1FF3602050080050180050280050380050480050580050680050780050880050980050A80050B80050C80050D80050E80050F80051080051180051280051380051480051580051680051780051880051980051A80051B80051C80051D80051E80051F80052080052180052280052380052480052580052680052780052880052980052A80052B80052C80052D80052E80052F80053080053180053280053380053480053580053680053780053880053980053A80053B80053C80053D80053E80053F80054080054180054280054380054480054580054680054780054880054980054A80054B80054C80054D80054E80054F80055080055180055280055380055480055580055680055780055880055980055A80055B80055C80055D80055E80055F80056080056180056280056380182403162C04135A494732303134325A423333303030332D3234240500240600250794
- [1658223434.719078][5712:5717] CHIP:TOO: ...................: 2624080018317D307B020103801462FA823359ACFAA9963E1CFA140ADDF504F37160300B0609608648016503040201300A06082A8648CE3D04030204473045022024E5D1F47A7D7B0D206A26EF699B7C9757B72D469089DE3192E678C745E7F60C022100F8AA2FA711FCB79B97E397CEDA667BAE464E2BD3FFDFC3CCED7AA8CA5F4C1A7C3002203577CA6EFFFC560E287604663AE5BE2F11D1B1CF99BE326AF5B3B114A2E9139524030018
- [1658223434.719110][5712:5717] CHIP:TOO: signature: 7E18271F57FFC60492CA74943FC897493FB2FECDD4A4DC9F2AD348AAD1F5C57DAEB144A4D1C79419386C746F28AC145F3185C64AD99DD829EE70C3690D29642D
- [1658223434.719135][5712:5717] CHIP:TOO: }
- disabled: true
-
- - label:
- "Step 6: TH1 sends CertificateChainRequest Command to DUT for the PAI
- and saves the certififate as 'PAICert'"
- PICS: OPCREDS.S.C02.Rsp && OPCREDS.S.C03.Tx
- verification: |
- ./chip-tool operationalcredentials certificate-chain-request 2 1 0 --trace_decode 1
-
-
- Verify the CertificateChainResponse and verify that the size of certificate is less than or equal to 600 bytes and of type octstr in TH Log
-
- [1660214092.609231][14671:14676] CHIP:DMG: InvokeRequestMessage =
- [1660214092.609243][14671:14676] CHIP:DMG: {
- [1660214092.609255][14671:14676] CHIP:DMG: suppressResponse = false,
- [1660214092.609269][14671:14676] CHIP:DMG: timedRequest = false,
- [1660214092.609281][14671:14676] CHIP:DMG: InvokeRequests =
- [1660214092.609301][14671:14676] CHIP:DMG: [
- [1660214092.609311][14671:14676] CHIP:DMG: CommandDataIB =
- [1660214092.609326][14671:14676] CHIP:DMG: {
- [1660214092.609338][14671:14676] CHIP:DMG: CommandPathIB =
- [1660214092.609352][14671:14676] CHIP:DMG: {
- [1660214092.609367][14671:14676] CHIP:DMG: EndpointId = 0x0,
- [1660214092.609383][14671:14676] CHIP:DMG: ClusterId = 0x3e,
- [1660214092.609396][14671:14676] CHIP:DMG: CommandId = 0x2,
- [1660214092.609410][14671:14676] CHIP:DMG: },
- [1660214092.609426][14671:14676] CHIP:DMG:
- [1660214092.609437][14671:14676] CHIP:DMG: CommandFields =
- [1660214092.609452][14671:14676] CHIP:DMG: {
- [1660214092.609467][14671:14676] CHIP:DMG: 0x0 = 2,
- [1660214092.609481][14671:14676] CHIP:DMG: },
- [1660214092.609493][14671:14676] CHIP:DMG: },
- [1660214092.609511][14671:14676] CHIP:DMG:
- [1660214092.609522][14671:14676] CHIP:DMG: ],
- [1660214092.609541][14671:14676] CHIP:DMG:
- [1660214092.609551][14671:14676] CHIP:DMG: InteractionModelRevision = 1
- [1660214092.609563][14671:14676] CHIP:DMG: },
- [1660214092.609576][14671:14676] CHIP:DMG:
- [1660214092.609674][14671:14676] CHIP:DMG: ICR moving to [CommandSen]
- [1660214092.609707][14671:14676] CHIP:EM: Sending Standalone Ack for MessageCounter:33263154 on exchange 56685i
- [1660214092.609876][14671:14676] CHIP:IN: Prepared unauthenticated message 0x7f5ae77fd000 to 0x0000000000000000 (0) of type 0x10 and protocolId (0, 0) on exchange 56685i with MessageCounter:66323624.
- [1660214092.609904][14671:14676] CHIP:IN: Sending unauthenticated msg 0x7f5ae77fd000 with MessageCounter:66323624 to 0x0000000000000000 at monotonic time: 00000000012052C1 msec
- [1660214092.610138][14671:14676] CHIP:DMG: >> to UDP:[fe80::e65f:1ff:fe0f:2753%enp0s31f6]:5540 | 66323624 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 0 / Exchange = 56685]
- [1660214092.610167][14671:14676] CHIP:DMG: Header Flags =
- [1660214092.610177][14671:14676] CHIP:DMG: {
- [1660214092.610198][14671:14676] CHIP:DMG: Message (0x04) =
- [1660214092.610208][14671:14676] CHIP:DMG: {
- [1660214092.610222][14671:14676] CHIP:DMG: SourceNodeId = 86B22B3066A1B459
- [1660214092.610234][14671:14676] CHIP:DMG: }
- [1660214092.610255][14671:14676] CHIP:DMG: Exchange (0x03) =
- [1660214092.610265][14671:14676] CHIP:DMG: {
- [1660214092.610276][14671:14676] CHIP:DMG: Initiator = true
- [1660214092.610290][14671:14676] CHIP:DMG: AckMsg = 33263154
- [1660214092.610301][14671:14676] CHIP:DMG: }
- [1660214092.610333][14671:14676] CHIP:DMG: }
- [1660214092.610355][14671:14676] CHIP:DMG:
- [1660214092.610379][14671:14676] CHIP:DMG: Encrypted Payload (26 bytes) =
- [1660214092.610394][14671:14676] CHIP:DMG: {
- [1660214092.610407][14671:14676] CHIP:DMG: data = 04000000a804f40359b4a166302bb28603106ddd0000328efb01
- [1660214092.610423][14671:14676] CHIP:DMG: buffer_ptr = 140028080604320
- [1660214092.610436][14671:14676] CHIP:DMG: }
- [1660214092.610450][14671:14676] CHIP:DMG:
- [1660214092.610521][14671:14676] CHIP:EM: Flushed pending ack for MessageCounter:33263154 on exchange 56685i
- [1660214092.617596][14671:14676] CHIP:DMG: << from UDP:[fe80::e65f:1ff:fe0f:2753%enp0s31f6]:5540 | 219026739 | [Interaction Model (1) / InvokeCommandResponse (0x09) / Session = 20731 / Exchange = 56686]
- [1660214092.617620][14671:14676] CHIP:DMG: Header Flags =
- [1660214092.617626][14671:14676] CHIP:DMG: {
- [1660214092.617637][14671:14676] CHIP:DMG: Exchange (0x06) =
- [1660214092.617645][14671:14676] CHIP:DMG: {
- [1660214092.617652][14671:14676] CHIP:DMG: AckMsg = 21510045
- [1660214092.617657][14671:14676] CHIP:DMG: NeedsAck = true
- [1660214092.617663][14671:14676] CHIP:DMG: }
- [1660214092.617672][14671:14676] CHIP:DMG: }
- [1660214092.617678][14671:14676] CHIP:DMG:
- [1660214092.617686][14671:14676] CHIP:DMG: Encrypted Payload (531 bytes) =
- [1660214092.617692][14671:14676] CHIP:DMG: {
- [1660214092.617698][14671:14676] CHIP:DMG: data = 00fb500033150e0d1ee5b6538768098d8ef37ec0e09fbeb30c158a93ffdd1ca81041b2baa637a7e200110cd7cf06f5ffa40a8e4529a8a38cdd47e50715aaa344941b0c760264022f21b37432352c00f457fade1bdee072261fcb5cde3fcd70e2e71d5a8ec9fa038e670a404d8641162b8fb34919e9d6e431a1c895a6e01cbd3125c9322ff741caf28b79f69f103ec0e9c5b1b74c43fde4d4ac21f15e48b2090916feca5662682ae9eb1f8d18011d618492d57139ad99e94f99e3a755d2a8e46ba7133a0f1d2fe20b7e5cf2906542c4685866c7ccbd8e2e15e84e3dc653057623dac7d65d7bb785466bab3e816e06f378d0165aadf7ef38d23afdb42731191683a995fa1223bcccf27c0314aced823b2a00ff0da758b1f910631fab7098f013a7fed82136cf072c1150e4f351541f194f0aa2987bc0d1d7688d7955d94560b34bbce0b407d340b0ebaef6f5e9343af6cb8d030fb8040a9a6b7cd9465974a692072d05597b98ec66c42cf4edd86d841048cf5f045f90fb74d4066f2f23e038530e18dd4a0f3c1d86800077661bbd5ff28ff873bb87c6a2545871c6eeca5426466cecff984822b8dd3b7822fb109ec80c9ca3c9bb70b20056f2f4f8b25d1ec3bd8c17a86403bdd42d8cf2c2f66ca8983812361f34770992a7724fc33c5297169a2dcc99b92f290d2894bad6c612684f29c71eb0190b5d8d31dee66650da1942a798de69389d9c5bcfbf0e56a08c820092a53d4f34
- [1660214092.617712][14671:14676] CHIP:DMG: buffer_ptr = 140028080581472
- [1660214092.617717][14671:14676] CHIP:DMG: }
- [1660214092.617722][14671:14676] CHIP:DMG:
- [1660214092.617768][14671:14676] CHIP:DMG: DAC/PAI (463) =
- [1660214092.617789][14671:14676] CHIP:DMG: {
- -----BEGIN CERTIFICATE-----
- MIIByzCCAXGgAwIBAgIIVq2CIq2UW2QwCgYIKoZIzj0EAwIwMDEYMBYGA1UEAwwP
- TWF0dGVyIFRlc3QgUEFBMRQwEgYKKwYBBAGConwCAQwERkZGMTAgFw0yMjAyMDUw
- MDAwMDBaGA85OTk5MTIzMTIzNTk1OVowPTElMCMGA1UEAwwcTWF0dGVyIERldiBQ
- QUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjO
- PQIBBggqhkjOPQMBBwNCAARBmpMVwhc+DIyHbQPM/JRIUmR/f+xeUIL0BZko7KiU
- xZQVEwmsYx5MsDOSr2hLC6+35ls7gWLC9Sv5MbjneqqCo2YwZDASBgNVHRMBAf8E
- CDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUY1QOR/ZLHDjROISk
- YtFsGV2P+zwwHwYDVR0jBBgwFoAUav0idx9RH+y/FkGXZxDc3DGhcX4wCgYIKoZI
- zj0EAwIDSAAwRQIhALLvJ/Sa6bUPuR7qyUxNC9u415KcbLiPrOUpNo0SBUwMAiBl
- Xckrhr2QmIKmxiF3uCXX0F7b58Ivn+pxIg5+pwP4kQ==
- -----END CERTIFICATE-----
- [1660214092.617801][14671:14676] CHIP:DMG: }
- [1660214092.617807][14671:14676] CHIP:DMG:
- [1660214092.617815][14671:14676] CHIP:DMG:
- [1660214092.617827][14671:14676] CHIP:DMG: Additional Fields =
- [1660214092.617832][14671:14676] CHIP:DMG: {
- [1660214092.617839][14671:14676] CHIP:DMG: peer_address = UDP:[fe80::e65f:1ff:fe0f:2753%enp0s31f6]:5540
- [1660214092.617845][14671:14676] CHIP:DMG: }
- [1660214092.617851][14671:14676] CHIP:DMG:
- [1660214092.617861][14671:14676] CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:219026739 on exchange 56686i
- [1660214092.617870][14671:14676] CHIP:EM: Found matching exchange: 56686i, Delegate: 0x7f5ad4003a48
- [1660214092.617885][14671:14676] CHIP:EM: Rxd Ack; Removing MessageCounter:21510045 from Retrans Table on exchange 56686i
- [1660214092.617891][14671:14676] CHIP:EM: Removed CHIP MessageCounter:21510045 from RetransTable on exchange 56686i
- [1660214092.617904][14671:14676] CHIP:DMG: ICR moving to [ResponseRe]
- disabled: true
-
- - label:
- "Step 7: TH1 sends CertificateChainRequest Command to DUT for the DAC
- and saves the certififate as 'DACCert'"
- PICS: OPCREDS.S.C02.Rsp && OPCREDS.S.C03.Tx
- verification: |
- ./chip-tool operationalcredentials certificate-chain-request 1 1 0
-
- Verify the CertificateChainResponse in TH Log
-
- [1660218221.819087][17048:17053] CHIP:DMG: InvokeRequestMessage =
- [1660218221.819106][17048:17053] CHIP:DMG: {
- [1660218221.819126][17048:17053] CHIP:DMG: suppressResponse = false,
- [1660218221.819147][17048:17053] CHIP:DMG: timedRequest = false,
- [1660218221.819164][17048:17053] CHIP:DMG: InvokeRequests =
- [1660218221.819194][17048:17053] CHIP:DMG: [
- [1660218221.819210][17048:17053] CHIP:DMG: CommandDataIB =
- [1660218221.819233][17048:17053] CHIP:DMG: {
- [1660218221.819251][17048:17053] CHIP:DMG: CommandPathIB =
- [1660218221.819274][17048:17053] CHIP:DMG: {
- [1660218221.819296][17048:17053] CHIP:DMG: EndpointId = 0x0,
- [1660218221.819319][17048:17053] CHIP:DMG: ClusterId = 0x3e,
- [1660218221.819341][17048:17053] CHIP:DMG: CommandId = 0x2,
- [1660218221.819361][17048:17053] CHIP:DMG: },
- [1660218221.819386][17048:17053] CHIP:DMG:
- [1660218221.819403][17048:17053] CHIP:DMG: CommandFields =
- [1660218221.819425][17048:17053] CHIP:DMG: {
- [1660218221.819448][17048:17053] CHIP:DMG: 0x0 = 1,
- [1660218221.819470][17048:17053] CHIP:DMG: },
- [1660218221.819488][17048:17053] CHIP:DMG: },
- [1660218221.819515][17048:17053] CHIP:DMG:
- [1660218221.819530][17048:17053] CHIP:DMG: ],
- [1660218221.819559][17048:17053] CHIP:DMG:
- [1660218221.819575][17048:17053] CHIP:DMG: InteractionModelRevision = 1
- [1660218221.819592][17048:17053] CHIP:DMG: },
- [1660218221.819611][17048:17053] CHIP:DMG:
- [1660218221.819755][17048:17053] CHIP:DMG: ICR moving to [CommandSen]
- [1660218221.819807][17048:17053] CHIP:EM: Sending Standalone Ack for MessageCounter:33263156 on exchange 41890i
- [1660218221.820060][17048:17053] CHIP:IN: Prepared unauthenticated message 0x7f950d02b000 to 0x0000000000000000 (0) of type 0x10 and protocolId (0, 0) on exchange 41890i with MessageCounter:146063148.
- [1660218221.820102][17048:17053] CHIP:IN: Sending unauthenticated msg 0x7f950d02b000 with MessageCounter:146063148 to 0x0000000000000000 at monotonic time: 00000000015F547B msec
- [1660218221.820457][17048:17053] CHIP:DMG: >> to UDP:[fe80::e65f:1ff:fe0f:2753%enp0s31f6]:5540 | 146063148 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 0 / Exchange = 41890]
- [1660218221.820501][17048:17053] CHIP:DMG: Header Flags =
- [1660218221.820519][17048:17053] CHIP:DMG: {
- [1660218221.820578][17048:17053] CHIP:DMG: Message (0x04) =
- [1660218221.820596][17048:17053] CHIP:DMG: {
- [1660218221.820622][17048:17053] CHIP:DMG: SourceNodeId = EB2A0D2FCD128BCD
- [1660218221.820642][17048:17053] CHIP:DMG: }
- [1660218221.820677][17048:17053] CHIP:DMG: Exchange (0x03) =
- [1660218221.820692][17048:17053] CHIP:DMG: {
- [1660218221.820709][17048:17053] CHIP:DMG: Initiator = true
- [1660218221.820730][17048:17053] CHIP:DMG: AckMsg = 33263156
- [1660218221.820747][17048:17053] CHIP:DMG: }
- [1660218221.820778][17048:17053] CHIP:DMG: }
- [1660218221.820792][17048:17053] CHIP:DMG:
- [1660218221.820819][17048:17053] CHIP:DMG: Encrypted Payload (26 bytes) =
- [1660218221.820834][17048:17053] CHIP:DMG: {
- [1660218221.820853][17048:17053] CHIP:DMG: data = 040000002cbfb408cd8b12cd2f0d2aeb0310a2a30000348efb01
- [1660218221.820871][17048:17053] CHIP:DMG: buffer_ptr = 140277792687280
- [1660218221.820888][17048:17053] CHIP:DMG: }
- [1660218221.820906][17048:17053] CHIP:DMG:
- [1660218221.820997][17048:17053] CHIP:EM: Flushed pending ack for MessageCounter:33263156 on exchange 41890i
- [1660218221.826505][17048:17053] CHIP:DMG: << from UDP:[fe80::e65f:1ff:fe0f:2753%enp0s31f6]:5540 | 217571241 | [Interaction Model (1) / InvokeCommandResponse (0x09) / Session = 16041 / Exchange = 41891]
- [1660218221.826559][17048:17053] CHIP:DMG: Header Flags =
- [1660218221.826581][17048:17053] CHIP:DMG: {
- [1660218221.826620][17048:17053] CHIP:DMG: Exchange (0x06) =
- [1660218221.826636][17048:17053] CHIP:DMG: {
- [1660218221.826658][17048:17053] CHIP:DMG: AckMsg = 228316047
- [1660218221.826677][17048:17053] CHIP:DMG: NeedsAck = true
- [1660218221.826695][17048:17053] CHIP:DMG: }
- [1660218221.826723][17048:17053] CHIP:DMG: }
- [1660218221.826736][17048:17053] CHIP:DMG:
- [1660218221.826764][17048:17053] CHIP:DMG: Encrypted Payload (559 bytes) =
- [1660218221.826778][17048:17053] CHIP:DMG: {
- [1660218221.826796][17048:17053] CHIP:DMG: data = 00a93e00a9dff70c44f908196a2718a5b4cd8fb67b67d2223ade09fa1f23a5e9d6081ef9003a293b4f7ddf1e64767c15165a5544c4bc162a2eea22b085a5392580dec393bc15a705abc25360a7f05f99baf448b6c29e93defc8d01b00c11b268b2a197f88fc5984fe4c541fc523e2ecd2316b5dc1109c54408186296772f48d484047770f70a6af3e639833481b4663c7b65b902a850a8d55d3a86c73523a6853f47727582113480efece0e72f552a42ce49a26746e8d6b405ae87fadc7711a313f1865b90ac934486e05d2ed6868a5b5c4e13010eec98f917308c6fe5e9c6816c045f4640aea37804278a600cede11aee2bb591224edd0524bda56ee2d4d64c8a29c664edb006f4f42855f3868f272e94d8648d2431c0e95f6a55802c18d5938497b6b5c5aa37e37597a6782ca55a2948ceededd45e63537f4f1985f45653dbb118a0e1108eca228973b5c8fb48a1afeb649c46aec6259a649f0795c677ca492452c9fcb07969b6f851421252d30d6e160a350feb8baee6ccea79f54e0ebfae94c99eafa466964671b1fe3aa8585c83c28d9484444ba7d5a8a8e3178aedea00d292a53e3f0939b15bb7bee982e346410d5b064ec496409ba26e6a3b2182cff7b1955ba8f980d99590dfa0f2b690d1f1e5d8d178b1a64893dfcd242949ade66269336bc6c0440e9e4a120af59bfbbaabee32871ec1208915f63f91bdb1305045afeface4c7fc39e8eae7db8923b95aa01d4fee30d525664297305e569a3bfca01a767d47f6fdc0eb1b7706bc4547b1
- [1660218221.826837][17048:17053] CHIP:DMG: buffer_ptr = 140277792657648
- [1660218221.826854][17048:17053] CHIP:DMG: }
- [1660218221.826870][17048:17053] CHIP:DMG:
- [1660218221.826979][17048:17053] CHIP:DMG: DAC/PAI (491) =
- [1660218221.827025][17048:17053] CHIP:DMG: {
- -----BEGIN CERTIFICATE-----
- MIIB5zCCAY6gAwIBAgIIac3xDenlTtEwCgYIKoZIzj0EAwIwPTElMCMGA1UEAwwc
- TWF0dGVyIERldiBQQUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZG
- RjEwIBcNMjIwMjA1MDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMFMxJTAjBgNVBAMM
- HE1hdHRlciBEZXYgREFDIDB4RkZGMS8weDgwMDExFDASBgorBgEEAYKifAIBDARG
- RkYxMRQwEgYKKwYBBAGConwCAgwEODAwMTBZMBMGByqGSM49AgEGCCqGSM49AwEH
- A0IABEY6xpNCkQoOVYj8b/Vrtj5i7M7LFI99TrA+5VJgFBV2fRalxmP3k+SRIyYL
- gpenzX58/HsxaznZjpDSk3dzjoKjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/
- BAQDAgeAMB0GA1UdDgQWBBSI3eezADgpMs/3NMBGJIEPRBaKbzAfBgNVHSMEGDAW
- gBRjVA5H9kscONE4hKRi0WwZXY/7PDAKBggqhkjOPQQDAgNHADBEAiABJ6J7S0Rh
- DuL83E0reIVWNmC8D3bxchntagjfsrPBzQIga1ngr0Xz6yqFuRnTVzFSjGAoxBUj
- lUXhCOTlTnCXE1M=
- -----END CERTIFICATE-----
- [1660218221.827089][17048:17053] CHIP:DMG: }
- [1660218221.827105][17048:17053] CHIP:DMG:
- [1660218221.827125][17048:17053] CHIP:DMG:
- [1660218221.827158][17048:17053] CHIP:DMG: Additional Fields =
- [1660218221.827173][17048:17053] CHIP:DMG: {
- [1660218221.827194][17048:17053] CHIP:DMG: peer_address = UDP:[fe80::e65f:1ff:fe0f:2753%enp0s31f6]:5540
- [1660218221.827211][17048:17053] CHIP:DMG: }
- [1660218221.827226][17048:17053] CHIP:DMG:
- [1660218221.827257][17048:17053] CHIP:EM: Received message of type 0x9 with protocolId (0, 1) and MessageCounter:217571241 on exchange 41891i
- [1660218221.827276][17048:17053] CHIP:EM: Found matching exchange: 41891i, Delegate: 0x7f94f8003a48
- [1660218221.827310][17048:17053] CHIP:EM: Rxd Ack; Removing MessageCounter:228316047 from Retrans Table on exchange 41891i
- [1660218221.827326][17048:17053] CHIP:EM: Removed CHIP MessageCounter:228316047 from RetransTable on exchange 41891i
- [1660218221.827357][17048:17053] CHIP:DMG: ICR moving to [ResponseRe]
- disabled: true
-
- - label: "Step 8: TH1 Sends CSRRequest command with a random 32-byte nonce"
- PICS: OPCREDS.S.C04.Rsp
- verification: |
- To get SCR Nonce give below command 2 times
- echo hex:$(hexdump -vn32 -e'4/4 "%08X" ' /dev/urandom)
-
- ./chip-tool operationalcredentials csrrequest hex:A61BFCE6E2C6AAF48FDEC4BF9DCEF08EB65B976997D82BE5F359902982717603 1 0
-
- Verify the CSRResponse in TH Log
-
- [1658223679.580697][6136:6141] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0005
- [1658223679.580761][6136:6141] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0005
- [1658223679.580823][6136:6141] CHIP:TOO: CSRResponse: {
- [1658223679.580875][6136:6141] CHIP:TOO: NOCSRElements: 153001CB3081C83070020100300E310C300A060355040A0C034353523059301306072A8648CE3D020106082A8648CE3D030107034200047DA16C714034D3B96716F64DC0E742D007233212025E305AF6CE56DFA057718E149E52B39584456C8F954A1596B64F8BBC02E501276B962D4AB2C0A607D983C9A000300A06082A8648CE3D040302034800304502206FB78A61A7B0F021C396FEC1CCD6802129AC3EE5EA2727ABCCB19DBAEA7DEE1A022100A5C81ADC5D8BFAA5DB84A1261D8BBCEA5C26B24D4405F0B978E19B17D8458C9E300220A61BFCE6E2C6AAF48FDEC4BF9DCEF08EB65B976997D82BE5F35990298271760318
- [1658223679.580915][6136:6141] CHIP:TOO: attestationSignature: EB731B40B20501AF32C468AA522948F7848D3AEDFA24D9A879575B4A265886C97109EE0DE1ECEB969B1A7F98F127DB4C275292B986BF8DA56EF7B16DA8EC8ABE
- [1658223679.580943][6136:6141] CHIP:TOO: }
-
- Verify attestation signature is an octstr type and has maximum length of 64
-
- Example:
- EB731B40B20501AF32C468AA522948F7848D3AEDFA24D9A879575B4A265886C97109EE0DE1ECEB969B1A7F98F127DB4C275292B986BF8DA56EF7B16DA8EC8ABE
- disabled: true
-
- - label: "Step 9: TH1 validates the attestation response"
- verification: |
-
- disabled: true
-
- - label:
- "Step 10: TH1 obtains or generates the NOC, the Root CA Certificate
- and ICAC using the CSR elements from step 8 and selects an IPK. The
- certificates shall have their subjects padded with additional data
- such that they are each the maximum certificate size of 400 bytes when
- encoded in the MatterCertificateEncoding. Save RCAC as
- Root_CA_Certificate_TH1 Save ICAC as Intermediate_Certificate_TH1 Save
- NOC as Node_Operational_Certificate_TH1 Save IPK as IPK_TH1 Extract
- the RCAC public key and save as Root_Public_Key_TH1"
- verification: |
-
- disabled: true
-
- - label:
- "Step 11: TH1 obtains or generates Root Certificate with a different
- Root CA ID and the corresponding ICAC, NOC and IPK using the CSR
- elements from step 8 Save RCAC as Root_CA_Certificate_TH1_2 Save ICAC
- as Intermediate_Certificate_TH1_2 Save NOC as
- Node_Operational_Certificate_TH1_2 Save IPK as IPK_TH1_2"
- verification: |
-
- disabled: true
-
- - label:
- "Step 12: TH1 generates an INVALID Root Certificate where the
- signature does not match the public key and saves it as
- Root_CA_Malformed"
- verification: |
-
- disabled: true
-
- - label:
- "Step 13: TH1 sends AddTrustedRootCertificate command to DUT to
- install Root_CA_Malformed"
- PICS: OPCREDS.S.C0b.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 14: TH1 sends AddTrustedRootCertificate command to DUT with
- RootCACertificate set to Root_CA_Certificate_TH1"
- PICS: OPCREDS.S.C0b.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 15: TH1 sends AddTrustedRootCertificate command to DUT again
- with the RootCACertificate field set to Root_CA_Certificate_TH1"
- PICS: OPCREDS.S.C0b.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 16: TH1 sends AddTrustedRootCertificate command to DUT again
- with the RootCACertificate field set to Root_CA_Certificate_TH1_2"
- PICS: OPCREDS.S.C0b.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 17: TH1 reads the TrustedRootCertificates list from DUT and
- saves as TrustedRootsList"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label:
- "Step 18: TH1 appends Root_CA_Certificate_TH1_2 to TrustedRootsList
- and writes the TrustedRootCertificates attribute with that value"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label: "Step 19: TH1 reads the TrustedRootCertificates list from DUT"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label:
- "Step 20: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1_2 ICACValue as
- Intermediate_Certificate_TH1_2 IpkValue as IPK_TH1_2 CaseAdminSubject
- as the NodeID of TH1 AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 21: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1 ICACValue as
- Intermediate_Certificate_TH1 IpkValue as IPK_TH1 CaseAdminSubject is
- an invalid NodeID (not an operational Node ID or Case Authenticated
- Tag - ex. 0) AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 22: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1 ICACValue as
- Intermediate_Certificate_TH1 IpkValue as IPK_TH1 CaseAdminSubject as
- the NodeID of TH1 AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 23: TH1 saves the FabricIndex as FabricIndex_TH1 for future use"
- verification: |
-
- disabled: true
-
- - label:
- "Step 24: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1_1 ICACValue as
- Intermediate_Certificate_TH1_1 IpkValue as IPK_TH1_1 CaseAdminSubject
- as the NodeID of TH1 AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 25: TH1 reads the NOCs attribute from DUT using a
- non-fabric-filtered read and saves the list as NOClist"
- PICS: OPCREDS.S.A0000
- verification: |
-
- disabled: true
-
- - label:
- "Step 26: TH1 appends a second list item to 'NOClist' and writes that
- value to the NOCs attribute"
- PICS: OPCREDS.S.A0000
- verification: |
-
- disabled: true
-
- - label:
- "Step 27: TH1 reads the NOCs attribute from DUT using a
- non-fabric-filtered read"
- PICS: OPCREDS.S.A0000
- verification: |
-
- disabled: true
-
- - label:
- "Step 28: TH1 sends UpdateFabricLabel command with 'Label 1' as Label
- field to DUT"
- PICS: OPCREDS.S.C09.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 29: TH1 reads the Fabrics Attribute from DUT using a
- non-fabric-filtered read and gets the FabricDescriptorStruct for which
- the FabricIndex field equals FabricIndex_TH1"
- verification: |
-
- disabled: true
-
- - label:
- "Step 31: TH1 sends ArmFailSafe command to the DUT with
- ExpiryLengthSeconds field set to 0"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
-
- disabled: true
-
- - label: "Step 32: TH1 reconnects to the DUT over PASE"
- verification: |
-
- disabled: true
-
- - label: "Step 33: TH1 reads the TrustedRootCertificates list from DUT"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label:
- "Step 34: TH1 reads the NOCs attribute from DUT using a
- non-fabric-filtered read"
- PICS: OPCREDS.S.A0000
- verification: |
-
- disabled: true
-
- - label:
- "Step 35: TH1 reads the Fabrics attribute from the DUT using a
- non-fabric-filtered read"
- PICS: OPCREDS.S.A0001
- verification: |
-
- disabled: true
-
- - label:
- "Step 36: TH1 fully commissions DUT onto the fabric, using
- 'Root_CA_Certificate_TH1' and the AddNOC parameters specified in step
- . This will update the value of FabricIndex_TH1 so that it references
- the fabric the DUT was just commissioned onto"
- verification: |
-
- disabled: true
-
- - label: "Step 37: TH1 reads the TrustedRootCertificates list from DUT"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label:
- "Step 38: TH1 reads the NOCs attribute from DUT using a
- non-fabric-filtered read"
- PICS: OPCREDS.S.A0000
- verification: |
-
- disabled: true
-
- - label:
- "Step 39: TH1 sends UpdateFabricLabel command with 'Label 1' as Label
- field to DUT"
- PICS: OPCREDS.S.C09.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 40: TH1 reads the Fabrics Attribute from DUT using a
- non-fabric-filtered read and gets the FabricDescriptorStruct for which
- the FabricIndex field equals FabricIndex_TH1"
- PICS: OPCREDS.S.A0001
- verification: |
-
- disabled: true
-
- - label:
- "Step 42: TH1 reads the ACL attribute from the Access Control cluster"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 43: TH1 issues a KeySetRead command to the DUT for GroupKeySetID
- 0"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 44: TH1 sends an OpenCommissioningWindow command to the
- Administrator Commissioning cluster"
- verification: |
-
- disabled: true
-
- - label:
- "Step 45: TH2 begins the process of commissionning the DUT. After
- receiving the CSRResponse TH2 obtains or generates a NOC, the Root CA
- Certificate, ICAC and IPK. The certificates shall have their subjects
- padded with additional data such that they are each the maximum
- certificate size of 400 bytes when encoded in the
- MatterCertificateEncoding. Save RCAC as Root_CA_Certificate_TH2 Save
- ICAC as Intermediate_Certificate_TH2 Save NOC as
- Node_Operational_Certificate_TH2 Save IPK as IPK_TH2 Extract the RCAC
- public key and save as Root_Public_Key_TH2"
- verification: |
-
- disabled: true
-
- - label:
- "Step 46: TH2 completes the commissioning process using
- Root_CA_Certificate_TH2 when performing the AddTrustedRootCertificate
- command and sending AddNOC with the following parameters: NOCValue as
- Node_Operational_Certificate_TH2 ICACValue as
- Intermediate_Certificate_TH2 IpkValue as IPK_TH2 CaseAdminSubject as
- CAT_TH2 AdminVendorId as the Vendor ID of TH2"
- verification: |
- Not verifiable
- disabled: true
-
- - label: "Step 47: TH2 reads the TrustedRootCertificates list from DUT"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label:
- "Step 48: TH2 reads the NOCs attribute from DUT using a
- non-fabric-filtered read"
- PICS: OPCREDS.S.A0000
- verification: |
-
- disabled: true
-
- - label:
- "Step 49: TH2 sends UpdateFabricLabel command with 'Label 2' as Label
- field to DUT"
- PICS: OPCREDS.S.C09.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 50: TH2 sends UpdateFabricLabel command with 'Label 1' as Label
- field to DUT"
- PICS: OPCREDS.S.C09.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 51: Read the Fabrics List from DUT using a non-fabric-filtered
- read"
- PICS: OPCREDS.S.A0001
- verification: |
-
- disabled: true
-
- - label:
- "Step 52: TH1 sends ArmFailSafe command to the DUT with the
- ExpiryLengthSeconds field set to 900"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
-
- disabled: true
-
- - label:
- "Step 53: TH1 sends AddTrustedRootCertificate command to DUT with
- RootCACertificate set to Root_CA_Certificate_TH1_2"
- PICS: OPCREDS.S.C0b.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 54: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1_2 ICACValue as
- Intermediate_Certificate_TH1_2 IpkValue as IPK_TH1_2 CaseAdminSubject
- as the NodeID of TH1 AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label: "Step 55: TH1 Sends CSRRequest command with a random 32-byte nonce"
- PICS: OPCREDS.S.C04.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 56: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1_2 ICACValue as
- Intermediate_Certificate_TH1_2 IpkValue as IPK_TH1_2 CaseAdminSubject
- as the NodeID of TH1 AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 57: TH1 obtains or generates a NOC and ICAC using the CSR
- elements from step 55 with a different NodeID, but the same Root CA
- Certificate and fabric ID as step 10. Save as
- Node_Operational_Certificates_TH1_fabric_conflict and
- Intermediate_Certificate_TH1_fabric_conflict"
- verification: |
-
- disabled: true
-
- - label:
- "Step 58: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1_fabric_conflict
- ICACValue as Intermediate_Certificate_TH1_fabric_conflict
- CaseAdminSubject as the NodeID of TH1 AdminVendorId as the Vendor ID
- of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 59: TH1 sends ArmFailSafe command to the DUT with
- ExpiryLengthSeconds set to 0"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
-
- disabled: true
-
- - label: "Step 60: TH1 reads the TrustedRootCertificates list from DUT"
- PICS: OPCREDS.S.A0004
- verification: |
-
- disabled: true
-
- - label:
- "Step 61: TH1 sends ArmFailSafe command to the DUT with the
- ExpiryLengthSeconds field set to 900"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
-
- disabled: true
-
- - label:
- "Step 62: TH1 Sends CSRRequest command with a random 32-byte nonce and
- the IsForUpdateNOC field set to true"
- PICS: OPCREDS.S.C04.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 63: TH1 obtains or generates a NOC, Root CA Certificate, ICAC
- using the CSR elements from the previous step Save RCAC as
- Root_CA_Certificate_TH1_3 Save ICAC as Intermediate_Certificate_TH1_3
- Save NOC as Node_Operational_Certificate_TH1_3"
- verification: |
-
- disabled: true
-
- - label:
- "Step 64: TH1 sends AddTrustedRootCertificate command to DUT with
- RootCACertificate set to Root_CA_Certificate_TH1_3"
- PICS: OPCREDS.S.C0b.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 65: TH1 sends the AddNOC Command to DUT with the following
- fields: NOCValue as Node_Operational_Certificate_TH1_3 ICACValue as
- Intermediate_Certificate_TH1_3 CaseAdminSubject as the NodeID of TH1
- AdminVendorId as the Vendor ID of TH1"
- PICS: OPCREDS.S.C06.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 66: TH1 sends ArmFailSafe command to the DUT with
- ExpiryLengthSeconds set to 0"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
-
- disabled: true
-
- - label:
- "Step 67: TH1 sends ArmFailSafe command to the DUT with the
- ExpiryLengthSeconds field set to 900"
- PICS: CGEN.S.C00.Rsp && CGEN.S.C01.Tx
- verification: |
-
- disabled: true
-
- - label:
- "Step 68: TH2 sends RemoveFabric command with Fabric Index as
- FabricIndexTH2 + 5 (Invalid Fabric Index) to DUT"
- PICS: OPCREDS.S.C0a.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 69: TH2 reads the Fabrics List from DUT using a
- non-fabric-filtered read"
- PICS: OPCREDS.S.A0001
- verification: |
-
- disabled: true
-
- - label:
- "Step 70: TH2 sends RemoveFabric command with Fabric Index as
- FabricIndex_TH1 (Valid Fabric Index) to DUT"
- PICS: OPCREDS.S.C0a.Rsp
- verification: |
-
- disabled: true
-
- - label:
- "Step 71: TH2 reads the Fabrics List from DUT using a
- non-fabric-filtetered read"
- PICS: OPCREDS.S.A0001
- verification: |
-
- disabled: true
-
- - label: "Step 72: TH2 sends a CommissioningComplete command to the DUT"
- verification: |
-
- disabled: true
-
- - label:
- "Step 73: TH2 sends an OpenCommissioningWindow command to the
- Administrator Commissioning cluster"
- verification: |
-
- disabled: true
-
- - label:
- "Step 74: TH1 fully commissions the DUT using subject-padded, 400 byte
- certificates"
- verification: |
-
- disabled: true
-
- - label:
- "Step 75: Repeat steps 73 and 74 to fill the fabric table using the
- remaining test harnesses (TH3 through TH NumSupportedFabrics). Each
- test harness should commission the DUT using subject-padded, 400-byte
- certificates"
- verification: |
-
- disabled: true
-
- - label: "Step 76: TH1 reads CommissionedFabrics attribute"
- PICS: OPCREDS.S.A0003
- verification: |
-
- disabled: true
-
- - label: "Step 77: Repeat steps 73 and 74 with TH NumSupportedFabrics + 1"
- verification: |
-
- disabled: true
-
- - label:
- "Step 78: TH1 reads the SubjectsPerAccessControlEntry attribute from
- the Access Control Cluster and saves the value as maxSubjects"
- verification: |
-
- disabled: true
-
- - label:
- "Step 79: TH1 reads the TargetsPerAccessControlEntry attribute from
- the Access Control Cluster and saves the value as maxTargets"
- verification: |
-
- disabled: true
-
- - label:
- "Step 80: TH1 reads the AccessControlEntriesPerFabric attribute from
- the Access Control Cluster and saves the value as maxEntries"
- verification: |
-
- disabled: true
-
- - label:
- "Step 81: TH1 creates a valid list of AccessControlEntryStructs with
- maxEntries entries. Each AccessControlEntryStruct specifies
- maxSubjects subjects and maxTargets targets. TH1 writes this list to
- the AccessControl cluster ACL attribute"
- verification: |
-
- disabled: true
-
- - label:
- "Step 82: Repeat step 81 for TH2 through TH NumSupportedFabrics to
- fill the ACL table"
- verification: |
-
- disabled: true
diff --git a/src/app/tests/suites/certification/Test_TC_VALCC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_VALCC_1_1.yaml
new file mode 100644
index 00000000000000..cf00d40a21a02f
--- /dev/null
+++ b/src/app/tests/suites/certification/Test_TC_VALCC_1_1.yaml
@@ -0,0 +1,186 @@
+# Copyright (c) 2024 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: 62.1.1. [TC-VALCC-1.1] Global attributes with server as DUT
+
+PICS:
+ - VALCC.S
+
+config:
+ nodeId: 0x12344321
+ cluster: "Valve Configuration and Control"
+ endpoint: 1
+
+tests:
+ - label: "Step 1: Wait for the commissioned device to be retrieved"
+ cluster: "DelayCommands"
+ command: "WaitForCommissionee"
+ arguments:
+ values:
+ - name: "nodeId"
+ value: nodeId
+
+ - label: "Step 2: Read the global attribute: ClusterRevision"
+ command: "readAttribute"
+ attribute: "ClusterRevision"
+ response:
+ value: 1
+ constraints:
+ type: int16u
+
+ - label: "Step 3a: Read the global attribute: FeatureMap"
+ command: "readAttribute"
+ attribute: "FeatureMap"
+ PICS: ( !VALCC.S.F00 && !VALCC.S.F01 )
+ response:
+ value: 0
+ constraints:
+ type: bitmap32
+
+ - label:
+ "Step 3b: Given VALCC.S.F00(TS) ensure featuremap has the correct bit
+ set"
+ command: "readAttribute"
+ attribute: "FeatureMap"
+ PICS: VALCC.S.F00
+ response:
+ constraints:
+ type: bitmap32
+ hasMasksSet: [0x1]
+
+ - label:
+ "Step 3c: Given VALCC.S.F01(LVL) ensure featuremap has the correct bit
+ set"
+ command: "readAttribute"
+ attribute: "FeatureMap"
+ PICS: VALCC.S.F01
+ response:
+ constraints:
+ type: bitmap32
+ hasMasksSet: [0x2]
+
+ - label: "Step 4a: Read the global attribute: AttributeList"
+ PICS: PICS_EVENT_LIST_ENABLED
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [0, 1, 3, 4, 65528, 65529, 65530, 65531, 65532, 65533]
+
+ - label: "Step 4a: Read the global attribute: AttributeList"
+ PICS: "!PICS_EVENT_LIST_ENABLED"
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [0, 1, 3, 4, 65528, 65529, 65531, 65532, 65533]
+
+ - label:
+ "Step 4b: Read the feature dependent(VALCC.S.F00) attribute in
+ AttributeList"
+ PICS: VALCC.S.F00
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [2]
+
+ - label:
+ "Step 4c: Read the feature dependent(VALCC.S.F01) attribute in
+ AttributeList"
+ PICS: VALCC.S.F01
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [6, 7]
+
+ - label:
+ "Step 4d: Read the feature dependent(VALCC.S.F01) optional attribute
+ in AttributeList"
+ PICS: VALCC.S.F01 && VALCC.S.A0008
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [8]
+
+ - label:
+ "Step 4e: Read the feature dependent(VALCC.S.F01) optional attribute
+ in AttributeList"
+ PICS: VALCC.S.F01 && VALCC.S.A000a
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [10]
+
+ - label:
+ "Step 4f: TH reads optional (ValveFault) attribute in AttributeList"
+ PICS: VALCC.S.A0009
+ command: "readAttribute"
+ attribute: "AttributeList"
+ response:
+ constraints:
+ type: list
+ contains: [9]
+
+ - label: "Step 5a: Read the global attribute: EventList"
+ PICS: PICS_EVENT_LIST_ENABLED && !VALCC.S.E00 && !VALCC.S.E01
+ command: "readAttribute"
+ attribute: "EventList"
+ response:
+ value: []
+ constraints:
+ type: list
+
+ - label: "Step 5b: Read the optional (ValveStateChanged) event in EventList"
+ PICS: PICS_EVENT_LIST_ENABLED && VALCC.S.E00
+ command: "readAttribute"
+ attribute: "EventList"
+ response:
+ constraints:
+ type: list
+ contains: [0]
+
+ - label: "Step 5c: Read the optional (ValveFault) event in EventList"
+ PICS: PICS_EVENT_LIST_ENABLED && VALCC.S.E01
+ command: "readAttribute"
+ attribute: "EventList"
+ response:
+ constraints:
+ type: list
+ contains: [1]
+
+ - label: "Step 6: Read the global attribute: AcceptedCommandList"
+ command: "readAttribute"
+ attribute: "AcceptedCommandList"
+ response:
+ constraints:
+ type: list
+ contains: [0, 1]
+
+ - label: "Step 7: Read the global attribute: GeneratedCommandList"
+ command: "readAttribute"
+ attribute: "GeneratedCommandList"
+ response:
+ value: []
+ constraints:
+ type: list
diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values
index 079781a0c2d59e..1dcd7edc09597a 100644
--- a/src/app/tests/suites/certification/ci-pics-values
+++ b/src/app/tests/suites/certification/ci-pics-values
@@ -2656,6 +2656,7 @@ REFALM.S.E00=1
REFALM.S.C00.Rsp=1
REFALM.S.C01.Rsp=1
+#Boolean State Configuration
BOOLCFG.S=1
BOOLCFG.S.F00=1
BOOLCFG.S.F01=1
@@ -2673,3 +2674,23 @@ BOOLCFG.S.E00=1
BOOLCFG.S.E01=1
BOOLCFG.S.C00.Rsp=1
BOOLCFG.S.C01.Rsp=1
+
+#Valve Configuration and Control
+VALCC.S=1
+VALCC.S.F00=1
+VALCC.S.F01=1
+VALCC.S.A0000=1
+VALCC.S.A0001=1
+VALCC.S.A0002=1
+VALCC.S.A0003=1
+VALCC.S.A0004=1
+VALCC.S.A0005=1
+VALCC.S.A0006=1
+VALCC.S.A0007=1
+VALCC.S.A0008=1
+VALCC.S.A0009=1
+VALCC.S.A000a=1
+VALCC.S.E00=1
+VALCC.S.E01=1
+VALCC.S.C00.Rsp=1
+VALCC.S.C01.Rsp=1
diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml
index 1a866b5f5868da..9f102dd8b63b15 100644
--- a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml
+++ b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml
@@ -33,6 +33,7 @@ limitations under the License.
+
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index 9b39b0d849af15..32f85159295d80 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -3298,6 +3298,7 @@ cluster RvcRunMode = 84 {
enum ModeTag : enum16 {
kIdle = 16384;
kCleaning = 16385;
+ kMapping = 16386;
}
enum StatusCode : enum8 {
diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py
index c21cc5388f81af..5f57c5e8266d9e 100644
--- a/src/controller/python/chip/ChipDeviceCtrl.py
+++ b/src/controller/python/chip/ChipDeviceCtrl.py
@@ -690,8 +690,12 @@ def DiscoverAllCommissioning(self):
self.devCtrl)
).raise_on_error()
+ class CommissioningWindowPasscode(enum.IntEnum):
+ kOriginalSetupCode = 0,
+ kTokenWithRandomPin = 1,
+
def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: int,
- discriminator: int, option: int) -> CommissioningParameters:
+ discriminator: int, option: CommissioningWindowPasscode) -> CommissioningParameters:
''' Opens a commissioning window on the device with the given nodeid.
nodeid: Node id of the device
timeout: Command timeout
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index ecc9b63039e8bc..9d62cf5eba9b40 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -17415,6 +17415,7 @@ class Enums:
class ModeTag(MatterIntEnum):
kIdle = 0x4000
kCleaning = 0x4001
+ kMapping = 0x4002
# kUnknownEnumValue intentionally not defined. This enum never goes
# through DataModel::Decode, likely because it is a part of a derived
# cluster. As a result having kUnknownEnumValue in this enum is error
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index 7271543d1242db..e599bc3d82f804 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -16830,6 +16830,7 @@ typedef NS_OPTIONS(uint32_t, MTRLaundryWasherControlsFeature) {
typedef NS_ENUM(uint16_t, MTRRVCRunModeModeTag) {
MTRRVCRunModeModeTagIdle MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x4000,
MTRRVCRunModeModeTagCleaning MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x4001,
+ MTRRVCRunModeModeTagMapping MTR_PROVISIONALLY_AVAILABLE = 0x4002,
} MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4));
typedef NS_ENUM(uint8_t, MTRRVCRunModeStatusCode) {
diff --git a/src/platform/ESP32/ESP32Utils.cpp b/src/platform/ESP32/ESP32Utils.cpp
index 9d2fcfc4845a03..ffa45ee72241dd 100644
--- a/src/platform/ESP32/ESP32Utils.cpp
+++ b/src/platform/ESP32/ESP32Utils.cpp
@@ -82,7 +82,7 @@ bool ESP32Utils::IsStationProvisioned(void)
CHIP_ERROR ESP32Utils::IsStationConnected(bool & connected)
{
wifi_ap_record_t apInfo;
- connected = (esp_wifi_sta_get_ap_info(&apInfo) == ESP_OK);
+ connected = (esp_wifi_sta_get_ap_info(&apInfo) == ESP_OK && apInfo.ssid[0] != 0);
return CHIP_NO_ERROR;
}
diff --git a/src/platform/Tizen/NetworkCommissioningDriver.h b/src/platform/Tizen/NetworkCommissioningDriver.h
index 64db40b2d5ce23..0e08269fa82830 100644
--- a/src/platform/Tizen/NetworkCommissioningDriver.h
+++ b/src/platform/Tizen/NetworkCommissioningDriver.h
@@ -101,6 +101,7 @@ class TizenWiFiDriver final : public WiFiDriver
Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText,
uint8_t & outNetworkIndex) override;
void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override;
+ uint32_t GetSupportedWiFiBandsMask() const override;
private:
bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId);
diff --git a/src/platform/Tizen/NetworkCommissioningWiFiDriver.cpp b/src/platform/Tizen/NetworkCommissioningWiFiDriver.cpp
index a92ead9764c203..4bb57a823d0cdf 100644
--- a/src/platform/Tizen/NetworkCommissioningWiFiDriver.cpp
+++ b/src/platform/Tizen/NetworkCommissioningWiFiDriver.cpp
@@ -168,6 +168,12 @@ void TizenWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * cal
}
}
+uint32_t TizenWiFiDriver::GetSupportedWiFiBandsMask() const
+{
+ return static_cast((1UL << chip::to_underlying(WiFiBandEnum::k2g4)) |
+ (1UL << chip::to_underlying(WiFiBandEnum::k5g)));
+}
+
size_t TizenWiFiDriver::WiFiNetworkIterator::Count()
{
return driver->mStagingNetwork.ssidLen == 0 ? 0 : 1;
diff --git a/src/python_testing/TC_OPCREDS_3_1.py b/src/python_testing/TC_OPCREDS_3_1.py
new file mode 100644
index 00000000000000..661c3b0b9cd8fb
--- /dev/null
+++ b/src/python_testing/TC_OPCREDS_3_1.py
@@ -0,0 +1,626 @@
+#
+# 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.
+#
+
+import copy
+import logging
+import random
+
+import chip.clusters as Clusters
+import chip.discovery as Discovery
+from chip import ChipDeviceCtrl
+from chip.exceptions import ChipStackError
+from chip.interaction_model import InteractionModelError, Status
+from chip.tlv import TLVReader, TLVWriter
+from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_OPCREDS_3_1(MatterBaseTest):
+ def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid: int, dev_ctrl: ChipDeviceCtrl = None):
+ if dev_ctrl is None:
+ dev_ctrl = self.default_controller
+
+ devices = dev_ctrl.DiscoverCommissionableNodes(
+ filterType=Discovery.FilterType.LONG_DISCRIMINATOR, filter=longDiscriminator, stopOnFirst=False)
+ # For some reason, the devices returned here aren't filtered, so filter ourselves
+ device = next(filter(lambda d: d.commissioningMode ==
+ Discovery.FilterType.LONG_DISCRIMINATOR and d.longDiscriminator == longDiscriminator, devices))
+ for a in device.addresses:
+ try:
+ dev_ctrl.EstablishPASESessionIP(ipaddr=a, setupPinCode=setupPinCode,
+ nodeid=nodeid, port=device.port)
+ break
+ except ChipStackError:
+ continue
+ try:
+ dev_ctrl.GetConnectedDeviceSync(nodeid=nodeid, allowPASE=True, timeoutMs=1000)
+ except TimeoutError:
+ asserts.fail("Unable to establish a PASE session to the device")
+
+ def OpenCommissioningWindow(self, dev_ctrl: ChipDeviceCtrl, node_id: int):
+ # TODO: abstract this in the base layer? Do we do this a lot?
+ longDiscriminator = random.randint(0, 4095)
+ try:
+ params = dev_ctrl.OpenCommissioningWindow(
+ nodeid=node_id, timeout=600, iteration=10000, discriminator=longDiscriminator, option=ChipDeviceCtrl.ChipDeviceControllerBase.CommissioningWindowPasscode.kTokenWithRandomPin)
+ except Exception as e:
+ logging.exception('Error running OpenCommissioningWindow %s', e)
+ asserts.assert_true(False, 'Failed to open commissioning window')
+ return (longDiscriminator, params)
+
+ @async_test_body
+ async def test_TC_OPCREDS_3_1(self):
+ opcreds = Clusters.OperationalCredentials
+ # Create TH1
+ # Maximize cert chains so we can use this below
+ TH1_CA_real = self.certificate_authority_manager.NewCertificateAuthority(maximizeCertChains=True)
+ TH1_vid = 0xFFF2
+ TH1_fabric_admin_real = TH1_CA_real.NewFabricAdmin(vendorId=TH1_vid, fabricId=2)
+ TH1_nodeid = self.default_controller.nodeId+1
+ TH1 = TH1_fabric_admin_real.NewController(nodeId=TH1_nodeid)
+
+ commissioned_fabric_count = await self.read_single_attribute_check_success(
+ cluster=opcreds, attribute=opcreds.Attributes.CommissionedFabrics)
+
+ supported_fabric_count = await self.read_single_attribute_check_success(
+ cluster=opcreds, attribute=opcreds.Attributes.SupportedFabrics)
+
+ # Make sure we have space
+ # TODO: Add step here to just remove extra fabrics if required.
+ asserts.assert_less(commissioned_fabric_count, supported_fabric_count,
+ "Device fabric table is full - please remove one fabric and retry")
+
+ self.print_step(1, "TH0 opens a commissioning window on the DUT")
+ longDiscriminator, params = self.OpenCommissioningWindow(self.default_controller, self.dut_node_id)
+
+ self.print_step(
+ 2, "TH0 reads the BasicCommissioningInfo field from the General commissioning cluster saves MaxCumulativeFailsafeSeconds as `failsafe_max`")
+ basic_commissioning_info = await self.read_single_attribute_check_success(cluster=Clusters.GeneralCommissioning, attribute=Clusters.GeneralCommissioning.Attributes.BasicCommissioningInfo)
+ failsafe_max = basic_commissioning_info.maxCumulativeFailsafeSeconds
+
+ self.print_step(3, "TH1 opens a PASE connection to the DUT")
+ newNodeId = self.dut_node_id + 1
+ self.FindAndEstablishPase(dev_ctrl=TH1, longDiscriminator=longDiscriminator,
+ setupPinCode=params.setupPinCode, nodeid=newNodeId)
+
+ self.print_step(4, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to failsafe_max")
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=Clusters.GeneralCommissioning.Commands.ArmFailSafe(failsafe_max))
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(5, "TH1 Sends CSRRequest command with a random 32-byte nonce and saves the response as`csrResponse")
+ nonce = random.randbytes(32)
+ csrResponse = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=opcreds.Commands.CSRRequest(CSRNonce=nonce, isForUpdateNOC=False))
+
+ self.print_step(6, "TH1 obtains or generates the NOC, the Root CA Certificate and ICAC using csrResponse and selects an IPK. The certificates shall have their subjects padded with additional data such that they are each the maximum certificate size of 400 bytes when encoded in the MatterCertificateEncoding.")
+ # Our CA is set up to maximize cert chains already
+ # Extract the RCAC public key and save as `Root_Public_Key_TH1`
+ TH1_certs_real = TH1.IssueNOCChain(csrResponse, newNodeId)
+ if (TH1_certs_real.rcacBytes is None or
+ TH1_certs_real.icacBytes is None or
+ TH1_certs_real.nocBytes is None or TH1_certs_real.ipkBytes is None):
+ # Expiring the failsafe timer in an attempt to clean up.
+ await TH1.SendCommand(newNodeId, 0, Clusters.GeneralCommissioning.Commands.ArmFailSafe(0))
+ asserts.fail("Unable to generate NOC chain for DUT - this is a script failure, please report this as a bug")
+ th1_rcac_decoded = TLVReader(TH1_certs_real.rcacBytes).get()["Any"]
+ # public key is field 9
+ root_public_key_th1 = th1_rcac_decoded[9]
+
+ self.print_step(
+ 7, "TH1 obtains or generates Root Certificate with a different Root CA ID and the corresponding ICAC, NOC and IPK using csrResponse")
+ TH1_CA_fake = self.certificate_authority_manager.NewCertificateAuthority()
+ TH1_fabric_admin_fake = TH1_CA_fake.NewFabricAdmin(vendorId=0xFFF1, fabricId=2)
+ TH1_fake = TH1_fabric_admin_fake.NewController(nodeId=self.default_controller.nodeId)
+ TH1_certs_fake = TH1_fake.IssueNOCChain(csrResponse, newNodeId)
+ if (TH1_certs_fake.rcacBytes is None or
+ TH1_certs_fake.icacBytes is None or
+ TH1_certs_fake.nocBytes is None or TH1_certs_real.ipkBytes is None):
+ # Expiring the failsafe timer in an attempt to clean up.
+ await TH1.SendCommand(newNodeId, 0, Clusters.GeneralCommissioning.Commands.ArmFailSafe(0))
+ asserts.fail("Unable to generate NOC chain for DUT - this is a script failure, please report this as a bug")
+
+ self.print_step(
+ 8, "TH1 generates an INVALID Root Certificate where the signature does not match the public key and saves it as `Root_CA_Malformed`")
+ TH1_root_CA_malformed_decoded = copy.deepcopy(th1_rcac_decoded)
+ # signature is field 11
+ print(TH1_root_CA_malformed_decoded[11])
+ malformed_sig_int = int.from_bytes(TH1_root_CA_malformed_decoded[11], 'big') + 1
+ malformed_sig = malformed_sig_int.to_bytes(len(TH1_root_CA_malformed_decoded[11]), 'big')
+ TH1_root_CA_malformed_decoded[11] = malformed_sig
+
+ writer = TLVWriter(bytearray())
+ writer.startStructure(None)
+ for tag, val in TH1_root_CA_malformed_decoded.items():
+ TH1_root_CA_malformed = writer.put(tag, val)
+ writer.endContainer()
+ TH1_root_CA_malformed = writer.encoding
+
+ self.print_step(9, "TH1 reads the trusted root cert list from the DUT. Save the list size as trusted_root_original_size")
+ trusted_root_list = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ trusted_root_original_size = len(trusted_root_list)
+
+ self.print_step(
+ 10, "TH1 reads the NOCs attribute from the DUT using a non-fabric-filtered read. Save the list size as nocs_original_size")
+ nocs = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=False)
+ nocs_original_size = len(nocs)
+
+ self.print_step(11, "TH1 reads the fabrics attribute from the DUT. Save the list size as fabrics_original_size")
+ fabrics = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.Fabrics, fabric_filtered=False)
+ fabrics_original_size = len(fabrics)
+
+ self.print_step(
+ 12, "TH1 sends AddTrustedRootCertificate command to DUT to install `Root_CA_Malformed` and verifies INVALID_COMMAND is returned")
+ cmd = opcreds.Commands.AddTrustedRootCertificate(TH1_root_CA_malformed)
+ try:
+ await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.fail("Unexpected success adding trusted root cert with malformed signature")
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.InvalidCommand,
+ "Unexpected error adding trusted root cert with malformed signature")
+ self.print_step(
+ 13, "TH1 reads the TrustedRootCertificate attribute and confirm it contains only trusted_root_original_size entries")
+ ret = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(ret), trusted_root_original_size,
+ "Unexpected number of entries in the TrustedRootCertificates table")
+
+ self.print_step(
+ 14, "TH1 sends AddTrustedRootCertificate command to DUT with RootCACertificate set to `Root_CA_Certificate_TH1`, verify SUCCESS")
+ cmd = opcreds.Commands.AddTrustedRootCertificate(TH1_certs_real.rcacBytes)
+ await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+
+ self.print_step(
+ 15, "TH1 reads the TrustedRootCertificate attribute and confirms it contains trusted_root_original_size + 1 entries")
+ ret = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(ret), trusted_root_original_size + 1,
+ "Unexpected number of entries in the TrustedRootCertificates table")
+
+ self.print_step(
+ 16, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to `Root_CA_Certificate_TH1`, verify SUCCESS")
+ # TODO: This currently fails - bug in the SDK? See #30798
+ # await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+
+ self.print_step(
+ 17, "TH1 reads the TrustedRootCertificate attribute and confirms it contains trusted_root_original_size + 1 entries")
+ ret = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(ret), trusted_root_original_size + 1,
+ "Unexpected number of entries in the TrustedRootCertificates table")
+
+ self.print_step(
+ 18, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to `Root_CA_Certificate_TH1_2`, verify CONSTRAINT_ERROR")
+ try:
+ cmd = opcreds.Commands.AddTrustedRootCertificate(TH1_certs_fake.rcacBytes)
+ await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.fail("Unexpected success when adding second trusted root certificate")
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.ConstraintError, "Unexpected error when adding second trusted root certificate")
+
+ self.print_step(
+ 19, "TH1 reads the TrustedRootCertificate attribute and confirms it contains trusted_root_original_size + 1 entries")
+ ret = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(ret), trusted_root_original_size + 1,
+ "Unexpected number of entries in the TrustedRootCertificates table")
+
+ self.print_step(
+ 20, "TH1 appends `Root_CA_Certificate_TH1_2` to `TrustedRootsList` and writes the TrustedRootCertificates attribute with that value, Verify UNSUPPORTED_WRITE")
+ trusted_root_list.append(TH1_certs_fake.rcacBytes)
+ attr = opcreds.Attributes.TrustedRootCertificates(trusted_root_list)
+ err = await TH1.WriteAttribute(nodeid=newNodeId, attributes=[(0, attr)])
+ asserts.assert_equal(err[0].Status, Status.UnsupportedWrite,
+ "Unexpected error trying to write TrustedRootCertificate attribute")
+
+ self.print_step(21, "TH1 reads the TrustedRootCertificates list from DUT | Verify that there is only one instance of Root CA Certificate in the list and that its content matches `Root_CA_Certificate_TH1`")
+ ret = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(ret), trusted_root_original_size + 1,
+ "Unexpected number of entries in the TrustedRootCertificates table")
+
+ self.print_step(22, "TH1 sends the AddNOC Command to DUT for the certs generated with the second trusted root cert")
+ # Node_Operational_Certificate_TH1_2`
+ # ICACValue as `Intermediate_Certificate_TH1_2`
+ # IpkValue as `IPK_TH1_2`
+ # CaseAdminSubject as the NodeID of TH1
+ # AdminVendorId as the Vendor ID of TH1 a|* Verify that DUT responds with NOCResponse command with status code InvalidNOC
+ cmd = opcreds.Commands.AddNOC(NOCValue=TH1_certs_fake.nocBytes, ICACValue=TH1_certs_fake.icacBytes,
+ IPKValue=TH1_certs_fake.ipkBytes, caseAdminSubject=TH1_nodeid, adminVendorId=TH1_vid)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC,
+ "Unexpected error when adding Invalid NOC")
+
+ self.print_step(23, "TH1 sends the AddNOC Command to DUT with an invalid node ID")
+ # NOCValue as `Node_Operational_Certificate_TH1`
+ # ICACValue as `Intermediate_Certificate_TH1`
+ # IpkValue as `IPK_TH1`
+ # CaseAdminSubject is an invalid NodeID (not an operational Node ID or Case Authenticated Tag - ex. 0)
+ # AdminVendorId as the Vendor ID of TH1 a|* Verify that DUT responds with NOCResponse command with status code InvalidAdminSubject
+ cmd = opcreds.Commands.AddNOC(NOCValue=TH1_certs_real.nocBytes, ICACValue=TH1_certs_real.icacBytes,
+ IPKValue=TH1_certs_real.ipkBytes, caseAdminSubject=0, adminVendorId=TH1_vid)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidAdminSubject,
+ "Unexpected error when adding NOC with invalid case admin subject")
+
+ self.print_step(24, "TH1 sends the AddNOC Command to DUT a valid NOC")
+ # NOCValue as `Node_Operational_Certificate_TH1`
+ # ICACValue as `Intermediate_Certificate_TH1`
+ # IpkValue as `IPK_TH1`
+ # CaseAdminSubject as the NodeID of TH1
+ # AdminVendorId as the Vendor ID of TH1 a|* Verify that DUT responds with NOCResponse command with status code OK
+ # Verify that FabricIndex has a size of 1 byte
+ # save the fabric index.
+ cmd = opcreds.Commands.AddNOC(NOCValue=TH1_certs_real.nocBytes, ICACValue=TH1_certs_real.icacBytes,
+ IPKValue=TH1_certs_real.ipkBytes, caseAdminSubject=TH1_nodeid, adminVendorId=TH1_vid)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk, "Failure when adding NOC")
+
+ self.print_step(25, "TH1 re-sends the AddNOC Command to DUT and verifies CONSTRAINT_ERROR")
+ # NOCValue as `Node_Operational_Certificate_TH1_1`
+ # ICACValue as `Intermediate_Certificate_TH1_1`
+ # IpkValue as `IPK_TH1_1`
+ # CaseAdminSubject as the NodeID of TH1
+ # AdminVendorId as the Vendor ID of TH1 | Verify that DUT responds with status code CONSTRAINT_ERROR
+ try:
+ await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.fail("Unexpected success adding NOC for a second time")
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.ConstraintError, "Unexpected error when adding NOC for a second time")
+
+ self.print_step(26, "TH1 reads the NOCs attribute from DUT using a fabric-filtered read and saves the list as `NOCList`")
+ noc_list = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.NOCs)
+ asserts.assert_equal(len(noc_list), 1, "More than one NOC entry found for TH1")
+ asserts.assert_equal(noc_list[0].noc, TH1_certs_real.nocBytes, "NOC for TH1 does not match supplied NOC")
+ asserts.assert_equal(noc_list[0].icac, TH1_certs_real.icacBytes, "ICAC for TH1 does not match supplied ICAC")
+
+ self.print_step(
+ 27, "TH1 modified the TH1 NOC and ICAC to be from the Root_CA_Certificate_TH1_2 and writes that value to the NOCs attribute. Verify UNSUPPORTED_WRITE")
+ noc_list[0].noc = TH1_certs_fake.nocBytes
+ noc_list[0].icac = TH1_certs_fake.icacBytes
+ attr = opcreds.Attributes.NOCs(noc_list)
+ resp = await TH1.WriteAttribute(nodeid=newNodeId, attributes=[(0, attr)])
+ asserts.assert_equal(resp[0].Status, Status.UnsupportedWrite, "Write to NOC attribute did not fail with UnsupportedWrite")
+
+ self.print_step(
+ 28, "TH1 reads the NOCs attribute from DUT. Verify the NOC has not been updated.")
+ noc_list = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.NOCs)
+ asserts.assert_equal(len(noc_list), 1, "More than one NOC entry found for TH1")
+ asserts.assert_equal(noc_list[0].noc, TH1_certs_real.nocBytes, "NOC for TH1 does not match supplied NOC")
+ asserts.assert_equal(noc_list[0].icac, TH1_certs_real.icacBytes, "ICAC for TH1 does not match supplied ICAC")
+
+ self.print_step(29, "TH1 sends UpdateFabricLabel command with 'Label 1' as Label field to DUT, verify status OK")
+ cmd = opcreds.Commands.UpdateFabricLabel(label="Label 1")
+ resp = await self.send_single_cmd(cmd=cmd, dev_ctrl=TH1, node_id=newNodeId)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk, "Failure on UpdateFabricLabel")
+
+ self.print_step(30, "TH1 reads the Fabrics Attribute from DUT")
+ fabrics = await self.read_single_attribute_check_success(
+ dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.Fabrics)
+ asserts.assert_equal(len(fabrics), 1, "Unexpected number of fabrics returned")
+
+ self.print_step(31, "Read the other fields from FabricDescriptorStruct")
+ # 1. RootPublicKey
+ # 2. VendorID
+ # 3. FabricID
+ # 4. NodeID
+ # 5. Label
+ # Verify that the size of RootPublicKey is exactly 65 bytes
+ # Verify that the RootPublicKey matches `Root_Public_Key_TH1`
+ # Verify that the NodeID is the same as the matter-node-id field in the NOC sent with AddNOC Command
+ # Verify that the VendorID is the same as the AdminVendorID sent with AddNOC Command
+ # Verify that the FabricID is the same as the matter-fabric-id field in the NOC sent with AddNOC Command
+ # Verify that the Label field has value "Label 1"
+ asserts.assert_equal(len(fabrics[0].rootPublicKey), 65, "Root public key is not exactly 65 bytes")
+ asserts.assert_equal(fabrics[0].rootPublicKey, root_public_key_th1,
+ "Root public key in fabrics table does not match supplied key")
+ asserts.assert_equal(fabrics[0].nodeID, newNodeId, "NodeID in the fabrics table does not match the supplied node ID")
+ asserts.assert_equal(fabrics[0].vendorID, TH1_vid,
+ "VendorID in the fabrics table does not match the supplied vendor ID")
+ th1_noc_decoded = TLVReader(TH1_certs_real.nocBytes).get()["Any"]
+ # subject is field 6
+ noc_subject = th1_noc_decoded[6]
+ # noc_subject is a TLVList, so it can be accessed by key. Fabric ID is dn-attribute 21.
+ asserts.assert_equal(fabrics[0].fabricID, noc_subject[21],
+ "Fabric ID in the fabric table does not match the fabric ID in the NOC")
+
+ self.print_step(32, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds field set to 0")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=0, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, cmd=cmd, node_id=newNodeId)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(33, "TH1 reconnects to the DUT over PASE")
+ TH1.ExpireSessions(newNodeId)
+ self.FindAndEstablishPase(dev_ctrl=TH1, longDiscriminator=longDiscriminator,
+ setupPinCode=params.setupPinCode, nodeid=newNodeId)
+
+ self.print_step(34, "TH1 reads the TrustedRootCertificates list from DUT and verifies the TH1 root is not present")
+ trusted_root_list = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(trusted_root_list), trusted_root_original_size,
+ "TrustedRootCertificate was not properly removed from the list on ArmFailSafe expiration")
+
+ self.print_step(
+ 35, "TH1 reads the NOCs attribute from DUT using a non-fabric-filtered read and verifies that the list contains only nocs_original_size entries")
+ nocs = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=False)
+ asserts.assert_equal(len(nocs), nocs_original_size, "NOC list size does not match original")
+
+ self.print_step(
+ 36, "TH1 reads the Fabrics attribute from the DUT using a non-fabric-filtered read and verifies that the list contains only fabric_original_size entries")
+ fabrics = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.Fabrics, fabric_filtered=False)
+ asserts.assert_equal(len(fabrics), fabrics_original_size, "Fabric list size does not match original")
+
+ self.print_step(37, "TH1 fully commissions DUT onto the fabric using a set of valid certificates")
+ TH1.Commission(newNodeId)
+
+ self.print_step(
+ 38, "TH1 reads the TrustedRootCertificates list from DUT and verify that there are trusted_root_original_size + 1 entries")
+ trusted_root_list = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates)
+ asserts.assert_equal(len(trusted_root_list), trusted_root_original_size + 1, "Unexpected number of root certificates")
+
+ self.print_step(
+ 39, "TH1 reads the NOCs attribute from DUT using a non-fabric-filtered read and verifies that there are nocs_original_size + 1 entries")
+ nocs = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=False)
+ asserts.assert_equal(len(nocs), nocs_original_size+1, "Unexpected number of NOCs")
+
+ self.print_step(
+ 40, "TH1 reads the Fabrics attribute from DUT using a non-fabric-filtered read and verifies that there are fabrics_original_size + 1 entries")
+ fabrics = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.Fabrics, fabric_filtered=False)
+ asserts.assert_equal(len(fabrics), fabrics_original_size+1, "Fabric list size is incorrect")
+
+ self.print_step(41, "TH1 reads the ACL attribute from the Access Control cluster using a fabric-filtered read")
+ th1_fabric_index = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.CurrentFabricIndex)
+ acl = await self.read_single_attribute_check_success(dev_ctrl=TH1, node_id=newNodeId, cluster=Clusters.AccessControl, attribute=Clusters.AccessControl.Attributes.Acl)
+ # a| * Verify that the returned list includes an entry with:
+ # Fabric index of `FabricIndex_TH1`
+ # Administer privilege (5)
+ # CASE AuthMode (2)
+ # Includes the NodeID of TH1 in the list of subjects
+ th1_acl = [x for x in acl if x.fabricIndex == th1_fabric_index and x.privilege ==
+ Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister and x.authMode == Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase]
+ # There should be exactly one ACL for this fabric since we JUST commissioned it and didn't add any extra
+ asserts.assert_equal(len(th1_acl), 1, "Unexpected number of ACL entries for TH1")
+ asserts.assert_equal(th1_acl[0].subjects, [TH1_nodeid], "Unexpected subject list in ACL")
+
+ self.print_step(42, "TH1 issues a KeySetRead command to the DUT for GroupKeySetID 0")
+ cmd = Clusters.GroupKeyManagement.Commands.KeySetRead(groupKeySetID=0)
+ ret = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(ret.groupKeySet.groupKeySetID, 0, "Unexpected response from KeySetRead")
+
+ self.print_step(43, "TH1 sends UpdateFabricLabel command with 'Label 1' as Label field to DUT, verify status OK")
+ cmd = opcreds.Commands.UpdateFabricLabel(label="Label 1")
+ resp = await self.send_single_cmd(cmd=cmd, dev_ctrl=TH1, node_id=newNodeId)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk, "Failure on UpdateFabricLabel")
+
+ self.print_step(44, "TH1 sends an OpenCommissioningWindow command to the Administrator Commissioning cluster")
+ longDiscriminator, params = self.OpenCommissioningWindow(TH1, newNodeId)
+
+ self.print_step(45, "TH2 commissions the DUT")
+ TH2_CA = self.certificate_authority_manager.NewCertificateAuthority(maximizeCertChains=True)
+ TH2_vid = 0xFFF3
+ TH2_fabric_admin = TH2_CA.NewFabricAdmin(vendorId=TH2_vid, fabricId=3)
+ TH2_nodeid = self.default_controller.nodeId+2
+ TH2 = TH2_fabric_admin.NewController(nodeId=TH2_nodeid)
+ TH2_dut_nodeid = self.dut_node_id+2
+ TH2.CommissionOnNetwork(
+ nodeId=TH2_dut_nodeid, setupPinCode=params.setupPinCode,
+ filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=longDiscriminator)
+
+ self.print_step(
+ 46, "TH2 sends UpdateFabricLabel command with 'Label 2' as Label field to DUT and verify status OK")
+ cmd = opcreds.Commands.UpdateFabricLabel(label="Label 2")
+ resp = await self.send_single_cmd(cmd=cmd, dev_ctrl=TH2, node_id=TH2_dut_nodeid)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk, "Failure on UpdateFabricLabel")
+
+ self.print_step(
+ 47, "TH2 sends UpdateFabricLabel command with 'Label 1' as Label field to DUT and verify status is LabelConflict")
+ cmd = opcreds.Commands.UpdateFabricLabel(label="Label 1")
+ resp = await self.send_single_cmd(cmd=cmd, dev_ctrl=TH2, node_id=TH2_dut_nodeid)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kLabelConflict, "Unexpected error code on UpdateFabricLabel")
+
+ self.print_step(48, "Read the Fabrics List from DUT using a non-fabric-filtered read, verify fabrics_original_size + 2, check labels")
+ fabrics = await self.read_single_attribute_check_success(
+ dev_ctrl=TH1, node_id=newNodeId, cluster=opcreds, attribute=opcreds.Attributes.Fabrics, fabric_filtered=False)
+ asserts.assert_equal(len(fabrics), fabrics_original_size + 2, "Unexpected number of fabrics")
+ th1_fabric = [x for x in fabrics if x.vendorID == TH1_vid]
+ th2_fabric = [x for x in fabrics if x.vendorID == TH2_vid]
+ asserts.assert_equal(len(th1_fabric), 1, "Unexpected number of fabrics with TH1 vendor ID")
+ asserts.assert_equal(len(th2_fabric), 1, "Unexpected number of fabrics with TH2 vendor ID")
+ asserts.assert_equal(th1_fabric[0].label, "Label 1", "Unexpected label for TH1 fabric")
+ asserts.assert_equal(th2_fabric[0].label, "Label 2", "Unexpected label for TH2 fabric")
+
+ self.print_step(49, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to failsafe_max| Verify that the DUT sends ArmFailSafeResponse Command to TH1 with field ErrorCode as 'OK'(0)")
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=Clusters.GeneralCommissioning.Commands.ArmFailSafe(failsafe_max))
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(50, "TH1 sends AddTrustedRootCertificate command to DUT with RootCACertificate set to `Root_CA_Certificate_TH1_1` |Verify that AddTrustedRootCertificate Command succeeds by sending the status code as SUCCESS")
+ cmd = opcreds.Commands.AddTrustedRootCertificate(TH1_certs_real.rcacBytes)
+ await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+
+ self.print_step(51, "TH1 sends the AddNOC Command to DUT with the following fields:")
+ # NOCValue as `Node_Operational_Certificate_TH1_2`
+ # ICACValue as `Intermediate_Certificate_TH1_2`
+ # IpkValue as `IPK_TH1_2`
+ # CaseAdminSubject as the NodeID of TH1
+ # AdminVendorId as the Vendor ID of TH1 | Verify that DUT responds with status code MissingCsr
+ cmd = opcreds.Commands.AddNOC(NOCValue=TH1_certs_real.nocBytes, ICACValue=TH1_certs_real.icacBytes,
+ IPKValue=TH1_certs_real.ipkBytes, caseAdminSubject=TH1_nodeid, adminVendorId=TH1_vid)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Unexpected error code on AddNOC with no CSR")
+
+ self.print_step(52, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds set to 0")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=0, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(53, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds set to failsafe_max")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=failsafe_max, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(54, "TH1 Sends CSRRequest command with a random 32-byte nonce")
+ nonce = random.randbytes(32)
+ csrResponse_new = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=opcreds.Commands.CSRRequest(CSRNonce=nonce, isForUpdateNOC=False))
+
+ self.print_step(
+ 55, "TH1 generates a new RCAC, ICAC and NOC using the csr returned in step 4 (ie, NOT the most recent CSR)")
+ temp_CA = self.certificate_authority_manager.NewCertificateAuthority()
+ temp_fabric_admin = temp_CA.NewFabricAdmin(vendorId=0xFFF1, fabricId=3)
+ temp_controller = temp_fabric_admin.NewController(nodeId=self.default_controller.nodeId)
+ temp_certs = temp_controller.IssueNOCChain(csrResponse, newNodeId)
+ if (temp_certs.rcacBytes is None or
+ temp_certs.icacBytes is None or
+ temp_certs.nocBytes is None or temp_certs.ipkBytes is None):
+ # Expiring the failsafe timer in an attempt to clean up.
+ await TH1.SendCommand(newNodeId, 0, Clusters.GeneralCommissioning.Commands.ArmFailSafe(0))
+ asserts.fail("Unable to generate NOC chain for DUT - this is a script failure, please report this as a bug")
+
+ self.print_step(56, "TH1 sends the AddTrustedRootCert command using the certs generated in step 54")
+ cmd = opcreds.Commands.AddTrustedRootCertificate(temp_certs.rcacBytes)
+ await self.send_single_cmd(cmd=cmd, dev_ctrl=TH1, node_id=newNodeId)
+
+ self.print_step(57, "TH1 sends the AddNOC Command to DUT using the certs generated in step 54")
+ cmd = opcreds.Commands.AddNOC(NOCValue=temp_certs.nocBytes, ICACValue=temp_certs.icacBytes,
+ IPKValue=temp_certs.ipkBytes, caseAdminSubject=TH1_nodeid, adminVendorId=TH1_vid)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey, "Unexpected error code on AddNOC with mismatched CSR")
+
+ self.print_step(58, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds set to 0")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=0, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(59, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds set to failsafe_max")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=failsafe_max, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(60, "TH1 Sends CSRRequest command with a random 32-byte nonce")
+ nonce = random.randbytes(32)
+ csrResponse_new = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=opcreds.Commands.CSRRequest(CSRNonce=nonce, isForUpdateNOC=False))
+
+ self.print_step(61, "TH1 obtains or generates a NOC and ICAC using the CSR elements from the previous step with a different NodeID, but the same Root CA Certificate and fabric ID as step <>. Save as `Node_Operational_Certificates_TH1_fabric_conflict` and `Intermediate_Certificate_TH1_fabric_conflict`|")
+ anotherNodeId = newNodeId + 1
+ TH1_certs_fabric_conflict = TH1.IssueNOCChain(csrResponse_new, anotherNodeId)
+ if (TH1_certs_fabric_conflict.rcacBytes is None or
+ TH1_certs_fabric_conflict.icacBytes is None or
+ TH1_certs_fabric_conflict.nocBytes is None or TH1_certs_fabric_conflict.ipkBytes is None):
+ # Expiring the failsafe timer in an attempt to clean up.
+ await TH1.SendCommand(newNodeId, 0, Clusters.GeneralCommissioning.Commands.ArmFailSafe(0))
+ asserts.fail("Unable to generate NOC chain for DUT - this is a script failure, please report this as a bug")
+
+ self.print_step(62, "TH1 sends the AddTrustedRootCert command using the certs generated in step 60")
+ cmd = opcreds.Commands.AddTrustedRootCertificate(TH1_certs_fabric_conflict.rcacBytes)
+ await self.send_single_cmd(cmd=cmd, dev_ctrl=TH1, node_id=newNodeId)
+
+ self.print_step(63, "TH1 sends the AddNOC Command to DUT with the fabric conflict certs")
+ cmd = opcreds.Commands.AddNOC(NOCValue=TH1_certs_fabric_conflict.nocBytes, ICACValue=TH1_certs_fabric_conflict.icacBytes,
+ IPKValue=TH1_certs_fabric_conflict.ipkBytes, caseAdminSubject=TH1_nodeid, adminVendorId=TH1_vid)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(
+ resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kFabricConflict, "Unexpected error code on AddNOC with mismatched CSR")
+
+ self.print_step(64, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds set to 0| Verify that the DUT sends ArmFailSafeResponse Command to TH1 with field ErrorCode as 'OK'(0)")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=0, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(
+ 65, "TH1 reads the TrustedRootCertificates list from DUT | Verify the list contains `trusted_root_original_size` + 2 entries")
+ resp = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.TrustedRootCertificates, dev_ctrl=TH1, node_id=newNodeId)
+ asserts.assert_equal(len(resp), trusted_root_original_size + 2, "Unexpected number of trusted roots")
+
+ self.print_step(66, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to failsafe_max| Verify that the DUT sends ArmFailSafeResponse Command to TH1 with field ErrorCode as 'OK'(0)")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=failsafe_max, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(
+ 67, "TH1 Sends CSRRequest command with a random 32-byte nonce and the IsForUpdateNOC field set to true a|* Verify that the DUT responds with the CSRResponse Command")
+ nonce = random.randbytes(32)
+ csrResponse = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=opcreds.Commands.CSRRequest(CSRNonce=nonce, isForUpdateNOC=True))
+ asserts.assert_true(isinstance(csrResponse, opcreds.Commands.CSRResponse),
+ "Unexpected response type for UpdateNOC csr request")
+
+ self.print_step(68, "TH1 obtains or generates a NOC, Root CA Certificate, ICAC using the CSR elements from the previous step")
+ TH1_certs_3 = TH1.IssueNOCChain(csrResponse, anotherNodeId)
+ if (TH1_certs_3.rcacBytes is None or
+ TH1_certs_3.icacBytes is None or
+ TH1_certs_3.nocBytes is None or TH1_certs_3.ipkBytes is None):
+ # Expiring the failsafe timer in an attempt to clean up.
+ await TH1.SendCommand(newNodeId, 0, Clusters.GeneralCommissioning.Commands.ArmFailSafe(0))
+ asserts.fail("Unable to generate NOC chain for DUT - this is a script failure, please report this as a bug")
+ # Save RCAC as `Root_CA_Certificate_TH1_3`
+ # Save ICAC as `Intermediate_Certificate_TH1_3`
+ # Save NOC as `Node_Operational_Certificate_TH1_3` |
+
+ self.print_step(69, "TH1 sends AddTrustedRootCertificate command to DUT with RootCACertificate set to `Root_CA_Certificate_TH1_3` |Verify that AddTrustedRootCertificate Command succeeds by sending the status code as SUCCESS")
+ # TODO(#3126): This currently fails. This failure actually makes sense, though, and we should backport this to the spec and expect a failure here.
+ # cmd = opcreds.Commands.AddTrustedRootCertificate(TH1_certs_3.rcacBytes)
+ # await self.send_single_cmd(cmd=cmd, dev_ctrl=TH1, node_id=newNodeId)
+
+ self.print_step(70, "TH1 sends the AddNOC Command to DUT with the following fields:")
+ # TODO(#3126) - consider removing this when we adjust the spec to expect a failure on the above.
+ # cmd = opcreds.Commands.UpdateNOC(NOCValue=TH1_certs_3.nocBytes, ICACValue=TH1_certs_3.icacBytes)
+ # resp = await self.send_single_cmd(cmd=cmd, dev_ctrl=TH1, node_id=newNodeId)
+
+ self.print_step(71, "TH1 sends ArmFailSafe command to the DUT with ExpiryLengthSeconds set to 0| Verify that the DUT sends ArmFailSafeResponse Command to TH1 with field ErrorCode as 'OK'(0)")
+ cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=0, breadcrumb=0)
+ resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=cmd)
+ asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk,
+ "Failure status returned from arm failsafe")
+
+ self.print_step(72, "TH2 reads its fabric index from the CurrentFabricIndex attribute and saves as FabricIndex_TH2")
+ fabric_index_th2 = await self.read_single_attribute_check_success(
+ cluster=opcreds, attribute=opcreds.Attributes.CurrentFabricIndex, dev_ctrl=TH2, node_id=TH2_dut_nodeid)
+
+ self.print_step(73, "TH2 sends RemoveFabric command with Fabric Index as FabricIndexTH2 + 5 (Invalid Fabric Index) to DUT | Verify that DUT sends NOCResponse Command with StatusCode of InvalidFabricIndex")
+ cmd = opcreds.Commands.RemoveFabric(fabric_index_th2 + 5)
+ resp = await self.send_single_cmd(dev_ctrl=TH2, node_id=TH2_dut_nodeid, cmd=cmd)
+ asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidFabricIndex)
+
+ self.print_step(74, "TH2 reads the Fabrics List from DUT using a non-fabric-filtered read")
+ resp = await self.read_single_attribute_check_success(cluster=opcreds, attribute=opcreds.Attributes.Fabrics, dev_ctrl=TH2, node_id=TH2_dut_nodeid, fabric_filtered=False)
+ asserts.assert_equal(len(resp), fabrics_original_size + 2, "Unexpected number of fabrics on device")
+
+ self.print_step(75, "TH1 reads its fabric index from the CurrentFabricIndex attribute and saves as FabricIndex_TH1")
+ fabric_index_th1 = await self.read_single_attribute_check_success(
+ cluster=opcreds, attribute=opcreds.Attributes.CurrentFabricIndex, dev_ctrl=TH1, node_id=newNodeId)
+
+ self.print_step(
+ 76, "TH0 sends RemoveFabric command with Fabric Index as FabricIndex_TH1")
+ cmd = opcreds.Commands.RemoveFabric(fabric_index_th1)
+ resp = await self.send_single_cmd(cmd=cmd)
+ asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk)
+
+ self.print_step(
+ 77, "TH0 sends RemoveFabric command with Fabric Index as FabricIndex_TH2")
+ cmd = opcreds.Commands.RemoveFabric(fabric_index_th2)
+ resp = await self.send_single_cmd(cmd=cmd)
+ asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk)
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_2_1.py b/src/python_testing/TC_VALCC_2_1.py
new file mode 100644
index 00000000000000..c9f40d34694432
--- /dev/null
+++ b/src/python_testing/TC_VALCC_2_1.py
@@ -0,0 +1,177 @@
+#
+# 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.
+#
+
+import logging
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_2_1(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_2_1(self) -> str:
+ return "[TC-VALCC-2.1] Attributes with DUT as Server"
+
+ def steps_TC_VALCC_2_1(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Read attribute list to determine supported attributes"),
+ TestStep(3, "Read OpenDuration attribute, if supported"),
+ TestStep(4, "Read DefaultOpenDuration attribute, if supported"),
+ TestStep(5, "Read AutoCloseTime attribute, if supported"),
+ TestStep(6, "Read RemainingDuration attribute, if supported"),
+ TestStep(7, "Read CurrentState attribute, if supported"),
+ TestStep(8, "Read TargetState attribute, if supported"),
+ TestStep(9, "Read CurrentLevel attribute, if supported"),
+ TestStep(10, "Read TargetLevel attribute, if supported"),
+ TestStep(11, "Read DefaultOpenLevel attribute, if supported"),
+ TestStep(12, "Read ValveFault attribute, if supported"),
+ TestStep(13, "Read LevelStep attribute, if supported")
+ ]
+ return steps
+
+ def pics_TC_VALCC_2_1(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_2_1(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ attribute_list = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList)
+
+ self.step(3)
+ if attributes.OpenDuration.attribute_id in attribute_list:
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+
+ if open_duration_dut is not NullValue:
+ asserts.assert_less_equal(open_duration_dut, 0xFFFFFFFE, "OpenDuration attribute is out of range")
+ asserts.assert_greater_equal(open_duration_dut, 1, "OpenDuration attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(4)
+ if attributes.DefaultOpenDuration.attribute_id in attribute_list:
+ default_open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultOpenDuration)
+
+ if default_open_duration_dut is not NullValue:
+ asserts.assert_less_equal(default_open_duration_dut, 0xFFFFFFFE, "DefaultOpenDuration attribute is out of range")
+ asserts.assert_greater_equal(default_open_duration_dut, 1, "DefaultOpenDuration attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(5)
+ if attributes.AutoCloseTime.attribute_id in attribute_list:
+ auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime)
+
+ if auto_close_time_dut is not NullValue:
+ asserts.assert_less_equal(auto_close_time_dut, 0xFFFFFFFFFFFFFFFE, "OpenDuration attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(6)
+ if attributes.RemainingDuration.attribute_id in attribute_list:
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+
+ if remaining_duration_dut is not NullValue:
+ asserts.assert_less_equal(remaining_duration_dut, 0xFFFFFFFE, "RemainingDuration attribute is out of range")
+ asserts.assert_greater_equal(remaining_duration_dut, 1, "RemainingDuration attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(7)
+ if attributes.CurrentState.attribute_id in attribute_list:
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+
+ if current_state_dut is not NullValue:
+ asserts.assert_less(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kUnknownEnumValue,
+ "CurrentState is not in valid range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(8)
+ if attributes.TargetState.attribute_id in attribute_list:
+ target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState)
+
+ if target_state_dut is not NullValue:
+ asserts.assert_less(target_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kUnknownEnumValue,
+ "TargetState is not in valid range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(9)
+ if attributes.CurrentLevel.attribute_id in attribute_list:
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+
+ if current_level_dut is not NullValue:
+ asserts.assert_less_equal(current_level_dut, 100, "CurrentLevel attribute is out of range")
+ asserts.assert_greater_equal(current_level_dut, 0, "CurrentLevel attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(10)
+ if attributes.TargetLevel.attribute_id in attribute_list:
+ target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel)
+
+ if target_level_dut is not NullValue:
+ asserts.assert_less_equal(target_level_dut, 100, "TargetLevel attribute is out of range")
+ asserts.assert_greater_equal(target_level_dut, 0, "TargetLevel attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(11)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ default_open_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultOpenLevel)
+
+ if default_open_level_dut is not NullValue:
+ asserts.assert_less_equal(default_open_level_dut, 100, "DefaultOpenLevel attribute is out of range")
+ asserts.assert_greater_equal(default_open_level_dut, 1, "DefaultOpenLevel attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(12)
+ if attributes.ValveFault.attribute_id in attribute_list:
+ valve_fault_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.ValveFault)
+
+ asserts.assert_less_equal(valve_fault_dut, 0b00000111, "ValveFault is not in valid range")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(13)
+ if attributes.LevelStep.attribute_id in attribute_list:
+ level_step_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.LevelStep)
+
+ asserts.assert_less_equal(level_step_dut, 50, "LevelStep attribute is out of range")
+ asserts.assert_greater_equal(level_step_dut, 1, "LevelStep attribute is out of range")
+ else:
+ logging.info("Test step skipped")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_3_1.py b/src/python_testing/TC_VALCC_3_1.py
new file mode 100644
index 00000000000000..1b73976bdd9aae
--- /dev/null
+++ b/src/python_testing/TC_VALCC_3_1.py
@@ -0,0 +1,117 @@
+#
+# 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.
+#
+
+import time
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_3_1(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_3_1(self) -> str:
+ return "[TC-VALCC-3.1] Basic state functionality with DUT as Server"
+
+ def steps_TC_VALCC_3_1(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Send Open command"),
+ TestStep(3, "Read TargetState attribute"),
+ TestStep(4, "Read CurrentState attribute"),
+ TestStep(5, "Send Close command"),
+ TestStep(6, "Read TargetState attribute"),
+ TestStep(7, "Read CurrentState attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_3_1(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_3_1(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(3)
+ target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState)
+
+ asserts.assert_true(target_state_dut is not NullValue, "TargetState is null")
+ asserts.assert_equal(target_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen,
+ "TargetState is not the expected value")
+
+ self.step(4)
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+
+ while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning:
+ time.sleep(1)
+
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+
+ asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen,
+ "CurrentState is not the expected value")
+
+ self.step(5)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(6)
+ target_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState)
+
+ asserts.assert_true(target_state_dut is not NullValue, "TargetState is null")
+ asserts.assert_equal(target_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed,
+ "TargetState is not the expected value")
+
+ self.step(7)
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+
+ while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning:
+ time.sleep(1)
+
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+
+ asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed,
+ "CurrentState is not the expected value")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_3_2.py b/src/python_testing/TC_VALCC_3_2.py
new file mode 100644
index 00000000000000..1cd672f6a3ee2c
--- /dev/null
+++ b/src/python_testing/TC_VALCC_3_2.py
@@ -0,0 +1,138 @@
+#
+# 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.
+#
+
+import logging
+import time
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_3_2(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_3_2(self) -> str:
+ return "[TC-VALCC-3.2] Basic level functionality with DUT as Server"
+
+ def steps_TC_VALCC_3_2(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Read FeatureMap attribute"),
+ TestStep(3, "Send Open command with TargetLevel set to 100"),
+ TestStep(4, "Read TargetLevel attribute"),
+ TestStep(5, "Read CurrentLevel attribute"),
+ TestStep(6, "Send Close command"),
+ TestStep(7, "Read TargetLevel attribute"),
+ TestStep(8, "Read CurrentLevel attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_3_2(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_3_2(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ feature_map = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap)
+
+ is_lvl_feature_supported = feature_map & Clusters.ValveConfigurationAndControl.Bitmaps.Feature.kLevel
+
+ self.step(3)
+ if is_lvl_feature_supported:
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(targetLevel=100), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+ else:
+ logging.info("Test step skipped")
+
+ self.step(4)
+ if is_lvl_feature_supported:
+ target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel)
+
+ asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null")
+ asserts.assert_equal(target_level_dut, 100, "TargetLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(5)
+ if is_lvl_feature_supported:
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ while current_level_dut != 100:
+ time.sleep(1)
+
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ asserts.assert_equal(current_level_dut, 100, "CurrentLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(6)
+ if is_lvl_feature_supported:
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+ else:
+ logging.info("Test step skipped")
+
+ self.step(7)
+ if is_lvl_feature_supported:
+ target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel)
+
+ asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null")
+ asserts.assert_equal(target_level_dut, 0, "TargetLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(8)
+ if is_lvl_feature_supported:
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ while current_level_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning:
+ time.sleep(1)
+
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ asserts.assert_equal(current_level_dut, 0, "CurrentLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_3_3.py b/src/python_testing/TC_VALCC_3_3.py
new file mode 100644
index 00000000000000..d987516e67ccaa
--- /dev/null
+++ b/src/python_testing/TC_VALCC_3_3.py
@@ -0,0 +1,143 @@
+#
+# 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.
+#
+
+import logging
+import time
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_3_3(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_3_3(self) -> str:
+ return "[TC-VALCC-3.3] DefaultOpenLevel functionality with DUT as Server"
+
+ def steps_TC_VALCC_3_3(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Read AttributeList attribute"),
+ TestStep(3, "Read DefaultOpenLevel attribute, if supported"),
+ TestStep(4, "Send Open command"),
+ TestStep(5, "Read TargetLevel attribute"),
+ TestStep(6, "Read CurrentLevel attribute"),
+ TestStep(7, "Send Close command"),
+ TestStep(8, "Read TargetLevel attribute"),
+ TestStep(9, "Read CurrentLevel attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_3_3(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_3_3(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ attribute_list = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList)
+
+ self.step(3)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ defaultOpenLevel = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultOpenLevel)
+ else:
+ logging.info("Test step skipped")
+
+ self.step(4)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+ else:
+ logging.info("Test step skipped")
+
+ self.step(5)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel)
+
+ asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null")
+ asserts.assert_equal(target_level_dut, defaultOpenLevel, "TargetLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(6)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ while current_level_dut != defaultOpenLevel:
+ time.sleep(1)
+
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ asserts.assert_equal(current_level_dut, defaultOpenLevel, "CurrentLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(7)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+ else:
+ logging.info("Test step skipped")
+
+ self.step(8)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ target_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel)
+
+ asserts.assert_true(target_level_dut is not NullValue, "TargetLevel is null")
+ asserts.assert_equal(target_level_dut, 0, "TargetLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(9)
+ if attributes.DefaultOpenLevel.attribute_id in attribute_list:
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ while current_level_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning:
+ time.sleep(1)
+
+ current_level_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
+ asserts.assert_true(current_level_dut is not NullValue, "CurrentLevel is null")
+
+ asserts.assert_equal(current_level_dut, 0, "CurrentLevel is not the expected value")
+ else:
+ logging.info("Test step skipped")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_3_4.py b/src/python_testing/TC_VALCC_3_4.py
new file mode 100644
index 00000000000000..cef6bb81ee5ff0
--- /dev/null
+++ b/src/python_testing/TC_VALCC_3_4.py
@@ -0,0 +1,105 @@
+#
+# 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.
+#
+
+import logging
+
+import chip.clusters as Clusters
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_3_4(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_3_4(self) -> str:
+ return "[TC-VALCC-3.4] LevelStep behavior with DUT as Server"
+
+ def steps_TC_VALCC_3_4(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Read AttributeList attribute"),
+ TestStep(3, "Verify LevelStep is supported"),
+ TestStep(4, "Read LevelStep attribute"),
+ TestStep(5, "Verify the supported level values using Open Command"),
+ TestStep(6, "Send Close command"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_3_4(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_3_4(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ attribute_list = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList)
+
+ self.step(3)
+ if attributes.LevelStep.attribute_id not in attribute_list:
+ logging.info("LevelStep not supported skipping test case")
+
+ # Skipping all remainig steps
+ for step in self.get_test_steps(self.current_test_info.name)[self.current_step_index:]:
+ self.step(step.test_plan_number)
+ logging.info("Test step skipped")
+
+ return
+
+ else:
+ logging.info("Test step skipped")
+
+ self.step(4)
+ levelStep = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.LevelStep)
+
+ self.step(5)
+
+ for levelValue in range(1, 100):
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(targetLevel=levelValue), endpoint=endpoint)
+
+ if levelValue % levelStep != 0:
+ asserts.fail("Received Success response when an CONSTRAINT_ERROR was expected")
+
+ except InteractionModelError as e:
+ if levelValue % levelStep != 0:
+ asserts.assert_equal(e.status, Status.ConstraintError,
+ "Unexpected error returned when an CONSTRAINT_ERROR was expected")
+ else:
+ asserts.fail("Unexpected error returned")
+ pass
+
+ self.step(6)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_4_1.py b/src/python_testing/TC_VALCC_4_1.py
new file mode 100644
index 00000000000000..f9a1488ddf754d
--- /dev/null
+++ b/src/python_testing/TC_VALCC_4_1.py
@@ -0,0 +1,107 @@
+#
+# 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.
+#
+
+import time
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_4_1(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_4_1(self) -> str:
+ return "[TC-VALCC-4.1] Duration functionality with DUT as Server"
+
+ def steps_TC_VALCC_4_1(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Send Open command with duration set to 60"),
+ TestStep(3, "Read OpenDuration attribute"),
+ TestStep(4, "Read RemainingDuration attribute"),
+ TestStep(5, "Wait for 5 seconds"),
+ TestStep(6, "Read RemainingDuration attribute"),
+ TestStep(7, "Send Close command"),
+ TestStep(8, "Read OpenDuration attribute"),
+ TestStep(9, "Read RemainingDuration attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_4_1(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_4_1(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=60), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(3)
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+ asserts.assert_true(open_duration_dut is not NullValue, "OpenDuration is null")
+ asserts.assert_equal(open_duration_dut, 60, "OpenDuration is not the expected value")
+
+ self.step(4)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null")
+ asserts.assert_greater_equal(remaining_duration_dut, 55, "RemainingDuration is not in the expected range")
+ asserts.assert_less_equal(remaining_duration_dut, 60, "RemainingDuration is not in the expected range")
+
+ self.step(5)
+ time.sleep(5)
+
+ self.step(6)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null")
+ asserts.assert_greater_equal(remaining_duration_dut, 50, "RemainingDuration is not in the expected range")
+ asserts.assert_less_equal(remaining_duration_dut, 55, "RemainingDuration is not in the expected range")
+
+ self.step(7)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(8)
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+ asserts.assert_true(open_duration_dut is NullValue, "OpenDuration is not null")
+
+ self.step(9)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is NullValue, "RemainingDuration is not null")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_4_2.py b/src/python_testing/TC_VALCC_4_2.py
new file mode 100644
index 00000000000000..85ee4f8d4d34ec
--- /dev/null
+++ b/src/python_testing/TC_VALCC_4_2.py
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+
+import logging
+import time
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_4_2(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_4_2(self) -> str:
+ return "[TC-VALCC-4.2] DefaultOpenDuration functionality with DUT as Server"
+
+ def steps_TC_VALCC_4_2(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep("2a", "Read DefaultOpenDuration attribute"),
+ TestStep("2b", "Write DefaultOpenDuration attribute"),
+ TestStep(3, "Send Open command"),
+ TestStep(4, "Read OpenDuration attribute"),
+ TestStep(5, "Read RemainingDuration attribute"),
+ TestStep(6, "Wait for 5 seconds"),
+ TestStep(7, "Read RemainingDuration attribute"),
+ TestStep(8, "Send Close command"),
+ TestStep(9, "Read OpenDuration attribute"),
+ TestStep(10, "Read RemainingDuration attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_4_2(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_4_2(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step("2a")
+ defaultOpenDuration = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultOpenDuration)
+
+ self.step("2b")
+ if defaultOpenDuration is NullValue:
+ defaultOpenDuration = 60
+
+ result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.DefaultOpenDuration(defaultOpenDuration))])
+ asserts.assert_equal(result[0].Status, Status.Success, "DefaultOpenDuration write failed")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(3)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(4)
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+ asserts.assert_true(open_duration_dut is not NullValue, "OpenDuration is null")
+ asserts.assert_equal(open_duration_dut, defaultOpenDuration, "OpenDuration is not the expected value")
+
+ self.step(5)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null")
+ asserts.assert_greater_equal(remaining_duration_dut, (defaultOpenDuration - 5),
+ "RemainingDuration is not in the expected range")
+ asserts.assert_less_equal(remaining_duration_dut, defaultOpenDuration, "RemainingDuration is not in the expected range")
+
+ self.step(6)
+ time.sleep(5)
+
+ self.step(7)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null")
+ asserts.assert_greater_equal(remaining_duration_dut, (defaultOpenDuration - 10),
+ "RemainingDuration is not in the expected range")
+ asserts.assert_less_equal(remaining_duration_dut, (defaultOpenDuration - 5),
+ "RemainingDuration is not in the expected range")
+
+ self.step(8)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(9)
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+ asserts.assert_true(open_duration_dut is NullValue, "OpenDuration is not null")
+
+ self.step(10)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is NullValue, "RemainingDuration is not null")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_4_3.py b/src/python_testing/TC_VALCC_4_3.py
new file mode 100644
index 00000000000000..5869328958f64a
--- /dev/null
+++ b/src/python_testing/TC_VALCC_4_3.py
@@ -0,0 +1,168 @@
+#
+# 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.
+#
+
+import logging
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_4_3(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_4_3(self) -> str:
+ return "[TC-VALCC-4.3] AutoCloseTime functionality with DUT as Server"
+
+ def steps_TC_VALCC_4_3(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Read FeatureMap attribute"),
+ TestStep(3, "Verify TimeSync feature is supported"),
+ TestStep(4, "Send Open command with duration set to 60"),
+ TestStep(5, "Read UTCTime attribute from TimeSync cluster"),
+ TestStep(6, "Read AutoCloseTime attribute"),
+ TestStep(7, "Send Close command"),
+ TestStep(8, "Read AutoCloseTime attribute"),
+ TestStep("9a", "Read DefaultOpenDuration attribute"),
+ TestStep("9b", "Write DefaultOpenDuration attribute"),
+ TestStep(10, "Send Open command"),
+ TestStep(11, "Read UTCTime attribute from TimeSync cluster"),
+ TestStep(12, "Read AutoCloseTime attribute"),
+ TestStep(13, "Send Close command"),
+ TestStep(14, "Read AutoCloseTime attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_4_3(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_4_3(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ feature_map = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap)
+
+ is_ts_feature_supported = feature_map & Clusters.ValveConfigurationAndControl.Bitmaps.Feature.kTimeSync
+
+ self.step(3)
+ if not is_ts_feature_supported:
+ logging.info("TimeSync feature not supported skipping test case")
+
+ # Skipping all remainig steps
+ for step in self.get_test_steps(self.current_test_info.name)[self.current_step_index:]:
+ self.step(step.test_plan_number)
+ logging.info("Test step skipped")
+
+ return
+
+ else:
+ logging.info("Test step skipped")
+
+ self.step(4)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=60), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(5)
+ utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime)
+ asserts.assert_true(utcTime is not NullValue, "OpenDuration is null")
+
+ self.step(6)
+ auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime)
+
+ asserts.assert_true(auto_close_time_dut is not NullValue, "AutoCloseTime is null")
+ asserts.assert_greater_equal(auto_close_time_dut, (utcTime + 55000000),
+ "AutoCloseTime is not in the expected range")
+ asserts.assert_less_equal(auto_close_time_dut, (utcTime + 60000000), "AutoCloseTime is not in the expected range")
+
+ self.step(7)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(8)
+ auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime)
+
+ asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null")
+
+ self.step("9a")
+ defaultOpenDuration = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+
+ asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null")
+
+ self.step("9b")
+ if defaultOpenDuration is NullValue:
+ defaultOpenDuration = 60
+
+ result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.DefaultOpenDuration(defaultOpenDuration))])
+ asserts.assert_equal(result[0].Status, Status.Success, "DefaultOpenDuration write failed")
+ else:
+ logging.info("Test step skipped")
+
+ self.step(10)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(11)
+ utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime)
+
+ asserts.assert_true(utcTime is not NullValue, "OpenDuration is null")
+
+ self.step(12)
+ auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime)
+
+ asserts.assert_true(auto_close_time_dut is not NullValue, "AutoCloseTime is null")
+ asserts.assert_greater_equal(auto_close_time_dut, (utcTime + ((defaultOpenDuration - 5) * 1000000)),
+ "AutoCloseTime is not in the expected range")
+ asserts.assert_less_equal(auto_close_time_dut, (utcTime + (defaultOpenDuration * 1000000)),
+ "AutoCloseTime is not in the expected range")
+
+ self.step(13)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(14)
+ auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime)
+
+ asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VALCC_4_4.py b/src/python_testing/TC_VALCC_4_4.py
new file mode 100644
index 00000000000000..0d7d1184dbcda3
--- /dev/null
+++ b/src/python_testing/TC_VALCC_4_4.py
@@ -0,0 +1,113 @@
+#
+# 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.
+#
+
+import time
+
+import chip.clusters as Clusters
+from chip.clusters.Types import NullValue
+from chip.interaction_model import InteractionModelError, Status
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_VALCC_4_4(MatterBaseTest):
+ async def read_valcc_attribute_expect_success(self, endpoint, attribute):
+ cluster = Clusters.Objects.ValveConfigurationAndControl
+ return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
+
+ def desc_TC_VALCC_4_4(self) -> str:
+ return "[TC-VALCC-4.4] Auto close functionality with DUT as Server"
+
+ def steps_TC_VALCC_4_4(self) -> list[TestStep]:
+ steps = [
+ TestStep(1, "Commissioning, already done", is_commissioning=True),
+ TestStep(2, "Send Open command with duration set to 5"),
+ TestStep(3, "Read OpenDuration attribute"),
+ TestStep(4, "Read RemainingDuration attribute"),
+ TestStep(5, "Read CurrentState attribute"),
+ TestStep(6, "Wait 6 seconds"),
+ TestStep(7, "Read OpenDuration attribute"),
+ TestStep(8, "Read RemainingDuration attribute"),
+ TestStep(9, "Read CurrentState attribute"),
+ ]
+ return steps
+
+ def pics_TC_VALCC_4_4(self) -> list[str]:
+ pics = [
+ "VALCC.S",
+ ]
+ return pics
+
+ @async_test_body
+ async def test_TC_VALCC_4_4(self):
+
+ endpoint = self.user_params.get("endpoint", 1)
+
+ self.step(1)
+ attributes = Clusters.ValveConfigurationAndControl.Attributes
+
+ self.step(2)
+ try:
+ await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=5), endpoint=endpoint)
+ except InteractionModelError as e:
+ asserts.assert_equal(e.status, Status.Success, "Unexpected error returned")
+ pass
+
+ self.step(3)
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+ asserts.assert_true(open_duration_dut is not NullValue, "OpenDuration is null")
+ asserts.assert_equal(open_duration_dut, 5, "OpenDuration is not the expected value")
+
+ self.step(4)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null")
+ asserts.assert_greater_equal(remaining_duration_dut, 1, "RemainingDuration is not in the expected range")
+ asserts.assert_less_equal(remaining_duration_dut, 5, "RemainingDuration is not in the expected range")
+
+ self.step(5)
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+
+ while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning:
+ time.sleep(1)
+
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+
+ asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen,
+ "CurrentState is not the expected value")
+
+ self.step(6)
+ time.sleep(6)
+
+ self.step(7)
+ open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
+ asserts.assert_true(open_duration_dut is NullValue, "OpenDuration is not null")
+
+ self.step(8)
+ remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
+ asserts.assert_true(remaining_duration_dut is NullValue, "RemainingDuration is not null")
+
+ self.step(9)
+ current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
+ asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null")
+ asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed,
+ "CurrentState is not the expected value")
+
+
+if __name__ == "__main__":
+ default_matter_test_main()
diff --git a/src/python_testing/TC_VCC_2_1.py b/src/python_testing/TC_VCC_2_1.py
deleted file mode 100644
index 9d976e377e7e57..00000000000000
--- a/src/python_testing/TC_VCC_2_1.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-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_VCC_2_1(MatterBaseTest):
- async def read_ts_attribute_expect_success(self, endpoint, attribute):
- cluster = Clusters.Objects.ValveConfigurationAndControl
- return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute)
-
- @async_test_body
- async def test_TC_VCC_2_1(self):
-
- endpoint = self.user_params.get("endpoint", 1)
-
- self.print_step(1, "Commissioning, already done")
- attributes = Clusters.ValveConfigurationAndControl.Attributes
-
- self.print_step(2, "Read attribute list to determine supported attributes")
- attribute_list = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList)
-
- print(attribute_list)
-
- self.print_step(3, "Read OpenDuration attribute, if supported")
- if attributes.OpenDuration.attribute_id in attribute_list:
- open_duration_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration)
-
- if open_duration_dut is not NullValue:
- asserts.assert_less_equal(open_duration_dut, 0xFFFFFFFE, "OpenDuration attribute is out of range")
- asserts.assert_greater_equal(open_duration_dut, 1, "OpenDuration attribute is out of range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(4, "Read AutoCloseTime attribute, if supported")
- if attributes.AutoCloseTime.attribute_id in attribute_list:
- auto_close_time_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime)
-
- if auto_close_time_dut is not NullValue:
- asserts.assert_less_equal(auto_close_time_dut, 0xFFFFFFFFFFFFFFFE, "OpenDuration attribute is out of range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(5, "Read RemainingDuration attribute, if supported")
- if attributes.RemainingDuration.attribute_id in attribute_list:
- remaining_duration_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration)
-
- if remaining_duration_dut is not NullValue:
- asserts.assert_less_equal(remaining_duration_dut, 0xFFFFFFFE, "RemainingDuration attribute is out of range")
- asserts.assert_greater_equal(remaining_duration_dut, 1, "RemainingDuration attribute is out of range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(6, "Read CurrentState attribute, if supported")
- if attributes.CurrentState.attribute_id in attribute_list:
- current_state_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState)
-
- if current_state_dut is not NullValue:
- asserts.assert_less(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kUnknownEnumValue,
- "CurrentState is not in valid range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(7, "Read TargetState attribute, if supported")
- if attributes.TargetState.attribute_id in attribute_list:
- target_state_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetState)
-
- if target_state_dut is not NullValue:
- asserts.assert_less(target_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kUnknownEnumValue,
- "TargetState is not in valid range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(8, "Read StartUpState attribute, if supported")
- if attributes.StartUpState.attribute_id in attribute_list:
- start_up_state_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.StartUpState)
-
- asserts.assert_less(start_up_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kUnknownEnumValue,
- "StartUpState is not in valid range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(9, "Read CurrentLevel attribute, if supported")
- if attributes.CurrentLevel.attribute_id in attribute_list:
- current_level_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentLevel)
-
- if current_level_dut is not NullValue:
- asserts.assert_less_equal(current_level_dut, 100, "CurrentLevel attribute is out of range")
- asserts.assert_greater_equal(current_level_dut, 0, "CurrentLevel attribute is out of range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(10, "Read TargetLevel attribute, if supported")
- if attributes.TargetLevel.attribute_id in attribute_list:
- target_level_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TargetLevel)
-
- if target_level_dut is not NullValue:
- asserts.assert_less_equal(target_level_dut, 100, "TargetLevel attribute is out of range")
- asserts.assert_greater_equal(target_level_dut, 0, "TargetLevel attribute is out of range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(11, "Read OpenLevel attribute, if supported")
- if attributes.OpenLevel.attribute_id in attribute_list:
- open_level_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenLevel)
-
- if open_level_dut is not NullValue:
- asserts.assert_less_equal(open_level_dut, 100, "OpenLevel attribute is out of range")
- asserts.assert_greater_equal(open_level_dut, 1, "OpenLevel attribute is out of range")
- else:
- logging.info("Test step skipped")
-
- self.print_step(12, "Read ValveFault attribute, if supported")
- if attributes.ValveFault.attribute_id in attribute_list:
- valve_fault_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.ValveFault)
-
- asserts.assert_less_equal(valve_fault_dut, 0b00000111, "ValveFault is not in valid range")
- else:
- logging.info("Test step skipped")
-
-
-if __name__ == "__main__":
- default_matter_test_main()
diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py
index 306ddb89a4a2c1..036331d7dd7bf7 100644
--- a/src/python_testing/matter_testing_support.py
+++ b/src/python_testing/matter_testing_support.py
@@ -736,7 +736,7 @@ async def read_single_attribute(
async def read_single_attribute_check_success(
self, cluster: Clusters.ClusterObjects.ClusterCommand, attribute: Clusters.ClusterObjects.ClusterAttributeDescriptor,
- dev_ctrl: ChipDeviceCtrl = None, node_id: int = None, endpoint: int = None, assert_on_error: bool = True, test_name: str = "") -> object:
+ dev_ctrl: ChipDeviceCtrl = None, node_id: int = None, endpoint: int = None, fabric_filtered: bool = True, assert_on_error: bool = True, test_name: str = "") -> object:
if dev_ctrl is None:
dev_ctrl = self.default_controller
if node_id is None:
@@ -744,7 +744,7 @@ async def read_single_attribute_check_success(
if endpoint is None:
endpoint = self.matter_test_config.endpoint
- result = await dev_ctrl.ReadAttribute(node_id, [(endpoint, attribute)])
+ result = await dev_ctrl.ReadAttribute(node_id, [(endpoint, attribute)], fabricFiltered=fabric_filtered)
attr_ret = result[endpoint][cluster][attribute]
read_err_msg = f"Error reading {str(cluster)}:{str(attribute)} = {attr_ret}"
desired_type = attribute.attribute_type.Type
@@ -768,7 +768,7 @@ async def read_single_attribute_check_success(
async def read_single_attribute_expect_error(
self, cluster: object, attribute: object,
error: Status, dev_ctrl: ChipDeviceCtrl = None, node_id: int = None, endpoint: int = None,
- assert_on_error: bool = True, test_name: str = "") -> object:
+ fabric_filtered: bool = True, assert_on_error: bool = True, test_name: str = "") -> object:
if dev_ctrl is None:
dev_ctrl = self.default_controller
if node_id is None:
@@ -776,7 +776,7 @@ async def read_single_attribute_expect_error(
if endpoint is None:
endpoint = self.matter_test_config.endpoint
- result = await dev_ctrl.ReadAttribute(node_id, [(endpoint, attribute)])
+ result = await dev_ctrl.ReadAttribute(node_id, [(endpoint, attribute)], fabricFiltered=fabric_filtered)
attr_ret = result[endpoint][cluster][attribute]
err_msg = "Did not see expected error when reading {}:{}".format(str(cluster), str(attribute))
error_type_ok = attr_ret is not None and isinstance(
diff --git a/third_party/openthread/repo b/third_party/openthread/repo
index d81c6fab98df8f..f1e74a036b5bd2 160000
--- a/third_party/openthread/repo
+++ b/third_party/openthread/repo
@@ -1 +1 @@
-Subproject commit d81c6fab98df8fbeb0f3611ce5ec4c131c84cbce
+Subproject commit f1e74a036b5bd2e9dd6565161ab806cc854dc0b4
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
index 7a056869230537..a7957243e3149e 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
@@ -1698,6 +1698,7 @@ enum class ModeTag : uint16_t
{
kIdle = 0x4000,
kCleaning = 0x4001,
+ kMapping = 0x4002,
// kUnknownEnumValue intentionally not defined. This enum never goes
// through DataModel::Decode, likely because it is a part of a derived
// cluster. As a result having kUnknownEnumValue in this enum is error