From 14aa3c2471475eed88e6285c6619b57a22a6f098 Mon Sep 17 00:00:00 2001 From: kowsisoundhar12 <57476670+kowsisoundhar12@users.noreply.github.com> Date: Tue, 28 Jun 2022 23:00:33 +0530 Subject: [PATCH 01/76] Added PICS Condition (#19998) * Added PICS condition * Added Auto generated files * Restyled by whitespace * Restyled by clang-format Co-authored-by: Restyled.io --- src/app/tests/suites/certification/PICS.yaml | 211 ++++++++ .../suites/certification/Test_TC_GR_2_2.yaml | 438 --------------- ...Test_TC_GR_1_1.yaml => Test_TC_G_1_1.yaml} | 2 +- ...Test_TC_GR_2_1.yaml => Test_TC_G_2_1.yaml} | 3 +- .../suites/certification/Test_TC_G_2_2.yaml | 510 ++++++++++++++++++ ...Test_TC_GR_2_3.yaml => Test_TC_G_2_3.yaml} | 15 +- ...Test_TC_GR_3_1.yaml => Test_TC_G_3_1.yaml} | 4 +- ...Test_TC_GR_3_2.yaml => Test_TC_G_3_2.yaml} | 44 +- .../suites/certification/Test_TC_I_2_2.yaml | 7 + .../suites/certification/Test_TC_I_2_3.yaml | 11 + .../suites/certification/Test_TC_I_3_1.yaml | 89 ++- .../suites/certification/Test_TC_I_3_2.yaml | 57 +- .../certification/Test_TC_SWTCH_1_1.yaml | 59 +- .../certification/Test_TC_SWTCH_2_1.yaml | 1 + .../certification/Test_TC_SWTCH_2_2.yaml | 190 ++++++- .../certification/Test_TC_SWTCH_3_1.yaml | 140 +++-- .../suites/certification/Test_TC_S_2_2.yaml | 25 + .../suites/certification/Test_TC_S_2_3.yaml | 12 + .../tests/suites/certification/ci-pics-values | 72 +++ src/app/tests/suites/tests.js | 12 +- .../chip-tool/zap-generated/test/Commands.h | 79 +-- .../zap-generated/test/Commands.h | 76 +++ 22 files changed, 1486 insertions(+), 571 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_GR_2_2.yaml rename src/app/tests/suites/certification/{Test_TC_GR_1_1.yaml => Test_TC_G_1_1.yaml} (98%) rename src/app/tests/suites/certification/{Test_TC_GR_2_1.yaml => Test_TC_G_2_1.yaml} (96%) create mode 100644 src/app/tests/suites/certification/Test_TC_G_2_2.yaml rename src/app/tests/suites/certification/{Test_TC_GR_2_3.yaml => Test_TC_G_2_3.yaml} (96%) rename src/app/tests/suites/certification/{Test_TC_GR_3_1.yaml => Test_TC_G_3_1.yaml} (96%) rename src/app/tests/suites/certification/{Test_TC_GR_3_2.yaml => Test_TC_G_3_2.yaml} (82%) diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 4f0cc3c2991636..0ace5778596e81 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -866,3 +866,214 @@ PICS: - label: "Does the DUT(server) support the MinLevel attribute?" id: LVL.S.A0002 + + #Groups Cluster + - label: "Does the DUT(Server) support NameSupport attribute?" + id: G.S.A0000 + + - label: "Does the DUT(Server) support GroupTable attribute?" + id: GRPKEY.S.A0001 + + - label: "Does the DUT(server) implement receiving AddGroup Command?" + id: G.S.C00.Rsp + + - label: "Does the DUT(server) implement receiving ViewGroup Command?" + id: G.S.C01.Rsp + + - label: + "Does the DUT(server) implement receiving GetGroupMembership Command?" + id: G.S.C02.Rsp + + - label: "Does the DUT(server) implement receiving RemoveGroup Command?" + id: G.S.C03.Rsp + + - label: "Does the DUT(server) implement receiving RemoveAllGroups Command?" + id: G.S.C04.Rsp + + - label: + "Does the DUT(server) implement receiving AddGroupIfIdentifying + Command?" + id: G.S.C05.Rsp + + - label: + "Does the DUT(server) invoking/generating AddGroupResponse Command?" + id: G.S.C00.Tx + + - label: + "Does the DUT(server) invoking/generating ViewGroupResponse Command?" + id: G.S.C01.Tx + + - label: + "Does the DUT(server) invoking/generating GetGroupMembershipResponse + Command?" + id: G.S.C02.Tx + + - label: + "Does the DUT(server) invoking/generating RemoveGroupResponse Command?" + id: G.S.C03.Tx + + - label: "Does the DUT(client) support NameSupport attribute?" + id: G.C.A0000 + + - label: "Does the DUT(client) implement receiving AddGroup Command?" + id: G.C.C00.Rsp + + - label: "Does the DUT(client) implement receiving ViewGroup Command?" + id: G.C.C01.Rsp + + - label: + "Does the DUT(client) implement receiving GetGroupMembership Command?" + id: G.C.C02.Rsp + + - label: "Does the DUT(client) implement receiving RemoveGroup Command?" + id: G.C.C03.Rsp + + - label: "Does the DUT(client) implement receiving RemoveAllGroups Command?" + id: G.C.C04.Rsp + + - label: + "Does the DUT(client) implement receiving AddGroupIfIdentifying + Command?" + id: G.C.C05.Rsp + + #Identify Cluster + - label: "Does the device implement the IdentifyTime attribute?" + id: I.S.A0000 + + - label: "Does the device implement the IdentifyType attribute?" + id: I.S.A0001 + + - label: "Does the device implement receiving the Identify command?" + id: I.S.C00.Rsp + + - label: "Does the device implement receiving the IdentifyQuery command?" + id: I.S.C01.Rsp + + - label: "Does the device implement receiving the TriggerEffect command?" + id: I.S.C40.Rsp + + - label: + "Does the device implement sending the IdentifyQueryResponse command?" + id: I.S.C00.Tx + + - label: "Does the device implement sending the Identify command?" + id: I.C.C00.Tx + + - label: "Does the device implement sending the IdentifyQuery command?" + id: I.C.C01.Tx + + - label: "Does the device implement sending the TriggerEffect command?" + id: I.C.C40.Tx + + - label: + "Does the device implement receiving the IdentifyQueryResponse + command?" + id: I.C.C00.Rsp + + #Scenes Cluster + - label: "Does the device implement the SceneCount attribute?" + id: S.S.A0000 + + - label: "Does the device implement the CurrentScene attribute?" + id: S.S.A0001 + + - label: "Does the device implement the CurrentGroup attribute?" + id: S.S.A0002 + + - label: "Does the device implement the SceneValid attribute?" + id: S.S.A0003 + + - label: "Does the device implement the NameSupport attribute?" + id: S.S.A0004 + + - label: "Does the device implement the LastConfiguredBy attribute?" + id: S.S.A0005 + + - label: "Does the device implement receiving the AddScene command?" + id: S.S.C00.Rsp + + - label: "Does the device implement receiving the ViewScene command?" + id: S.S.C01.Rsp + + - label: "Does the device implement receiving the RemoveScene command?" + id: S.S.C02.Rsp + + - label: "Does the device implement receiving the RemoveAllScenes command?" + id: S.S.C03.Rsp + + - label: "Does the device implement receiving the StoreScene command?" + id: S.S.C04.Rsp + + - label: "Does the device implement receiving the RecallScene command?" + id: S.S.C05.Rsp + + - label: + "Does the device implement receiving the GetSceneMembership command?" + id: S.S.C06.Rsp + + - label: "Does the device implement receiving the EnhancedAddScene command?" + id: S.S.C40.Rsp + + - label: + "Does the device implement receiving the EnhancedViewScene command?" + id: S.S.C41.Rsp + + - label: "Does the device implement receiving the CopyScene command?" + id: S.S.C42.Rsp + + - label: + "Does the device process the TransitionTime parameter of the + RecallScene command?" + id: S.S.C05.Rsp + + - label: "Does the device receive the AddGroup Command?" + id: G.S.C00.Rsp + + - label: "Does the device receive the RemoveAllGroups Command?" + id: G.S.C04.Rsp + + - label: "Does the device implement sending the AddScene command?" + id: S.C.C00.Tx + + - label: "Does the device implement sending the ViewScene command?" + id: S.C.C01.Tx + + - label: "Does the device implement sending the RemoveScene command?" + id: S.C.C02.Tx + + - label: "Does the device implement sending the RemoveAllScenes command?" + id: S.C.C03.Tx + + - label: "Does the device implement sending the StoreScene command?" + id: S.C.C04.Tx + + - label: "Does the device implement sending the RecallScene command?" + id: S.C.C05.Tx + + - label: "Does the device implement sending the GetSceneMembership command?" + id: S.C.C06.Tx + + - label: "Does the device implement sending the EnhancedAddScene command?" + id: S.C.C40.Tx + + - label: "Does the device implement sending the EnhancedViewScene command?" + id: S.C.C41.Tx + + - label: "Does the device implement sending the CopyScene command?" + id: S.C.C42.Tx + + #Switch Cluster + - label: "Does the device represent a Latching Switch?" + id: SWTCH.S.F00 + + - label: "Does the device implement the CurrentScene attribute?" + id: SWTCH.S.F01 + + - label: "Does the MS device support Momentary Switch Release?" + id: SWTCH.S.F02 + + - label: "Does the MS device support Momentary Switch LongPress?" + id: SWTCH.S.F03 + + - label: "Does the MS device support Momentary Switch MultiPress?" + id: SWTCH.S.F04 diff --git a/src/app/tests/suites/certification/Test_TC_GR_2_2.yaml b/src/app/tests/suites/certification/Test_TC_GR_2_2.yaml deleted file mode 100644 index a7d3caa2278263..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_GR_2_2.yaml +++ /dev/null @@ -1,438 +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: 120.2.2. [TC-GR-2.2] Groups Cluster Commands [DUT-Server] - -config: - nodeId: 0x12344321 - cluster: "Basic" - endpoint: 0 - -tests: - - label: - "TH sends AddGroup command to DUT as unicast with the following fields - : GroupID as 0x0001 GroupName as Gp1 TH reads GroupTable attribute - from the GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups add-group 0x0001 grp1 1 0 - - [1651218084.427102][2526:2531] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 - [1651218084.427203][2526:2531] CHIP:TOO: AddGroupResponse: { - [1651218084.427241][2526:2531] CHIP:TOO: status: 0 - [1651218084.427264][2526:2531] CHIP:TOO: groupId: 1 - [1651218084.427314][2526:2531] CHIP:TOO: } - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651218198.062850][2538:2543] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 - [1651218198.062980][2538:2543] CHIP:TOO: GroupTable: 1 entries - [1651218198.067019][2538:2543] CHIP:TOO: [1]: { - [1651218198.067076][2538:2543] CHIP:TOO: GroupId: 1 - [1651218198.067123][2538:2543] CHIP:TOO: Endpoints: 1 entries - [1651218198.067192][2538:2543] CHIP:TOO: [1]: 0 - [1651218198.067241][2538:2543] CHIP:TOO: GroupName: grp1 - [1651218198.067284][2538:2543] CHIP:TOO: FabricIndex: 1 - [1651218198.067327][2538:2543] CHIP:TOO: } - disabled: true - - - label: - "TH sends AddGroup command to DUT as unicast with the following fields - : GroupID as 0x0002 GroupName as Gp2 TH reads GroupTable attribute - from the GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups add-group 0x0002 gp2 1 0 - - [1651218295.126708][2549:2554] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 - [1651218295.126880][2549:2554] CHIP:TOO: AddGroupResponse: { - [1651218295.126955][2549:2554] CHIP:TOO: status: 0 - [1651218295.127009][2549:2554] CHIP:TOO: groupId: 2 - [1651218295.127065][2549:2554] CHIP:TOO: } - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651218330.067438][2555:2560] CHIP:TOO: GroupTable: 2 entries - [1651218330.067549][2555:2560] CHIP:TOO: [1]: { - [1651218330.067584][2555:2560] CHIP:TOO: GroupId: 1 - [1651218330.067618][2555:2560] CHIP:TOO: Endpoints: 1 entries - [1651218330.067671][2555:2560] CHIP:TOO: [1]: 0 - [1651218330.067708][2555:2560] CHIP:TOO: GroupName: grp1 - [1651218330.067739][2555:2560] CHIP:TOO: FabricIndex: 1 - [1651218330.067771][2555:2560] CHIP:TOO: } - [1651218330.067814][2555:2560] CHIP:TOO: [2]: { - [1651218330.067845][2555:2560] CHIP:TOO: GroupId: 2 - [1651218330.067877][2555:2560] CHIP:TOO: Endpoints: 1 entries - [1651218330.067912][2555:2560] CHIP:TOO: [1]: 0 - [1651218330.067945][2555:2560] CHIP:TOO: GroupName: gp2 - [1651218330.067975][2555:2560] CHIP:TOO: FabricIndex: 1 - [1651218330.068004][2555:2560] CHIP:TOO: } - disabled: true - - - label: - "TH sends AddGroup command to DUT as unicast with the following fields - : GroupID as 0xffff1 GroupName as Gp1" - verification: | - ./chip-tool any command-by-id 0x0004 0x00 '{ "0": 65536, "1": "my-group-name"}' 1 0 - - [1652694139.686651][3527:3532] CHIP:DMG: StatusIB = - [1652694139.686694][3527:3532] CHIP:DMG: { - [1652694139.686739][3527:3532] CHIP:DMG: status = 0x85 (INVALID_COMMAND), - [1652694139.686805][3527:3532] CHIP:DMG: }, - disabled: true - - - label: - "TH sends AddGroup command to DUT as unicast with the following fields - : GroupID as 0x0001 GroupName as Gp1" - verification: | - ./chip-tool groups add-group 0x0001 grp1 1 0 - - [1651218468.562070][2571:2576] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 - [1651218468.562159][2571:2576] CHIP:TOO: AddGroupResponse: { - [1651218468.562200][2571:2576] CHIP:TOO: status: 0 - [1651218468.562228][2571:2576] CHIP:TOO: groupId: 1 - [1651218468.562256][2571:2576] CHIP:TOO: } - disabled: true - - - label: - "TH sends AddGroup command to DUT as groupcast with the following - fields : GroupID as 0x0001 GroupName as Gp1" - verification: | - Not Verifiable - Groupcast is not implemented - disabled: true - - - label: - "TH sends ViewGroup command to DUT as unicast with the following - fields: GroupID as 0x0001 TH reads GroupTable attribute from the - GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups view-group 0x0001 1 0 - - [1651218576.149152][2635:2640] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 - [1651218576.149231][2635:2640] CHIP:TOO: ViewGroupResponse: { - [1651218576.149265][2635:2640] CHIP:TOO: status: 0 - [1651218576.149289][2635:2640] CHIP:TOO: groupId: 1 - [1651218576.149311][2635:2640] CHIP:TOO: groupName: grp1 - [1651218576.149335][2635:2640] CHIP:TOO: } - disabled: true - - - label: - "TH sends ViewGroup command to DUT as unicast with the following - fields: GroupID as 0xffff1 TH reads GroupTable attribute from the - GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool any command-by-id 0x0004 0x01 '{ "0": 65536}' 1 0 - - [1652694208.352334][3535:3540] CHIP:DMG: StatusIB = - [1652694208.352389][3535:3540] CHIP:DMG: { - [1652694208.352444][3535:3540] CHIP:DMG: status = 0x85 (INVALID_COMMAND), - [1652694208.352499][3535:3540] CHIP:DMG: }, - disabled: true - - - label: - "TH sends ViewGroup command to DUT as unicast with the following - fields: GroupID as 0x0021 TH reads GroupTable attribute from the - GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups view-group 0x0021 1 0 - - [1651218681.672376][2670:2675] CHIP:TOO: ViewGroupResponse: { - [1651218681.672425][2670:2675] CHIP:TOO: status: 139 - [1651218681.672459][2670:2675] CHIP:TOO: groupId: 33 - [1651218681.672491][2670:2675] CHIP:TOO: groupName: - [1651218681.672525][2670:2675] CHIP:TOO: } - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651218720.422085][2679:2684] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 - [1651218720.422183][2679:2684] CHIP:TOO: GroupTable: 2 entries - [1651218720.422287][2679:2684] CHIP:TOO: [1]: { - [1651218720.422319][2679:2684] CHIP:TOO: GroupId: 1 - [1651218720.422350][2679:2684] CHIP:TOO: Endpoints: 1 entries - [1651218720.422397][2679:2684] CHIP:TOO: [1]: 0 - [1651218720.422430][2679:2684] CHIP:TOO: GroupName: grp1 - [1651218720.422458][2679:2684] CHIP:TOO: FabricIndex: 1 - [1651218720.422487][2679:2684] CHIP:TOO: } - [1651218720.422525][2679:2684] CHIP:TOO: [2]: { - [1651218720.422554][2679:2684] CHIP:TOO: GroupId: 2 - [1651218720.422583][2679:2684] CHIP:TOO: Endpoints: 1 entries - [1651218720.422614][2679:2684] CHIP:TOO: [1]: 0 - [1651218720.422644][2679:2684] CHIP:TOO: GroupName: gp2 - [1651218720.422671][2679:2684] CHIP:TOO: FabricIndex: 1 - [1651218720.422697][2679:2684] CHIP:TOO: } - disabled: true - - - label: - "TH sends ViewGroup command to DUT as groupcast with the following - fields: GroupID as 0x0001" - verification: | - Not Verifiable - Groupcast is not implemented - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT with the following fields - : GroupList as NULL" - verification: | - ./chip-tool groups get-group-membership null 1 0 - [1651225366.576335][3070:3070] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT with the following fields - : GroupList as 0x0087" - verification: | - ./chip-tool groups get-group-membership 0x0087 1 0 - [1651223496.759731][2878:2878] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT as unicast with the - following fields : GroupList as 0x0087, 0x0059" - verification: | - ./chip-tool groups get-group-membership 0x0087 0x0059 1 0 - [1651223591.798819][2884:2884] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT with the following fields - : GroupList as 0x0087" - verification: | - ./chip-tool groups get-group-membership 0x0087 1 0 - [1651223496.759731][2878:2878] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT with the following fields - : GroupList as 0x0087" - verification: | - ./chip-tool groups get-group-membership 0x0087 1 0 - [1651223496.759731][2878:2878] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT with the following fields - : GroupList as 0x0087" - verification: | - ./chip-tool groups get-group-membership 0x0087 1 0 - [1651223496.759731][2878:2878] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends GetGroupMembership command to DUT with the following fields - : GroupList as 0x0087" - verification: | - ./chip-tool groups get-group-membership 0x0087 1 0 - [1651223496.759731][2878:2878] CHIP:TOO: Error while encoding GroupList as an array. - disabled: true - - - label: - "TH sends RemoveGroup command to DUT as unicast with the following - field : GroupID as 0x0001" - verification: | - ./chip-tool groups remove-group 0x0001 1 0 - - [1651224005.648529][2908:2913] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0003 - [1651224005.648605][2908:2913] CHIP:TOO: RemoveGroupResponse: { - [1651224005.648641][2908:2913] CHIP:TOO: status: 0 - [1651224005.648664][2908:2913] CHIP:TOO: groupId: 1 - [1651224005.648688][2908:2913] CHIP:TOO: } - disabled: true - - - label: - "TH sends ViewGroup command to DUT as unicast with the following field - : GroupID as 0x0001 TH reads GroupTable attribute from the - GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups remove-group 0x0001 1 0 - - - [1651224045.228384][2914:2919] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0003 - [1651224045.228459][2914:2919] CHIP:TOO: RemoveGroupResponse: { - [1651224045.228494][2914:2919] CHIP:TOO: status: 139 - [1651224045.228517][2914:2919] CHIP:TOO: groupId: 1 - [1651224045.228540][2914:2919] CHIP:TOO: } - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651224212.774362][2968:2973] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 - [1651224212.774556][2968:2973] CHIP:TOO: GroupTable: 2 entries - [1651224212.774677][2968:2973] CHIP:TOO: [1]: { - [1651224212.774714][2968:2973] CHIP:TOO: GroupId: 1 - [1651224212.774749][2968:2973] CHIP:TOO: Endpoints: 0 entries - [1651224212.774805][2968:2973] CHIP:TOO: GroupName: grp1 - [1651224212.774840][2968:2973] CHIP:TOO: FabricIndex: 1 - [1651224212.774874][2968:2973] CHIP:TOO: } - [1651224212.774921][2968:2973] CHIP:TOO: [2]: { - [1651224212.774955][2968:2973] CHIP:TOO: GroupId: 2 - [1651224212.774990][2968:2973] CHIP:TOO: Endpoints: 1 entries - [1651224212.775027][2968:2973] CHIP:TOO: [1]: 0 - [1651224212.775063][2968:2973] CHIP:TOO: GroupName: gp2 - [1651224212.775096][2968:2973] CHIP:TOO: FabricIndex: 1 - [1651224212.775128][2968:2973] CHIP:TOO: } - disabled: true - - - label: - "TH sends RemoveGroup command to DUT as unicast with the following - field : GroupID as 0xfffd1" - verification: | - ./chip-tool any command-by-id 0x0004 0x03 '{ "0": 65536}' 1 0 - - [1652694249.934023][3542:3547] CHIP:DMG: StatusIB = - [1652694249.934061][3542:3547] CHIP:DMG: { - [1652694249.934099][3542:3547] CHIP:DMG: status = 0x85 (INVALID_COMMAND), - [1652694249.934137][3542:3547] CHIP:DMG: }, - disabled: true - - - label: - "TH sends RemoveGroup command to DUT as unicast with the following - field : GroupID as 0x0034" - verification: | - ./chip-tool groups remove-group 0x0034 1 0 - - [1651224136.480197][2924:2929] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0003 - [1651224136.480339][2924:2929] CHIP:TOO: RemoveGroupResponse: { - [1651224136.480403][2924:2929] CHIP:TOO: status: 139 - [1651224136.480452][2924:2929] CHIP:TOO: groupId: 52 - [1651224136.480501][2924:2929] CHIP:TOO: } - disabled: true - - - label: "TH sends RemoveAllGroup command to DUT as unicast method" - verification: | - ./chip-tool groups remove-all-groups 1 0 - - [1651224377.831704][2989:2994] CHIP:DMG: StatusIB = - [1651224377.831757][2989:2994] CHIP:DMG: { - [1651224377.831812][2989:2994] CHIP:DMG: status = 0x00 (SUCCESS), - [1651224377.831866][2989:2994] CHIP:DMG: }, - [1651224377.832439][2989:2994] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0004 Command=0x0000_0004 Status=0x0 - disabled: true - - - label: - "TH sends ViewGroup command to DUT as unicast with the following - fields: GroupID as 0x0021 TH reads GroupTable attribute from the - GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups view-group 0x0021 1 0 - - [1651224444.124557][2996:3001] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 - [1651224444.124663][2996:3001] CHIP:TOO: ViewGroupResponse: { - [1651224444.124712][2996:3001] CHIP:TOO: status: 139 - [1651224444.124745][2996:3001] CHIP:TOO: groupId: 33 - [1651224444.124778][2996:3001] CHIP:TOO: groupName: - [1651224444.124811][2996:3001] CHIP:TOO: } - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651224488.427512][3006:3011] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 - [1651224488.427617][3006:3011] CHIP:TOO: GroupTable: 2 entries - [1651224488.427728][3006:3011] CHIP:TOO: [1]: { - [1651224488.427763][3006:3011] CHIP:TOO: GroupId: 1 - [1651224488.427797][3006:3011] CHIP:TOO: Endpoints: 0 entries - [1651224488.427848][3006:3011] CHIP:TOO: GroupName: grp1 - [1651224488.427881][3006:3011] CHIP:TOO: FabricIndex: 1 - [1651224488.427912][3006:3011] CHIP:TOO: } - [1651224488.427954][3006:3011] CHIP:TOO: [2]: { - [1651224488.427987][3006:3011] CHIP:TOO: GroupId: 2 - [1651224488.428019][3006:3011] CHIP:TOO: Endpoints: 0 entries - [1651224488.428053][3006:3011] CHIP:TOO: GroupName: gp2 - [1651224488.428083][3006:3011] CHIP:TOO: FabricIndex: 1 - [1651224488.428113][3006:3011] CHIP:TOO: } - [1651224488.428226][3006:3011] CHIP:EM: Sending Sta - disabled: true - - - label: - "TH sends AddGroupIfIdentifying command to DUT as unicast method with - the following fields: GroupID as 0x0025 GroupName as Gp37 TH reads - GroupTable attribute from the GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups add-group-if-identifying 0x0025 gp37 1 0 - - [1651224553.023824][3016:3021] CHIP:DMG: StatusIB = - [1651224553.023865][3016:3021] CHIP:DMG: { - [1651224553.023910][3016:3021] CHIP:DMG: status = 0x00 (SUCCESS), - [1651224553.023954][3016:3021] CHIP:DMG: }, - - [1651224553.024349][3016:3021] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0004 Command=0x0000_0005 Status=0x0 - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651224613.251309][3026:3031] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 - [1651224613.251399][3026:3031] CHIP:TOO: GroupTable: 2 entries - [1651224613.251489][3026:3031] CHIP:TOO: [1]: { - [1651224613.251515][3026:3031] CHIP:TOO: GroupId: 1 - [1651224613.251539][3026:3031] CHIP:TOO: Endpoints: 0 entries - [1651224613.251579][3026:3031] CHIP:TOO: GroupName: grp1 - [1651224613.251603][3026:3031] CHIP:TOO: FabricIndex: 1 - [1651224613.251627][3026:3031] CHIP:TOO: } - [1651224613.251658][3026:3031] CHIP:TOO: [2]: { - [1651224613.251682][3026:3031] CHIP:TOO: GroupId: 2 - [1651224613.251705][3026:3031] CHIP:TOO: Endpoints: 0 entries - [1651224613.251729][3026:3031] CHIP:TOO: GroupName: gp2 - [1651224613.251751][3026:3031] CHIP:TOO: FabricIndex: 1 - [1651224613.251772][3026:3031] CHIP:TOO: } - disabled: true - - - label: - "TH sends AddGroupIfIdentifying command to DUT as unicast method with - the following fields: GroupID as 0xffff5 GroupName as Gp45" - verification: | - ./chip-tool any command-by-id 0x0004 0x05 '{ "0": 65536, "1": "my-group-name"}' 1 0 - - - [1652694344.895200][3560:3565] CHIP:DMG: StatusIB = - [1652694344.895245][3560:3565] CHIP:DMG: { - [1652694344.895298][3560:3565] CHIP:DMG: status = 0x85 (INVALID_COMMAND), - [1652694344.895347][3560:3565] CHIP:DMG: }, - disabled: true - - - label: - "TH sends AddGroupIfIdentifying command to DUT as unicast method with - the following fields: GroupID as 0x0067 GroupName as Gp31" - verification: | - ./chip-tool groups add-group-if-identifying 0x0067 gp31 1 0 - - [1651224746.146005][3038:3043] CHIP:DMG: StatusIB = - [1651224746.146038][3038:3043] CHIP:DMG: { - [1651224746.146073][3038:3043] CHIP:DMG: status = 0x00 (SUCCESS), - [1651224746.146106][3038:3043] CHIP:DMG: }, - disabled: true - - - label: - "TH sends AddGroupIfIdentifying command to DUT as unicast method with - the following fields: GroupID as 0x0052 GroupName as Gp54 TH reads - GroupTable attribute from the GroupKeyManagement cluster from DUT" - verification: | - ./chip-tool groups add-group-if-identifying 0x0052 gp54 1 0 - - [1651225850.524282][3091:3096] CHIP:DMG: StatusIB = - [1651225850.524314][3091:3096] CHIP:DMG: { - [1651225850.524347][3091:3096] CHIP:DMG: status = 0x00 (SUCCESS), - [1651225850.524379][3091:3096] CHIP:DMG: }, - - ./chip-tool groupkeymanagement read group-table 1 0 - - [1651225880.217707][3099:3104] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 - [1651225880.217848][3099:3104] CHIP:TOO: GroupTable: 2 entries - [1651225880.217995][3099:3104] CHIP:TOO: [1]: { - [1651225880.218042][3099:3104] CHIP:TOO: GroupId: 1 - [1651225880.218087][3099:3104] CHIP:TOO: Endpoints: 0 entries - [1651225880.218156][3099:3104] CHIP:TOO: GroupName: grp1 - [1651225880.218200][3099:3104] CHIP:TOO: FabricIndex: 1 - [1651225880.218243][3099:3104] CHIP:TOO: } - [1651225880.218299][3099:3104] CHIP:TOO: [2]: { - [1651225880.218342][3099:3104] CHIP:TOO: GroupId: 2 - [1651225880.218384][3099:3104] CHIP:TOO: Endpoints: 0 entries - [1651225880.218429][3099:3104] CHIP:TOO: GroupName: gp2 - [1651225880.218470][3099:3104] CHIP:TOO: FabricIndex: 1 - [1651225880.218509][3099:3104] CHIP:TOO: } - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_GR_1_1.yaml b/src/app/tests/suites/certification/Test_TC_G_1_1.yaml similarity index 98% rename from src/app/tests/suites/certification/Test_TC_GR_1_1.yaml rename to src/app/tests/suites/certification/Test_TC_G_1_1.yaml index a8c4468b85433f..8391a2e8a397b5 100644 --- a/src/app/tests/suites/certification/Test_TC_GR_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_G_1_1.yaml @@ -13,7 +13,7 @@ # 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: 120.1.1. [TC-GR-1.1] Global Attributes [DUT-Server] +name: 119.1.1. [TC-G-1.1] Global Attributes [DUT-Server] config: nodeId: 0x12344321 diff --git a/src/app/tests/suites/certification/Test_TC_GR_2_1.yaml b/src/app/tests/suites/certification/Test_TC_G_2_1.yaml similarity index 96% rename from src/app/tests/suites/certification/Test_TC_GR_2_1.yaml rename to src/app/tests/suites/certification/Test_TC_G_2_1.yaml index d18fbe21449373..f94b52a4e81339 100644 --- a/src/app/tests/suites/certification/Test_TC_GR_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_G_2_1.yaml @@ -13,7 +13,7 @@ # 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: 120.2.1. [TC-GR-2.1] Groups Cluster Attributes [DUT-Server] +name: 119.2.1. [TC-G-2.1] Attributes [DUT-Server] config: nodeId: 0x12344321 @@ -22,6 +22,7 @@ config: tests: - label: "TH reads NameSupport attribute from DUT" + PICS: G.S.A0000 verification: | ./chip-tool groups read name-support 1 0 diff --git a/src/app/tests/suites/certification/Test_TC_G_2_2.yaml b/src/app/tests/suites/certification/Test_TC_G_2_2.yaml new file mode 100644 index 00000000000000..cf1dbb283c218e --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_G_2_2.yaml @@ -0,0 +1,510 @@ +# 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: + 119.2.2. [TC-G-2.2] Commands - AddGroup, ViewGroup, RemoveGroup, + RemoveAllGroups [DUT-Server] + +config: + nodeId: 0x12344321 + cluster: "Basic" + endpoint: 0 + +tests: + - label: + "TH sends AddGroup command to DUT as unicast with the following fields + : GroupID as 0x0001 GroupName as Gp1" + PICS: G.S.C00.Rsp && G.S.C00.Tx + verification: | + ./chip-tool groups add-group 0x0001 grp1 1 0 + + [1651218084.427102][2526:2531] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 + [1651218084.427203][2526:2531] CHIP:TOO: AddGroupResponse: { + [1651218084.427241][2526:2531] CHIP:TOO: status: 0 + [1651218084.427264][2526:2531] CHIP:TOO: groupId: 1 + [1651218084.427314][2526:2531] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1651218198.062850][2538:2543] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 2261933069 + [1651218198.062980][2538:2543] CHIP:TOO: GroupTable: 1 entries + [1651218198.067019][2538:2543] CHIP:TOO: [1]: { + [1651218198.067076][2538:2543] CHIP:TOO: GroupId: 1 + [1651218198.067123][2538:2543] CHIP:TOO: Endpoints: 1 entries + [1651218198.067192][2538:2543] CHIP:TOO: [1]: 0 + [1651218198.067241][2538:2543] CHIP:TOO: GroupName: grp1 + [1651218198.067284][2538:2543] CHIP:TOO: FabricIndex: 1 + [1651218198.067327][2538:2543] CHIP:TOO: } + disabled: true + + - label: + "TH sends AddGroup command to DUT as unicast with the following fields + : GroupID as 0x0002 GroupName as Gp2" + PICS: G.S.C00.Rsp && G.S.C00.Tx + verification: | + ./chip-tool groups add-group 0x0002 grp2 1 0 + + [1653484028.897698][11275:11280] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 + [1653484028.897804][11275:11280] CHIP:TOO: AddGroupResponse: { + [1653484028.897851][11275:11280] CHIP:TOO: status: 0 + [1653484028.897884][11275:11280] CHIP:TOO: groupId: 2 + [1653484028.897917][11275:11280] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653484065.934504][11281:11286] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1368205390 + [1653484065.934631][11281:11286] CHIP:TOO: GroupTable: 2 entries + [1653484065.937522][11281:11286] CHIP:TOO: [1]: { + [1653484065.937573][11281:11286] CHIP:TOO: GroupId: 1 + [1653484065.937615][11281:11286] CHIP:TOO: Endpoints: 1 entries + [1653484065.937678][11281:11286] CHIP:TOO: [1]: 0 + [1653484065.937723][11281:11286] CHIP:TOO: GroupName: grp1 + [1653484065.937763][11281:11286] CHIP:TOO: FabricIndex: 1 + [1653484065.937802][11281:11286] CHIP:TOO: } + [1653484065.937854][11281:11286] CHIP:TOO: [2]: { + [1653484065.937893][11281:11286] CHIP:TOO: GroupId: 2 + [1653484065.937933][11281:11286] CHIP:TOO: Endpoints: 1 entries + [1653484065.937974][11281:11286] CHIP:TOO: [1]: 0 + [1653484065.938014][11281:11286] CHIP:TOO: GroupName: grp2 + [1653484065.938051][11281:11286] CHIP:TOO: FabricIndex: 1 + [1653484065.938089][11281:11286] CHIP:TOO: } + disabled: true + + - label: + "TH sends AddGroup command to DUT as unicast with the following fields + : GroupID as 0x0003 GroupName as Gp3" + PICS: G.S.C00.Rsp && G.S.C00.Tx + verification: | + ./chip-tool groups add-group 0x0003 grp3 1 0 + + [1653484116.857523][11289:11294] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 + [1653484116.857675][11289:11294] CHIP:TOO: AddGroupResponse: { + [1653484116.857739][11289:11294] CHIP:TOO: status: 0 + [1653484116.857787][11289:11294] CHIP:TOO: groupId: 3 + [1653484116.857834][11289:11294] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653484156.968253][11299:11304] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1368205390 + [1653484156.968414][11299:11304] CHIP:TOO: GroupTable: 3 entries + [1653484156.968565][11299:11304] CHIP:TOO: [1]: { + [1653484156.968612][11299:11304] CHIP:TOO: GroupId: 1 + [1653484156.968657][11299:11304] CHIP:TOO: Endpoints: 1 entries + [1653484156.968725][11299:11304] CHIP:TOO: [1]: 0 + [1653484156.968773][11299:11304] CHIP:TOO: GroupName: grp1 + [1653484156.968814][11299:11304] CHIP:TOO: FabricIndex: 1 + [1653484156.968855][11299:11304] CHIP:TOO: } + [1653484156.968912][11299:11304] CHIP:TOO: [2]: { + [1653484156.968955][11299:11304] CHIP:TOO: GroupId: 2 + [1653484156.968997][11299:11304] CHIP:TOO: Endpoints: 1 entries + [1653484156.969042][11299:11304] CHIP:TOO: [1]: 0 + [1653484156.969087][11299:11304] CHIP:TOO: GroupName: grp2 + [1653484156.969127][11299:11304] CHIP:TOO: FabricIndex: 1 + [1653484156.969165][11299:11304] CHIP:TOO: } + [1653484156.969221][11299:11304] CHIP:TOO: [3]: { + [1653484156.969262][11299:11304] CHIP:TOO: GroupId: 3 + [1653484156.969304][11299:11304] CHIP:TOO: Endpoints: 1 entries + [1653484156.969349][11299:11304] CHIP:TOO: [1]: 0 + [1653484156.969393][11299:11304] CHIP:TOO: GroupName: grp3 + [1653484156.969432][11299:11304] CHIP:TOO: FabricIndex: 1 + [1653484156.969471][11299:11304] CHIP:TOO: } + disabled: true + + - label: + "TH sends AddGroup command to DUT n+1 times as unicast with the + following fields : GroupID as 0x0004 GroupName as Gp4" + PICS: G.S.C00.Rsp && G.S.C00.Tx + verification: | + ./chip-tool groups add-group 0x0004 grp4 1 0 + + [1653484187.170553][11306:11311] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 + [1653484187.170637][11306:11311] CHIP:TOO: AddGroupResponse: { + [1653484187.170677][11306:11311] CHIP:TOO: status: 137 + [1653484187.170702][11306:11311] CHIP:TOO: groupId: 4 + [1653484187.170727][11306:11311] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653484324.735216][11318:11323] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1368205390 + [1653484324.735368][11318:11323] CHIP:TOO: GroupTable: 3 entries + [1653484324.735515][11318:11323] CHIP:TOO: [1]: { + [1653484324.735561][11318:11323] CHIP:TOO: GroupId: 1 + [1653484324.735605][11318:11323] CHIP:TOO: Endpoints: 1 entries + [1653484324.735672][11318:11323] CHIP:TOO: [1]: 0 + [1653484324.735721][11318:11323] CHIP:TOO: GroupName: grp1 + [1653484324.735761][11318:11323] CHIP:TOO: FabricIndex: 1 + [1653484324.735823][11318:11323] CHIP:TOO: } + [1653484324.735881][11318:11323] CHIP:TOO: [2]: { + [1653484324.735924][11318:11323] CHIP:TOO: GroupId: 2 + [1653484324.735966][11318:11323] CHIP:TOO: Endpoints: 1 entries + [1653484324.736012][11318:11323] CHIP:TOO: [1]: 0 + [1653484324.736055][11318:11323] CHIP:TOO: GroupName: grp2 + [1653484324.736096][11318:11323] CHIP:TOO: FabricIndex: 1 + [1653484324.736134][11318:11323] CHIP:TOO: } + [1653484324.736188][11318:11323] CHIP:TOO: [3]: { + [1653484324.736232][11318:11323] CHIP:TOO: GroupId: 3 + [1653484324.736274][11318:11323] CHIP:TOO: Endpoints: 1 entries + [1653484324.736319][11318:11323] CHIP:TOO: [1]: 0 + [1653484324.736363][11318:11323] CHIP:TOO: GroupName: grp3 + [1653484324.736403][11318:11323] CHIP:TOO: FabricIndex: 1 + [1653484324.736441][11318:11323] CHIP:TOO: } + disabled: true + + - label: + "TH sends AddGroup command to DUT as unicast with the following fields + : GroupID as 0x0000 GroupName as Gp6" + PICS: G.S.C00.Rsp && G.S.C00.Tx + verification: | + ./chip-tool groups add-group 0x0000 grp6 1 0 + + [1653484439.884144][11341:11346] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0000 + [1653484439.884258][11341:11346] CHIP:TOO: AddGroupResponse: { + [1653484439.884310][11341:11346] CHIP:TOO: status: 135 + [1653484439.884346][11341:11346] CHIP:TOO: groupId: 0 + [1653484439.884383][11341:11346] CHIP:TOO: } + disabled: true + + - label: + "TH sends ViewGroup command to DUT as unicast with the following + fields: GroupID as 0x0001" + PICS: G.S.C01.Rsp && G.S.C01.Tx + verification: | + ./chip-tool groups view-group 0x0001 1 0 + + 1653484504.667714][11349:11354] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 + [1653484504.667841][11349:11354] CHIP:TOO: ViewGroupResponse: { + [1653484504.667927][11349:11354] CHIP:TOO: status: 0 + [1653484504.667974][11349:11354] CHIP:TOO: groupId: 1 + [1653484504.668018][11349:11354] CHIP:TOO: groupName: grp1 + [1653484504.668064][11349:11354] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT Iterate the GroupID in ViewGroup command the GroupId in + GroupTable" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653484552.793059][11397:11402] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1368205390 + [1653484552.793197][11397:11402] CHIP:TOO: GroupTable: 3 entries + [1653484552.793327][11397:11402] CHIP:TOO: [1]: { + [1653484552.793368][11397:11402] CHIP:TOO: GroupId: 1 + [1653484552.793407][11397:11402] CHIP:TOO: Endpoints: 1 entries + [1653484552.793467][11397:11402] CHIP:TOO: [1]: 0 + [1653484552.793510][11397:11402] CHIP:TOO: GroupName: grp1 + [1653484552.793546][11397:11402] CHIP:TOO: FabricIndex: 1 + [1653484552.793583][11397:11402] CHIP:TOO: } + [1653484552.793632][11397:11402] CHIP:TOO: [2]: { + [1653484552.793669][11397:11402] CHIP:TOO: GroupId: 2 + [1653484552.793706][11397:11402] CHIP:TOO: Endpoints: 1 entries + [1653484552.793747][11397:11402] CHIP:TOO: [1]: 0 + [1653484552.793786][11397:11402] CHIP:TOO: GroupName: grp2 + [1653484552.793822][11397:11402] CHIP:TOO: FabricIndex: 1 + [1653484552.793856][11397:11402] CHIP:TOO: } + [1653484552.793905][11397:11402] CHIP:TOO: [3]: { + [1653484552.793942][11397:11402] CHIP:TOO: GroupId: 3 + [1653484552.793979][11397:11402] CHIP:TOO: Endpoints: 1 entries + [1653484552.794019][11397:11402] CHIP:TOO: [1]: 0 + [1653484552.794057][11397:11402] CHIP:TOO: GroupName: grp3 + [1653484552.794092][11397:11402] CHIP:TOO: FabricIndex: 1 + [1653484552.794126][11397:11402] CHIP:TOO: } + disabled: true + + - label: + "TH sends ViewGroup command to DUT as unicast with the following + fields: GroupID as 0x0000" + PICS: G.S.C01.Rsp && G.S.C01.Tx + verification: | + ./chip-tool groups view-group 0x0000 1 0 + + [1653484611.595344][11412:11417] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 + [1653484611.595454][11412:11417] CHIP:TOO: ViewGroupResponse: { + [1653484611.595501][11412:11417] CHIP:TOO: status: 135 + [1653484611.595534][11412:11417] CHIP:TOO: groupId: 0 + [1653484611.595565][11412:11417] CHIP:TOO: groupName: + [1653484611.595599][11412:11417] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT Iterate the GroupID in ViewGroup command with the GroupId in + GroupTable" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653484552.793059][11397:11402] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1368205390 + [1653484552.793197][11397:11402] CHIP:TOO: GroupTable: 3 entries + [1653484552.793327][11397:11402] CHIP:TOO: [1]: { + [1653484552.793368][11397:11402] CHIP:TOO: GroupId: 1 + [1653484552.793407][11397:11402] CHIP:TOO: Endpoints: 1 entries + [1653484552.793467][11397:11402] CHIP:TOO: [1]: 0 + [1653484552.793510][11397:11402] CHIP:TOO: GroupName: grp1 + [1653484552.793546][11397:11402] CHIP:TOO: FabricIndex: 1 + [1653484552.793583][11397:11402] CHIP:TOO: } + [1653484552.793632][11397:11402] CHIP:TOO: [2]: { + [1653484552.793669][11397:11402] CHIP:TOO: GroupId: 2 + [1653484552.793706][11397:11402] CHIP:TOO: Endpoints: 1 entries + [1653484552.793747][11397:11402] CHIP:TOO: [1]: 0 + [1653484552.793786][11397:11402] CHIP:TOO: GroupName: grp2 + [1653484552.793822][11397:11402] CHIP:TOO: FabricIndex: 1 + [1653484552.793856][11397:11402] CHIP:TOO: } + [1653484552.793905][11397:11402] CHIP:TOO: [3]: { + [1653484552.793942][11397:11402] CHIP:TOO: GroupId: 3 + [1653484552.793979][11397:11402] CHIP:TOO: Endpoints: 1 entries + [1653484552.794019][11397:11402] CHIP:TOO: [1]: 0 + [1653484552.794057][11397:11402] CHIP:TOO: GroupName: grp3 + [1653484552.794092][11397:11402] CHIP:TOO: FabricIndex: 1 + [1653484552.794126][11397:11402] CHIP:TOO: } + disabled: true + + - label: + "TH sends ViewGroup command to DUT as unicast with the following + fields: GroupID as 0x0021" + PICS: G.S.C01.Rsp && G.S.C01.Tx + verification: | + ./chip-tool groups view-group 0x0021 1 0 + + [1653484707.569962][11436:11441] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 + [1653484707.570073][11436:11441] CHIP:TOO: ViewGroupResponse: { + [1653484707.570122][11436:11441] CHIP:TOO: status: 139 + [1653484707.570154][11436:11441] CHIP:TOO: groupId: 33 + [1653484707.570185][11436:11441] CHIP:TOO: groupName: + [1653484707.570218][11436:11441] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT Iterate the GroupID in ViewGroup command with the GroupId in + GroupTable" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653559604.877250][3163:3168] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 3214629634 + [1653559604.877441][3163:3168] CHIP:TOO: GroupTable: 3 entries + [1653559604.877556][3163:3168] CHIP:TOO: [1]: { + [1653559604.877621][3163:3168] CHIP:TOO: GroupId: 1 + [1653559604.877671][3163:3168] CHIP:TOO: Endpoints: 1 entries + [1653559604.877722][3163:3168] CHIP:TOO: [1]: 0 + [1653559604.877769][3163:3168] CHIP:TOO: GroupName: grp1 + [1653559604.877812][3163:3168] CHIP:TOO: FabricIndex: 1 + [1653559604.877853][3163:3168] CHIP:TOO: } + [1653559604.877912][3163:3168] CHIP:TOO: [2]: { + [1653559604.877955][3163:3168] CHIP:TOO: GroupId: 2 + [1653559604.877999][3163:3168] CHIP:TOO: Endpoints: 1 entries + [1653559604.878045][3163:3168] CHIP:TOO: [1]: 0 + [1653559604.878090][3163:3168] CHIP:TOO: GroupName: grp2 + [1653559604.878132][3163:3168] CHIP:TOO: FabricIndex: 1 + [1653559604.878178][3163:3168] CHIP:TOO: } + [1653559604.878234][3163:3168] CHIP:TOO: [3]: { + [1653559604.878276][3163:3168] CHIP:TOO: GroupId: 3 + [1653559604.878319][3163:3168] CHIP:TOO: Endpoints: 1 entries + [1653559604.878366][3163:3168] CHIP:TOO: [1]: 0 + [1653559604.878411][3163:3168] CHIP:TOO: GroupName: grp3 + [1653559604.878454][3163:3168] CHIP:TOO: FabricIndex: 1 + [1653559604.878494][3163:3168] CHIP:TOO: } + disabled: true + + - label: + "TH sends RemoveGroup command to DUT as unicast with the following + field : GroupID as 0x0001" + PICS: G.S.C03.Rsp && G.S.C03.Tx + verification: | + ./chip-tool groups remove-group 0x0001 1 0 + + [1653484876.432744][11451:11456] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0003 + [1653484876.432915][11451:11456] CHIP:TOO: RemoveGroupResponse: { + [1653484876.432989][11451:11456] CHIP:TOO: status: 0 + [1653484876.433044][11451:11456] CHIP:TOO: groupId: 1 + [1653484876.433098][11451:11456] CHIP:TOO: } + disabled: true + + - label: + "TH sends ViewGroup command to DUT as unicast with the following field + : GroupID as 0x0001" + PICS: G.S.C01.Rsp && G.S.C01.Tx + verification: | + ./chip-tool groups view-group 0x0001 1 0 + + [1653484952.142387][11458:11463] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 + [1653484952.142476][11458:11463] CHIP:TOO: ViewGroupResponse: { + [1653484952.142516][11458:11463] CHIP:TOO: status: 139 + [1653484952.142541][11458:11463] CHIP:TOO: groupId: 1 + [1653484952.142566][11458:11463] CHIP:TOO: groupName: + [1653484952.142592][11458:11463] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT Iterate the GroupID in ViewGroup command with the GroupId in + GroupTable" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1655125356.123370][27657:27662] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1860794324 + [1655125356.123494][27657:27662] CHIP:TOO: GroupTable: 2 entries + [1655125356.123616][27657:27662] CHIP:TOO: [1]: { + [1655125356.123726][27657:27662] CHIP:TOO: GroupId: 2 + [1655125356.123779][27657:27662] CHIP:TOO: Endpoints: 1 entries + [1655125356.123830][27657:27662] CHIP:TOO: [1]: 0 + [1655125356.123878][27657:27662] CHIP:TOO: GroupName: grp2 + [1655125356.123923][27657:27662] CHIP:TOO: FabricIndex: 1 + [1655125356.123964][27657:27662] CHIP:TOO: } + [1655125356.124023][27657:27662] CHIP:TOO: [2]: { + [1655125356.124066][27657:27662] CHIP:TOO: GroupId: 3 + [1655125356.124110][27657:27662] CHIP:TOO: Endpoints: 1 entries + [1655125356.124158][27657:27662] CHIP:TOO: [1]: 0 + [1655125356.124202][27657:27662] CHIP:TOO: GroupName: grp3 + [1655125356.124245][27657:27662] CHIP:TOO: FabricIndex: 1 + [1655125356.124285][27657:27662] CHIP:TOO: } + disabled: true + + - label: + "TH sends RemoveGroup command to DUT as unicast with the following + field : GroupID as 0x0000" + PICS: G.S.C03.Rsp && G.S.C03.Tx + verification: | + ./chip-tool groups remove-group 0x0000 1 0 + + [1653485045.328766][11473:11478] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0003 + [1653485045.328896][11473:11478] CHIP:TOO: RemoveGroupResponse: { + [1653485045.328954][11473:11478] CHIP:TOO: status: 135 + [1653485045.328994][11473:11478] CHIP:TOO: groupId: 0 + [1653485045.329036][11473:11478] CHIP:TOO: } + disabled: true + + - label: + "TH sends RemoveGroup command to DUT as unicast with the following + field : GroupID as 0x0034" + PICS: G.S.C03.Rsp && G.S.C03.Tx + verification: | + ./chip-tool groups remove-group 0x0034 1 0 + + [1653485126.672869][11483:11488] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0003 + [1653485126.672969][11483:11488] CHIP:TOO: RemoveGroupResponse: { + [1653485126.673015][11483:11488] CHIP:TOO: status: 139 + [1653485126.673045][11483:11488] CHIP:TOO: groupId: 52 + [1653485126.673075][11483:11488] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT Iterate the GroupID in ViewGroup command with the GroupId in + GroupTable" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1655125356.123370][27657:27662] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1860794324 + [1655125356.123494][27657:27662] CHIP:TOO: GroupTable: 2 entries + [1655125356.123616][27657:27662] CHIP:TOO: [1]: { + [1655125356.123726][27657:27662] CHIP:TOO: GroupId: 2 + [1655125356.123779][27657:27662] CHIP:TOO: Endpoints: 1 entries + [1655125356.123830][27657:27662] CHIP:TOO: [1]: 0 + [1655125356.123878][27657:27662] CHIP:TOO: GroupName: grp2 + [1655125356.123923][27657:27662] CHIP:TOO: FabricIndex: 1 + [1655125356.123964][27657:27662] CHIP:TOO: } + [1655125356.124023][27657:27662] CHIP:TOO: [2]: { + [1655125356.124066][27657:27662] CHIP:TOO: GroupId: 3 + [1655125356.124110][27657:27662] CHIP:TOO: Endpoints: 1 entries + [1655125356.124158][27657:27662] CHIP:TOO: [1]: 0 + [1655125356.124202][27657:27662] CHIP:TOO: GroupName: grp3 + [1655125356.124245][27657:27662] CHIP:TOO: FabricIndex: 1 + [1655125356.124285][27657:27662] CHIP:TOO: } + disabled: true + + - label: "TH sends RemoveAllGroups command to DUT as unicast method" + PICS: G.S.C04.Rsp + verification: | + ./chip-tool groups remove-all-groups 1 0 + + [1653485455.344097][11508:11513] CHIP:DMG: StatusIB = + [1653485455.344141][11508:11513] CHIP:DMG: { + [1653485455.344190][11508:11513] CHIP:DMG: status = 0x00 (SUCCESS), + [1653485455.344236][11508:11513] CHIP:DMG: }, + disabled: true + + - label: + "TH sends ViewGroup command to DUT as unicast with the following + fields: GroupID as 0x0001" + PICS: G.S.C01.Rsp && G.S.C01.Tx + verification: | + ./chip-tool groups view-group 0x0001 1 0 + + [1653559917.259920][3227:3232] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 + [1653559917.259993][3227:3232] CHIP:TOO: ViewGroupResponse: { + [1653559917.260040][3227:3232] CHIP:TOO: status: 139 + [1653559917.260075][3227:3232] CHIP:TOO: groupId: 1 + [1653559917.260107][3227:3232] CHIP:TOO: groupName: + [1653559917.260138][3227:3232] CHIP:TOO: } + disabled: true + + - label: + "TH reads GroupTable attribute from the GroupKeyManagement cluster + from DUT Iterate the GroupID in ViewGroup command with the GroupId in + GroupTable" + PICS: GRPKEY.S.A0001 + verification: | + ./chip-tool groupkeymanagement read group-table 1 0 + + [1653485761.350290][11533:11538] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003F Attribute 0x0000_0001 DataVersion: 1368205390 + [1653485761.350411][11533:11538] CHIP:TOO: GroupTable: 3 entries + [1653485761.350532][11533:11538] CHIP:TOO: [1]: { + [1653485761.350568][11533:11538] CHIP:TOO: GroupId: 1 + [1653485761.350603][11533:11538] CHIP:TOO: Endpoints: 0 entries + [1653485761.350657][11533:11538] CHIP:TOO: GroupName: grp1 + [1653485761.350692][11533:11538] CHIP:TOO: FabricIndex: 1 + [1653485761.350726][11533:11538] CHIP:TOO: } + [1653485761.350771][11533:11538] CHIP:TOO: [2]: { + [1653485761.350805][11533:11538] CHIP:TOO: GroupId: 2 + [1653485761.350839][11533:11538] CHIP:TOO: Endpoints: 0 entries + [1653485761.350874][11533:11538] CHIP:TOO: GroupName: grp2 + [1653485761.350906][11533:11538] CHIP:TOO: FabricIndex: 1 + [1653485761.350937][11533:11538] CHIP:TOO: } + [1653485761.350981][11533:11538] CHIP:TOO: [3]: { + [1653485761.351015][11533:11538] CHIP:TOO: GroupId: 3 + [1653485761.351048][11533:11538] CHIP:TOO: Endpoints: 0 entries + [1653485761.351082][11533:11538] CHIP:TOO: GroupName: grp3 + [1653485761.351115][11533:11538] CHIP:TOO: FabricIndex: 1 + [1653485761.351145][11533:11538] CHIP:TOO: } + disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_GR_2_3.yaml b/src/app/tests/suites/certification/Test_TC_G_2_3.yaml similarity index 96% rename from src/app/tests/suites/certification/Test_TC_GR_2_3.yaml rename to src/app/tests/suites/certification/Test_TC_G_2_3.yaml index 637999bf9eb4e7..59238afb9f22b6 100644 --- a/src/app/tests/suites/certification/Test_TC_GR_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_G_2_3.yaml @@ -14,7 +14,7 @@ # Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default name: - 121.2.3. [TC-GR-2.3] Commands - GetGroupMembership, AddGroupIfIdentifying + 119.2.3. [TC-G-2.3] Commands - GetGroupMembership, AddGroupIfIdentifying [DUT-Server] config: @@ -26,6 +26,7 @@ tests: - label: "TH sends AddGroup command to DUT as unicast with the following fields : GroupID as 0x0002 GroupName as Gp2" + PICS: G.S.C00.Rsp && G.S.C00.Tx verification: | ./chip-tool groups add-group 0x0002 gp2 1 0 @@ -39,6 +40,7 @@ tests: - label: "TH reads GroupTable attribute from the GroupKeyManagement cluster from DUT" + PICS: GRPKEY.S.A0001 verification: | ./chip-tool groupkeymanagement read group-table 1 0 @@ -56,6 +58,7 @@ tests: - label: "TH sends AddGroup command to DUT as unicast with the following fields : GroupID as 0x0003 GroupName as Gp3" + PICS: G.S.C00.Rsp && G.S.C00.Tx verification: | ./chip-tool groups add-group 0x0003 gp3 1 0 @@ -69,6 +72,7 @@ tests: - label: "TH reads GroupTable attribute from the GroupKeyManagement cluster from DUT" + PICS: GRPKEY.S.A0001 verification: | ./chip-tool groupkeymanagement read group-table 1 0 @@ -93,6 +97,7 @@ tests: - label: "TH sends GetGroupMembership command to DUT with the following fields : GroupList as NULL" + PICS: G.S.C02.Rsp && G.S.C02.Tx verification: | ./chip-tool groups get-group-membership [] 1 0 @@ -108,6 +113,7 @@ tests: - label: "TH sends GetGroupMembership command to DUT with the following fields : GroupList as [0x0002]" + PICS: G.S.C02.Rsp && G.S.C02.Tx verification: | ./chip-tool groups get-group-membership [0002] 1 0 @@ -121,6 +127,7 @@ tests: - label: "TH sends GetGroupMembership command to DUT as unicast with the following fields : GroupList as [0x0002, 0x0003]" + PICS: G.S.C02.Rsp && G.S.C02.Tx verification: | ./chip-tool groups get-group-membership [0002,0003] 1 0 @@ -133,6 +140,7 @@ tests: disabled: true - label: "TH sends RemoveAllGroups command to DUT as unicast method" + PICS: G.S.C04.Rsp verification: | ./chip-tool groups remove-all-groups 1 0 @@ -146,6 +154,7 @@ tests: - label: "TH sends AddGroupIfIdentifying command to DUT as unicast method with the following fields: GroupID as 0x0006 GroupName as Gp6" + PICS: G.S.C05.Rsp verification: | ./chip-tool groups add-group-if-identifying 0x0006 gp6 1 0 @@ -158,6 +167,7 @@ tests: - label: "TH reads GroupTable attribute from the GroupKeyManagement cluster from DUT" + PICS: GRPKEY.S.A0001 verification: | ./chip-tool groupkeymanagement read group-table 1 0 @@ -180,6 +190,7 @@ tests: - label: "TH sends AddGroupIfIdentifying command to DUT as unicast method with the following fields: GroupID as 0x0000 GroupName as Gp45" + PICS: G.S.C05.Rsp verification: | ./chip-tool groups add-group-if-identifying 0x0000 gp45 1 0 @@ -193,6 +204,7 @@ tests: - label: "TH sends AddGroupIfIdentifying command to DUT n+1 times as unicast method with the following fields: GroupID as 0x0007 GroupName as Gp54" + PICS: G.S.C05.Rsp verification: | ./chip-tool groups add-group-if-identifying 0x0067 gp31 1 0 @@ -205,6 +217,7 @@ tests: - label: "TH reads GroupTable attribute from the GroupKeyManagement cluster from DUT" + PICS: GRPKEY.S.A0001 verification: | ./chip-tool groupkeymanagement read group-table 1 0 diff --git a/src/app/tests/suites/certification/Test_TC_GR_3_1.yaml b/src/app/tests/suites/certification/Test_TC_G_3_1.yaml similarity index 96% rename from src/app/tests/suites/certification/Test_TC_GR_3_1.yaml rename to src/app/tests/suites/certification/Test_TC_G_3_1.yaml index c05374dc1072e3..efb46693c13dad 100644 --- a/src/app/tests/suites/certification/Test_TC_GR_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_G_3_1.yaml @@ -13,15 +13,15 @@ # 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: 120.3.1. [TC-GR-3.1] Groups Cluster Attributes [DUT-Client] +name: 119.3.1. [TC-G-3.1] Attributes [DUT-Client] config: nodeId: 0x12344321 cluster: "Basic" endpoint: 0 - tests: - label: "DUT reads NameSupport attribute from TH" + PICS: G.C.A0000 verification: | [1651217683.754603][2825:2825] CHIP:IM: Received Read request [1651217683.754677][2825:2825] CHIP:DMG: ReadRequestMessage = diff --git a/src/app/tests/suites/certification/Test_TC_GR_3_2.yaml b/src/app/tests/suites/certification/Test_TC_G_3_2.yaml similarity index 82% rename from src/app/tests/suites/certification/Test_TC_GR_3_2.yaml rename to src/app/tests/suites/certification/Test_TC_G_3_2.yaml index 16135033b43667..85a644017a3c3a 100644 --- a/src/app/tests/suites/certification/Test_TC_GR_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_G_3_2.yaml @@ -13,7 +13,7 @@ # 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: 120.3.2. [TC-GR-3.2] Groups Cluster Commands [DUT-Client] +name: 119.3.2. [TC-G-3.2] Commands [DUT-Client] config: nodeId: 0x12344321 @@ -22,6 +22,7 @@ config: tests: - label: "DUT sends AddGroup command to TH" + PICS: G.C.C00.Rsp verification: | ./chip-tool groups add-group 0x0021 gp1 1 0 @@ -60,6 +61,7 @@ tests: disabled: true - label: "DUT sends ViewGroup command to TH" + PICS: G.C.C01.Rsp verification: | ./chip-tool groups view-group 0x0021 1 0 @@ -98,12 +100,46 @@ tests: disabled: true - label: "DUT sends GetGroupMembership command to TH" + PICS: G.C.C02.Rsp verification: | - ./chip-tool groups get-group-membership 0x23 1 0 - [1651226161.642052][3143:3143] CHIP:TOO: Error while encoding GroupList as an array. + ./chip-tool groups get-group-membership '[33]' 1 0 + + [1653077452169] [4058:5758073] CHIP: [DMG] ICR moving to [ResponseRe] + [1653077452169] [4058:5758073] CHIP: [DMG] InvokeResponseMessage = + [1653077452169] [4058:5758073] CHIP: [DMG] { + [1653077452169] [4058:5758073] CHIP: [DMG] suppressResponse = false, + [1653077452169] [4058:5758073] CHIP: [DMG] InvokeResponseIBs = + [1653077452169] [4058:5758073] CHIP: [DMG] [ + [1653077452169] [4058:5758073] CHIP: [DMG] InvokeResponseIB = + [1653077452169] [4058:5758073] CHIP: [DMG] { + [1653077452169] [4058:5758073] CHIP: [DMG] CommandDataIB = + [1653077452169] [4058:5758073] CHIP: [DMG] { + [1653077452169] [4058:5758073] CHIP: [DMG] CommandPathIB = + [1653077452169] [4058:5758073] CHIP: [DMG] { + [1653077452169] [4058:5758073] CHIP: [DMG] EndpointId = 0x0, + [1653077452169] [4058:5758073] CHIP: [DMG] ClusterId = 0x4, + [1653077452169] [4058:5758073] CHIP: [DMG] CommandId = 0x2, + [1653077452169] [4058:5758073] CHIP: [DMG] }, + [1653077452169] [4058:5758073] CHIP: [DMG] + [1653077452169] [4058:5758073] CHIP: [DMG] CommandData = + [1653077452169] [4058:5758073] CHIP: [DMG] { + [1653077452169] [4058:5758073] CHIP: [DMG] 0x0 = NULL + [1653077452169] [4058:5758073] CHIP: [DMG] 0x1 = [ + [1653077452169] [4058:5758073] CHIP: [DMG] 33, + [1653077452169] [4058:5758073] CHIP: [DMG] ], + [1653077452169] [4058:5758073] CHIP: [DMG] }, + [1653077452169] [4058:5758073] CHIP: [DMG] }, + [1653077452169] [4058:5758073] CHIP: [DMG] + [1653077452169] [4058:5758073] CHIP: [DMG] }, + [1653077452169] [4058:5758073] CHIP: [DMG] + [1653077452169] [4058:5758073] CHIP: [DMG] ], + [1653077452169] [4058:5758073] CHIP: [DMG] + [1653077452169] [4058:5758073] CHIP: [DMG] InteractionModelRevision = 1 + [1653077452169] [4058:5758073] CHIP: [DMG] }, disabled: true - label: "DUT sends RemoveGroup command to TH" + PICS: G.C.C03.Rsp verification: | ./chip-tool groups remove-group 0x0021 1 0 @@ -141,6 +177,7 @@ tests: disabled: true - label: "DUT sends RemoveAllGroup command to TH" + PICS: G.C.C04.Rsp verification: | ./chip-tool groups remove-all-groups 1 0 @@ -178,6 +215,7 @@ tests: disabled: true - label: "DUT sends AddGroupIfIdentifying command to TH" + PICS: G.C.C05.Rsp verification: | ./chip-tool groups add-group-if-identifying 0x0052 gp54 1 0 diff --git a/src/app/tests/suites/certification/Test_TC_I_2_2.yaml b/src/app/tests/suites/certification/Test_TC_I_2_2.yaml index a2fffff9a09379..2326a6c0f11b62 100644 --- a/src/app/tests/suites/certification/Test_TC_I_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_2_2.yaml @@ -32,6 +32,7 @@ tests: - label: "TH sends Identify command to DUT, with the identify time field set to 0x003c (60s)." + PICS: I.S.C00.Rsp command: "Identify" arguments: values: @@ -39,6 +40,7 @@ tests: value: 60 - label: "TH reads immediately IdentifyTime attribute from DUT1" + PICS: I.S.A0000 command: "readAttribute" attribute: "identify time" response: @@ -55,6 +57,7 @@ tests: value: 10000 - label: "After 10 seconds, the TH reads IdentifyTime attribute from DUT" + PICS: I.S.A0000 command: "readAttribute" attribute: "identify time" response: @@ -81,6 +84,7 @@ tests: - label: "TH sends Identify command to DUT, with the identify time field set to 0x0000 (stop identifying)." + PICS: I.S.C00.Rsp command: "Identify" arguments: values: @@ -88,6 +92,7 @@ tests: value: 0 - label: "TH reads immediately IdentifyTime attribute from DUT2" + PICS: I.S.A0000 command: "readAttribute" attribute: "identify time" response: @@ -109,6 +114,7 @@ tests: - label: "TH writes a value of 0x000f (15s) to IdentifyTime attribute of DUT" + PICS: I.S.A0000 command: "writeAttribute" attribute: "identify time" arguments: @@ -123,6 +129,7 @@ tests: value: 5000 - label: "After 5 seconds, the TH reads IdentifyTime attribute from DUT" + PICS: I.S.A0000 command: "readAttribute" attribute: "identify time" response: diff --git a/src/app/tests/suites/certification/Test_TC_I_2_3.yaml b/src/app/tests/suites/certification/Test_TC_I_2_3.yaml index 9e864e4ae15584..ef95f90c19ddc9 100644 --- a/src/app/tests/suites/certification/Test_TC_I_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_2_3.yaml @@ -32,6 +32,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x00 blink and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -52,6 +53,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -72,6 +74,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x02 okay and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -92,6 +95,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x0b channel change and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -112,6 +116,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -132,6 +137,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0xfe finish effect and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -143,6 +149,7 @@ tests: - label: "Manually check DUT stops the breathe effect after the current effect sequence" + PICS: I.S.C40.Rsp cluster: "LogCommands" command: "UserPrompt" arguments: @@ -156,6 +163,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -176,6 +184,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0xff stop effect and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -196,6 +205,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x00 blink and the effect variant field set to 0x42 unknown" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: @@ -216,6 +226,7 @@ tests: "TH sends TriggerEffect command to DUT with the effect identifier field set to 0xff stop effect and the effect variant field set to 0x00 default" + PICS: I.S.C40.Rsp command: "TriggerEffect" arguments: values: diff --git a/src/app/tests/suites/certification/Test_TC_I_3_1.yaml b/src/app/tests/suites/certification/Test_TC_I_3_1.yaml index ce5a6086c0c740..e1c91f79f51c9a 100644 --- a/src/app/tests/suites/certification/Test_TC_I_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_3_1.yaml @@ -13,7 +13,7 @@ # 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: 57.3.1. [TC-I-3.1] Attributes with client as DUT +name: 58.3.1. [TC-I-3.1] Attributes with Client as DUT config: nodeId: 0x12344321 @@ -22,8 +22,8 @@ config: tests: - label: - "DUT reads all supported mandatory attributes from TH once at a time - in a manufacturer specific order" + "DUT reads all supported mandatory attributes from TH one at a time in + a manufacturer specific order" verification: | ./chip-tool identify read identify-time 1 1 @@ -66,15 +66,15 @@ tests: disabled: true - label: - "DUT reads all supported optional attributes from TH once at a time in + "DUT reads all supported optional attributes from TH one at a time in a manufacturer specific order" verification: | - see above + There is no optional attibute for this cluster disabled: true - label: "DUT writes a suitable value to all supported mandatory attributes on - the TH once at a time in a manufacturer specific order" + the TH one at a time in a manufacturer specific order" verification: | On TestHarnes (all-cluster-app) a received write request looks like this (f.e identify-time (id 0) value 60): ./chip-tool identify write identify-time 1 1 1 @@ -108,7 +108,80 @@ tests: - label: "DUT writes a suitable value to all supported optional attributes on - the TH once at a time in a manufacturer specific order" + the TH one at a time in a manufacturer specific order" + verification: | + There is no optional attibute for this cluster + disabled: true + + - label: + "Configure TH such that it implements mandatory and none of the + optional attributes of the server-side of the cluster, and that it + also reflects this in global attributes such as FeatureMap and + AttributeList. Commission DUT to TH again" + verification: | + ./chip-tool identify read attribute-list 1 1 + + [1654242827039] [91286:3990827] CHIP: [TOO] Endpoint: 1 Cluster: 0x0000_0003 Attribute 0x0000_FFFB DataVersion: 2002457420 + [1654242827039] [91286:3990827] CHIP: [TOO] AttributeList: 7 entries + [1654242827039] [91286:3990827] CHIP: [TOO] [1]: 0 + [1654242827039] [91286:3990827] CHIP: [TOO] [2]: 1 + [1654242827039] [91286:3990827] CHIP: [TOO] [3]: 65528 + [1654242827039] [91286:3990827] CHIP: [TOO] [4]: 65529 + [1654242827040] [91286:3990827] CHIP: [TOO] [5]: 65531 + [1654242827040] [91286:3990827] CHIP: [TOO] [6]: 65532 + [1654242827040] [91286:3990827] CHIP: [TOO] [7]: 65533 + + + "./chip-tool identify read identify-time 1 1 + + [1648015371.159715][2506:2506] CHIP:IM: Received Read request + [1648015371.159805][2506:2506] CHIP:DMG: ReadRequestMessage = + [1648015371.159840][2506:2506] CHIP:DMG: { + [1648015371.159866][2506:2506] CHIP:DMG: AttributePathIBs = + [1648015371.159903][2506:2506] CHIP:DMG: [ + [1648015371.159932][2506:2506] CHIP:DMG: AttributePathIB = + [1648015371.159968][2506:2506] CHIP:DMG: { + [1648015371.160006][2506:2506] CHIP:DMG: Endpoint = 0x1, + [1648015371.160047][2506:2506] CHIP:DMG: Cluster = 0x3, + [1648015371.160087][2506:2506] CHIP:DMG: Attribute = 0x0000_0000, + [1648015371.160127][2506:2506] CHIP:DMG: } + [1648015371.160164][2506:2506] CHIP:DMG: + [1648015371.160201][2506:2506] CHIP:DMG: ], + [1648015371.160238][2506:2506] CHIP:DMG: + [1648015371.160270][2506:2506] CHIP:DMG: isFabricFiltered = true, + [1648015371.160300][2506:2506] CHIP:DMG: InteractionModelRevision = 1 + [1648015371.160324][2506:2506] CHIP:DMG: }, + + ./chip-tool identify read identify-type 1 1 + [1648015519.017225][2506:2506] CHIP:IM: Received Read request + [1648015519.017293][2506:2506] CHIP:DMG: ReadRequestMessage = + [1648015519.017332][2506:2506] CHIP:DMG: { + [1648015519.017363][2506:2506] CHIP:DMG: AttributePathIBs = + [1648015519.017403][2506:2506] CHIP:DMG: [ + [1648015519.017437][2506:2506] CHIP:DMG: AttributePathIB = + [1648015519.017577][2506:2506] CHIP:DMG: { + [1648015519.017624][2506:2506] CHIP:DMG: Endpoint = 0x1, + [1648015519.017673][2506:2506] CHIP:DMG: Cluster = 0x3, + [1648015519.017721][2506:2506] CHIP:DMG: Attribute = 0x0000_0001, + [1648015519.017768][2506:2506] CHIP:DMG: } + [1648015519.017813][2506:2506] CHIP:DMG: + [1648015519.017853][2506:2506] CHIP:DMG: ], + [1648015519.017894][2506:2506] CHIP:DMG: + [1648015519.017932][2506:2506] CHIP:DMG: isFabricFiltered = true, + [1648015519.017969][2506:2506] CHIP:DMG: InteractionModelRevision = 1 + [1648015519.018003][2506:2506] CHIP:DMG: }," + disabled: true + + - label: + "DUT reads all supported optional attributes from TH one at a time in + a manufacturer specific order" + verification: | + There is no optional attibute for this cluster + disabled: true + + - label: + "DUT writes a suitable value to all supported optional attributes on + the TH one at a time in a manufacturer specific order" verification: | - see above + There is no optional attibute for this cluster disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_I_3_2.yaml b/src/app/tests/suites/certification/Test_TC_I_3_2.yaml index dbbaf49d21efd0..d1cd451bcf39b4 100644 --- a/src/app/tests/suites/certification/Test_TC_I_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_3_2.yaml @@ -13,7 +13,7 @@ # 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: 57.3.2. [TC-I-3.2] Functionality with client as DUT +name: 58.3.2. [TC-I-3.2] Functionality with Client as DUT config: nodeId: 0x12344321 @@ -25,9 +25,10 @@ tests: "DUT issues an Identify command to the Test Harness, with the IdentifyTime argument set to 0x003C (60 seconds) or a reasonable time that is supported by the DUT." + PICS: I.C.C00.Tx verification: | On TestHarnes (all-cluster-app) a received Identify command with f.e. 60 as IdentifyTime looks like this: - + ./chip-tool identify identify 60 1 1 [1646010972.583498][33190:33190] CHIP:EM: Handling via exchange: 60250r, Delegate: 0xaaaace1730c8 [1646010972.583578][33190:33190] CHIP:DMG: InvokeRequestMessage = [1646010972.583611][33190:33190] CHIP:DMG: { @@ -59,37 +60,46 @@ tests: [1646010972.584474][33190:33190] CHIP:DMG: Endpoint 1, Cluster 0x0000_0003 update version to d4fdf424 disabled: true + - label: + "DUT issues an IdentifyQuery command to the Test Harness. Note: + IdentifyQuery is not supported by Matter" + PICS: I.C.C01.Tx + verification: | + IdentifyQuery is not supported by Matter + disabled: true + - label: "DUT issues an Identify command to the Test Harness, with the IdentifyTime argument set to 0x0000 (Stop)." + PICS: I.C.C00.Tx verification: | On TestHarnes (all-cluster-app) a received Identify command with an IdentifyTime of 0 looks like this: - + ./chip-tool identify identify 0 1 1 [1646011311.206353][33190:33190] CHIP:EM: Handling via exchange: 12024r, Delegate: 0xaaaace1730c8 [1646011311.206436][33190:33190] CHIP:DMG: InvokeRequestMessage = [1646011311.206462][33190:33190] CHIP:DMG: { - [1646011311.206483][33190:33190] CHIP:DMG: suppressResponse = false, - [1646011311.206514][33190:33190] CHIP:DMG: timedRequest = false, - [1646011311.206544][33190:33190] CHIP:DMG: InvokeRequests = - [1646011311.206575][33190:33190] CHIP:DMG: [ - [1646011311.206599][33190:33190] CHIP:DMG: CommandDataIB = - [1646011311.206628][33190:33190] CHIP:DMG: { - [1646011311.206656][33190:33190] CHIP:DMG: CommandPathIB = - [1646011311.206687][33190:33190] CHIP:DMG: { - [1646011311.206719][33190:33190] CHIP:DMG: EndpointId = 0x1, - [1646011311.206754][33190:33190] CHIP:DMG: ClusterId = 0x3, - [1646011311.206786][33190:33190] CHIP:DMG: CommandId = 0x0, - [1646011311.206815][33190:33190] CHIP:DMG: }, + [1646011311.206483][33190:33190] CHIP:DMG: suppressResponse = false, + [1646011311.206514][33190:33190] CHIP:DMG: timedRequest = false, + [1646011311.206544][33190:33190] CHIP:DMG: InvokeRequests = + [1646011311.206575][33190:33190] CHIP:DMG: [ + [1646011311.206599][33190:33190] CHIP:DMG: CommandDataIB = + [1646011311.206628][33190:33190] CHIP:DMG: { + [1646011311.206656][33190:33190] CHIP:DMG: CommandPathIB = + [1646011311.206687][33190:33190] CHIP:DMG: { + [1646011311.206719][33190:33190] CHIP:DMG: EndpointId = 0x1, + [1646011311.206754][33190:33190] CHIP:DMG: ClusterId = 0x3, + [1646011311.206786][33190:33190] CHIP:DMG: CommandId = 0x0, + [1646011311.206815][33190:33190] CHIP:DMG: }, [1646011311.206848][33190:33190] CHIP:DMG: - [1646011311.206875][33190:33190] CHIP:DMG: CommandData = - [1646011311.206906][33190:33190] CHIP:DMG: { - [1646011311.206937][33190:33190] CHIP:DMG: 0x0 = 0, - [1646011311.206970][33190:33190] CHIP:DMG: }, - [1646011311.207000][33190:33190] CHIP:DMG: }, + [1646011311.206875][33190:33190] CHIP:DMG: CommandData = + [1646011311.206906][33190:33190] CHIP:DMG: { + [1646011311.206937][33190:33190] CHIP:DMG: 0x0 = 0, + [1646011311.206970][33190:33190] CHIP:DMG: }, + [1646011311.207000][33190:33190] CHIP:DMG: }, [1646011311.207032][33190:33190] CHIP:DMG: - [1646011311.207055][33190:33190] CHIP:DMG: ], + [1646011311.207055][33190:33190] CHIP:DMG: ], [1646011311.207085][33190:33190] CHIP:DMG: - [1646011311.207108][33190:33190] CHIP:DMG: InteractionModelRevision = 1 + [1646011311.207108][33190:33190] CHIP:DMG: InteractionModelRevision = 1 [1646011311.207133][33190:33190] CHIP:DMG: }, [1646011311.207188][33190:33190] CHIP:DMG: AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_0003 e=1 p=o [1646011311.207295][33190:33190] CHIP:DMG: Received command for Endpoint=1 Cluster=0x0000_0003 Command=0x0000_0000 @@ -100,9 +110,10 @@ tests: - label: "DUT sends a TriggerEffect command to the Test Harness, with any supported EffectIdentifier argument and EffectVariant set to 0 ." + PICS: I.C.C40.Tx verification: | On TestHarnes (all-cluster-app) a received Identify command with f.e. 1 as EffectIdentifier looks like this: - + ./chip-tool identify trigger-effect 0 0 1 1 [1646011549.034604][33190:33190] CHIP:EM: Received message of type 0x8 with protocolId (0, 1) and MessageCounter:3605482 on exchange 36067r [1646011549.034646][33190:33190] CHIP:EM: Handling via exchange: 36067r, Delegate: 0xaaaace1730c8 [1646011549.034790][33190:33190] CHIP:DMG: InvokeRequestMessage = diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml index 6ee4bc45edbff6..42f94bd96b2128 100644 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml @@ -13,7 +13,7 @@ # 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: 74.1.1. [TC-SWTCH-1.1] Global attributes with server as DUT +name: 73.1.1. [TC-SWTCH-1.1] Global attributes with server as DUT config: nodeId: 0x12344321 @@ -30,31 +30,84 @@ tests: verification: | ./chip-tool switch read feature-map 1 1 - [1646208136.241983][2390:2395] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_FFFCDataVersion: 1206711661 - [1646208136.242043][2390:2395] CHIP:TOO: FeatureMap: 0 + [1655271856.827371][2855:2860] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_FFFC DataVersion: 4291766665 + [1655271856.827493][2855:2860] CHIP:TOO: FeatureMap: 1 disabled: true - label: "Check values of flags in this FeatureMap" + PICS: SWTCH.S.F00 verification: | no Matter messages, but TH internal checking disabled: true - label: "Check values of flags in this FeatureMap" + PICS: SWTCH.S.F01 verification: | no Matter messages, but TH internal checking disabled: true - label: "Check values of flags in this FeatureMap" + PICS: SWTCH.S.F02 verification: | no Matter messages, but TH internal checking disabled: true - label: "Check values of flags in this FeatureMap" + PICS: SWTCH.S.F03 verification: | no Matter messages, but TH internal checking disabled: true - label: "Check values of flags in this FeatureMap" + PICS: SWTCH.S.F04 verification: | no Matter messages, but TH internal checking disabled: true + + - label: "Read ClusterRevision (global attribute 65533)" + verification: | + ./chip-tool switch read cluster-revision 1 1 + + + [1651563714.073979][8331:8336] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_FFFD DataVersion: 3331396879 + [1651563714.074140][8331:8336] CHIP:TOO: ClusterRevision: 1 + disabled: true + + - label: "Read AttributeList (global attribute 65531)" + verification: | + ./chip-tool switch read attribute-list 1 1 + + + [1651563753.140074][8338:8343] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_FFFB DataVersion: 3331396879 + [1651563753.140200][8338:8343] CHIP:TOO: AttributeList: 8 entries + [1651563753.140246][8338:8343] CHIP:TOO: [1]: 0 + [1651563753.140283][8338:8343] CHIP:TOO: [2]: 1 + [1651563753.140319][8338:8343] CHIP:TOO: [3]: 2 + [1651563753.140355][8338:8343] CHIP:TOO: [4]: 65528 + [1651563753.140389][8338:8343] CHIP:TOO: [5]: 65529 + [1651563753.140425][8338:8343] CHIP:TOO: [6]: 65531 + [1651563753.140460][8338:8343] CHIP:TOO: [7]: 65532 + [1651563753.140495][8338:8343] CHIP:TOO: [8]: 65533 + disabled: true + + - label: "Read EventList (global attribute 65530)" + verification: | + OUT OF SCOPE FOR V1.0 + disabled: true + + - label: "Read AcceptedCommandList (global attribute 65529)" + verification: | + ./chip-tool switch read accepted-command-list 1 1 + + + [1651563822.164319][8348:8353] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_FFF9 DataVersion: 3331396879 + [1651563822.164424][8348:8353] CHIP:TOO: AcceptedCommandList: 0 entries + disabled: true + + - label: "Read GeneratedCommandList (global attribute 65528)" + verification: | + ./chip-tool switch read generated-command-list 1 1 + + [1651563849.608873][8355:8361] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_FFF8 DataVersion: 3331396879 + [1651563849.608977][8355:8361] CHIP:TOO: GeneratedCommandList: 0 entries + disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_2_1.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_2_1.yaml index c59c42321e21a6..ed0384b4bffa88 100644 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWTCH_2_1.yaml @@ -47,6 +47,7 @@ tests: minValue: 0 - label: "Read MultiPressMax attribute" + PICS: SWTCH.S.F04 command: "readAttribute" attribute: "multi press max" response: diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml index 90a0207cd07359..140030690d9dc3 100644 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml @@ -13,11 +13,13 @@ # 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: "[TC-SWTCH-2.2] Primary functionality with server as DUT" +name: 73.2.2. [TC-SWTCH-2.2] Primary functionality with server as DUT + config: - nodeId: "0x12344321" + nodeId: 0x12344321 cluster: "Basic" endpoint: 0 + tests: - label: "Commission DUT to TH (can be skipped if done in a preceding test)" verification: | @@ -25,6 +27,7 @@ tests: disabled: true - label: "Set up subscription to SwitchLatched event" + PICS: SWTCH.S.F00 verification: | ./chip-tool switch subscribe-event switch-latched 1 100 1 1 @@ -38,11 +41,13 @@ tests: disabled: true - label: "Operator sets switch to first position" + PICS: SWTCH.S.F00 verification: | no Matter messages disabled: true - label: "Read CurrentPosition attribute" + PICS: SWTCH.S.F00 verification: | ./chip-tool switch read current-position 1 1 [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 @@ -50,11 +55,14 @@ tests: disabled: true - label: "Operator sets switch to second position" + PICS: SWTCH.S.F00 verification: | - no Matter messages + (no chip-tool message to DUT) + DUT sends event message disabled: true - label: "Read CurrentPosition attribute" + PICS: SWTCH.S.F00 verification: | ./chip-tool switch read current-position 1 1 [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 @@ -64,6 +72,7 @@ tests: - label: "If NumberOfPositions>2 (see 2c of TC-SWTCH-2.1) : - Operator sets switch to next position - Read CurrentPosition attribute" + PICS: SWTCH.S.F00 verification: | ./chip-tool switch read current-position 1 1 @@ -80,25 +89,27 @@ tests: "If NumberOfPositions>3 : - Repeat step 2f for NumberOfPositions-3 times - After each time Operator has set switch to next position, - Read CurrentPosition attribute" + PICS: SWTCH.S.F00 verification: | - ./chip-tool switch read current-position 1 1 - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1646209289.746228][2617:2622] CHIP:TOO: current position: 0 + 2 disabled: true - label: "Operator returns switch to first position" + PICS: SWTCH.S.F00 verification: | Event (content will vary on the device) [1646209167.923346][2190:2190] CHIP:DMG: StatusResponseMessage = [1646209167.923415][2190:2190] CHIP:DMG: { [1646209167.923472][2190:2190] CHIP:DMG: Status = 0x0, [1646209167.923533][2190:2190] CHIP:DMG: InteractionModelRevision = 1 [1646209167.923583][2190:2190] CHIP:DMG: } [1646209167.923640][2190:2190] CHIP:IM: Received status response, status is 0 disabled: true - label: "Read CurrentPosition attribute" - verification: |+ + PICS: SWTCH.S.F00 + verification: | ./chip-tool switch read current-position 1 1 [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 [1646209289.746228][2617:2622] CHIP:TOO: current position: 0 disabled: true - label: "Set up subscription to InitialPress event" + PICS: SWTCH.S.F01 verification: | ./chip-tool switch subscribe-event initial-press 1 100 1 1 [1646209546.313236][2641:2646] CHIP:DMG: SubscribeResponseMessage = @@ -112,38 +123,45 @@ tests: disabled: true - label: "Operator does not operate switch" + PICS: SWTCH.S.F01 verification: | no Matter messages disabled: true - label: "Read CurrentPosition attribute" - verification: |+ + PICS: SWTCH.S.F01 + verification: | ./chip-tool switch read current-position 1 1 [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 [1646209289.746228][2617:2622] CHIP:TOO: current position: 0 disabled: true - label: "Operator operates switch (keep it pressed)" + PICS: SWTCH.S.F01 verification: | receive event disabled: true - label: "Read CurrentPosition attribute" + PICS: SWTCH.S.F01 verification: | - Read attrbute + ./chip-tool switch read current-position 1 1 disabled: true - label: "Operator does not operate switch (release switch)" + PICS: SWTCH.S.F01 verification: | no Matter messages disabled: true - label: "Read CurrentPosition attribute" + PICS: SWTCH.S.F01 verification: | Read attrbute disabled: true - label: "Set up subscription to InitialPress and ShortRelease events" + PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 verification: | ./chip-tool switch subscribe-event initial-press 1 100 1 1 1 @@ -151,27 +169,32 @@ tests: disabled: true - label: "Operator does not operate switch" + PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 verification: | no Matter messages disabled: true - label: "Operator operates switch (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 verification: | Event (content will vary on the device) [1646209167.923346][2190:2190] CHIP:DMG: StatusResponseMessage = [1646209167.923415][2190:2190] CHIP:DMG: { [1646209167.923472][2190:2190] CHIP:DMG: Status = 0x0, [1646209167.923533][2190:2190] CHIP:DMG: InteractionModelRevision = 1 [1646209167.923583][2190:2190] CHIP:DMG: } [1646209167.923640][2190:2190] CHIP:IM: Received status response, status is 0 disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 verification: | Event (content will vary on the device) [1646209167.923346][2190:2190] CHIP:DMG: StatusResponseMessage = [1646209167.923415][2190:2190] CHIP:DMG: { [1646209167.923472][2190:2190] CHIP:DMG: Status = 0x0, [1646209167.923533][2190:2190] CHIP:DMG: InteractionModelRevision = 1 [1646209167.923583][2190:2190] CHIP:DMG: } [1646209167.923640][2190:2190] CHIP:IM: Received status response, status is 0 disabled: true - label: "Operator operates switch (keep pressed for long time, e.g. 5 seconds)" + PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 verification: | Event (content will vary on the device) [1646209167.923346][2190:2190] CHIP:DMG: StatusResponseMessage = [1646209167.923415][2190:2190] CHIP:DMG: { [1646209167.923472][2190:2190] CHIP:DMG: Status = 0x0, [1646209167.923533][2190:2190] CHIP:DMG: InteractionModelRevision = 1 [1646209167.923583][2190:2190] CHIP:DMG: } [1646209167.923640][2190:2190] CHIP:IM: Received status response, status is 0 disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 verification: | Event (content will vary on the device) [1646209167.923346][2190:2190] CHIP:DMG: StatusResponseMessage = [1646209167.923415][2190:2190] CHIP:DMG: { [1646209167.923472][2190:2190] CHIP:DMG: Status = 0x0, [1646209167.923533][2190:2190] CHIP:DMG: InteractionModelRevision = 1 [1646209167.923583][2190:2190] CHIP:DMG: } [1646209167.923640][2190:2190] CHIP:IM: Received status response, status is 0 disabled: true @@ -179,38 +202,158 @@ tests: - label: "Set up subscription to InitialPress, LongPress, ShortRelease, LongRelease events" + PICS: SWTCH.S.F01 && SWTCH.S.F03 verification: | - ./chip-tool switch subscribe-event initial-press 1 100 1 1 1 - - ./chip-tool switch subscribe-event short-release 1 100 1 1 1 - - ./chip-tool switch subscribe-event long-press 1 100 1 1 1 + ./chip-tool switch subscribe-event initial-press 1 100 1 1 - ./chip-tool switch subscribe-event long-release 1 100 1 1 1 + ./chip-tool switch subscribe-event short-release 1 100 1 1 + + [1655272080.983330][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.983357][2922:2927] CHIP:TOO: Event number: 2 + [1655272080.983380][2922:2927] CHIP:TOO: Priority: Info + [1655272080.983402][2922:2927] CHIP:TOO: Timestamp: 1137653 + [1655272080.983506][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.984432][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.984461][2922:2927] CHIP:TOO: } + [1655272080.984555][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.984580][2922:2927] CHIP:TOO: Event number: 3 + [1655272080.984602][2922:2927] CHIP:TOO: Priority: Info + [1655272080.984624][2922:2927] CHIP:TOO: Timestamp: 1137671 + [1655272080.984651][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.984676][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.984699][2922:2927] CHIP:TOO: } + [1655272080.984785][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.984808][2922:2927] CHIP:TOO: Event number: 4 + [1655272080.984831][2922:2927] CHIP:TOO: Priority: Info + [1655272080.984852][2922:2927] CHIP:TOO: Timestamp: 1137689 + [1655272080.984879][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.984903][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.984926][2922:2927] CHIP:TOO: } + [1655272080.985009][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.985033][2922:2927] CHIP:TOO: Event number: 5 + [1655272080.985055][2922:2927] CHIP:TOO: Priority: Info + [1655272080.985076][2922:2927] CHIP:TOO: Timestamp: 1137711 + [1655272080.985103][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.985127][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.985150][2922:2927] CHIP:TOO: } + [1655272080.985233][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.985257][2922:2927] CHIP:TOO: Event number: 6 + [1655272080.985279][2922:2927] CHIP:TOO: Priority: Info + [1655272080.985300][2922:2927] CHIP:TOO: Timestamp: 1137723 + [1655272080.985327][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.985352][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.985374][2922:2927] CHIP:TOO: } + [1655272080.985459][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.985482][2922:2927] CHIP:TOO: Event number: 7 + [1655272080.985504][2922:2927] CHIP:TOO: Priority: Info + [1655272080.985526][2922:2927] CHIP:TOO: Timestamp: 1137739 + [1655272080.985552][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.985576][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.985599][2922:2927] CHIP:TOO: } + [1655272080.985681][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.985704][2922:2927] CHIP:TOO: Event number: 8 + [1655272080.985726][2922:2927] CHIP:TOO: Priority: Info + [1655272080.985748][2922:2927] CHIP:TOO: Timestamp: 1137753 + [1655272080.985774][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.985798][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.985821][2922:2927] CHIP:TOO: } + [1655272080.985907][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.985931][2922:2927] CHIP:TOO: Event number: 9 + [1655272080.985953][2922:2927] CHIP:TOO: Priority: Info + [1655272080.985974][2922:2927] CHIP:TOO: Timestamp: 1137773 + [1655272080.986001][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.986025][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.986047][2922:2927] CHIP:TOO: } + [1655272080.986134][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.986158][2922:2927] CHIP:TOO: Event number: 10 + [1655272080.986180][2922:2927] CHIP:TOO: Priority: Info + [1655272080.986202][2922:2927] CHIP:TOO: Timestamp: 1137785 + [1655272080.986228][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.986252][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.986274][2922:2927] CHIP:TOO: } + [1655272080.986361][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.986385][2922:2927] CHIP:TOO: Event number: 11 + [1655272080.986407][2922:2927] CHIP:TOO: Priority: Info + [1655272080.986429][2922:2927] CHIP:TOO: Timestamp: 1137801 + [1655272080.986455][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.986479][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.986502][2922:2927] CHIP:TOO: } + [1655272080.986588][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.986612][2922:2927] CHIP:TOO: Event number: 12 + [1655272080.986634][2922:2927] CHIP:TOO: Priority: Info + [1655272080.986655][2922:2927] CHIP:TOO: Timestamp: 1137816 + [1655272080.986682][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.986705][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.986728][2922:2927] CHIP:TOO: } + [1655272080.986813][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.986836][2922:2927] CHIP:TOO: Event number: 13 + [1655272080.986858][2922:2927] CHIP:TOO: Priority: Info + [1655272080.986895][2922:2927] CHIP:TOO: Timestamp: 1137858 + [1655272080.986923][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.986948][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.986970][2922:2927] CHIP:TOO: } + [1655272080.987056][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.987080][2922:2927] CHIP:TOO: Event number: 14 + [1655272080.987102][2922:2927] CHIP:TOO: Priority: Info + [1655272080.987123][2922:2927] CHIP:TOO: Timestamp: 1137896 + [1655272080.987150][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.987174][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.987196][2922:2927] CHIP:TOO: } + [1655272080.987280][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.987304][2922:2927] CHIP:TOO: Event number: 15 + [1655272080.987326][2922:2927] CHIP:TOO: Priority: Info + [1655272080.987347][2922:2927] CHIP:TOO: Timestamp: 1137899 + [1655272080.987374][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.987398][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.987421][2922:2927] CHIP:TOO: } + [1655272080.987503][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.987526][2922:2927] CHIP:TOO: Event number: 16 + [1655272080.987548][2922:2927] CHIP:TOO: Priority: Info + [1655272080.987570][2922:2927] CHIP:TOO: Timestamp: 1137916 + [1655272080.987597][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.987621][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.987644][2922:2927] CHIP:TOO: } + [1655272080.987729][2922:2927] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 + [1655272080.987752][2922:2927] CHIP:TOO: Event number: 17 + [1655272080.987774][2922:2927] CHIP:TOO: Priority: Info + [1655272080.987796][2922:2927] CHIP:TOO: Timestamp: 1137949 + [1655272080.987822][2922:2927] CHIP:TOO: ShortRelease: { + [1655272080.987846][2922:2927] CHIP:TOO: PreviousPosition: 10 + [1655272080.987869][2922:2927] CHIP:TOO: } + + + ./chip-tool switch subscribe-event long-press 1 100 1 1 + + ./chip-tool switch subscribe-event long-release 1 100 1 1 disabled: true - label: "Operator does not operate switch" + PICS: SWTCH.S.F01 && SWTCH.S.F03 verification: | no Matter messages disabled: true - label: "Operator operates switch (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F03 verification: | receive event disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F03 verification: | receive event disabled: true - label: "Operator operates switch (keep pressed for long time, e.g. 5 seconds)" + PICS: SWTCH.S.F01 && SWTCH.S.F03 verification: | receive 2 events disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F03 verification: | receive event disabled: true @@ -218,6 +361,7 @@ tests: - label: "Set up subscription to InitialPress, ShortRelease, MultiPressOngoing, MultiPressComplete events" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | ./chip-tool switch subscribe-event initial-press 1 100 1 1 1 @@ -225,75 +369,89 @@ tests: ./chip-tool switch subscribe-event multi-press-ongoing 1 100 1 1 1 - ./chip-tool switch subscribe-event multi-presscomplete 1 100 1 1 1 + ./chip-tool switch subscribe-event multi-press-complete 1 100 1 1 1 disabled: true - label: "Operator does not operate switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | no Matter messages for this step disabled: true - label: "Operator operates switch (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive event disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive 2 events disabled: true - label: "Operator operates switch (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive event disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive event disabled: true - label: "Briefly after 6f, operator operates switch again (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive 2 events disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive 2 events disabled: true - label: "If MultiPressMax == 2, skip steps 6j .. 6o" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | no Matter messages for this step disabled: true - label: "Operator operates switch (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive event disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive event disabled: true - label: "Briefly after 6k, operator operates switch again (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive 2 events disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive event disabled: true - label: "Briefly after 6m, operator operates switch again (press briefly)" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive 2 events disabled: true - label: "Operator releases switch" + PICS: SWTCH.S.F01 && SWTCH.S.F04 verification: | receive 2 events disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_3_1.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_3_1.yaml index 5e614086f71d78..a917082d14f509 100644 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWTCH_3_1.yaml @@ -13,7 +13,7 @@ # 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: 74.3.1. [TC-SWTCH-3.1] Attributes with client as DUT +name: 73.3.2. [TC-SWTCH-3.1] Global attributes with client as DUT config: nodeId: 0x12344321 @@ -22,49 +22,51 @@ config: tests: - label: - "DUT reads all supported mandatory attributes from TH once at a time - in a manufacturer specific order" + "DUT reads all supported mandatory attributes from TH one at a time in + a manufacturer specific order" verification: | ./chip-tool switch read number-of-positions 1 1 - [1646209806.545525][2190:2190] CHIP:DMG: ReadRequestMessage = - [1646209806.545648][2190:2190] CHIP:DMG: { - [1646209806.545672][2190:2190] CHIP:DMG: AttributePathIBs = - [1646209806.545702][2190:2190] CHIP:DMG: [ - [1646209806.545746][2190:2190] CHIP:DMG: AttributePathIB = - [1646209806.545783][2190:2190] CHIP:DMG: { - [1646209806.545815][2190:2190] CHIP:DMG: Endpoint = 0x1, - [1646209806.545852][2190:2190] CHIP:DMG: Cluster = 0x3b, - [1646209806.545886][2190:2190] CHIP:DMG: Attribute = 0x0000_0000, - [1646209806.545946][2190:2190] CHIP:DMG: } - [1646209806.545980][2190:2190] CHIP:DMG: - [1646209806.546025][2190:2190] CHIP:DMG: ], - [1646209806.546070][2190:2190] CHIP:DMG: - [1646209806.546117][2190:2190] CHIP:DMG: isFabricFiltered = false, - [1646209806.546156][2190:2190] CHIP:DMG: InteractionModelRevision = 1 - [1646209806.546180][2190:2190] CHIP:DMG: }, + + [1650539419.579618][3678:3678] CHIP:IM: Received Read request + [1650539419.579683][3678:3678] CHIP:DMG: ReadRequestMessage = + [1650539419.579718][3678:3678] CHIP:DMG: { + [1650539419.579748][3678:3678] CHIP:DMG: AttributePathIBs = + [1650539419.579783][3678:3678] CHIP:DMG: [ + [1650539419.579816][3678:3678] CHIP:DMG: AttributePathIB = + [1650539419.579857][3678:3678] CHIP:DMG: { + [1650539419.579895][3678:3678] CHIP:DMG: Endpoint = 0x1, + [1650539419.579943][3678:3678] CHIP:DMG: Cluster = 0x3b, + [1650539419.579990][3678:3678] CHIP:DMG: Attribute = 0x0000_0000, + [1650539419.580034][3678:3678] CHIP:DMG: } + [1650539419.580075][3678:3678] CHIP:DMG: + [1650539419.580111][3678:3678] CHIP:DMG: ], + [1650539419.580150][3678:3678] CHIP:DMG: + [1650539419.580184][3678:3678] CHIP:DMG: isFabricFiltered = true, + [1650539419.580218][3678:3678] CHIP:DMG: InteractionModelRevision = 1 + [1650539419.580250][3678:3678] CHIP:DMG: }, ./chip-tool switch read current-position 1 1 - [1646209852.886417][2190:2190] CHIP:DMG: ReadRequestMessage = - [1646209852.886459][2190:2190] CHIP:DMG: { - [1646209852.886489][2190:2190] CHIP:DMG: AttributePathIBs = - [1646209852.886521][2190:2190] CHIP:DMG: [ - [1646209852.886551][2190:2190] CHIP:DMG: AttributePathIB = - [1646209852.886589][2190:2190] CHIP:DMG: { - [1646209852.886624][2190:2190] CHIP:DMG: Endpoint = 0x1, - [1646209852.886660][2190:2190] CHIP:DMG: Cluster = 0x3b, - [1646209852.886703][2190:2190] CHIP:DMG: Attribute = 0x0000_0001, - [1646209852.886741][2190:2190] CHIP:DMG: } - [1646209852.886776][2190:2190] CHIP:DMG: - [1646209852.886807][2190:2190] CHIP:DMG: ], - [1646209852.886841][2190:2190] CHIP:DMG: - [1646209852.886870][2190:2190] CHIP:DMG: isFabricFiltered = false, - [1646209852.886900][2190:2190] CHIP:DMG: InteractionModelRevision = 1 - [1646209852.886927][2190:2190] CHIP:DMG: }, - [1646209852.887004][2190:2190] CHIP:DMG: IM RH moving to [GeneratingReports] + + [1650539484.199120][3678:3678] CHIP:DMG: ReadRequestMessage = + [1650539484.199188][3678:3678] CHIP:DMG: { + [1650539484.199243][3678:3678] CHIP:DMG: AttributePathIBs = + [1650539484.199308][3678:3678] CHIP:DMG: [ + [1650539484.199368][3678:3678] CHIP:DMG: AttributePathIB = + [1650539484.199442][3678:3678] CHIP:DMG: { + [1650539484.199515][3678:3678] CHIP:DMG: Endpoint = 0x1, + [1650539484.199600][3678:3678] CHIP:DMG: Cluster = 0x3b, + [1650539484.199685][3678:3678] CHIP:DMG: Attribute = 0x0000_0001, + [1650539484.199760][3678:3678] CHIP:DMG: } + [1650539484.199835][3678:3678] CHIP:DMG: + [1650539484.199901][3678:3678] CHIP:DMG: ], + [1650539484.199971][3678:3678] CHIP:DMG: + [1650539484.200035][3678:3678] CHIP:DMG: isFabricFiltered = true, + [1650539484.200098][3678:3678] CHIP:DMG: InteractionModelRevision = 1 + [1650539484.200156][3678:3678] CHIP:DMG: }, disabled: true - label: - "DUT reads all supported optional attributes from TH once at a time in + "DUT reads all supported optional attributes from TH one at a time in a manufacturer specific order" verification: | ./chip-tool switch read multi-press-max 1 1 @@ -90,14 +92,74 @@ tests: - label: "DUT writes a suitable value to all supported mandatory attributes on - the TH once at a time in a manufacturer specific order" + the TH one at a time in a manufacturer specific order" + verification: | + no writable attributes + disabled: true + + - label: + "DUT writes a suitable value to all supported optional attributes on + the TH one at a time in a manufacturer specific order" verification: | no writable attributes disabled: true + - label: + "Configure TH such that it implements mandatory and none of the + optional attributes of the server-side of the cluster, and that it + also reflects this in global attributes such as FeatureMap and + AttributeList. Commission DUT to TH again" + verification: | + ./chip-tool switch read number-of-positions 1 1 + + [1650539419.579618][3678:3678] CHIP:IM: Received Read request + [1650539419.579683][3678:3678] CHIP:DMG: ReadRequestMessage = + [1650539419.579718][3678:3678] CHIP:DMG: { + [1650539419.579748][3678:3678] CHIP:DMG: AttributePathIBs = + [1650539419.579783][3678:3678] CHIP:DMG: [ + [1650539419.579816][3678:3678] CHIP:DMG: AttributePathIB = + [1650539419.579857][3678:3678] CHIP:DMG: { + [1650539419.579895][3678:3678] CHIP:DMG: Endpoint = 0x1, + [1650539419.579943][3678:3678] CHIP:DMG: Cluster = 0x3b, + [1650539419.579990][3678:3678] CHIP:DMG: Attribute = 0x0000_0000, + [1650539419.580034][3678:3678] CHIP:DMG: } + [1650539419.580075][3678:3678] CHIP:DMG: + [1650539419.580111][3678:3678] CHIP:DMG: ], + [1650539419.580150][3678:3678] CHIP:DMG: + [1650539419.580184][3678:3678] CHIP:DMG: isFabricFiltered = true, + [1650539419.580218][3678:3678] CHIP:DMG: InteractionModelRevision = 1 + [1650539419.580250][3678:3678] CHIP:DMG: }, + + ./chip-tool switch read current-position 1 1 + + [1650539484.199120][3678:3678] CHIP:DMG: ReadRequestMessage = + [1650539484.199188][3678:3678] CHIP:DMG: { + [1650539484.199243][3678:3678] CHIP:DMG: AttributePathIBs = + [1650539484.199308][3678:3678] CHIP:DMG: [ + [1650539484.199368][3678:3678] CHIP:DMG: AttributePathIB = + [1650539484.199442][3678:3678] CHIP:DMG: { + [1650539484.199515][3678:3678] CHIP:DMG: Endpoint = 0x1, + [1650539484.199600][3678:3678] CHIP:DMG: Cluster = 0x3b, + [1650539484.199685][3678:3678] CHIP:DMG: Attribute = 0x0000_0001, + [1650539484.199760][3678:3678] CHIP:DMG: } + [1650539484.199835][3678:3678] CHIP:DMG: + [1650539484.199901][3678:3678] CHIP:DMG: ], + [1650539484.199971][3678:3678] CHIP:DMG: + [1650539484.200035][3678:3678] CHIP:DMG: isFabricFiltered = true, + [1650539484.200098][3678:3678] CHIP:DMG: InteractionModelRevision = 1 + [1650539484.200156][3678:3678] CHIP:DMG: }, + disabled: true + + - label: + "DUT reads all supported optional attributes from TH one at a time in + a manufacturer specific order" + verification: | + ./chip-tool switch read multi-press-max 1 1 + disabled: true + - label: "DUT writes a suitable value to all supported optional attributes on - the TH once at a time in a manufacturer specific order" + the TH one at a time in a manufacturer specific order" verification: | no writable attributes disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml index 8eb44544e29936..6aad611db29191 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml @@ -22,6 +22,7 @@ config: tests: - label: "TH sends a RemoveAllGroups command to DUT." + PICS: G.S.C04.Rsp verification: | If a status response is expected, DUT sends a response to TH with the Status field equal to 0x00 (SUCCESS). disabled: true @@ -38,6 +39,7 @@ tests: - label: "TH sends a AddGroup command to DUT with the GroupID field set to 0x0001." + PICS: G.S.C00.Rsp verification: | DUT sends a AddGroupResponse command to TH with the Status field set to 0x00 (SUCCESS) and the GroupID field set to 0x0001. disabled: true @@ -45,6 +47,7 @@ tests: - label: "TH sends a RemoveAllScenes command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C03.Rsp verification: | DUT sends a RemoveAllScenesResponse command to TH with the Status field set to 0x00 (SUCCESS) and GroupID field set to 0x0001. disabled: true @@ -52,6 +55,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to the value SC0, the GroupID field set to 0x0001 and the SceneCount field set to 0x00. disabled: true @@ -66,6 +70,7 @@ tests: - label: "TH sends a StoreScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C04.Rsp verification: | DUT sends a StoreSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to 0x0001 and the SceneID field set to 0x01. disabled: true @@ -80,6 +85,7 @@ tests: - label: "TH sends a RecallScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C05.Rsp verification: | If a status response is expected, DUT sends a response to TH with the Status field equal to 0x00 (SUCCESS). DUT returns to AC1. disabled: true @@ -87,6 +93,7 @@ tests: - label: "TH reads attributes SceneCount, CurrentScene, CurrentGroup and SceneValid from DUT." + PICS: S.S.A0000 && S.S.A0001 && S.S.A0002 && S.S.A0003 verification: | DUT provides these attribute values: SceneCount attribute has the value (PIXIT.S.SceneTableEntriesOnFactoryNew + 1) CurrentScene attribute has the value 0x01 CurrentGroup attribute has the value G1 SceneValid attribute has the value TRUE. disabled: true @@ -111,6 +118,7 @@ tests: - label: "TH sends a RecallScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C05.Rsp verification: | If a status response is expected, DUT sends a response to TH with the Status field equal to 0x00 (SUCCESS). DUT returns to AC1. disabled: true @@ -118,6 +126,7 @@ tests: - label: "TH sends a ViewScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C01.Rsp verification: | DUT sends a ViewSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to 0x0001, the SceneID field set to 0x01, the TransitionTime field set to 0x0000 and a set of extension fields appropriate to AC1. disabled: true @@ -125,6 +134,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values (SC0 - 1), 0xfe or null, the GroupID field set to 0x0001, the SceneCount field set to 0x01 and the SceneList field containing only the scene ID 0x01. disabled: true @@ -132,6 +142,7 @@ tests: - label: "TH sends a RemoveAllScenes command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C03.Rsp verification: | DUT sends a RemoveAllScenesResponse command to TH with the Status field set to 0x00 (SUCCESS) and GroupID field set to 0x0001. disabled: true @@ -139,6 +150,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values SC0, 0xfe or null, the GroupID field set to 0x0001 and the SceneCount field set to 0x00. disabled: true @@ -147,6 +159,7 @@ tests: "TH sends a AddScene command to DUT with the GroupID field set to 0x0001, the SceneID field set to 0x01, the TransitionTime field set to 0x0001 and a set of extension fields appropriate to AC1." + PICS: S.S.C00.Rsp verification: | DUT sends a AddSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to 0x0001 and the SceneID field set to 0x01. disabled: true @@ -154,6 +167,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values (SC0 - 1), 0xfe or null, the GroupID field set to 0x0001, the SceneCount field set to 0x01 and the SceneList field containing only the scene ID 0x01. disabled: true @@ -161,6 +175,7 @@ tests: - label: "TH sends a RemoveScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C02.Rsp verification: | DUT sends a RemoveSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to 0x0001 and the SceneID field set to 0x01. disabled: true @@ -168,6 +183,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values SC0, 0xfe or null, the GroupID field set to 0x0001 and the SceneCount field set to 0x00. disabled: true @@ -182,6 +198,7 @@ tests: - label: "TH sends a RecallScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C05.Rsp verification: | If a status response is expected, DUT sends a response to TH with the Status field equal to 0x8b (NOT_FOUND). disabled: true @@ -196,6 +213,7 @@ tests: - label: "TH sends a StoreScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x01." + PICS: S.S.C04.Rsp verification: | DUT sends a StoreSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to 0x0001 and the SceneID field set to 0x01. disabled: true @@ -210,6 +228,7 @@ tests: - label: "TH sends a StoreScene command to DUT with the GroupID field set to 0x0001 and the SceneID field set to 0x02." + PICS: S.S.C04.Rsp verification: | DUT sends a StoreSceneResponse command to TH with the Status field set to 0x00 (SUCCESS) or 0x89 (INSUFFICIENT_SPACE). If SUCCESS, with the GroupID field set to 0x0001 and the SceneID field set to 0x02. If INSUFFICIENT_SPACE, the following steps SHALL NOT be executed. disabled: true @@ -217,6 +236,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0001." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values (SC0 - 2), 0xfe or null, the GroupID field set to 0x0001, the SceneCount field set to 0x02 and the SceneList field containing the scene IDs 0x01 and 0x02. disabled: true @@ -224,6 +244,7 @@ tests: - label: "If capacity allows, TH sends a AddGroup command to DUT with the GroupID field set to 0x0002." + PICS: G.S.C00.Rsp verification: | DUT sends a AddGroupResponse command to TH with the Status field set to 0x00 (SUCCESS) and the GroupID field set to 0x0002. disabled: true @@ -231,6 +252,7 @@ tests: - label: "TH sends a RemoveAllScenes command to DUT with the GroupID field set to 0x0002." + PICS: S.S.C03.Rsp verification: | DUT sends a RemoveAllScenesResponse command to TH with the Status field set to 0x00 (SUCCESS) and GroupID field set to 0x0002. disabled: true @@ -238,6 +260,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0002." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to the value SC1, the GroupID field set to 0x0002 and the SceneCount field set to 0x00. disabled: true @@ -252,6 +275,7 @@ tests: - label: "TH sends a StoreScene command to DUT with the GroupID field set to 0x0002 and the SceneID field set to 0x03." + PICS: S.S.C04.Rsp verification: | DUT sends a StoreSceneResponse command to TH with the Status field set to 0x00 (SUCCESS) or 0x89 (INSUFFICIENT_SPACE). If SUCCESS, with the GroupID field set to 0x0002 and the SceneID field set to 0x03. IF INSUFFICIENT_SPACE, the following steps SHALL NOT be executed. disabled: true @@ -259,6 +283,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to 0x0002." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values (SC1 - 3), 0xfe or null, the GroupID field set to 0x0002, the SceneCount field set to 0x01 and the SceneList field containing only the scene ID 0x03. disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_S_2_3.yaml b/src/app/tests/suites/certification/Test_TC_S_2_3.yaml index 3ea2eb3e8f0fa9..77833e7a1a0954 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_3.yaml @@ -32,6 +32,7 @@ tests: - label: "TH sends a AddGroup command to DUT with the GroupID field set to G1." + PICS: G.S.C00.Rsp verification: | DUT sends a AddGroupResponse command to TH with the Status field set to 0x00 (SUCCESS) or 0x8a (DUPLICATE_EXISTS) and the GroupID field set to G1. disabled: true @@ -39,6 +40,7 @@ tests: - label: "TH sends a RemoveAllScenes command to DUT with the GroupID field set to G1." + PICS: S.S.C03.Rsp verification: | DUT sends a RemoveAllScenesResponse command to TH with the Status field set to 0x00 (SUCCESS) and GroupID field set to G1. disabled: true @@ -46,6 +48,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to G1." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to the value SC0, the GroupID field set to G1 and the SceneCount field set to 0x00. disabled: true @@ -54,6 +57,7 @@ tests: "TH sends a EnhancedAddScene command to DUT with the GroupID field set to G1, the SceneID field set to 0x01, the TransitionTime field set to 0x000a (1s) and a set of extension fields appropriate to AC1." + PICS: S.S.C40.Rsp verification: | DUT sends a EnhancedAddSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1 and the SceneID field set to 0x01. disabled: true @@ -62,6 +66,7 @@ tests: "TH sends a AddScene command to DUT with the GroupID field set to G1, the SceneID field set to 0x01, the TransitionTime field set to 0x0001 (1s) and a set of extension fields appropriate to AC1." + PICS: S.S.C40.Rsp verification: | DUT sends a AddSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1 and the SceneID field set to 0x01. disabled: true @@ -69,6 +74,7 @@ tests: - label: "TH sends a EnhancedViewScene command to DUT with the GroupID field set to G1 and the SceneID field set to 0x01." + PICS: S.S.C41.Rsp verification: | DUT sends a EnhancedViewSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1, the SceneID field set to 0x01, the TransitionTime field set to 0x000a (1s) and a set of extension fields appropriate to AC1. disabled: true @@ -76,6 +82,7 @@ tests: - label: "TH sends a ViewScene command to DUT with the GroupID field set to G1 and the SceneID field set to 0x01." + PICS: "!S.S.C41.Rsp" verification: | DUT sends a ViewSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1 and the SceneID field set to 0x01, the TransitionTime field set to 0x0001 (1s) and a set of extension fields appropriate to AC1. disabled: true @@ -83,6 +90,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to G1." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values (SC0 - 1), 0xfe or null, the GroupID field set to G1, the SceneCount field set to 0x01 and the SceneList field containing only the scene ID 0x01. disabled: true @@ -90,6 +98,7 @@ tests: - label: "TH configures AC2 on DUT for all implemented application clusters supporting scenes." + PICS: S.S.C04.Rsp verification: | DUT is configured with AC2 which is different from AC1. disabled: true @@ -97,6 +106,7 @@ tests: - label: "TH sends a RecallScene command to group G1 with the GroupID field set to G1 and the scene ID field set to 0x01." + PICS: S.S.C05.Rsp verification: | (There is no Status response since this was a groupcast) DUT returns to AC1. disabled: true @@ -106,6 +116,7 @@ tests: the group identifier from field set to G1, the scene identifier from field set to 0x01, the group identifier to field set to G1 and the scene identifier to field set to 0x02." + PICS: S.S.C42.Rsp verification: | DUT sends a CopySceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the group identifier from field set to G1 and the scene identifier from field set to 0x01. disabled: true @@ -113,6 +124,7 @@ tests: - label: "TH sends a GetSceneMembership command to DUT with the GroupID field set to G1." + PICS: S.S.C06.Rsp verification: | DUT sends a GetSceneMembershipResponse command to TH with the Status field set to 0x00 (SUCCESS), the Capacity field set to one of the values (SC0 - 2), 0xfe or null, the GroupID field set to G1, the SceneCount field set to 0x02 and the SceneList field containing the scene IDs 0x01 and 0x02. disabled: true diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 56661793643a69..e480cf0c63ae5b 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -232,6 +232,7 @@ MC_KEYPADINPUT.S.LK=0 MC_KEYPADINPUT.S.NK=0 MC_KEYPADINPUT.S.NV=0 MC_MEDIAINPUT.S.NU=0 + #PRS PRS.S.A0000=1 PRS.S.A0001=1 @@ -242,3 +243,74 @@ PRS.S.A0011=0 PRS.S.A0012=0 PRS.S.A0013=0 PRS.S.A0014=0 + +#Groups Cluster +G.S.A0000=0 +GRPKEY.S.A0001=0 +G.S.C00.Rsp=0 +G.S.C01.Rsp=0 +G.S.C02.Rsp=0 +G.S.C03.Rsp=0 +G.S.C04.Rsp=0 +G.S.C05.Rsp=0 +G.S.C00.Tx=0 +G.S.C01.Tx=0 +G.S.C02.Tx=0 +G.S.C03.Tx=0 +G.C.A0000=0 +G.C.C00.Rsp=0 +G.C.C01.Rsp=0 +G.C.C02.Rsp=0 +G.C.C03.Rsp=0 +G.C.C04.Rsp=0 +G.C.C05.Rsp=0 + +#Identify Cluster +I.S.A0000=1 +I.S.A0001=1 +I.S.C00.Rsp=1 +I.S.C01.Rsp=1 +I.S.C40.Rsp=1 +I.S.C00.Tx=1 +I.C.C00.Tx=1 +I.C.C01.Tx=1 +I.C.C40.Tx=1 +I.C.C00.Rsp=1 + +#Scenes Cluster +S.S.A0000=0 +S.S.A0001=0 +S.S.A0002=0 +S.S.A0003=0 +S.S.A0004=0 +S.S.A0005=0 +S.S.C00.Rsp=0 +S.S.C01.Rsp=0 +S.S.C02.Rsp=0 +S.S.C03.Rsp=0 +S.S.C04.Rsp=0 +S.S.C05.Rsp=0 +S.S.C06.Rsp=0 +S.S.C40.Rsp=0 +S.S.C41.Rsp=0 +S.S.C42.Rsp=0 +S.S.C05.Rsp=0 +G.S.C00.Rsp=0 +G.S.C04.Rsp=0 +S.C.C00.Tx=0 +S.C.C01.Tx=0 +S.C.C02.Tx=0 +S.C.C03.Tx=0 +S.C.C04.Tx=0 +S.C.C05.Tx=0 +S.C.C06.Tx=0 +S.C.C40.Tx=0 +S.C.C41.Tx=0 +S.C.C42.Tx=0 + +#Switch Cluster +SWTCH.S.F00=1 +SWTCH.S.F01=1 +SWTCH.S.F02=1 +SWTCH.S.F03=1 +SWTCH.S.F04=1 \ No newline at end of file diff --git a/src/app/tests/suites/tests.js b/src/app/tests/suites/tests.js index e3d978546acf8d..354657083104cf 100644 --- a/src/app/tests/suites/tests.js +++ b/src/app/tests/suites/tests.js @@ -68,12 +68,12 @@ function getManualTests() { const Groups = [ 'TestGroupDemoCommand', 'TestGroupDemoConfig', - 'Test_TC_GR_1_1', - 'Test_TC_GR_2_1', - 'Test_TC_GR_2_2', - 'Test_TC_GR_2_3', - 'Test_TC_GR_3_1', - 'Test_TC_GR_3_2', + 'Test_TC_G_1_1', + 'Test_TC_G_2_1', + 'Test_TC_G_2_2', + 'Test_TC_G_2_3', + 'Test_TC_G_3_1', + 'Test_TC_G_3_2', ]; const BulkDataExchangeProtocol = [ diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 5d61e62eb219d6..541d261353da3e 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -276,12 +276,12 @@ class ManualTestList : public Command printf("Test_TC_DD_3_20\n"); printf("TestGroupDemoCommand\n"); printf("TestGroupDemoConfig\n"); - printf("Test_TC_GR_1_1\n"); - printf("Test_TC_GR_2_1\n"); - printf("Test_TC_GR_2_2\n"); - printf("Test_TC_GR_2_3\n"); - printf("Test_TC_GR_3_1\n"); - printf("Test_TC_GR_3_2\n"); + printf("Test_TC_G_1_1\n"); + printf("Test_TC_G_2_1\n"); + printf("Test_TC_G_2_2\n"); + printf("Test_TC_G_2_3\n"); + printf("Test_TC_G_3_1\n"); + printf("Test_TC_G_3_2\n"); printf("Test_TC_BDX_1_1\n"); printf("Test_TC_BDX_1_2\n"); printf("Test_TC_BDX_1_3\n"); @@ -12874,6 +12874,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 1: { LogStep(1, "TH sends Identify command to DUT, with the identify time field set to 0x003c (60s)."); + VerifyOrDo(!ShouldSkip("I.S.C00.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::Identify::Type value; value.identifyTime = 60U; @@ -12884,6 +12885,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 2: { LogStep(2, "TH reads immediately IdentifyTime attribute from DUT1"); + VerifyOrDo(!ShouldSkip("I.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), Identify::Id, Identify::Attributes::IdentifyTime::Id, true, chip::NullOptional); } @@ -12896,6 +12898,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 4: { LogStep(4, "After 10 seconds, the TH reads IdentifyTime attribute from DUT"); + VerifyOrDo(!ShouldSkip("I.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), Identify::Id, Identify::Attributes::IdentifyTime::Id, true, chip::NullOptional); } @@ -12913,6 +12916,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 6: { LogStep(6, "TH sends Identify command to DUT, with the identify time field set to 0x0000 (stop identifying)."); + VerifyOrDo(!ShouldSkip("I.S.C00.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::Identify::Type value; value.identifyTime = 0U; @@ -12923,6 +12927,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 7: { LogStep(7, "TH reads immediately IdentifyTime attribute from DUT2"); + VerifyOrDo(!ShouldSkip("I.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), Identify::Id, Identify::Attributes::IdentifyTime::Id, true, chip::NullOptional); } @@ -12938,6 +12943,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 9: { LogStep(9, "TH writes a value of 0x000f (15s) to IdentifyTime attribute of DUT"); + VerifyOrDo(!ShouldSkip("I.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; uint16_t value; value = 15U; @@ -12953,6 +12959,7 @@ class Test_TC_I_2_2Suite : public TestCommand } case 11: { LogStep(11, "After 5 seconds, the TH reads IdentifyTime attribute from DUT"); + VerifyOrDo(!ShouldSkip("I.S.A0000"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), Identify::Id, Identify::Attributes::IdentifyTime::Id, true, chip::NullOptional); } @@ -13097,6 +13104,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(1, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x00 blink and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(0); @@ -13117,6 +13125,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(3, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(1); @@ -13137,6 +13146,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(5, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x02 okay and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(2); @@ -13157,6 +13167,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(7, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x0b channel change and the " "effect variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(11); @@ -13177,6 +13188,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(9, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(1); @@ -13197,6 +13209,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(11, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0xfe finish effect and the " "effect variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(254); @@ -13208,6 +13221,7 @@ class Test_TC_I_2_3Suite : public TestCommand } case 12: { LogStep(12, "Manually check DUT stops the breathe effect after the current effect sequence"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::LogCommands::Commands::UserPrompt::Type value; value.message = chip::Span( @@ -13218,6 +13232,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(13, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(1); @@ -13238,6 +13253,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(15, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0xff stop effect and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(255); @@ -13259,6 +13275,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(17, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0x00 blink and the effect " "variant field set to 0x42 unknown"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(0); @@ -13279,6 +13296,7 @@ class Test_TC_I_2_3Suite : public TestCommand LogStep(19, "TH sends TriggerEffect command to DUT with the effect identifier field set to 0xff stop effect and the effect " "variant field set to 0x00 default"); + VerifyOrDo(!ShouldSkip("I.S.C40.Rsp"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); ListFreer listFreer; chip::app::Clusters::Identify::Commands::TriggerEffect::Type value; value.effectIdentifier = static_cast(255); @@ -27096,6 +27114,7 @@ class Test_TC_SWTCH_2_1Suite : public TestCommand } case 3: { LogStep(3, "Read MultiPressMax attribute"); + VerifyOrDo(!ShouldSkip("SWTCH.S.F04"), return ContinueOnChipMainThread(CHIP_NO_ERROR)); return ReadAttribute(kIdentityAlpha, GetEndpoint(1), Switch::Id, Switch::Attributes::MultiPressMax::Id, true, chip::NullOptional); } @@ -66081,10 +66100,10 @@ class TestGroupDemoConfigSuite : public TestCommand } }; -class Test_TC_GR_1_1Suite : public TestCommand +class Test_TC_G_1_1Suite : public TestCommand { public: - Test_TC_GR_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_GR_1_1", 0, credsIssuerConfig) + Test_TC_G_1_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_G_1_1", 0, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -66092,7 +66111,7 @@ class Test_TC_GR_1_1Suite : public TestCommand AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } - ~Test_TC_GR_1_1Suite() {} + ~Test_TC_G_1_1Suite() {} chip::System::Clock::Timeout GetWaitDuration() const override { @@ -66137,10 +66156,10 @@ class Test_TC_GR_1_1Suite : public TestCommand } }; -class Test_TC_GR_2_1Suite : public TestCommand +class Test_TC_G_2_1Suite : public TestCommand { public: - Test_TC_GR_2_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_GR_2_1", 0, credsIssuerConfig) + Test_TC_G_2_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_G_2_1", 0, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -66148,7 +66167,7 @@ class Test_TC_GR_2_1Suite : public TestCommand AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } - ~Test_TC_GR_2_1Suite() {} + ~Test_TC_G_2_1Suite() {} chip::System::Clock::Timeout GetWaitDuration() const override { @@ -66193,10 +66212,10 @@ class Test_TC_GR_2_1Suite : public TestCommand } }; -class Test_TC_GR_2_2Suite : public TestCommand +class Test_TC_G_2_2Suite : public TestCommand { public: - Test_TC_GR_2_2Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_GR_2_2", 0, credsIssuerConfig) + Test_TC_G_2_2Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_G_2_2", 0, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -66204,7 +66223,7 @@ class Test_TC_GR_2_2Suite : public TestCommand AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } - ~Test_TC_GR_2_2Suite() {} + ~Test_TC_G_2_2Suite() {} chip::System::Clock::Timeout GetWaitDuration() const override { @@ -66249,10 +66268,10 @@ class Test_TC_GR_2_2Suite : public TestCommand } }; -class Test_TC_GR_2_3Suite : public TestCommand +class Test_TC_G_2_3Suite : public TestCommand { public: - Test_TC_GR_2_3Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_GR_2_3", 0, credsIssuerConfig) + Test_TC_G_2_3Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_G_2_3", 0, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -66260,7 +66279,7 @@ class Test_TC_GR_2_3Suite : public TestCommand AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } - ~Test_TC_GR_2_3Suite() {} + ~Test_TC_G_2_3Suite() {} chip::System::Clock::Timeout GetWaitDuration() const override { @@ -66305,10 +66324,10 @@ class Test_TC_GR_2_3Suite : public TestCommand } }; -class Test_TC_GR_3_1Suite : public TestCommand +class Test_TC_G_3_1Suite : public TestCommand { public: - Test_TC_GR_3_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_GR_3_1", 0, credsIssuerConfig) + Test_TC_G_3_1Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_G_3_1", 0, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -66316,7 +66335,7 @@ class Test_TC_GR_3_1Suite : public TestCommand AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } - ~Test_TC_GR_3_1Suite() {} + ~Test_TC_G_3_1Suite() {} chip::System::Clock::Timeout GetWaitDuration() const override { @@ -66361,10 +66380,10 @@ class Test_TC_GR_3_1Suite : public TestCommand } }; -class Test_TC_GR_3_2Suite : public TestCommand +class Test_TC_G_3_2Suite : public TestCommand { public: - Test_TC_GR_3_2Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_GR_3_2", 0, credsIssuerConfig) + Test_TC_G_3_2Suite(CredentialIssuerCommands * credsIssuerConfig) : TestCommand("Test_TC_G_3_2", 0, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -66372,7 +66391,7 @@ class Test_TC_GR_3_2Suite : public TestCommand AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } - ~Test_TC_GR_3_2Suite() {} + ~Test_TC_G_3_2Suite() {} chip::System::Clock::Timeout GetWaitDuration() const override { @@ -87215,12 +87234,12 @@ void registerCommandsTests(Commands & commands, CredentialIssuerCommands * creds make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index bdeef943c07882..befe82bd4f08a8 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -21289,10 +21289,18 @@ class Test_TC_I_2_2 : public TestCommandBridge { case 1: ChipLogProgress(chipTool, " ***** Test Step 1 : TH sends Identify command to DUT, with the identify time field set to 0x003c (60s).\n"); + if (ShouldSkip("I.S.C00.Rsp")) { + NextTest(); + return; + } err = TestThSendsIdentifyCommandToDutWithTheIdentifyTimeFieldSetTo0x003c60s_1(); break; case 2: ChipLogProgress(chipTool, " ***** Test Step 2 : TH reads immediately IdentifyTime attribute from DUT1\n"); + if (ShouldSkip("I.S.A0000")) { + NextTest(); + return; + } err = TestThReadsImmediatelyIdentifyTimeAttributeFromDut1_2(); break; case 3: @@ -21301,6 +21309,10 @@ class Test_TC_I_2_2 : public TestCommandBridge { break; case 4: ChipLogProgress(chipTool, " ***** Test Step 4 : After 10 seconds, the TH reads IdentifyTime attribute from DUT\n"); + if (ShouldSkip("I.S.A0000")) { + NextTest(); + return; + } err = TestAfter10SecondsTheThReadsIdentifyTimeAttributeFromDut_4(); break; case 5: @@ -21317,10 +21329,18 @@ class Test_TC_I_2_2 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 6 : TH sends Identify command to DUT, with the identify time field set to 0x0000 (stop " "identifying).\n"); + if (ShouldSkip("I.S.C00.Rsp")) { + NextTest(); + return; + } err = TestThSendsIdentifyCommandToDutWithTheIdentifyTimeFieldSetTo0x0000StopIdentifying_6(); break; case 7: ChipLogProgress(chipTool, " ***** Test Step 7 : TH reads immediately IdentifyTime attribute from DUT2\n"); + if (ShouldSkip("I.S.A0000")) { + NextTest(); + return; + } err = TestThReadsImmediatelyIdentifyTimeAttributeFromDut2_7(); break; case 8: @@ -21333,6 +21353,10 @@ class Test_TC_I_2_2 : public TestCommandBridge { break; case 9: ChipLogProgress(chipTool, " ***** Test Step 9 : TH writes a value of 0x000f (15s) to IdentifyTime attribute of DUT\n"); + if (ShouldSkip("I.S.A0000")) { + NextTest(); + return; + } err = TestThWritesAValueOf0x000f15sToIdentifyTimeAttributeOfDut_9(); break; case 10: @@ -21341,6 +21365,10 @@ class Test_TC_I_2_2 : public TestCommandBridge { break; case 11: ChipLogProgress(chipTool, " ***** Test Step 11 : After 5 seconds, the TH reads IdentifyTime attribute from DUT\n"); + if (ShouldSkip("I.S.A0000")) { + NextTest(); + return; + } err = TestAfter5SecondsTheThReadsIdentifyTimeAttributeFromDut_11(); break; } @@ -21642,6 +21670,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 1 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x00 blink and " "the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x00BlinkAndTheEffectVariantFieldSetTo0x00Default_1(); break; case 2: @@ -21652,6 +21684,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 3 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe " "and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x01BreatheAndTheEffectVariantFieldSetTo0x00Default_3(); break; case 4: @@ -21662,6 +21698,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 5 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x02 okay and " "the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x02OkayAndTheEffectVariantFieldSetTo0x00Default_5(); break; case 6: @@ -21672,6 +21712,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 7 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x0b channel " "change and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x0bChannelChangeAndTheEffectVariantFieldSetTo0x00Default_7(); break; case 8: @@ -21682,6 +21726,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 9 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe " "and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x01BreatheAndTheEffectVariantFieldSetTo0x00Default_9(); break; case 10: @@ -21692,17 +21740,29 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 11 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0xfe finish " "effect and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0xfeFinishEffectAndTheEffectVariantFieldSetTo0x00Default_11(); break; case 12: ChipLogProgress( chipTool, " ***** Test Step 12 : Manually check DUT stops the breathe effect after the current effect sequence\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestManuallyCheckDutStopsTheBreatheEffectAfterTheCurrentEffectSequence_12(); break; case 13: ChipLogProgress(chipTool, " ***** Test Step 13 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x01 breathe " "and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x01BreatheAndTheEffectVariantFieldSetTo0x00Default_13(); break; case 14: @@ -21713,6 +21773,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 15 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0xff stop " "effect and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0xffStopEffectAndTheEffectVariantFieldSetTo0x00Default_15(); break; case 16: @@ -21723,6 +21787,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 17 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0x00 blink " "and the effect variant field set to 0x42 unknown\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0x00BlinkAndTheEffectVariantFieldSetTo0x42Unknown_17(); break; case 18: @@ -21733,6 +21801,10 @@ class Test_TC_I_2_3 : public TestCommandBridge { ChipLogProgress(chipTool, " ***** Test Step 19 : TH sends TriggerEffect command to DUT with the effect identifier field set to 0xff stop " "effect and the effect variant field set to 0x00 default\n"); + if (ShouldSkip("I.S.C40.Rsp")) { + NextTest(); + return; + } err = TestThSendsTriggerEffectCommandToDutWithTheEffectIdentifierFieldSetTo0xffStopEffectAndTheEffectVariantFieldSetTo0x00Default_19(); break; case 20: @@ -43154,6 +43226,10 @@ class Test_TC_SWTCH_2_1 : public TestCommandBridge { break; case 3: ChipLogProgress(chipTool, " ***** Test Step 3 : Read MultiPressMax attribute\n"); + if (ShouldSkip("SWTCH.S.F04")) { + NextTest(); + return; + } err = TestReadMultiPressMaxAttribute_3(); break; } From 41e474d58cce5f1b4e85601ab9ef59a387f355f5 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 28 Jun 2022 19:55:47 +0200 Subject: [PATCH 02/76] [python] Fix Python device library build (#20043) * Drop chip_use_clusters_for_ip_commissioning It has been removed from build_python.sh already a while ago in 3a466490073abb3732013b5f3ac1e135593d53e0. * Drop unused variables --- scripts/build_python_device.sh | 9 +-------- src/controller/python/chip/server/ServerInit.cpp | 3 --- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/scripts/build_python_device.sh b/scripts/build_python_device.sh index 14fce377a6cdad..5f637fa41ad937 100755 --- a/scripts/build_python_device.sh +++ b/scripts/build_python_device.sh @@ -41,7 +41,6 @@ ENVIRONMENT_ROOT="$CHIP_ROOT/out/python_env" declare chip_detail_logging=false declare enable_pybindings=false declare chip_mdns -declare clusters=true help() { @@ -54,8 +53,6 @@ Input Options: By default it is false. -m, --chip_mdns ChipMDNSValue Specify ChipMDNSValue as platform or minimal. By default it is minimal. - -c, --clusters_for_ip_commissioning true/false Specify whether to use clusters for IP commissioning. - By default it is true. -p, --enable_pybindings EnableValue Specify whether to enable pybindings as python controller. " } @@ -76,10 +73,6 @@ while (($#)); do chip_mdns=$2 shift ;; - --clusters_for_ip_commissioning | -c) - clusters=$2 - shift - ;; --enable_pybindings | -p) enable_pybindings=$2 shift @@ -104,7 +97,7 @@ source "$CHIP_ROOT/scripts/activate.sh" chip_data_model_arg="chip_data_model=\"///examples/lighting-app/lighting-common\"" -gn --root="$CHIP_ROOT" gen "$OUTPUT_ROOT" --args="chip_detail_logging=$chip_detail_logging enable_pylib=$enable_pybindings enable_rtti=$enable_pybindings chip_use_clusters_for_ip_commissioning=$clusters $chip_mdns_arg chip_controller=false $chip_data_model_arg" +gn --root="$CHIP_ROOT" gen "$OUTPUT_ROOT" --args="chip_detail_logging=$chip_detail_logging enable_pylib=$enable_pybindings enable_rtti=$enable_pybindings $chip_mdns_arg chip_controller=false $chip_data_model_arg" # Compiles python files # Check pybindings was requested diff --git a/src/controller/python/chip/server/ServerInit.cpp b/src/controller/python/chip/server/ServerInit.cpp index c0b0d1086a66f4..a694698b6e43b0 100644 --- a/src/controller/python/chip/server/ServerInit.cpp +++ b/src/controller/python/chip/server/ServerInit.cpp @@ -168,9 +168,6 @@ void pychip_server_native_init() // parts from ChipLinuxAppMainLoop - uint16_t securePort = CHIP_PORT; - uint16_t unsecurePort = CHIP_UDC_PORT; - // Init ZCL Data Model and CHIP App Server static chip::CommonCaseDeviceServerInitParams initParams; (void) initParams.InitializeStaticResourcesBeforeServerInit(); From cab048f5c30e2d8e3366157da3f90859b6323cce Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 28 Jun 2022 16:40:15 -0400 Subject: [PATCH 03/76] Fix the extended discovery time limit to actually be obeyed properly. (#20019) * Fix the extended discovery time limit to actually be obeyed properly. Fixes https://github.com/project-chip/connectedhomeip/issues/16522 Tested that if CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS is set to CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT then we advertise extended discovery in all the conditions where we are not advertising commissionable discovery. If CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS is set to another value, verified that: 1. We do not start advertising extended discovery on startup. 2. If we start advertising commissionable discovery on startup, then after the commissioning window closes (whether due to being commissioned or timing out) we we start advertising extended discovery until that times out. 3. If we open a new commissioning window and then RevokeCommissioning, we start advertising extended discovery until it times out. 4. If we open a new commissioning window and then commission the device, we start advertising extended discovery until it times out. 5. If in a state with two fabrics commissioned we remove a fabric we do _not_ start advertising extended discovery (unlike before this change). 6. If in a state with two fabrics commissioned and extended discovery advertising ongoing we remove one of the fabrics, we keep advertising extended discovery until it times out. * Fix typo in comment. Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> * Advertise extended discovery on startup. Addresses review comments. Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> --- src/app/server/Dnssd.cpp | 108 +++++++++++++++------------------------ src/app/server/Dnssd.h | 21 ++++---- 2 files changed, 49 insertions(+), 80 deletions(-) diff --git a/src/app/server/Dnssd.cpp b/src/app/server/Dnssd.cpp index 3b1d7d7c9f0042..12fe2824ad3019 100644 --- a/src/app/server/Dnssd.cpp +++ b/src/app/server/Dnssd.cpp @@ -80,6 +80,13 @@ void DnssdServer::SetExtendedDiscoveryTimeoutSecs(int32_t secs) { ChipLogDetail(Discovery, "Setting extended discovery timeout to %" PRId32 "s", secs); mExtendedDiscoveryTimeoutSecs = MakeOptional(secs); + + if (mExtendedDiscoveryExpiration != kTimeoutCleared && + mExtendedDiscoveryExpiration > mTimeSource.GetMonotonicTimestamp() + System::Clock::Seconds32(secs)) + { + // Reset our timer to the new (shorter) timeout. + ScheduleExtendedDiscoveryExpiration(); + } } int32_t DnssdServer::GetExtendedDiscoveryTimeoutSecs() @@ -95,72 +102,15 @@ void HandleExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aApp void DnssdServer::OnExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState) { - if (!DnssdServer::OnExpiration(mExtendedDiscoveryExpiration)) - { - ChipLogDetail(Discovery, "Extended discovery timeout cancelled"); - return; - } - ChipLogDetail(Discovery, "Extended discovery timed out"); mExtendedDiscoveryExpiration = kTimeoutCleared; -} -#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY - -bool DnssdServer::OnExpiration(System::Clock::Timestamp expirationMs) -{ - if (expirationMs == kTimeoutCleared) - { - ChipLogDetail(Discovery, "OnExpiration callback for cleared session"); - return false; - } - System::Clock::Timestamp now = mTimeSource.GetMonotonicTimestamp(); - if (expirationMs > now) - { - ChipLogDetail(Discovery, "OnExpiration callback for reset session"); - return false; - } - - ChipLogDetail(Discovery, "OnExpiration - valid time out"); - - CHIP_ERROR err = Dnssd::ServiceAdvertiser::Instance().Init(chip::DeviceLayer::UDPEndPointManager()); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Failed to initialize advertiser: %" CHIP_ERROR_FORMAT, err.Format()); - } - - // reset advertising - err = Dnssd::ServiceAdvertiser::Instance().RemoveServices(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Failed to remove advertised services: %" CHIP_ERROR_FORMAT, err.Format()); - } - - // restart operational (if needed) - err = AdvertiseOperational(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Failed to advertise operational node: %" CHIP_ERROR_FORMAT, err.Format()); - } -#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY - err = AdvertiseCommissioner(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Failed to advertise commissioner: %" CHIP_ERROR_FORMAT, err.Format()); - } -#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY - - err = Dnssd::ServiceAdvertiser::Instance().FinalizeServiceUpdate(); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Failed to finalize service update: %" CHIP_ERROR_FORMAT, err.Format()); - } - - return true; + // Reset our advertising, now that we have flagged ourselves as possibly not + // needing extended discovery anymore. + StartServer(); } -#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY CHIP_ERROR DnssdServer::ScheduleExtendedDiscoveryExpiration() { int32_t extendedDiscoveryTimeoutSecs = GetExtendedDiscoveryTimeoutSecs(); @@ -362,6 +312,16 @@ CHIP_ERROR DnssdServer::AdvertiseCommissioner() CHIP_ERROR DnssdServer::AdvertiseCommissionableNode(chip::Dnssd::CommissioningMode mode) { +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + mCurrentCommissioningMode = mode; + if (mode != Dnssd::CommissioningMode::kDisabled) + { + // We're not doing extended discovery right now. + DeviceLayer::SystemLayer().CancelTimer(HandleExtendedDiscoveryExpiration, nullptr); + mExtendedDiscoveryExpiration = kTimeoutCleared; + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + return Advertise(true /* commissionableNode */, mode); } @@ -379,8 +339,6 @@ void DnssdServer::StartServer(Dnssd::CommissioningMode mode) { ChipLogProgress(Discovery, "Updating services using commissioning mode %d", static_cast(mode)); - ClearTimeouts(); - DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformEventWrapper, 0); CHIP_ERROR err = Dnssd::ServiceAdvertiser::Instance().Init(chip::DeviceLayer::UDPEndPointManager()); @@ -401,7 +359,7 @@ void DnssdServer::StartServer(Dnssd::CommissioningMode mode) ChipLogError(Discovery, "Failed to advertise operational node: %" CHIP_ERROR_FORMAT, err.Format()); } - if (mode != chip::Dnssd::CommissioningMode::kDisabled) + if (mode != Dnssd::CommissioningMode::kDisabled) { err = AdvertiseCommissionableNode(mode); if (err != CHIP_NO_ERROR) @@ -412,13 +370,27 @@ void DnssdServer::StartServer(Dnssd::CommissioningMode mode) #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY else if (GetExtendedDiscoveryTimeoutSecs() != CHIP_DEVICE_CONFIG_DISCOVERY_DISABLED) { - err = AdvertiseCommissionableNode(mode); - if (err != CHIP_NO_ERROR) + bool alwaysAdvertiseExtended = (GetExtendedDiscoveryTimeoutSecs() == CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT); + // We do extended discovery advertising in three cases: + // 1) We don't have a timeout for extended discovery. + // 2) We are transitioning out of commissioning mode (basic or enhanced) + // and should therefore start extended discovery. + // 3) We are resetting advertising while we are in the middle of an + // existing extended discovery advertising period. + if (alwaysAdvertiseExtended || mCurrentCommissioningMode != Dnssd::CommissioningMode::kDisabled || + mExtendedDiscoveryExpiration != kTimeoutCleared) { - ChipLogError(Discovery, "Failed to advertise extended commissionable node: %" CHIP_ERROR_FORMAT, err.Format()); + err = AdvertiseCommissionableNode(mode); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to advertise extended commissionable node: %" CHIP_ERROR_FORMAT, err.Format()); + } + if (mExtendedDiscoveryExpiration == kTimeoutCleared) + { + // set timeout + ScheduleExtendedDiscoveryExpiration(); + } } - // set timeout - ScheduleExtendedDiscoveryExpiration(); } #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY diff --git a/src/app/server/Dnssd.h b/src/app/server/Dnssd.h index af9cfaf6122e04..394c928e9c3943 100644 --- a/src/app/server/Dnssd.h +++ b/src/app/server/Dnssd.h @@ -139,13 +139,6 @@ class DLL_EXPORT DnssdServer Time::TimeSource mTimeSource; - void ClearTimeouts() - { -#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY - mExtendedDiscoveryExpiration = kTimeoutCleared; -#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY - } - FabricTable * mFabricTable = nullptr; CommissioningModeProvider * mCommissioningModeProvider = nullptr; @@ -156,11 +149,6 @@ class DLL_EXPORT DnssdServer // Ephemeral discriminator to use instead of the default if set Optional mEphemeralDiscriminator; - Optional mExtendedDiscoveryTimeoutSecs = NullOptional; - - /// return true if expirationMs is valid (not cleared and not in the future) - bool OnExpiration(System::Clock::Timestamp expiration); - #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY /// Get the current extended discovery timeout (set by /// SetExtendedDiscoveryTimeoutSecs, or the configuration default if not set). @@ -169,7 +157,16 @@ class DLL_EXPORT DnssdServer /// schedule next extended discovery expiration CHIP_ERROR ScheduleExtendedDiscoveryExpiration(); + // mExtendedDiscoveryExpiration, if not set to kTimeoutCleared, is used to + // indicate that we should be advertising extended discovery right now. System::Clock::Timestamp mExtendedDiscoveryExpiration = kTimeoutCleared; + Optional mExtendedDiscoveryTimeoutSecs = NullOptional; + + // The commissioning mode we are advertising right now. Used to detect when + // we need to start extended discovery advertisement. We start this off as + // kEnabledBasic, so that when we first start up we do extended discovery + // advertisement if we don't enter commissioning mode. + Dnssd::CommissioningMode mCurrentCommissioningMode = Dnssd::CommissioningMode::kEnabledBasic; #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY }; From 02c0e3c1bb75c5615c8c300fcd4599c593319636 Mon Sep 17 00:00:00 2001 From: amitnj <74272437+amitnj@users.noreply.github.com> Date: Tue, 28 Jun 2022 14:51:20 -0700 Subject: [PATCH 04/76] Add functionality to read attributes from content apps (#19924) * Add functionality to read attributes from content apps * Remove unused code * Fixed issues identified during review * restyle * Failure handling and fixed typo * restyle fixes. --- .../tv/app/api/MatterIntentConstants.java | 5 ++ .../receiver/MatterCommandReceiver.java | 83 ++++++++++++------- .../ContentAppEndpointManagerImpl.java | 20 +++++ .../service/ContentAppAgentService.java | 27 ++++++ examples/tv-app/android/BUILD.gn | 2 + .../AppContentLauncherManager.cpp | 66 +++++++++++++-- .../AppContentLauncherManager.h | 17 ++-- examples/tv-app/android/java/AppImpl.cpp | 4 +- examples/tv-app/android/java/AppImpl.h | 8 +- .../java/ContentAppAttributeDelegate.cpp | 64 ++++++++++++++ .../java/ContentAppAttributeDelegate.h | 76 +++++++++++++++++ .../java/ContentAppCommandDelegate.cpp | 14 ++-- .../tvapp/ContentAppEndpointManager.java | 2 + 13 files changed, 332 insertions(+), 56 deletions(-) create mode 100644 examples/tv-app/android/java/ContentAppAttributeDelegate.cpp create mode 100644 examples/tv-app/android/java/ContentAppAttributeDelegate.h diff --git a/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java b/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java index d5e95061b6f6c5..60fa854790000f 100644 --- a/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java +++ b/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java @@ -15,9 +15,14 @@ public class MatterIntentConstants { public static final String EXTRA_RESPONSE_PAYLOAD = "EXTRA_RESPONSE_PAYLOAD"; + public static final String EXTRA_ATTRIBUTE_ACTION = "EXTRA_ATTRIBUTE_ACTION"; + + public static final String ATTRIBUTE_ACTION_READ = "ATTRIBUTE_ACTION_READ"; + public static final String EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT = "EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT"; public static final String EXTRA_COMMAND_ID = "EXTRA_COMMAND_ID"; public static final String EXTRA_CLUSTER_ID = "EXTRA_CLUSTER_ID"; + public static final String EXTRA_ATTRIBUTE_ID = "EXTRA_ATTRIBUTE_ID"; } diff --git a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java index 5ac11d4b741dae..fc2e1271e61ad6 100644 --- a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java +++ b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java @@ -9,6 +9,8 @@ public class MatterCommandReceiver extends BroadcastReceiver { private static final String TAG = "MatterCommandReceiver"; + private static final int ACCEPT_HEADER = 0; + private static final int SUPPORTED_STREAMING_PROTOCOLS = 1; @Override public void onReceive(Context context, Intent intent) { @@ -21,37 +23,48 @@ public void onReceive(Context context, Intent intent) { switch (intentAction) { case MatterIntentConstants.ACTION_MATTER_COMMAND: - byte[] commandPayload = - intent.getByteArrayExtra(MatterIntentConstants.EXTRA_COMMAND_PAYLOAD); int commandId = intent.getIntExtra(MatterIntentConstants.EXTRA_COMMAND_ID, -1); - int clusterId = intent.getIntExtra(MatterIntentConstants.EXTRA_CLUSTER_ID, -1); - Log.d( - TAG, - new StringBuilder() - .append("Received matter command ") - .append(commandId) - .append(" on cluster ") - .append(clusterId) - .append(" with payload : ") - .append(new String(commandPayload)) - .toString()); - - PendingIntent pendingIntent = - intent.getParcelableExtra( - MatterIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT); - if (pendingIntent != null) { - final Intent responseIntent = - new Intent() - .putExtra( - MatterIntentConstants.EXTRA_RESPONSE_PAYLOAD, - "{\"value\":{\"0\":1, \"1\":\"custom response from content app\"}}" - .getBytes()); - try { - pendingIntent.send(context, 0, responseIntent); - } catch (final PendingIntent.CanceledException ex) { - Log.e(TAG, "Error sending pending intent to the Matter agent", ex); + if (commandId != -1) { + int clusterId = intent.getIntExtra(MatterIntentConstants.EXTRA_CLUSTER_ID, -1); + byte[] commandPayload = + intent.getByteArrayExtra(MatterIntentConstants.EXTRA_COMMAND_PAYLOAD); + Log.d( + TAG, + new StringBuilder() + .append("Received matter command ") + .append(commandId) + .append(" on cluster ") + .append(clusterId) + .append(" with payload : ") + .append(new String(commandPayload)) + .toString()); + String response = "{\"0\":1, \"1\":\"custom response from content app\"}"; + sendResponseViaPendingIntent(context, intent, response); + } else { + int attributeId = intent.getIntExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ID, -1); + String attributeAction = + intent.getStringExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ACTION); + if (attributeAction.equals(MatterIntentConstants.ATTRIBUTE_ACTION_READ)) { + String response; + if (attributeId == ACCEPT_HEADER) { + response = + "{\"0\": [\"video/mp4\", \"application/x-mpegURL\", \"application/dash+xml\"] }"; + } else if (attributeId == SUPPORTED_STREAMING_PROTOCOLS) { + response = "{\"1\":3}"; + } else { + response = ""; + } + sendResponseViaPendingIntent(context, intent, response); + } else { + Log.e( + TAG, + new StringBuilder() + .append("Received unknown Attribute Action: ") + .append(intent.getAction()) + .toString()); } } + break; default: Log.e( @@ -62,4 +75,18 @@ public void onReceive(Context context, Intent intent) { .toString()); } } + + private void sendResponseViaPendingIntent(Context context, Intent intent, String response) { + PendingIntent pendingIntent = + intent.getParcelableExtra(MatterIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT); + if (pendingIntent != null) { + final Intent responseIntent = + new Intent().putExtra(MatterIntentConstants.EXTRA_RESPONSE_PAYLOAD, response.getBytes()); + try { + pendingIntent.send(context, 0, responseIntent); + } catch (final PendingIntent.CanceledException ex) { + Log.e(TAG, "Error sending pending intent to the Matter agent", ex); + } + } + } } diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index 789089b0964271..0b9ea344b161ad 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -29,4 +29,24 @@ public String sendCommand(int endpointId, int clusterId, int commandId, String c } return "Success"; } + + public String readAttribute(int endpointId, int clusterId, int attributeId) { + Log.d( + TAG, + "Received a attribute read request for endpointId " + + endpointId + + "clusterId" + + clusterId + + " attributeId " + + attributeId); + for (ContentApp app : + ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values()) { + if (app.getEndpointId() == endpointId) { + Log.d(TAG, "Sending attribute read request for endpointId " + endpointId); + return ContentAppAgentService.sendAttributeReadRequest( + context, app.getAppName(), clusterId, attributeId); + } + } + return ""; + } } diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java index ccc72e4a9221b2..d68758b1152816 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java @@ -80,6 +80,33 @@ public static String sendCommand( return response; } + public static String sendAttributeReadRequest( + Context context, String packageName, int clusterId, int attributeId) { + Intent in = new Intent(MatterIntentConstants.ACTION_MATTER_COMMAND); + Bundle extras = new Bundle(); + extras.putString( + MatterIntentConstants.EXTRA_ATTRIBUTE_ACTION, MatterIntentConstants.ATTRIBUTE_ACTION_READ); + extras.putInt(MatterIntentConstants.EXTRA_ATTRIBUTE_ID, attributeId); + extras.putInt(MatterIntentConstants.EXTRA_CLUSTER_ID, clusterId); + in.putExtras(extras); + in.setPackage(packageName); + int flags = Intent.FLAG_INCLUDE_STOPPED_PACKAGES; + flags |= Intent.FLAG_RECEIVER_FOREGROUND; + in.setFlags(flags); + int messageId = responseRegistry.getNextMessageCounter(); + in.putExtra( + MatterIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT, + getPendingIntentForResponse(context, packageName, messageId)); + context.sendBroadcast(in); + responseRegistry.waitForMessage(messageId, 10, TimeUnit.SECONDS); + String response = responseRegistry.readAndRemoveResponse(messageId); + if (response == null) { + response = ""; + } + Log.d(TAG, "Response " + response + " being returned for message " + messageId); + return response; + } + private static PendingIntent getPendingIntentForResponse( final Context context, final String targetPackage, final int responseId) { Intent ackBackIntent = new Intent(ACTION_MATTER_RESPONSE); diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn index a616671f049cb6..17abcc4948802c 100644 --- a/examples/tv-app/android/BUILD.gn +++ b/examples/tv-app/android/BUILD.gn @@ -44,6 +44,8 @@ shared_library("jni") { "java/ChannelManager.cpp", "java/ChannelManager.h", "java/ClusterChangeAttribute.cpp", + "java/ContentAppAttributeDelegate.cpp", + "java/ContentAppAttributeDelegate.h", "java/ContentAppCommandDelegate.cpp", "java/ContentAppCommandDelegate.h", "java/ContentLauncherManager.cpp", diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp index 6dc80c5b164f5a..d898612977983a 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp @@ -17,18 +17,19 @@ */ #include "AppContentLauncherManager.h" -#include "../../java/ContentAppCommandDelegate.h" +#include "../../java/ContentAppAttributeDelegate.h" +#include using namespace std; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::DataModel; using namespace chip::app::Clusters::ContentLauncher; -using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate; +using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; -AppContentLauncherManager::AppContentLauncherManager(ContentAppCommandDelegate commandDelegate, list acceptHeaderList, - uint32_t supportedStreamingProtocols) : - mCommandDelegate(commandDelegate) +AppContentLauncherManager::AppContentLauncherManager(ContentAppAttributeDelegate attributeDelegate, + list acceptHeaderList, uint32_t supportedStreamingProtocols) : + mAttributeDelegate(attributeDelegate) { mAcceptHeaderList = acceptHeaderList; mSupportedStreamingProtocols = supportedStreamingProtocols; @@ -73,11 +74,8 @@ void AppContentLauncherManager::HandleLaunchUrl(CommandResponseHelper CHIP_ERROR { for (std::string & entry : mAcceptHeaderList) { @@ -98,6 +122,30 @@ CHIP_ERROR AppContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEn uint32_t AppContentLauncherManager::HandleGetSupportedStreamingProtocols() { ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols"); + chip::app::ConcreteReadAttributePath aPath(mEndpointId, chip::app::Clusters::ContentLauncher::Id, + chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id); + const char * resStr = mAttributeDelegate.Read(aPath); + ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response %s", resStr); + + if (resStr == nullptr || *resStr == 0) + { + return mSupportedStreamingProtocols; + } + + Json::Reader reader; + Json::Value value; + if (!reader.parse(resStr, value)) + { + return mSupportedStreamingProtocols; + } + std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id); + ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", + attrId.c_str()); + if (!value[attrId].empty()) + { + uint32_t supportedStreamingProtocols = static_cast(value[attrId].asInt()); + mSupportedStreamingProtocols = supportedStreamingProtocols; + } return mSupportedStreamingProtocols; } diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h index b5b8f7a533c4e2..bcce3add47f4a7 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h @@ -18,7 +18,7 @@ #pragma once -#include "../../java/ContentAppCommandDelegate.h" +#include "../../java/ContentAppAttributeDelegate.h" #include #include @@ -26,16 +26,16 @@ using chip::CharSpan; using chip::EndpointId; using chip::app::AttributeValueEncoder; using chip::app::CommandResponseHelper; -using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; -using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; -using ParameterType = chip::app::Clusters::ContentLauncher::Structs::Parameter::DecodableType; -using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type; -using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate; +using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; +using ParameterType = chip::app::Clusters::ContentLauncher::Structs::Parameter::DecodableType; +using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type; +using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; class AppContentLauncherManager : public ContentLauncherDelegate { public: - AppContentLauncherManager(ContentAppCommandDelegate commandDelegate, std::list acceptHeaderList, + AppContentLauncherManager(ContentAppAttributeDelegate attributeDelegate, std::list acceptHeaderList, uint32_t supportedStreamingProtocols); void HandleLaunchContent(CommandResponseHelper & helper, @@ -56,8 +56,9 @@ class AppContentLauncherManager : public ContentLauncherDelegate private: EndpointId mEndpointId; - ContentAppCommandDelegate mCommandDelegate; // TODO: set this based upon meta data from app uint32_t mDynamicEndpointFeatureMap = 3; + + ContentAppAttributeDelegate mAttributeDelegate; }; diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index 063a2be2528354..90e88c86f3cd09 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -357,7 +357,7 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend return nullptr; } -EndpointId ContentAppFactoryImpl::AddContentApp(ContentAppImpl * app) +EndpointId ContentAppFactoryImpl::AddContentApp(ContentAppImpl * app, jobject contentAppEndpointManager) { DataVersion dataVersionBuf[ArraySize(contentAppClusters)]; EndpointId epId = ContentAppPlatform::GetInstance().AddContentApp(app, &contentAppEndpoint, Span(dataVersionBuf), @@ -471,7 +471,7 @@ EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const cha ContentAppImpl * app = new ContentAppImpl(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, "20202021", manager); ChipLogProgress(DeviceLayer, "AppImpl: AddContentApp vendorId=%d applicationName=%s ", vendorId, szApplicationName); - return gFactory.AddContentApp(app); + return gFactory.AddContentApp(app, manager); #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED return 0; } diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index 98a6d61798bc07..6a5f919224ef0d 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -39,7 +39,7 @@ #include "../include/target-navigator/TargetNavigatorManager.h" #include "ChannelManager.h" #include "CommissionerMain.h" -#include "ContentAppCommandDelegate.h" +#include "ContentAppAttributeDelegate.h" #include "KeypadInputManager.h" #include "MediaPlaybackManager.h" #include "MyUserPrompter-JNI.h" @@ -72,7 +72,7 @@ using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; using SupportedStreamingProtocol = app::Clusters::ContentLauncher::SupportedStreamingProtocol; -using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate; +using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; static const int kCatalogVendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; @@ -86,7 +86,7 @@ class DLL_EXPORT ContentAppImpl : public ContentApp const char * szApplicationVersion, const char * setupPIN, jobject manager) : mApplicationBasicDelegate(kCatalogVendorId, BuildAppId(vendorId), szVendorName, vendorId, szApplicationName, productId, szApplicationVersion), - mAccountLoginDelegate(setupPIN), mContentLauncherDelegate(ContentAppCommandDelegate(manager), { "image/*", "video/*" }, + mAccountLoginDelegate(setupPIN), mContentLauncherDelegate(ContentAppAttributeDelegate(manager), { "image/*", "video/*" }, to_underlying(SupportedStreamingProtocol::kDash) | to_underlying(SupportedStreamingProtocol::kHls)), mTargetNavigatorDelegate({ "home", "search", "info", "guide", "menu" }, 0){}; @@ -131,7 +131,7 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory // Lookup ContentApp for this catalog id / app id and load it ContentApp * LoadContentApp(const CatalogVendorApp & vendorApp) override; - EndpointId AddContentApp(ContentAppImpl * app); + EndpointId AddContentApp(ContentAppImpl * app, jobject contentAppEndpointManager); void SendTestMessage(EndpointId epID, const char * message); diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp new file mode 100644 index 00000000000000..7fcf0b313a62a5 --- /dev/null +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp @@ -0,0 +1,64 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @brief Contains Implementation of the ContentAppAttributeDelegate + */ + +#include "ContentAppAttributeDelegate.h" +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace AppPlatform { + +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; + +const char * ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttributePath & aPath) +{ + if (aPath.mEndpointId < FIXED_ENDPOINT_COUNT) + { + return ""; + } + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", + aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); + + jstring resp = + (jstring) env->CallObjectMethod(mContentAppEndpointManager, mReadAttributeMethod, static_cast(aPath.mEndpointId), + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + if (env->ExceptionCheck()) + { + ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return ""; + } + const char * respStr = env->GetStringUTFChars(resp, 0); + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); + return respStr; +} + +} // namespace AppPlatform +} // namespace chip diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.h b/examples/tv-app/android/java/ContentAppAttributeDelegate.h new file mode 100644 index 00000000000000..592971de5ee60a --- /dev/null +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.h @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @brief Facilitates communication with the application handlers in Java + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace AppPlatform { + +class ContentAppAttributeDelegate +{ +public: + ContentAppAttributeDelegate(jobject manager) + { + if (manager == nullptr) + { + // To support the existing hardcoded sample apps. + return; + } + InitializeJNIObjects(manager); + } + + const char * Read(const chip::app::ConcreteReadAttributePath & aPath); + +private: + void InitializeJNIObjects(jobject manager) + { + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ContentAppEndpointManager")); + + mContentAppEndpointManager = env->NewGlobalRef(manager); + VerifyOrReturn(mContentAppEndpointManager != nullptr, + ChipLogError(Zcl, "Failed to NewGlobalRef ContentAppEndpointManager")); + + jclass ContentAppEndpointManagerClass = env->GetObjectClass(manager); + VerifyOrReturn(ContentAppEndpointManagerClass != nullptr, + ChipLogError(Zcl, "Failed to get ContentAppEndpointManager Java class")); + + mReadAttributeMethod = env->GetMethodID(ContentAppEndpointManagerClass, "readAttribute", "(III)Ljava/lang/String;"); + if (mReadAttributeMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ContentAppEndpointManager 'readAttribute' method"); + env->ExceptionClear(); + } + } + + jobject mContentAppEndpointManager = nullptr; + jmethodID mReadAttributeMethod = nullptr; +}; + +} // namespace AppPlatform +} // namespace chip diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index 1cc25f57ee6098..966f532ecd18ac 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -79,8 +79,9 @@ void ContentAppCommandDelegate::InvokeCommand(CommandHandlerInterface::HandlerCo return; } - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - UtfString jsonString(env, JsonToString(json).c_str()); + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + Json::Value value = json["value"]; + UtfString jsonString(env, JsonToString(value).c_str()); ChipLogProgress(Zcl, "ContentAppCommandDelegate::InvokeCommand send command being called with payload %s", JsonToString(json).c_str()); @@ -110,9 +111,12 @@ void ContentAppCommandDelegate::InvokeCommand(CommandHandlerInterface::HandlerCo void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::HandlerContext & handlerContext, const char * response) { Json::Reader reader; - Json::Value resJson; - reader.parse(response, resJson); - Json::Value value = resJson["value"]; + Json::Value value; + if (!reader.parse(response, value)) + { + handlerContext.SetCommandNotHandled(); + return; + } switch (handlerContext.mRequestPath.mClusterId) { diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java index 69a0eac364daa1..92c5e5243b85ad 100644 --- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java @@ -3,4 +3,6 @@ public interface ContentAppEndpointManager { public String sendCommand(int endpointId, int clusterId, int commandId, String commandPayload); + + public String readAttribute(int endpointId, int clusterId, int attributeId); } From 5c108e53a3098b83a03b0d6ebbfa38737b19b2d4 Mon Sep 17 00:00:00 2001 From: tehampson Date: Tue, 28 Jun 2022 18:20:21 -0400 Subject: [PATCH 05/76] Small refactor to TestCASESession bringing it inline with other unit tests (#20039) * Small refactor to TestCASESession to bring it inline with other unit test * Restyle * Remove CASE_ prefix on test and add comment to TestCASESession * Restyle --- src/protocols/secure_channel/CASESession.h | 2 +- .../secure_channel/tests/TestCASESession.cpp | 116 ++++++++++-------- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index 658cfcb184695d..35aa8ba2dd3b0d 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -188,7 +188,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, void Clear(); private: - friend class CASESessionForTest; + friend class TestCASESession; enum class State : uint8_t { kInitialized = 0, diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 412aa5e8e37a18..029d24307a8d2a 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -47,7 +47,6 @@ using namespace chip; using namespace Credentials; using namespace TestCerts; -using namespace chip; using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Messaging; @@ -55,7 +54,9 @@ using namespace chip::Protocols; using TestContext = Test::LoopbackMessagingContext; +namespace chip { namespace { + CHIP_ERROR InitFabricTable(chip::FabricTable & fabricTable, chip::TestPersistentStorageDelegate * testStorage, chip::Crypto::OperationalKeystore * opKeyStore, chip::Credentials::PersistentStorageOpCertStore * opCertStore) @@ -254,39 +255,57 @@ CHIP_ERROR InitCredentialSets() return CHIP_NO_ERROR; } -} // namespace +} // anonymous namespace -void CASE_SecurePairingWaitTest(nlTestSuite * inSuite, void * inContext) +// Specifically for SimulateUpdateNOCInvalidatePendingEstablishment, we need it to be static so that the class below can +// be a friend to CASESession so that test can get access to CASESession::State and test method that are not public. To +// keep the rest of this file consistent we brought all other tests into this class. +class TestCASESession +{ +public: + static void SecurePairingWaitTest(nlTestSuite * inSuite, void * inContext); + static void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext); + static void SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext); + static void SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inContext); + static void Sigma1ParsingTest(nlTestSuite * inSuite, void * inContext); + static void DestinationIdTest(nlTestSuite * inSuite, void * inContext); + static void SessionResumptionStorage(nlTestSuite * inSuite, void * inContext); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + static void SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuite * inSuite, void * inContext); +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST +}; + +void TestCASESession::SecurePairingWaitTest(nlTestSuite * inSuite, void * inContext) { SessionManager sessionManager; // Test all combinations of invalid parameters TestCASESecurePairingDelegate delegate; FabricTable fabrics; - // In normal operation scope of FabricTable outlives CASESession. Without this scoping we hit - // ASAN test issue since FabricTable is not normally on the stack. - { - CASESession caseSession; + CASESession caseSession; - NL_TEST_ASSERT(inSuite, caseSession.GetSecureSessionType() == SecureSession::Type::kCASE); + NL_TEST_ASSERT(inSuite, caseSession.GetSecureSessionType() == SecureSession::Type::kCASE); - caseSession.SetGroupDataProvider(&gDeviceGroupDataProvider); - NL_TEST_ASSERT(inSuite, - caseSession.PrepareForSessionEstablishment( - sessionManager, nullptr, nullptr, nullptr, nullptr, ScopedNodeId(), - Optional::Missing()) == CHIP_ERROR_INVALID_ARGUMENT); - NL_TEST_ASSERT(inSuite, - caseSession.PrepareForSessionEstablishment( - sessionManager, nullptr, nullptr, nullptr, &delegate, ScopedNodeId(), - Optional::Missing()) == CHIP_ERROR_INVALID_ARGUMENT); - NL_TEST_ASSERT( - inSuite, - caseSession.PrepareForSessionEstablishment(sessionManager, &fabrics, nullptr, nullptr, &delegate, ScopedNodeId(), - Optional::Missing()) == CHIP_NO_ERROR); - } + caseSession.SetGroupDataProvider(&gDeviceGroupDataProvider); + NL_TEST_ASSERT(inSuite, + caseSession.PrepareForSessionEstablishment(sessionManager, nullptr, nullptr, nullptr, nullptr, ScopedNodeId(), + Optional::Missing()) == + CHIP_ERROR_INVALID_ARGUMENT); + NL_TEST_ASSERT(inSuite, + caseSession.PrepareForSessionEstablishment(sessionManager, nullptr, nullptr, nullptr, &delegate, ScopedNodeId(), + Optional::Missing()) == + CHIP_ERROR_INVALID_ARGUMENT); + NL_TEST_ASSERT(inSuite, + caseSession.PrepareForSessionEstablishment(sessionManager, &fabrics, nullptr, nullptr, &delegate, ScopedNodeId(), + Optional::Missing()) == CHIP_NO_ERROR); + + // Calling Clear() here since ASAN will have an issue if FabricTable destructor is called before CASESession's + // destructor. We could reorder FabricTable and CaseSession, but this makes it a little more clear what we are + // doing here. + caseSession.Clear(); } -void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) +void TestCASESession::SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) { TestContext & ctx = *reinterpret_cast(inContext); SessionManager sessionManager; @@ -341,8 +360,8 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) loopback.mMessageSendError = CHIP_NO_ERROR; } -void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, SessionManager & sessionManager, - CASESession & pairingCommissioner, TestCASESecurePairingDelegate & delegateCommissioner) +void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, SessionManager & sessionManager, + CASESession & pairingCommissioner, TestCASESecurePairingDelegate & delegateCommissioner) { TestContext & ctx = *reinterpret_cast(inContext); @@ -400,18 +419,18 @@ void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inConte #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST } -void CASE_SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext) +void TestCASESession::SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext) { SessionManager sessionManager; TestCASESecurePairingDelegate delegateCommissioner; CASESession pairingCommissioner; pairingCommissioner.SetGroupDataProvider(&gCommissionerGroupDataProvider); - CASE_SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, delegateCommissioner); + SecurePairingHandshakeTestCommon(inSuite, inContext, sessionManager, pairingCommissioner, delegateCommissioner); } CASEServerForTest gPairingServer; -void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inContext) +void TestCASESession::SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inContext) { // TODO: Add cases for mismatching IPK config between initiator/responder @@ -489,7 +508,7 @@ struct Sigma1Params static constexpr bool expectSuccess = true; }; -void CASE_DestinationIdTest(nlTestSuite * inSuite, void * inContext) +void TestCASESession::DestinationIdTest(nlTestSuite * inSuite, void * inContext) { // Validate example test vector from CASE section of spec @@ -705,7 +724,7 @@ struct Sigma1SessionIdTooBig : public BadSigma1ParamsBase static constexpr uint32_t initiatorSessionId = UINT16_MAX + 1; }; -static void CASE_Sigma1ParsingTest(nlTestSuite * inSuite, void * inContext) +void TestCASESession::Sigma1ParsingTest(nlTestSuite * inSuite, void * inContext) { // 1280 bytes must be enough by definition. constexpr size_t bufferSize = 1280; @@ -778,7 +797,7 @@ struct SessionResumptionTestStorage : SessionResumptionStorage Crypto::P256ECDHDerivedSecret * mSharedSecret = nullptr; }; -static void CASE_SessionResumptionStorage(nlTestSuite * inSuite, void * inContext) +void TestCASESession::SessionResumptionStorage(nlTestSuite * inSuite, void * inContext) { // Test the SessionResumptionStorage external interface. // @@ -876,18 +895,8 @@ static void CASE_SessionResumptionStorage(nlTestSuite * inSuite, void * inContex } } -// TODO, move all tests above into this class #if CONFIG_BUILD_FOR_HOST_UNIT_TEST -namespace chip { -// TODO rename CASESessionForTest to TestCASESession. Not doing that immediately since that requires -// removing a lot of the `using namesapce` above which is a larger cleanup. -class CASESessionForTest -{ -public: - static void CASE_SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuite * inSuite, void * inContext); -}; - -void CASESessionForTest::CASE_SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuite * inSuite, void * inContext) +void TestCASESession::SimulateUpdateNOCInvalidatePendingEstablishment(nlTestSuite * inSuite, void * inContext) { SessionManager sessionManager; TestCASESecurePairingDelegate delegateCommissioner; @@ -954,9 +963,10 @@ void CASESessionForTest::CASE_SimulateUpdateNOCInvalidatePendingEstablishment(nl NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 0); NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 0); } -} // namespace chip #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST +} // namespace chip + // Test Suite /** @@ -965,17 +975,17 @@ void CASESessionForTest::CASE_SimulateUpdateNOCInvalidatePendingEstablishment(nl // clang-format off static const nlTest sTests[] = { - NL_TEST_DEF("WaitInit", CASE_SecurePairingWaitTest), - NL_TEST_DEF("Start", CASE_SecurePairingStartTest), - NL_TEST_DEF("Handshake", CASE_SecurePairingHandshakeTest), - NL_TEST_DEF("ServerHandshake", CASE_SecurePairingHandshakeServerTest), - NL_TEST_DEF("Sigma1Parsing", CASE_Sigma1ParsingTest), - NL_TEST_DEF("DestinationId", CASE_DestinationIdTest), - NL_TEST_DEF("SessionResumptionStorage", CASE_SessionResumptionStorage), + NL_TEST_DEF("WaitInit", chip::TestCASESession::SecurePairingWaitTest), + NL_TEST_DEF("Start", chip::TestCASESession::SecurePairingStartTest), + NL_TEST_DEF("Handshake", chip::TestCASESession::SecurePairingHandshakeTest), + NL_TEST_DEF("ServerHandshake", chip::TestCASESession::SecurePairingHandshakeServerTest), + NL_TEST_DEF("Sigma1Parsing", chip::TestCASESession::Sigma1ParsingTest), + NL_TEST_DEF("DestinationId", chip::TestCASESession::DestinationIdTest), + NL_TEST_DEF("SessionResumptionStorage", chip::TestCASESession::SessionResumptionStorage), #if CONFIG_BUILD_FOR_HOST_UNIT_TEST // This is compiled for host tests which is enough test coverage to ensure updating NOC invalidates // CASESession that are in the process of establishing. - NL_TEST_DEF("InvalidatePendingSessionEstablishment", chip::CASESessionForTest::CASE_SimulateUpdateNOCInvalidatePendingEstablishment), + NL_TEST_DEF("InvalidatePendingSessionEstablishment", chip::TestCASESession::SimulateUpdateNOCInvalidatePendingEstablishment), #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST NL_TEST_SENTINEL() @@ -1046,9 +1056,9 @@ int CASE_TestSecurePairing_Teardown(void * inContext) /** * Main */ -int TestCASESession() +int TestCASESessionTest() { return chip::ExecuteTestsWithContext(&sSuite); } -CHIP_REGISTER_TEST_SUITE(TestCASESession) +CHIP_REGISTER_TEST_SUITE(TestCASESessionTest) From d4bb6ee22dffa398a565b5f301f1682151997c12 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 28 Jun 2022 19:10:26 -0400 Subject: [PATCH 06/76] Stop using explicit BitMapObjectPool. (#20058) There were only two consumers (the retrans table and exchanges) left, which both used to fail unit tests if using ObjectPool due to use-after-free. One of those tests is now fixed; the other is fixed in this PR. So we can move to using ObjectPool everywhere. Fixes https://github.com/project-chip/connectedhomeip/issues/14509 Fixes https://github.com/project-chip/connectedhomeip/issues/14446 --- src/app/CommandSender.cpp | 3 +++ src/app/WriteClient.cpp | 9 ++++++++- src/messaging/ExchangeMgr.h | 2 +- src/messaging/ReliableMessageMgr.cpp | 2 +- src/messaging/ReliableMessageMgr.h | 6 +++--- src/messaging/tests/TestReliableMessageProtocol.cpp | 7 +++++-- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/app/CommandSender.cpp b/src/app/CommandSender.cpp index 1e04fb58bc75db..63053751240eb7 100644 --- a/src/app/CommandSender.cpp +++ b/src/app/CommandSender.cpp @@ -96,6 +96,9 @@ CHIP_ERROR CommandSender::SendGroupCommandRequest(const SessionHandle & session) ReturnErrorOnFailure(SendInvokeRequest()); + // Exchange is gone now, since it closed itself on successful send. + mpExchangeCtx = nullptr; + Close(); return CHIP_NO_ERROR; } diff --git a/src/app/WriteClient.cpp b/src/app/WriteClient.cpp index 106e99633b9db8..c17c63af372500 100644 --- a/src/app/WriteClient.cpp +++ b/src/app/WriteClient.cpp @@ -425,7 +425,8 @@ CHIP_ERROR WriteClient::SendWriteRequest() System::PacketBufferHandle data = mChunks.PopHead(); - if (!mChunks.IsNull() && mpExchangeCtx->IsGroupExchangeContext()) + bool isGroupWrite = mpExchangeCtx->IsGroupExchangeContext(); + if (!mChunks.IsNull() && isGroupWrite) { // Reject this request if we have more than one chunk (mChunks is not null after PopHead()), and this is a group // exchange context. @@ -434,6 +435,12 @@ CHIP_ERROR WriteClient::SendWriteRequest() // kExpectResponse is ignored by ExchangeContext in case of groupcast ReturnErrorOnFailure(mpExchangeCtx->SendMessage(MsgType::WriteRequest, std::move(data), SendMessageFlags::kExpectResponse)); + if (isGroupWrite) + { + // Exchange is closed now, since there are no group responses. Drop our + // ref to it. + mpExchangeCtx = nullptr; + } MoveToState(State::AwaitingResponse); return CHIP_NO_ERROR; } diff --git a/src/messaging/ExchangeMgr.h b/src/messaging/ExchangeMgr.h index ac796b8bd4e33b..e2ad4e8f20e388 100644 --- a/src/messaging/ExchangeMgr.h +++ b/src/messaging/ExchangeMgr.h @@ -226,7 +226,7 @@ class DLL_EXPORT ExchangeManager : public SessionMessageDelegate FabricIndex mFabricIndex = 0; - BitMapObjectPool mContextPool; + ObjectPool mContextPool; SessionManager * mSessionManager; ReliableMessageMgr mReliableMessageMgr; diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index e6bb6cb8f64a62..c85e3f952a6cdb 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -51,7 +51,7 @@ ReliableMessageMgr::RetransTableEntry::~RetransTableEntry() ec->SetMessageNotAcked(false); } -ReliableMessageMgr::ReliableMessageMgr(BitMapObjectPool & contextPool) : +ReliableMessageMgr::ReliableMessageMgr(ObjectPool & contextPool) : mContextPool(contextPool), mSystemLayer(nullptr) {} diff --git a/src/messaging/ReliableMessageMgr.h b/src/messaging/ReliableMessageMgr.h index 9538ad3f5e0c4c..ca3a9252e2f255 100644 --- a/src/messaging/ReliableMessageMgr.h +++ b/src/messaging/ReliableMessageMgr.h @@ -66,7 +66,7 @@ class ReliableMessageMgr including both successfully and failure send. */ }; - ReliableMessageMgr(BitMapObjectPool & contextPool); + ReliableMessageMgr(ObjectPool & contextPool); ~ReliableMessageMgr(); void Init(chip::System::Layer * systemLayer); @@ -177,7 +177,7 @@ class ReliableMessageMgr #endif // CHIP_CONFIG_TEST private: - BitMapObjectPool & mContextPool; + ObjectPool & mContextPool; chip::System::Layer * mSystemLayer; /* Placeholder function to run a function for all exchanges */ @@ -193,7 +193,7 @@ class ReliableMessageMgr void TicklessDebugDumpRetransTable(const char * log); // ReliableMessageProtocol Global tables for timer context - BitMapObjectPool mRetransTable; + ObjectPool mRetransTable; }; } // namespace Messaging diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index dc2118d3bb1c86..68c0ad717693f4 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -1569,6 +1569,9 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext) // We now have just the received message waiting for an ack. NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1); + // And receiver still has no ack pending. + NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending()); + // Reset various state so we can measure things again. mockReceiver.IsOnMessageReceivedCalled = false; mockReceiver.mReceivedPiggybackAck = false; @@ -1594,8 +1597,8 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); NL_TEST_ASSERT(inSuite, mockReceiver.mReceivedPiggybackAck); - // And that receiver has no ack pending. - NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending()); + // At this point all our exchanges and reliable message contexts should be + // dead, so we can't test anything about their state. // And that there are no un-acked messages left. NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); From b91727b6b04d006ffd751b90bf973756428daed8 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Tue, 28 Jun 2022 20:52:02 -0400 Subject: [PATCH 07/76] Properly handle crashes/reboots during FabricTable commit (#20010) * Properly handle crashes/reboots during FabricTable commit - Since #19819, commits are very small and safer. There is less surface to fail during commit. The previous large-scale fail-safe behavior stored too much data, for too long and could cause larger reverts even if nothing was committed yet. FabricTable data no longer is ever persisted without commit. - The existing code deleted fabrics unwittingly when not required, such as when powering off a light during a fail-safe for an update when there was nothing committed yet, assuming we still committed immediately. This change: - Detects failed commits - Only deletes data on failed commits - Fixes Thread driver to detect stale data where a backup was done (since we cannot prevent internal commits from OpenThread) Testing done: - Added unit test to FabricTable to generate the condition - Did manual testing of all-clusters-app/chip-tool Linux that aborted on second commissioning, during commit. Found that cleanup occurred as expected on restart - Integration/cert testing (including Cirque that validates fail-safe) still pass * Restyled by clang-format * Restyled by gn * Clear commit token after deferred cleanup * Applied code review comments * Restyled by clang-format * Fix CI * Fix CI * Remove revert at restart of openthread after other changes * Apply review comments * Try to fix nRF CI * Another attempt to fix nrfconnect CI * Fix CI some more * Fix CI again Co-authored-by: Restyled.io --- src/app/BUILD.gn | 2 + src/{platform => app}/FailSafeContext.cpp | 113 +-------- .../platform => app}/FailSafeContext.h | 27 +-- .../administrator-commissioning-server.cpp | 4 +- .../general-commissioning-server.cpp | 10 +- .../network-commissioning.cpp | 3 +- .../operational-credentials-server.cpp | 46 +--- src/app/server/CommissioningWindowManager.cpp | 6 +- src/app/server/Server.cpp | 72 +++--- src/app/server/Server.h | 4 + src/app/tests/BUILD.gn | 1 + .../tests/TestFailSafeContext.cpp | 44 +--- src/credentials/FabricTable.cpp | 141 +++++++++++- src/credentials/FabricTable.h | 68 +++++- src/credentials/tests/TestFabricTable.cpp | 214 ++++++++++++++++++ src/include/platform/ConfigurationManager.h | 2 +- src/include/platform/DeviceControlServer.h | 4 - src/lib/support/DefaultStorageKeyAllocator.h | 4 +- src/platform/BUILD.gn | 2 - ...enericNetworkCommissioningThreadDriver.cpp | 4 + src/platform/tests/BUILD.gn | 5 +- .../main/include/CHIPProjectConfig.h | 3 + 22 files changed, 515 insertions(+), 264 deletions(-) rename src/{platform => app}/FailSafeContext.cpp (53%) rename src/{include/platform => app}/FailSafeContext.h (89%) rename src/{platform => app}/tests/TestFailSafeContext.cpp (68%) diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 7ef2fd303ac445..0a3a865a678e7d 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -80,6 +80,8 @@ static_library("app") { "DeviceProxy.h", "EventManagement.cpp", "EventPathParams.h", + "FailSafeContext.cpp", + "FailSafeContext.h", "GlobalAttributes.h", "InteractionModelEngine.cpp", "InteractionModelRevision.h", diff --git a/src/platform/FailSafeContext.cpp b/src/app/FailSafeContext.cpp similarity index 53% rename from src/platform/FailSafeContext.cpp rename to src/app/FailSafeContext.cpp index 376881b05fab51..f85e538d2e5543 100644 --- a/src/platform/FailSafeContext.cpp +++ b/src/app/FailSafeContext.cpp @@ -20,20 +20,15 @@ * Provides the implementation of the FailSafeContext object. */ -#include - -#include #include -#include +#include -namespace chip { -namespace DeviceLayer { +#include "FailSafeContext.h" + +using namespace chip::DeviceLayer; -namespace { -constexpr TLV::Tag kFabricIndexTag = TLV::ContextTag(0); -constexpr TLV::Tag kAddNocCommandTag = TLV::ContextTag(1); -constexpr TLV::Tag kUpdateNocCommandTag = TLV::ContextTag(2); -} // anonymous namespace +namespace chip { +namespace app { void FailSafeContext::HandleArmFailSafeTimer(System::Layer * layer, void * aAppState) { @@ -89,7 +84,7 @@ void FailSafeContext::ScheduleFailSafeCleanup(FabricIndex fabricIndex, bool addN PlatformMgr().ScheduleWork(HandleDisarmFailSafe, reinterpret_cast(this)); } -CHIP_ERROR FailSafeContext::ArmFailSafe(FabricIndex accessingFabricIndex, System::Clock::Timeout expiryLength) +CHIP_ERROR FailSafeContext::ArmFailSafe(FabricIndex accessingFabricIndex, System::Clock::Seconds16 expiryLengthSeconds) { CHIP_ERROR err = CHIP_NO_ERROR; bool cancelTimersIfError = false; @@ -100,9 +95,8 @@ CHIP_ERROR FailSafeContext::ArmFailSafe(FabricIndex accessingFabricIndex, System cancelTimersIfError = true; } - SuccessOrExit(err = DeviceLayer::SystemLayer().StartTimer(expiryLength, HandleArmFailSafeTimer, this)); - SuccessOrExit(err = CommitToStorage()); - SuccessOrExit(err = ConfigurationMgr().SetFailSafeArmed(true)); + SuccessOrExit( + err = DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(expiryLengthSeconds), HandleArmFailSafeTimer, this)); mFailSafeArmed = true; mFabricIndex = accessingFabricIndex; @@ -124,96 +118,9 @@ void FailSafeContext::DisarmFailSafe() ResetState(); - if (ConfigurationMgr().SetFailSafeArmed(false) != CHIP_NO_ERROR) - { - ChipLogError(FailSafe, "Failed to set FailSafeArmed config to false"); - } - - if (DeleteFromStorage() != CHIP_NO_ERROR) - { - ChipLogError(FailSafe, "Failed to delete FailSafeContext from configuration"); - } - ChipLogProgress(FailSafe, "Fail-safe cleanly disarmed"); } -CHIP_ERROR FailSafeContext::SetAddNocCommandInvoked(FabricIndex nocFabricIndex) -{ - mAddNocCommandHasBeenInvoked = true; - mFabricIndex = nocFabricIndex; - - ReturnErrorOnFailure(CommitToStorage()); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FailSafeContext::SetUpdateNocCommandInvoked() -{ - mUpdateNocCommandHasBeenInvoked = true; - - ReturnErrorOnFailure(CommitToStorage()); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FailSafeContext::CommitToStorage() -{ - DefaultStorageKeyAllocator keyAlloc; - uint8_t buf[FailSafeContextTLVMaxSize()]; - TLV::TLVWriter writer; - writer.Init(buf); - - TLV::TLVType outerType; - ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType)); - ReturnErrorOnFailure(writer.Put(kFabricIndexTag, mFabricIndex)); - - // TODO: Stop storing this, and just make the fail-safe context volatile and sweep-up stale data next boot on partial commits - ReturnErrorOnFailure(writer.Put(kAddNocCommandTag, mAddNocCommandHasBeenInvoked)); - ReturnErrorOnFailure(writer.Put(kUpdateNocCommandTag, mUpdateNocCommandHasBeenInvoked)); - ReturnErrorOnFailure(writer.EndContainer(outerType)); - - const auto failSafeContextTLVLength = writer.GetLengthWritten(); - VerifyOrReturnError(CanCastTo(failSafeContextTLVLength), CHIP_ERROR_BUFFER_TOO_SMALL); - - return PersistedStorage::KeyValueStoreMgr().Put(keyAlloc.FailSafeContextKey(), buf, - static_cast(failSafeContextTLVLength)); -} - -CHIP_ERROR FailSafeContext::LoadFromStorage(FabricIndex & fabricIndex, bool & addNocCommandInvoked, bool & updateNocCommandInvoked) -{ - DefaultStorageKeyAllocator keyAlloc; - uint8_t buf[FailSafeContextTLVMaxSize()]; - ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Get(keyAlloc.FailSafeContextKey(), buf, sizeof(buf))); - - TLV::ContiguousBufferTLVReader reader; - reader.Init(buf, sizeof(buf)); - ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())); - - TLV::TLVType containerType; - ReturnErrorOnFailure(reader.EnterContainer(containerType)); - - ReturnErrorOnFailure(reader.Next(kFabricIndexTag)); - ReturnErrorOnFailure(reader.Get(fabricIndex)); - - ReturnErrorOnFailure(reader.Next(kAddNocCommandTag)); - ReturnErrorOnFailure(reader.Get(addNocCommandInvoked)); - - ReturnErrorOnFailure(reader.Next(kUpdateNocCommandTag)); - ReturnErrorOnFailure(reader.Get(updateNocCommandInvoked)); - - ReturnErrorOnFailure(reader.VerifyEndOfContainer()); - ReturnErrorOnFailure(reader.ExitContainer(containerType)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR FailSafeContext::DeleteFromStorage() -{ - DefaultStorageKeyAllocator keyAlloc; - - return PersistedStorage::KeyValueStoreMgr().Delete(keyAlloc.FailSafeContextKey()); -} - void FailSafeContext::ForceFailSafeTimerExpiry() { if (!IsFailSafeArmed()) @@ -228,5 +135,5 @@ void FailSafeContext::ForceFailSafeTimerExpiry() FailSafeTimerExpired(); } -} // namespace DeviceLayer +} // namespace app } // namespace chip diff --git a/src/include/platform/FailSafeContext.h b/src/app/FailSafeContext.h similarity index 89% rename from src/include/platform/FailSafeContext.h rename to src/app/FailSafeContext.h index 1af60d71a21a37..e2759d85e71f06 100644 --- a/src/include/platform/FailSafeContext.h +++ b/src/app/FailSafeContext.h @@ -23,10 +23,13 @@ #pragma once +#include +#include #include +#include namespace chip { -namespace DeviceLayer { +namespace app { class FailSafeContext { @@ -39,14 +42,18 @@ class FailSafeContext * when the fail-safe timer is currently armed, the currently-running fail-safe timer will * first be cancelled, then the fail-safe timer will be re-armed. */ - CHIP_ERROR ArmFailSafe(FabricIndex accessingFabricIndex, System::Clock::Timeout expiryLength); + CHIP_ERROR ArmFailSafe(FabricIndex accessingFabricIndex, System::Clock::Seconds16 expiryLengthSeconds); /** * @brief Cleanly disarm failsafe timer, such as on CommissioningComplete */ void DisarmFailSafe(); - CHIP_ERROR SetAddNocCommandInvoked(FabricIndex nocFabricIndex); - CHIP_ERROR SetUpdateNocCommandInvoked(); + void SetAddNocCommandInvoked(FabricIndex nocFabricIndex) + { + mAddNocCommandHasBeenInvoked = true; + mFabricIndex = nocFabricIndex; + } + void SetUpdateNocCommandInvoked() { mUpdateNocCommandHasBeenInvoked = true; } void SetAddTrustedRootCertInvoked() { mAddTrustedRootCertHasBeenInvoked = true; } void SetCsrRequestForUpdateNoc(bool isForUpdateNoc) { mIsCsrRequestForUpdateNoc = isForUpdateNoc; } @@ -90,9 +97,6 @@ class FailSafeContext // If the failsafe is not armed, this is a no-op. void ForceFailSafeTimerExpiry(); - static CHIP_ERROR LoadFromStorage(FabricIndex & fabricIndex, bool & addNocCommandInvoked, bool & updateNocCommandInvoked); - static CHIP_ERROR DeleteFromStorage(); - private: bool mFailSafeArmed = false; bool mFailSafeBusy = false; @@ -103,13 +107,6 @@ class FailSafeContext bool mIsCsrRequestForUpdateNoc = false; FabricIndex mFabricIndex = kUndefinedFabricIndex; - // TODO:: Track the state of what was mutated during fail-safe. - - static constexpr size_t FailSafeContextTLVMaxSize() - { - return TLV::EstimateStructOverhead(sizeof(FabricIndex), sizeof(bool), sizeof(bool)); - } - /** * @brief * The callback function to be called when "fail-safe timer" expires. @@ -146,5 +143,5 @@ class FailSafeContext CHIP_ERROR CommitToStorage(); }; -} // namespace DeviceLayer +} // namespace app } // namespace chip diff --git a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp index 0d0da53e155a06..215c99218ea2fb 100644 --- a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp +++ b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp @@ -107,7 +107,7 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); FabricInfo * fabricInfo = Server::GetInstance().GetFabricTable().FindFabricWithIndex(fabricIndex); - auto & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); auto & commissionMgr = Server::GetInstance().GetCommissioningWindowManager(); VerifyOrExit(fabricInfo != nullptr, status.Emplace(StatusCode::EMBER_ZCL_STATUS_CODE_PAKE_PARAMETER_ERROR)); @@ -169,7 +169,7 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); FabricInfo * fabricInfo = Server::GetInstance().GetFabricTable().FindFabricWithIndex(fabricIndex); - auto & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); auto & commissionMgr = Server::GetInstance().GetCommissioningWindowManager(); VerifyOrExit(fabricInfo != nullptr, status.Emplace(StatusCode::EMBER_ZCL_STATUS_CODE_PAKE_PARAMETER_ERROR)); diff --git a/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp b/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp index 9f9f0877748317..a4eddf662406b0 100644 --- a/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp +++ b/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp @@ -155,7 +155,7 @@ bool emberAfGeneralCommissioningClusterArmFailSafeCallback(app::CommandHandler * const Commands::ArmFailSafe::DecodableType & commandData) { MATTER_TRACE_EVENT_SCOPE("ArmFailSafe", "GeneralCommissioning"); - FailSafeContext & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); Commands::ArmFailSafeResponse::Type response; ChipLogProgress(FailSafe, "GeneralCommissioning: Received ArmFailSafe (%us)", @@ -219,9 +219,9 @@ bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback( { MATTER_TRACE_EVENT_SCOPE("CommissioningComplete", "GeneralCommissioning"); - DeviceControlServer * server = &DeviceLayer::DeviceControlServer::DeviceControlSvr(); - auto & failSafe = server->GetFailSafeContext(); - auto & fabricTable = Server::GetInstance().GetFabricTable(); + DeviceControlServer * devCtrl = &DeviceLayer::DeviceControlServer::DeviceControlSvr(); + auto & failSafe = Server::GetInstance().GetFailSafeContext(); + auto & fabricTable = Server::GetInstance().GetFabricTable(); ChipLogProgress(FailSafe, "GeneralCommissioning: Received CommissioningComplete"); @@ -267,7 +267,7 @@ bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback( */ failSafe.DisarmFailSafe(); CheckSuccess( - server->PostCommissioningCompleteEvent(handle->AsSecureSession()->GetPeerNodeId(), handle->GetFabricIndex()), + devCtrl->PostCommissioningCompleteEvent(handle->AsSecureSession()->GetPeerNodeId(), handle->GetFabricIndex()), Failure); Breadcrumb::Set(commandPath.mEndpointId, 0); diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index 1b22b34fe6a3a0..f6d7e11b992b9c 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -300,7 +301,7 @@ void FillDebugTextAndNetworkIndex(Commands::NetworkConfigResponse::Type & respon bool CheckFailSafeArmed(CommandHandlerInterface::HandlerContext & ctx) { - DeviceLayer::FailSafeContext & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = chip::Server::GetInstance().GetFailSafeContext(); if (failSafeContext.IsFailSafeArmed(ctx.mCommandHandler.GetAccessingFabricIndex())) { diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index e7f71c0e3a67cf..5ed6a89301d1c4 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #if CHIP_CRYPTO_HSM @@ -56,7 +55,6 @@ #endif using namespace chip; -using namespace ::chip::DeviceLayer; using namespace ::chip::Transport; using namespace chip::app; using namespace chip::app::Clusters; @@ -339,14 +337,6 @@ void FailSafeCleanup(const chip::DeviceLayer::ChipDeviceEvent * event) ChipLogError(Zcl, "OpCreds: failed to delete fabric at index %u: %" CHIP_ERROR_FORMAT, fabricIndex, err.Format()); } } - - // If an UpdateNOC command had been successfully invoked, revert the state of operational key pair, NOC and ICAC for that - // Fabric to the state prior to the Fail-Safe timer being armed, for the Fabric Index that was the subject of the UpdateNOC - // command. - if (event->FailSafeTimerExpired.updateNocCommandHasBeenInvoked) - { - // TODO: Revert the state of operational key pair, NOC and ICAC - } } void OnPlatformEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg) @@ -650,8 +640,8 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(app::CommandHandler * co FabricInfo * newFabricInfo = nullptr; auto & fabricTable = Server::GetInstance().GetFabricTable(); - auto * secureSession = commandObj->GetExchangeContext()->GetSessionHandle()->AsSecureSession(); - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto * secureSession = commandObj->GetExchangeContext()->GetSessionHandle()->AsSecureSession(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); uint8_t compressed_fabric_id_buffer[sizeof(uint64_t)]; MutableByteSpan compressed_fabric_id(compressed_fabric_id_buffer); @@ -737,8 +727,7 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(app::CommandHandler * co // The Fabric Index associated with the armed fail-safe context SHALL be updated to match the Fabric // Index just allocated. - err = failSafeContext.SetAddNocCommandInvoked(newFabricIndex); - VerifyOrExit(err == CHIP_NO_ERROR, nonDefaultStatus = Status::Failure); + failSafeContext.SetAddNocCommandInvoked(newFabricIndex); // Done all intermediate steps, we are now successful needRevert = false; @@ -816,16 +805,15 @@ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(app::CommandHandler * auto nocResponse = OperationalCertStatus::kSuccess; auto nonDefaultStatus = Status::Success; - bool needRevert = false; CHIP_ERROR err = CHIP_NO_ERROR; FabricIndex fabricIndex = 0; ChipLogProgress(Zcl, "OpCreds: Received an UpdateNOC command"); - auto & fabricTable = Server::GetInstance().GetFabricTable(); - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); - FabricInfo * fabricInfo = RetrieveCurrentFabric(commandObj); + auto & fabricTable = Server::GetInstance().GetFabricTable(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); + FabricInfo * fabricInfo = RetrieveCurrentFabric(commandObj); bool csrWasForUpdateNoc = false; //< Output param of HasPendingOperationalKey bool hasPendingKey = fabricTable.HasPendingOperationalKey(csrWasForUpdateNoc); @@ -849,15 +837,8 @@ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(app::CommandHandler * err = fabricTable.UpdatePendingFabricWithOperationalKeystore(fabricIndex, NOCValue, ICACValue.ValueOr(ByteSpan{})); VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); - // From here if we error-out, we should revert the fabric table pending updates - needRevert = true; - // Flag on the fail-safe context that the UpdateNOC command was invoked. - err = failSafeContext.SetUpdateNocCommandInvoked(); - VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); - - // Done all intermediate steps, we are now successful - needRevert = false; + failSafeContext.SetUpdateNocCommandInvoked(); // We might have a new operational identity, so we should start advertising // it right away. Also, we need to withdraw our old operational identity. @@ -866,11 +847,6 @@ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(app::CommandHandler * // Attribute notification was already done by fabric table exit: - if (needRevert) - { - fabricTable.RevertPendingOpCertsExceptRoot(); - } - // We have an NOC response if (nonDefaultStatus == Status::Success) { @@ -1039,8 +1015,8 @@ bool emberAfOperationalCredentialsClusterCSRRequestCallback(app::CommandHandler // logs by the end. We use finalStatus as our overall success marker, not error CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - auto & fabricTable = Server::GetInstance().GetFabricTable(); - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & fabricTable = Server::GetInstance().GetFabricTable(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); auto & CSRNonce = commandData.CSRNonce; bool isForUpdateNoc = commandData.isForUpdateNOC.ValueOr(false); @@ -1157,8 +1133,8 @@ bool emberAfOperationalCredentialsClusterAddTrustedRootCertificateCallback( // logs by the end. We use finalStatus as our overall success marker, not error CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - auto & rootCertificate = commandData.rootCertificate; - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & rootCertificate = commandData.rootCertificate; + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); ChipLogProgress(Zcl, "OpCreds: Received an AddTrustedRootCertificate command"); diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp index 0ad4a5b1ab5b1d..4aa945c860805e 100644 --- a/src/app/server/CommissioningWindowManager.cpp +++ b/src/app/server/CommissioningWindowManager.cpp @@ -160,7 +160,7 @@ void CommissioningWindowManager::OnSessionEstablished(const SessionHandle & sess StopAdvertisement(/* aShuttingDown = */ false); - DeviceLayer::FailSafeContext & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); // This should never be armed because we don't allow CASE sessions to arm the failsafe when the commissioning window is open and // we check that the failsafe is not armed before opening the commissioning window. None the less, it is good to double-check. CHIP_ERROR err = CHIP_NO_ERROR; @@ -194,7 +194,7 @@ CHIP_ERROR CommissioningWindowManager::OpenCommissioningWindow(Seconds16 commiss { VerifyOrReturnError(commissioningTimeout <= MaxCommissioningTimeout() && commissioningTimeout >= MinCommissioningTimeout(), CHIP_ERROR_INVALID_ARGUMENT); - DeviceLayer::FailSafeContext & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); VerifyOrReturnError(!failSafeContext.IsFailSafeArmed(), CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(Dnssd::ServiceAdvertiser::Instance().UpdateCommissionableInstanceName()); @@ -471,7 +471,7 @@ void CommissioningWindowManager::OnSessionReleased() void CommissioningWindowManager::ExpireFailSafeIfArmed() { - DeviceLayer::FailSafeContext & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + auto & failSafeContext = Server::GetInstance().GetFailSafeContext(); if (failSafeContext.IsFailSafeArmed()) { failSafeContext.ForceFailSafeTimerExpiry(); diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 0ea320dc9f0be8..8ea1db77b19271 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -169,9 +169,6 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) // This initializes clusters, so should come after lower level initialization. InitDataModelHandler(&mExchangeMgr); - // Clean-up previously standing fail-safes - InitFailSafe(); - // Init transport before operations with secure session mgr. err = mTransports.Init(UdpListenParameters(DeviceLayer::UDPEndPointManager()) .SetAddressType(IPAddressType::kIPv6) @@ -257,7 +254,6 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) else { #if CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART - GetFabricTable().DeleteAllFabrics(); SuccessOrExit(err = mCommissioningWindowManager.OpenBasicCommissioningWindow()); #endif } @@ -300,6 +296,41 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) RejoinExistingMulticastGroups(); #endif // !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT + // Handle deferred clean-up of a previously armed fail-safe that occurred during FabricTable commit. + // This is done at the very end since at the earlier time above when FabricTable::Init() is called, + // the delegates could not have been registered, and the other systems were not initialized. By now, + // everything is initialized, so we can do a deferred clean-up. + { + FabricIndex fabricIndexDeletedOnInit = GetFabricTable().GetDeletedFabricFromCommitMarker(); + if (fabricIndexDeletedOnInit != kUndefinedFabricIndex) + { + ChipLogError(AppServer, "FabricIndex 0x%x deleted due to restart while fail-safed. Processing a clean-up!", + static_cast(fabricIndexDeletedOnInit)); + + // Always pretend it was an add, since being in the middle of an update currently breaks + // the validity of the fabric table. This is expected to be extremely infrequent, so + // this "harsher" than usual clean-up is more likely to get us in a valid state for whatever + // remains. + const bool addNocCalled = true; + const bool updateNocCalled = false; + GetFailSafeContext().ScheduleFailSafeCleanup(fabricIndexDeletedOnInit, addNocCalled, updateNocCalled); + + // Schedule clearing of the commit marker to only occur after we have processed all fail-safe clean-up. + // Because Matter runs a single event loop for all scheduled work, it will occur after the above has + // taken place. If a reset occurs before we have cleaned everything up, the next boot will still + // see the commit marker. + PlatformMgr().ScheduleWork( + [](intptr_t arg) { + Server * server = reinterpret_cast(arg); + VerifyOrReturn(server != nullptr); + + server->GetFabricTable().ClearCommitMarker(); + ChipLogProgress(AppServer, "Cleared FabricTable pending commit marker"); + }, + reinterpret_cast(this)); + } + } + PlatformMgr().HandleServerStarted(); exit: @@ -315,39 +346,6 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) return err; } -void Server::InitFailSafe() -{ - bool failSafeArmed = false; - - CHIP_ERROR err = CHIP_NO_ERROR; - - // If the fail-safe was armed when the device last shutdown, initiate cleanup based on the pending Fail Safe Context with - // which the fail-safe timer was armed. - if (DeviceLayer::ConfigurationMgr().GetFailSafeArmed(failSafeArmed) == CHIP_NO_ERROR && failSafeArmed) - { - FabricIndex fabricIndex; - bool addNocCommandInvoked; - bool updateNocCommandInvoked; - - ChipLogProgress(AppServer, "Detected fail-safe armed on reboot"); - - err = DeviceLayer::FailSafeContext::LoadFromStorage(fabricIndex, addNocCommandInvoked, updateNocCommandInvoked); - if (err == CHIP_NO_ERROR) - { - DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext().ScheduleFailSafeCleanup( - fabricIndex, addNocCommandInvoked, updateNocCommandInvoked); - } - else - { - // This should not happen, but we should not fail system init based on it! - ChipLogError(DeviceLayer, "Failed to load fail-safe context from storage (err= %" CHIP_ERROR_FORMAT "), cleaning-up!", - err.Format()); - (void) DeviceLayer::ConfigurationMgr().SetFailSafeArmed(false); - err = CHIP_NO_ERROR; - } - } -} - void Server::RejoinExistingMulticastGroups() { ChipLogProgress(AppServer, "Joining Multicast groups"); diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 22fa2cd96a5e2f..13eac3aedd8a56 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -327,6 +328,8 @@ class Server PersistentStorageDelegate & GetPersistentStorage() { return *mDeviceStorage; } + app::FailSafeContext & GetFailSafeContext() { return mFailSafeContext; } + TestEventTriggerDelegate * GetTestEventTriggerDelegate() { return mTestEventTriggerDelegate; } Crypto::OperationalKeystore * GetOperationalKeystore() { return mOperationalKeystore; } @@ -500,6 +503,7 @@ class Server TestEventTriggerDelegate * mTestEventTriggerDelegate; Crypto::OperationalKeystore * mOperationalKeystore; Credentials::OperationalCertificateStore * mOpCertStore; + app::FailSafeContext mFailSafeContext; uint16_t mOperationalServicePort; uint16_t mUserDirectedCommissioningPort; diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 868f08a879aa7a..f9c3755c5d33df 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -83,6 +83,7 @@ chip_test_suite("tests") { "TestEventOverflow.cpp", "TestEventPathParams.cpp", "TestFabricScopedEventLogging.cpp", + "TestFailSafeContext.cpp", "TestInteractionModelEngine.cpp", "TestMessageDef.cpp", "TestNumericAttributeTraits.cpp", diff --git a/src/platform/tests/TestFailSafeContext.cpp b/src/app/tests/TestFailSafeContext.cpp similarity index 68% rename from src/platform/tests/TestFailSafeContext.cpp rename to src/app/tests/TestFailSafeContext.cpp index 1c998caee0a2aa..9e5d11dc320b73 100644 --- a/src/platform/tests/TestFailSafeContext.cpp +++ b/src/app/tests/TestFailSafeContext.cpp @@ -28,12 +28,12 @@ #include #include +#include #include #include #include #include #include -#include using namespace chip; using namespace chip::Logging; @@ -58,7 +58,7 @@ static void TestFailSafeContext_ArmFailSafe(nlTestSuite * inSuite, void * inCont { CHIP_ERROR err = CHIP_NO_ERROR; - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + chip::app::FailSafeContext failSafeContext; err = failSafeContext.ArmFailSafe(kTestAccessingFabricIndex1, System::Clock::Seconds16(1)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); @@ -75,57 +75,24 @@ static void TestFailSafeContext_NocCommandInvoked(nlTestSuite * inSuite, void * { CHIP_ERROR err = CHIP_NO_ERROR; - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); + chip::app::FailSafeContext failSafeContext; err = failSafeContext.ArmFailSafe(kTestAccessingFabricIndex1, System::Clock::Seconds16(1)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, failSafeContext.GetFabricIndex() == kTestAccessingFabricIndex1); - err = failSafeContext.SetAddNocCommandInvoked(kTestAccessingFabricIndex2); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + failSafeContext.SetAddNocCommandInvoked(kTestAccessingFabricIndex2); NL_TEST_ASSERT(inSuite, failSafeContext.NocCommandHasBeenInvoked() == true); NL_TEST_ASSERT(inSuite, failSafeContext.AddNocCommandHasBeenInvoked() == true); NL_TEST_ASSERT(inSuite, failSafeContext.GetFabricIndex() == kTestAccessingFabricIndex2); - err = failSafeContext.SetUpdateNocCommandInvoked(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + failSafeContext.SetUpdateNocCommandInvoked(); NL_TEST_ASSERT(inSuite, failSafeContext.NocCommandHasBeenInvoked() == true); NL_TEST_ASSERT(inSuite, failSafeContext.UpdateNocCommandHasBeenInvoked() == true); failSafeContext.DisarmFailSafe(); } -static void TestFailSafeContext_CommitToStorage(nlTestSuite * inSuite, void * inContext) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - FailSafeContext & failSafeContext = DeviceControlServer::DeviceControlSvr().GetFailSafeContext(); - - err = failSafeContext.ArmFailSafe(kTestAccessingFabricIndex1, System::Clock::Seconds16(1)); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, failSafeContext.GetFabricIndex() == kTestAccessingFabricIndex1); - - err = failSafeContext.SetAddNocCommandInvoked(kTestAccessingFabricIndex1); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, failSafeContext.AddNocCommandHasBeenInvoked() == true); - - err = failSafeContext.SetUpdateNocCommandInvoked(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, failSafeContext.UpdateNocCommandHasBeenInvoked() == true); - - FabricIndex fabricIndex; - bool addNocCommandInvoked; - bool updateNocCommandInvoked; - - err = FailSafeContext::LoadFromStorage(fabricIndex, addNocCommandInvoked, updateNocCommandInvoked); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, fabricIndex == kTestAccessingFabricIndex1); - NL_TEST_ASSERT(inSuite, addNocCommandInvoked == true); - NL_TEST_ASSERT(inSuite, updateNocCommandInvoked == true); - - failSafeContext.DisarmFailSafe(); -} - /** * Test Suite. It lists all the test functions. */ @@ -134,7 +101,6 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test PlatformMgr::Init", TestPlatformMgr_Init), NL_TEST_DEF("Test FailSafeContext::ArmFailSafe", TestFailSafeContext_ArmFailSafe), NL_TEST_DEF("Test FailSafeContext::NocCommandInvoked", TestFailSafeContext_NocCommandInvoked), - NL_TEST_DEF("Test FailSafeContext::CommitToStorage", TestFailSafeContext_CommitToStorage), NL_TEST_SENTINEL() }; diff --git a/src/credentials/FabricTable.cpp b/src/credentials/FabricTable.cpp index 52a714e82cfeee..a91feb68bdcbfb 100644 --- a/src/credentials/FabricTable.cpp +++ b/src/credentials/FabricTable.cpp @@ -51,6 +51,27 @@ constexpr TLV::Tag kFabricLabelTag = TLV::ContextTag(1); constexpr TLV::Tag kNextAvailableFabricIndexTag = TLV::ContextTag(0); constexpr TLV::Tag kFabricIndicesTag = TLV::ContextTag(1); +// Tags for commit marker storage +constexpr TLV::Tag kMarkerFabricIndexTag = TLV::ContextTag(0); +constexpr TLV::Tag kMarkerIsAdditionTag = TLV::ContextTag(1); + +constexpr size_t CommitMarkerContextTLVMaxSize() +{ + // Add 2x uncommitted uint64_t to leave space for backwards/forwards + // versioning for this critical feature that runs at boot. + return TLV::EstimateStructOverhead(sizeof(FabricIndex), sizeof(bool), sizeof(uint64_t), sizeof(uint64_t)); +} + +constexpr size_t IndexInfoTLVMaxSize() +{ + // We have a single next-available index and an array of anonymous-tagged + // fabric indices. + // + // The max size of the list is (1 byte control + bytes for actual value) + // times max number of list items, plus one byte for the list terminator. + return TLV::EstimateStructOverhead(sizeof(FabricIndex), CHIP_CONFIG_MAX_FABRICS * (1 + sizeof(FabricIndex)) + 1); +} + } // anonymous namespace CHIP_ERROR FabricInfo::Init(const FabricInfo::InitParams & initParams) @@ -994,7 +1015,35 @@ CHIP_ERROR FabricTable::Init(const FabricTable::InitParams & initParams) TLV::ContiguousBufferTLVReader reader; reader.Init(buf, size); - ReturnErrorOnFailure(ReadFabricInfo(reader)); + // TODO: A safer way would be to just clean-up the entire fabric table on this situation... + err = ReadFabricInfo(reader); + if (err != CHIP_NO_ERROR) + { + ChipLogError(FabricProvisioning, "Error loading fabric table: %" CHIP_ERROR_FORMAT ", we are in a bad state!", + err.Format()); + } + + ReturnErrorOnFailure(err); + } + + CommitMarker commitMarker; + err = GetCommitMarker(commitMarker); + if (err == CHIP_NO_ERROR) + { + // Found a commit marker! We need to possibly delete a loaded fabric + ChipLogError(FabricProvisioning, "Found a FabricTable aborted commit for index 0x%x (isAddition: %d), removing!", + static_cast(commitMarker.fabricIndex), static_cast(commitMarker.isAddition)); + + mDeletedFabricIndexFromInit = commitMarker.fabricIndex; + + // Can't do better on error. We just have to hope for the best. + (void) Delete(commitMarker.fabricIndex); + } + else if (err != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + // Got an error, but somehow value is not missing altogether: inconsistent state but touch nothing. + ChipLogError(FabricProvisioning, "Error loading Table commit marker: %" CHIP_ERROR_FORMAT ", hope for the best!", + err.Format()); } return CHIP_NO_ERROR; @@ -1036,6 +1085,16 @@ void FabricTable::Shutdown() mStorage = nullptr; } +FabricIndex FabricTable::GetDeletedFabricFromCommitMarker() +{ + FabricIndex retVal = mDeletedFabricIndexFromInit; + + // Reset for next read + mDeletedFabricIndexFromInit = kUndefinedFabricIndex; + + return retVal; +} + CHIP_ERROR FabricTable::AddFabricDelegate(FabricTable::Delegate * delegate) { VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT); @@ -1275,6 +1334,58 @@ CHIP_ERROR FabricTable::ReadFabricInfo(TLV::ContiguousBufferTLVReader & reader) return CHIP_NO_ERROR; } +CHIP_ERROR FabricTable::StoreCommitMarker(const CommitMarker & commitMarker) +{ + DefaultStorageKeyAllocator keyAlloc; + uint8_t tlvBuf[CommitMarkerContextTLVMaxSize()]; + TLV::TLVWriter writer; + writer.Init(tlvBuf); + + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType)); + ReturnErrorOnFailure(writer.Put(kMarkerFabricIndexTag, commitMarker.fabricIndex)); + ReturnErrorOnFailure(writer.Put(kMarkerIsAdditionTag, commitMarker.isAddition)); + ReturnErrorOnFailure(writer.EndContainer(outerType)); + + const auto markerContextTLVLength = writer.GetLengthWritten(); + VerifyOrReturnError(CanCastTo(markerContextTLVLength), CHIP_ERROR_BUFFER_TOO_SMALL); + + return mStorage->SyncSetKeyValue(keyAlloc.FailSafeCommitMarkerKey(), tlvBuf, static_cast(markerContextTLVLength)); +} + +CHIP_ERROR FabricTable::GetCommitMarker(CommitMarker & outCommitMarker) +{ + DefaultStorageKeyAllocator keyAlloc; + uint8_t tlvBuf[CommitMarkerContextTLVMaxSize()]; + uint16_t tlvSize = sizeof(tlvBuf); + ReturnErrorOnFailure(mStorage->SyncGetKeyValue(keyAlloc.FailSafeCommitMarkerKey(), tlvBuf, tlvSize)); + + // If buffer was too small, we won't reach here. + TLV::ContiguousBufferTLVReader reader; + reader.Init(tlvBuf, tlvSize); + ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())); + + TLV::TLVType containerType; + ReturnErrorOnFailure(reader.EnterContainer(containerType)); + + ReturnErrorOnFailure(reader.Next(kMarkerFabricIndexTag)); + ReturnErrorOnFailure(reader.Get(outCommitMarker.fabricIndex)); + + ReturnErrorOnFailure(reader.Next(kMarkerIsAdditionTag)); + ReturnErrorOnFailure(reader.Get(outCommitMarker.isAddition)); + + // Don't try to exit container: we got all we needed. This allows us to + // avoid erroring-out on newer versions. + + return CHIP_NO_ERROR; +} + +void FabricTable::ClearCommitMarker() +{ + DefaultStorageKeyAllocator keyAlloc; + mStorage->SyncDeleteKeyValue(keyAlloc.FailSafeCommitMarkerKey()); +} + bool FabricTable::HasOperationalKeyForFabric(FabricIndex fabricIndex) const { const FabricInfo * fabricInfo = FindFabricWithIndex(fabricIndex); @@ -1677,8 +1788,13 @@ CHIP_ERROR FabricTable::CommitPendingFabricData() } // ==== Start of actual commit transaction after pre-flight checks ==== + CHIP_ERROR stickyError = StoreCommitMarker(CommitMarker{ fabricIndexBeingCommitted, isAdding }); + bool failedCommitMarker = (stickyError != CHIP_NO_ERROR); + if (failedCommitMarker) + { + ChipLogError(FabricProvisioning, "Failed to store commit marker, may be inconsistent if reboot happens during fail-safe!"); + } - CHIP_ERROR stickyError = CHIP_NO_ERROR; { // This scope block is to illustrate the complete commit transaction // state. We can see it contains a LARGE number of items... @@ -1726,6 +1842,23 @@ CHIP_ERROR FabricTable::CommitPendingFabricData() } stickyError = (stickyError != CHIP_NO_ERROR) ? stickyError : keyErr; + // For testing only, early return (NEVER OCCURS OTHERWISE) during the commit + // so that clean-ups using the commit marker can be tested. +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + { + if (mStateFlags.Has(StateFlags::kAbortCommitForTest)) + { + // Clear state so that shutdown doesn't attempt clean-up + mStateFlags.ClearAll(); + mFabricIndexWithPendingState = kUndefinedFabricIndex; + mPendingFabric.Reset(); + + ChipLogError(FabricProvisioning, "Aborting commit in middle of transaction for testing."); + return CHIP_ERROR_INTERNAL; + } + } +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST + // Commit operational certs CHIP_ERROR opCertErr = mOpCertStore->CommitOpCertsForFabric(fabricIndexBeingCommitted); if (opCertErr != CHIP_NO_ERROR) @@ -1780,6 +1913,10 @@ CHIP_ERROR FabricTable::CommitPendingFabricData() NotifyFabricCommitted(fabricIndexBeingCommitted); } + // Clear commit marker no matter what: if we got here, there was no reboot and previous clean-ups + // did their job. + ClearCommitMarker(); + return stickyError; } diff --git a/src/credentials/FabricTable.h b/src/credentials/FabricTable.h index 445a9cfa9865f4..b7cffb12dcf114 100644 --- a/src/credentials/FabricTable.h +++ b/src/credentials/FabricTable.h @@ -422,6 +422,25 @@ class DLL_EXPORT FabricTable CHIP_ERROR Init(const FabricTable::InitParams & initParams); void Shutdown(); + /** + * @brief If `Init()` caused a Delete due to partial commit, the fabric index at play is returned. + * + * Allows caller to schedule more clean-up. This is because at Init() time, none of the delegates + * are registered yet, so no other modules would learn of the removal. + * + * The value is auto-reset to `kUndefinedFabricIndex` on being returned, so that subsequent + * `GetDeletedFabricFromCommitMarker()` after one that has a fabric index to give will provide + * `kUndefinedFabricIndex`. + * + * @return the fabric index of a just-deleted fabric, or kUndefinedFabricIndex if none were deleted. + */ + FabricIndex GetDeletedFabricFromCommitMarker(); + + /** + * @brief Clear the commit marker when we are sure we have proceeded with any remaining clean-up + */ + void ClearCommitMarker(); + // Forget a fabric in memory: doesn't delete any persistent state, just // reverts any pending state (blindly) and then resets the fabric table // entry. @@ -820,8 +839,24 @@ class DLL_EXPORT FabricTable return err; } + // For test only. See definition of `StateFlags::kAbortCommitForTest`. + void SetForceAbortCommitForTest(bool abortCommitForTest) + { + (void) abortCommitForTest; +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + if (abortCommitForTest) + { + mStateFlags.Set(StateFlags::kAbortCommitForTest); + } + else + { + mStateFlags.Clear(StateFlags::kAbortCommitForTest); + } +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST + } + private: - enum class StateFlags : uint8_t + enum class StateFlags : uint16_t { // If true, we are in the process of a fail-safe and there was at least one // operation that caused partial data in the fabric table. @@ -838,17 +873,25 @@ class DLL_EXPORT FabricTable // True if we allow more than one fabric with same root and fabricId in the fabric table // for test purposes. This disables a collision check. kAreCollidingFabricsIgnored = (1u << 6), + + // If set to true (only possible on test builds), will cause `CommitPendingFabricData()` to early + // return during commit, skipping clean-ups, so that we can validate commit marker fabric removal. + kAbortCommitForTest = (1u << 7), }; - static constexpr size_t IndexInfoTLVMaxSize() + // Stored to indicate a commit is in progress, so that it can be cleaned-up on next boot + // if stopped in the middle. + struct CommitMarker { - // We have a single next-available index and an array of anonymous-tagged - // fabric indices. - // - // The max size of the list is (1 byte control + bytes for actual value) - // times max number of list items, plus one byte for the list terminator. - return TLV::EstimateStructOverhead(sizeof(FabricIndex), CHIP_CONFIG_MAX_FABRICS * (1 + sizeof(FabricIndex)) + 1); - } + CommitMarker() = default; + CommitMarker(FabricIndex fabricIndex_, bool isAddition_) + { + this->fabricIndex = fabricIndex_; + this->isAddition = isAddition_; + } + FabricIndex fabricIndex = kUndefinedFabricIndex; + bool isAddition = false; + }; // Load a FabricInfo metatada item from storage for a given new fabric index. Returns internal error on failure. CHIP_ERROR LoadFromStorage(FabricInfo * fabric, FabricIndex newFabricIndex); @@ -955,6 +998,10 @@ class DLL_EXPORT FabricTable CHIP_ERROR NotifyFabricUpdated(FabricIndex fabricIndex); CHIP_ERROR NotifyFabricCommitted(FabricIndex fabricIndex); + // Commit management clean-up APIs + CHIP_ERROR StoreCommitMarker(const CommitMarker & commitMarker); + CHIP_ERROR GetCommitMarker(CommitMarker & outCommitMarker); + FabricInfo mStates[CHIP_CONFIG_MAX_FABRICS]; // Used for UpdateNOC pending fabric updates FabricInfo mPendingFabric; @@ -970,6 +1017,9 @@ class DLL_EXPORT FabricTable // for which there is currently pending data. FabricIndex mFabricIndexWithPendingState = kUndefinedFabricIndex; + // For when a revert occurs during init, so that more clean-up can be scheduled by caller. + FabricIndex mDeletedFabricIndexFromInit = kUndefinedFabricIndex; + LastKnownGoodTime mLastKnownGoodTime; // We may not have an mNextAvailableFabricIndex if our table is as large as diff --git a/src/credentials/tests/TestFabricTable.cpp b/src/credentials/tests/TestFabricTable.cpp index 8fa0a5aed55aa9..b652dfbfd120a3 100644 --- a/src/credentials/tests/TestFabricTable.cpp +++ b/src/credentials/tests/TestFabricTable.cpp @@ -1742,6 +1742,219 @@ void TestInvalidChaining(nlTestSuite * inSuite, void * inContext) // TODO: Write test } +void TestCommitMarker(nlTestSuite * inSuite, void * inContext) +{ + Crypto::P256PublicKey fIdx1PublicKey; + Crypto::P256PublicKey fIdx2PublicKey; + + Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority; + + chip::TestPersistentStorageDelegate storage; + + // Log verbosity on this test helps debug significantly + storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutationAndReads); + + NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess()); + + constexpr uint16_t kVendorId = 0xFFF1u; + + size_t numStorageKeysAfterFirstAdd = 0; + + // First scope: add 2 fabrics with same root: + // - FabricID 1111, Node ID 55 + // - FabricID 2222, Node ID 66 + // - Abort commit on second fabric + { + // Initialize a FabricTable + ScopedFabricTable fabricTableHolder; + NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR); + FabricTable & fabricTable = fabricTableHolder.GetFabricTable(); + + NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == kUndefinedFabricIndex); + NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0); + + // Add Fabric 1111 Node Id 55 + { + FabricId fabricId = 1111; + NodeId nodeId = 55; + + uint8_t csrBuf[chip::Crypto::kMAX_CSR_Length]; + MutableByteSpan csrSpan{ csrBuf }; + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan)); + + NL_TEST_ASSERT_SUCCESS( + inSuite, fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus()); + ByteSpan rcac = fabricCertAuthority.GetRcac(); + ByteSpan icac = fabricCertAuthority.GetIcac(); + ByteSpan noc = fabricCertAuthority.GetNoc(); + + NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0); + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac)); + FabricIndex newFabricIndex = kUndefinedFabricIndex; + NL_TEST_ASSERT_SUCCESS(inSuite, + fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex)); + NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1); + NL_TEST_ASSERT(inSuite, newFabricIndex == 1); + + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData()); + + // Validate contents + const auto * fabricInfo = fabricTable.FindFabricWithIndex(1); + NL_TEST_ASSERT(inSuite, fabricInfo != nullptr); + if (fabricInfo != nullptr) + { + Credentials::ChipCertificateSet certificates; + NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1)); + NL_TEST_ASSERT_SUCCESS(inSuite, + certificates.LoadCert(rcac, BitFlags(CertDecodeFlags::kIsTrustAnchor))); + Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey); + + NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1); + NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55); + NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111); + NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId); + NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0); + + Crypto::P256PublicKey rootPublicKeyOfFabric; + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric)); + NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey)); + } + + // Validate that fabric has the correct operational key by verifying a signature + { + Crypto::P256ECDSASignature sig; + uint8_t message[] = { 'm', 's', 'g' }; + + NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx1PublicKey)); + + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig)); + NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig)); + } + } + numStorageKeysAfterFirstAdd = storage.GetNumKeys(); + + NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time + + // The following test requires test methods not available on all builds. + // TODO: Debug why some CI jobs don't set it properly. +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + + // Add Fabric 2222 Node Id 66, no ICAC *** AND ABORT COMMIT *** + { + FabricId fabricId = 2222; + NodeId nodeId = 66; + + uint8_t csrBuf[chip::Crypto::kMAX_CSR_Length]; + MutableByteSpan csrSpan{ csrBuf }; + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan)); + + NL_TEST_ASSERT_SUCCESS( + inSuite, fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus()); + ByteSpan rcac = fabricCertAuthority.GetRcac(); + ByteSpan noc = fabricCertAuthority.GetNoc(); + + NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1); + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac)); + FabricIndex newFabricIndex = kUndefinedFabricIndex; + NL_TEST_ASSERT_SUCCESS( + inSuite, fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex)); + NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2); + NL_TEST_ASSERT(inSuite, newFabricIndex == 2); + + // Validate contents of pending + const auto * fabricInfo = fabricTable.FindFabricWithIndex(2); + NL_TEST_ASSERT(inSuite, fabricInfo != nullptr); + if (fabricInfo != nullptr) + { + Credentials::ChipCertificateSet certificates; + NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1)); + NL_TEST_ASSERT_SUCCESS(inSuite, + certificates.LoadCert(rcac, BitFlags(CertDecodeFlags::kIsTrustAnchor))); + Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey); + + NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2); + NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66); + NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222); + NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId); + NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0); + + Crypto::P256PublicKey rootPublicKeyOfFabric; + NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric)); + NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey)); + } + + // Make sure no additional storage yet + NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd); + + // --> FORCE AN ERROR ON COMMIT that will BYPASS commit clean-up (similar to reboot during commit) + fabricTable.SetForceAbortCommitForTest(true); + NL_TEST_ASSERT(inSuite, fabricTable.CommitPendingFabricData() == CHIP_ERROR_INTERNAL); + + // Check that there are more keys now, partially committed: at least a Commit Marker (+1) + // and some more keys from the aborted process. + NL_TEST_ASSERT(inSuite, storage.GetNumKeys() > (numStorageKeysAfterFirstAdd + 1)); + } +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST + } + +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + { + storage.DumpKeys(); + + // Initialize a FabricTable again. Make sure it succeeds in initing. + ScopedFabricTable fabricTableHolder; + + NL_TEST_ASSERT(inSuite, storage.GetNumKeys() > (numStorageKeysAfterFirstAdd + 1)); + + NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR); + FabricTable & fabricTable = fabricTableHolder.GetFabricTable(); + + // Make sure that after init, the fabricTable has only 1 fabric + NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1); + + // Make sure it caught the last partially committed fabric + NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == 2); + + // Second read must return kUndefinedFabricIndex + NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == kUndefinedFabricIndex); + + { + // Here we would do other clean-ups (e.g. see Server.cpp that uses the above) and then + // clear the commit marker after. + fabricTable.ClearCommitMarker(); + } + + // Make sure that all other pending storage got deleted + NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd); + + // Verify we can only see 1 fabric with the iterator + { + size_t numFabricsIterated = 0; + bool saw1 = false; + bool saw2 = false; + for (const auto & iterFabricInfo : fabricTable) + { + ++numFabricsIterated; + if (iterFabricInfo.GetFabricIndex() == 1) + { + NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55); + NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111); + saw1 = true; + } + if (iterFabricInfo.GetFabricIndex() == 2) + { + saw2 = true; + } + } + + NL_TEST_ASSERT(inSuite, numFabricsIterated == 1); + NL_TEST_ASSERT(inSuite, saw1 == true); + NL_TEST_ASSERT(inSuite, saw2 == false); + } + } +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST +} + // Test Suite /** @@ -1763,6 +1976,7 @@ static const nlTest sTests[] = NL_TEST_DEF("Test compressed fabric ID is properly generated", TestCompressedFabricId), NL_TEST_DEF("Test AddNOC root collision", TestAddNocRootCollision), NL_TEST_DEF("Test invalid chaining in AddNOC and UpdateNOC", TestInvalidChaining), + NL_TEST_DEF("Test proper detection of Commit Marker on init", TestCommitMarker), NL_TEST_SENTINEL() }; diff --git a/src/include/platform/ConfigurationManager.h b/src/include/platform/ConfigurationManager.h index 5d71e89e1eca51..fae1475030eb11 100644 --- a/src/include/platform/ConfigurationManager.h +++ b/src/include/platform/ConfigurationManager.h @@ -29,8 +29,8 @@ #include #include #include -#include #include +#include #include namespace chip { diff --git a/src/include/platform/DeviceControlServer.h b/src/include/platform/DeviceControlServer.h index 865211e016ad86..34c91401e4e5a5 100644 --- a/src/include/platform/DeviceControlServer.h +++ b/src/include/platform/DeviceControlServer.h @@ -23,7 +23,6 @@ #pragma once #include -#include #include namespace chip { @@ -38,14 +37,11 @@ class DeviceControlServer final CHIP_ERROR SetRegulatoryConfig(uint8_t location, const CharSpan & countryCode); CHIP_ERROR PostConnectedToOperationalNetworkEvent(ByteSpan networkID); - FailSafeContext & GetFailSafeContext() { return mFailSafeContext; } - static DeviceControlServer & DeviceControlSvr(); private: // ===== Members for internal use by the following friends. static DeviceControlServer sInstance; - FailSafeContext mFailSafeContext; // ===== Private members reserved for use by this class only. diff --git a/src/lib/support/DefaultStorageKeyAllocator.h b/src/lib/support/DefaultStorageKeyAllocator.h index b17b0b3d6f905b..efddd0f1f743f6 100644 --- a/src/lib/support/DefaultStorageKeyAllocator.h +++ b/src/lib/support/DefaultStorageKeyAllocator.h @@ -50,8 +50,8 @@ class DefaultStorageKeyAllocator const char * FabricMetadata(FabricIndex fabric) { return Format("f/%x/m", fabric); } const char * FabricOpKey(FabricIndex fabric) { return Format("f/%x/o", fabric); } - // FailSafeContext - const char * FailSafeContextKey() { return Format("g/fs/c"); } + // Fail-safe handling + const char * FailSafeCommitMarkerKey() { return Format("g/fs/c"); } static const char * FailSafeNetworkConfig() { return "g/fs/n"; } // LastKnownGoodTime diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 4a5cdf0b61d204..fdcc45d0424ac7 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -321,7 +321,6 @@ if (chip_device_platform != "none") { "../include/platform/ConnectivityManager.h", "../include/platform/DeviceControlServer.h", "../include/platform/DeviceInstanceInfoProvider.h", - "../include/platform/FailSafeContext.h", "../include/platform/GeneralUtils.h", "../include/platform/KeyValueStoreManager.h", "../include/platform/KvsPersistentStorageDelegate.h", @@ -366,7 +365,6 @@ if (chip_device_platform != "none") { "DeviceInstanceInfoProvider.cpp", "DiagnosticDataProvider.cpp", "Entropy.cpp", - "FailSafeContext.cpp", "GeneralUtils.cpp", "Globals.cpp", "LockTracker.cpp", diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp index b48c09164389a1..5b41aac5f2fdf2 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,8 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration() ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); ReturnErrorOnFailure(error); + ChipLogError(NetworkProvisioning, "Found Thread configuration backup: reverting configuration"); + // Not all KVS implementations support zero-length values, so handle a special value representing an empty dataset. ByteSpan dataset(datasetBytes, datasetLength); @@ -97,6 +100,7 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration() ReturnErrorOnFailure(mStagingNetwork.Init(dataset)); ReturnErrorOnFailure(DeviceLayer::ThreadStackMgrImpl().AttachToThreadNetwork(mStagingNetwork, /* callback */ nullptr)); + // TODO: What happens on errors above? Why do we not remove the failsafe? return KeyValueStoreMgr().Delete(DefaultStorageKeyAllocator::FailSafeNetworkConfig()); } diff --git a/src/platform/tests/BUILD.gn b/src/platform/tests/BUILD.gn index 9f447b6b4c5aa0..d34c8b00c88ce4 100644 --- a/src/platform/tests/BUILD.gn +++ b/src/platform/tests/BUILD.gn @@ -88,10 +88,7 @@ if (chip_device_platform != "none" && chip_device_platform != "fake") { } if (chip_device_platform == "linux") { - test_sources += [ - "TestConnectivityMgr.cpp", - "TestFailSafeContext.cpp", - ] + test_sources += [ "TestConnectivityMgr.cpp" ] } } } else { diff --git a/src/test_driver/nrfconnect/main/include/CHIPProjectConfig.h b/src/test_driver/nrfconnect/main/include/CHIPProjectConfig.h index 3a25601cfd884e..3c3df5b97d593a 100644 --- a/src/test_driver/nrfconnect/main/include/CHIPProjectConfig.h +++ b/src/test_driver/nrfconnect/main/include/CHIPProjectConfig.h @@ -30,4 +30,7 @@ // Enable support functions for parsing command-line arguments #define CHIP_CONFIG_ENABLE_ARG_PARSER 1 +// Enable unit-test only features +#define CONFIG_BUILD_FOR_HOST_UNIT_TEST 1 + #endif // CHIP_PROJECT_CONFIG_H From a0a5c10eb9a3c724f0a9648afe3ee89657026f9f Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 28 Jun 2022 20:59:33 -0400 Subject: [PATCH 08/76] Increase session pool size on Darwin so we don't run out of sessions. (#20086) We want to have enough sessions for all the subscriptions we will want to have. --- config/ios/CHIPProjectConfig.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/ios/CHIPProjectConfig.h b/config/ios/CHIPProjectConfig.h index 6a9d7eb3213836..dfa35f7cfd5254 100644 --- a/config/ios/CHIPProjectConfig.h +++ b/config/ios/CHIPProjectConfig.h @@ -44,4 +44,9 @@ #define CHIP_CONFIG_KVS_PATH "chip.store" #endif +// The session pool size limits how many subscriptions we can have live at +// once. Home supports up to 1000 accessories, and we subscribe to all of them, +// so we need to make sure the pool is big enough for that. +#define CHIP_CONFIG_SECURE_SESSION_POOL_SIZE 1000 + #endif /* CHIPPROJECTCONFIG_H */ From b9068aa333fa9555d070d16b58701c9f57dfe070 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 28 Jun 2022 22:05:59 -0400 Subject: [PATCH 09/76] Restore return statement that went missing. (#20087) The changes in https://github.com/project-chip/connectedhomeip/pull/19870 incorrectly removed a return here. Now we'll fall through to the cases that assume the proxy is not in a connected state to start with, which is not desirable. --- src/controller/CHIPDeviceController.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 258e49441041de..af7754600d4cf4 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -335,6 +335,7 @@ CHIP_ERROR DeviceController::DisconnectDevice(NodeId nodeId) if (proxy->IsConnected()) { proxy->Disconnect(); + return CHIP_NO_ERROR; } if (proxy->IsConnecting()) From 5d2472186a47ade0bf07f9e74fef5b9e7e875130 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 28 Jun 2022 23:11:05 -0400 Subject: [PATCH 10/76] =?UTF-8?q?Add=20fake=20platform=20argument=20to=20r?= =?UTF-8?q?unning=20fake=20tests,=20exclude=20TestFailsaf=E2=80=A6=20(#200?= =?UTF-8?q?91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add fake platform argument to running fake tests, exclude TestFailsafeContext from fake platform (no timer impl) * Restyle --- scripts/build/builders/host.py | 1 + scripts/build/testdata/build_linux_on_x64.txt | 2 +- src/app/tests/BUILD.gn | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 161f9d35870ce5..765e9bcb17e1d3 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -285,6 +285,7 @@ def GnBuildArgs(self): 'custom_toolchain="//build/toolchain/fake:fake_x64_gcc"', 'chip_link_tests=true', 'chip_device_platform="fake"', + 'chip_fake_platform=true', ] ) return self.extra_gn_options diff --git a/scripts/build/testdata/build_linux_on_x64.txt b/scripts/build/testdata/build_linux_on_x64.txt index 33118450a90e8e..15cb6388a0ca6f 100644 --- a/scripts/build/testdata/build_linux_on_x64.txt +++ b/scripts/build/testdata/build_linux_on_x64.txt @@ -142,7 +142,7 @@ PKG_CONFIG_PATH="SYSROOT_AARCH64/lib/aarch64-linux-gnu/pkgconfig" \ gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/tv-casting-app/linux '"'"'--args=chip_inet_config_enable_ipv4=false target_cpu="arm64" is_clang=true chip_crypto="mbedtls" sysroot="SYSROOT_AARCH64"'"'"' {out}/linux-arm64-tv-casting-app-ipv6only' # Generating linux-fake-tests -gn gen --check --fail-on-unused-args --export-compile-commands --root={root} '--args=chip_build_tests=true custom_toolchain="//build/toolchain/fake:fake_x64_gcc" chip_link_tests=true chip_device_platform="fake"' {out}/linux-fake-tests +gn gen --check --fail-on-unused-args --export-compile-commands --root={root} '--args=chip_build_tests=true custom_toolchain="//build/toolchain/fake:fake_x64_gcc" chip_link_tests=true chip_device_platform="fake" chip_fake_platform=true' {out}/linux-fake-tests # Generating linux-x64-address-resolve-tool gn gen --check --fail-on-unused-args --export-compile-commands --root={root} {out}/linux-x64-address-resolve-tool diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index f9c3755c5d33df..fd8d1571623cf6 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -83,7 +83,6 @@ chip_test_suite("tests") { "TestEventOverflow.cpp", "TestEventPathParams.cpp", "TestFabricScopedEventLogging.cpp", - "TestFailSafeContext.cpp", "TestInteractionModelEngine.cpp", "TestMessageDef.cpp", "TestNumericAttributeTraits.cpp", @@ -96,6 +95,10 @@ chip_test_suite("tests") { "TestWriteInteraction.cpp", ] + if (!chip_fake_platform) { + test_sources += [ "TestFailSafeContext.cpp" ] + } + # # On NRF platforms, the allocation of a large number of pbufs in this test # to exercise chunking causes it to run out of memory. For now, disable it there. From 81c7f2aacebbe5bb304a62ecdbeaff9220d72c69 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Tue, 28 Jun 2022 23:23:53 -0400 Subject: [PATCH 11/76] Remove duplicate P256Keypair::ECDSA_sign_hash code (#20078) * Remove duplicate P256Keypair::ECDSA_sign_hash code - The ECDSA_sign_hash method is a near identical copy of of ECDSA_sign_msg, that takes a raw hash. - This is problematic since some platforms, like Android, cannot directly sign a pre-computed hash with OS-aided APIs, and overall this is not consistent with signature APIs that work on messages, and where a digest is an internal implementation detail. - Overall, the method adds little value and prevents easy transition to different signing algorithms over time if the hash assumption is kept Fixes #18430 This PR: - Removes the sign_hash API - Replaces its usage throughout the SDK - Updates all tests - Leaves the ECDSA_verify_hash_signature (since it's only used in one place, already in native code, and always against raw public keys) Testing done: - Cert tests still pass, including device attestation during commissioning - Unit tests still pass including updated unit tests * Restyled by clang-format * Remove missed removals * Apply review comments Co-authored-by: Restyled.io --- .../DeviceAttestationSe05xCredsExample.cpp | 8 +- .../tv-app/android/java/JNIDACProvider.cpp | 6 +- examples/tv-app/android/java/JNIDACProvider.h | 2 +- .../app/src/main/jni/cpp/JNIDACProvider.cpp | 6 +- .../App/app/src/main/jni/cpp/JNIDACProvider.h | 2 +- .../operational-credentials-server.cpp | 94 +++++++++---------- .../credentials/TestHarnessDACProvider.cpp | 6 +- .../credentials/TestHarnessDACProvider.h | 2 +- .../DeviceAttestationCredsProvider.cpp | 4 +- .../DeviceAttestationCredsProvider.h | 10 +- .../DeviceAttestationCredsExample.cpp | 9 +- .../TestDeviceAttestationCredentials.cpp | 10 +- src/crypto/CHIPCryptoPAL.h | 20 ---- src/crypto/CHIPCryptoPALOpenSSL.cpp | 22 ++--- src/crypto/CHIPCryptoPALmbedTLS.cpp | 21 +---- src/crypto/hsm/CHIPCryptoPALHsm.h | 2 - .../hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp | 48 ---------- src/crypto/tests/CHIPCryptoPALTest.cpp | 86 +++++------------ .../Framework/CHIP/CHIPP256KeypairBridge.h | 3 - .../Framework/CHIP/CHIPP256KeypairBridge.mm | 10 -- .../Darwin/CHIPP256KeypairNativeBridge.cpp | 6 -- .../Darwin/CHIPP256KeypairNativeBridge.h | 2 - .../ESP32/ESP32FactoryDataProvider.cpp | 4 +- src/platform/ESP32/ESP32FactoryDataProvider.h | 2 +- .../android/CHIPP256KeypairBridge.cpp | 12 --- src/platform/android/CHIPP256KeypairBridge.h | 3 - .../nrfconnect/FactoryDataProvider.cpp | 4 +- src/platform/nrfconnect/FactoryDataProvider.h | 2 +- 28 files changed, 120 insertions(+), 286 deletions(-) diff --git a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp index 1e4a657277e3e0..b7be4c2ed91242 100644 --- a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp +++ b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp @@ -48,7 +48,7 @@ class ExampleSe05xDACProvider : public DeviceAttestationCredentialsProvider CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override; }; CHIP_ERROR ExampleSe05xDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) @@ -130,7 +130,7 @@ CHIP_ERROR ExampleSe05xDACProvider::GetFirmwareInformation(MutableByteSpan & out return CHIP_NO_ERROR; } -CHIP_ERROR ExampleSe05xDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, +CHIP_ERROR ExampleSe05xDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) { Crypto::P256ECDSASignature signature; @@ -139,14 +139,14 @@ CHIP_ERROR ExampleSe05xDACProvider::SignWithDeviceAttestationKey(const ByteSpan ChipLogDetail(Crypto, "Sign using DA key from se05x"); VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(IsSpanUsable(digest_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); keypair.SetKeyId(DEV_ATTESTATION_KEY_ID); keypair.provisioned_key = true; keypair.Initialize(); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digest_to_sign.data(), digest_to_sign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer); } diff --git a/examples/tv-app/android/java/JNIDACProvider.cpp b/examples/tv-app/android/java/JNIDACProvider.cpp index 81f23f36a24dec..19fb4dd64da1c1 100644 --- a/examples/tv-app/android/java/JNIDACProvider.cpp +++ b/examples/tv-app/android/java/JNIDACProvider.cpp @@ -145,14 +145,14 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto: return keypair.Deserialize(serialized_keypair); } -CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) +CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) { ChipLogProgress(Zcl, "Received SignWithDeviceAttestationKey"); Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(IsSpanUsable(digest_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); uint8_t privateKeyBuf[Crypto::kP256_PrivateKey_Length]; @@ -166,7 +166,7 @@ CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_ // In a non-exemplary implementation, the public key is not needed here. It is used here merely because // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. ReturnErrorOnFailure(LoadKeypairFromRaw(privateKeyBufSpan, publicKeyBufSpan, keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digest_to_sign.data(), digest_to_sign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer); } diff --git a/examples/tv-app/android/java/JNIDACProvider.h b/examples/tv-app/android/java/JNIDACProvider.h index a9181dc59295b3..1498eb66c07dcd 100644 --- a/examples/tv-app/android/java/JNIDACProvider.h +++ b/examples/tv-app/android/java/JNIDACProvider.h @@ -28,7 +28,7 @@ class JNIDACProvider : public chip::Credentials::DeviceAttestationCredentialsPro CHIP_ERROR GetFirmwareInformation(chip::MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(chip::MutableByteSpan & out_dac_buffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(chip::MutableByteSpan & out_pai_buffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const chip::ByteSpan & digest_to_sign, + CHIP_ERROR SignWithDeviceAttestationKey(const chip::ByteSpan & message_to_sign, chip::MutableByteSpan & out_signature_buffer) override; private: diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.cpp index 81f23f36a24dec..19fb4dd64da1c1 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.cpp @@ -145,14 +145,14 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto: return keypair.Deserialize(serialized_keypair); } -CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) +CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) { ChipLogProgress(Zcl, "Received SignWithDeviceAttestationKey"); Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(IsSpanUsable(digest_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); uint8_t privateKeyBuf[Crypto::kP256_PrivateKey_Length]; @@ -166,7 +166,7 @@ CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_ // In a non-exemplary implementation, the public key is not needed here. It is used here merely because // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. ReturnErrorOnFailure(LoadKeypairFromRaw(privateKeyBufSpan, publicKeyBufSpan, keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digest_to_sign.data(), digest_to_sign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer); } diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.h b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.h index a9181dc59295b3..1498eb66c07dcd 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.h +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/JNIDACProvider.h @@ -28,7 +28,7 @@ class JNIDACProvider : public chip::Credentials::DeviceAttestationCredentialsPro CHIP_ERROR GetFirmwareInformation(chip::MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(chip::MutableByteSpan & out_dac_buffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(chip::MutableByteSpan & out_pai_buffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const chip::ByteSpan & digest_to_sign, + CHIP_ERROR SignWithDeviceAttestationKey(const chip::ByteSpan & message_to_sign, chip::MutableByteSpan & out_signature_buffer) override; private: diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index 5ed6a89301d1c4..d02a994e9b3498 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -247,33 +247,6 @@ CHIP_ERROR OperationalCredentialsAttrAccess::Read(const ConcreteReadAttributePat return CHIP_NO_ERROR; } -// Utility to compute Attestation signature for NOCSRResponse and AttestationResponse -CHIP_ERROR ComputeAttestationSignature(app::CommandHandler * commandObj, - Credentials::DeviceAttestationCredentialsProvider * dacProvider, const ByteSpan & payload, - MutableByteSpan & signatureSpan) -{ - uint8_t md[Crypto::kSHA256_Hash_Length]; - MutableByteSpan messageDigestSpan(md); - - VerifyOrReturnError(signatureSpan.size() >= Crypto::P256ECDSASignature::Capacity(), CHIP_ERROR_INVALID_ARGUMENT); - - // TODO: Create an alternative way to retrieve the Attestation Challenge without this huge amount of calls. - // Retrieve attestation challenge - ByteSpan attestationChallenge = - commandObj->GetExchangeContext()->GetSessionHandle()->AsSecureSession()->GetCryptoContext().GetAttestationChallenge(); - - Hash_SHA256_stream hashStream; - ReturnErrorOnFailure(hashStream.Begin()); - ReturnErrorOnFailure(hashStream.AddData(payload)); - ReturnErrorOnFailure(hashStream.AddData(attestationChallenge)); - ReturnErrorOnFailure(hashStream.Finish(messageDigestSpan)); - - ReturnErrorOnFailure(dacProvider->SignWithDeviceAttestationKey(messageDigestSpan, signatureSpan)); - VerifyOrReturnError(signatureSpan.size() == Crypto::P256ECDSASignature::Capacity(), CHIP_ERROR_INTERNAL); - - return CHIP_NO_ERROR; -} - FabricInfo * RetrieveCurrentFabric(CommandHandler * aCommandHandler) { FabricIndex index = aCommandHandler->GetAccessingFabricIndex(); @@ -930,6 +903,7 @@ bool emberAfOperationalCredentialsClusterAttestationRequestCallback(app::Command auto finalStatus = Status::Failure; CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + ByteSpan tbsSpan; Platform::ScopedMemoryBuffer attestationElements; size_t attestationElementsLen = 0; @@ -938,6 +912,11 @@ bool emberAfOperationalCredentialsClusterAttestationRequestCallback(app::Command // See DeviceAttestationCredsExample MutableByteSpan certDeclSpan(certDeclBuf); + // TODO: Create an alternative way to retrieve the Attestation Challenge without this huge amount of calls. + // Retrieve attestation challenge + ByteSpan attestationChallenge = + commandObj->GetExchangeContext()->GetSessionHandle()->AsSecureSession()->GetCryptoContext().GetAttestationChallenge(); + // TODO: in future versions, retrieve vendor information to populate the fields below. uint32_t timestamp = 0; Credentials::DeviceAttestationVendorReservedConstructor emptyVendorReserved(nullptr, 0); @@ -961,7 +940,7 @@ bool emberAfOperationalCredentialsClusterAttestationRequestCallback(app::Command attestationElementsLen = TLV::EstimateStructOverhead(certDeclSpan.size(), attestationNonce.size(), sizeof(uint64_t) * 8); - if (!attestationElements.Alloc(attestationElementsLen)) + if (!attestationElements.Alloc(attestationElementsLen + attestationChallenge.size())) { err = CHIP_ERROR_NO_MEMORY; VerifyOrExit(err == CHIP_NO_ERROR, finalStatus = Status::ResourceExhausted); @@ -972,14 +951,21 @@ bool emberAfOperationalCredentialsClusterAttestationRequestCallback(app::Command emptyVendorReserved, attestationElementsSpan); VerifyOrExit((err == CHIP_NO_ERROR) && (attestationElementsSpan.size() <= kMaxRspLen), finalStatus = Status::Failure); - // Prepare response payload with signature - { - Commands::AttestationResponse::Type response; + // Append attestation challenge in the back of the reserved space for the signature + memcpy(attestationElements.Get() + attestationElementsSpan.size(), attestationChallenge.data(), attestationChallenge.size()); + tbsSpan = ByteSpan{ attestationElements.Get(), attestationElementsSpan.size() + attestationChallenge.size() }; + { Crypto::P256ECDSASignature signature; MutableByteSpan signatureSpan{ signature.Bytes(), signature.Capacity() }; - err = ComputeAttestationSignature(commandObj, dacProvider, attestationElementsSpan, signatureSpan); + + // Getnerate attestation signature + err = dacProvider->SignWithDeviceAttestationKey(tbsSpan, signatureSpan); + ClearSecretData(attestationElements.Get() + attestationElementsSpan.size(), attestationChallenge.size()); VerifyOrExit(err == CHIP_NO_ERROR, finalStatus = Status::Failure); + VerifyOrExit(signatureSpan.size() == Crypto::P256ECDSASignature::Capacity(), finalStatus = Status::Failure); + + Commands::AttestationResponse::Type response; response.attestationElements = attestationElementsSpan; response.signature = signatureSpan; @@ -1010,6 +996,7 @@ bool emberAfOperationalCredentialsClusterCSRRequestCallback(app::CommandHandler chip::Platform::ScopedMemoryBuffer nocsrElements; MutableByteSpan nocsrElementsSpan; auto finalStatus = Status::Failure; + ByteSpan tbsSpan; // Start with CHIP_ERROR_INVALID_ARGUMENT so that cascading errors yield correct // logs by the end. We use finalStatus as our overall success marker, not error @@ -1021,6 +1008,11 @@ bool emberAfOperationalCredentialsClusterCSRRequestCallback(app::CommandHandler auto & CSRNonce = commandData.CSRNonce; bool isForUpdateNoc = commandData.isForUpdateNOC.ValueOr(false); + // TODO: Create an alternative way to retrieve the Attestation Challenge without this huge amount of calls. + // Retrieve attestation challenge + ByteSpan attestationChallenge = + commandObj->GetExchangeContext()->GetSessionHandle()->AsSecureSession()->GetCryptoContext().GetAttestationChallenge(); + failSafeContext.SetCsrRequestForUpdateNoc(isForUpdateNoc); FabricInfo * fabricInfo = RetrieveCurrentFabric(commandObj); @@ -1075,7 +1067,7 @@ bool emberAfOperationalCredentialsClusterCSRRequestCallback(app::CommandHandler 0u // no vendor reserved data ); - if (!nocsrElements.Alloc(nocsrLengthEstimate)) + if (!nocsrElements.Alloc(nocsrLengthEstimate + attestationChallenge.size())) { err = CHIP_ERROR_NO_MEMORY; VerifyOrExit(err == CHIP_NO_ERROR, finalStatus = Status::ResourceExhausted); @@ -1086,26 +1078,32 @@ bool emberAfOperationalCredentialsClusterCSRRequestCallback(app::CommandHandler err = Credentials::ConstructNOCSRElements(ByteSpan{ csrSpan.data(), csrSpan.size() }, CSRNonce, kNoVendorReserved, kNoVendorReserved, kNoVendorReserved, nocsrElementsSpan); VerifyOrExit((err == CHIP_NO_ERROR) && (nocsrElementsSpan.size() <= kMaxRspLen), finalStatus = Status::Failure); - } - // Prepare response payload with signature - { - Commands::CSRResponse::Type response; - - Credentials::DeviceAttestationCredentialsProvider * dacProvider = Credentials::GetDeviceAttestationCredentialsProvider(); + // Append attestation challenge in the back of the reserved space for the signature + memcpy(nocsrElements.Get() + nocsrElementsSpan.size(), attestationChallenge.data(), attestationChallenge.size()); + tbsSpan = ByteSpan{ nocsrElements.Get(), nocsrElementsSpan.size() + attestationChallenge.size() }; - Crypto::P256ECDSASignature signature; - MutableByteSpan signatureSpan{ signature.Bytes(), signature.Capacity() }; + { + Credentials::DeviceAttestationCredentialsProvider * dacProvider = + Credentials::GetDeviceAttestationCredentialsProvider(); + Crypto::P256ECDSASignature signature; + MutableByteSpan signatureSpan{ signature.Bytes(), signature.Capacity() }; + + // Getnerate attestation signature + err = dacProvider->SignWithDeviceAttestationKey(tbsSpan, signatureSpan); + ClearSecretData(nocsrElements.Get() + nocsrElementsSpan.size(), attestationChallenge.size()); + VerifyOrExit(err == CHIP_NO_ERROR, finalStatus = Status::Failure); + VerifyOrExit(signatureSpan.size() == Crypto::P256ECDSASignature::Capacity(), finalStatus = Status::Failure); - err = ComputeAttestationSignature(commandObj, dacProvider, nocsrElementsSpan, signatureSpan); - VerifyOrExit(err == CHIP_NO_ERROR, finalStatus = Status::Failure); + Commands::CSRResponse::Type response; - response.NOCSRElements = nocsrElementsSpan; - response.attestationSignature = signatureSpan; + response.NOCSRElements = nocsrElementsSpan; + response.attestationSignature = signatureSpan; - ChipLogProgress(Zcl, "OpCreds: CSRRequest successful."); - finalStatus = Status::Success; - commandObj->AddResponse(commandPath, response); + ChipLogProgress(Zcl, "OpCreds: CSRRequest successful."); + finalStatus = Status::Success; + commandObj->AddResponse(commandPath, response); + } } exit: diff --git a/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp b/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp index c675ecb1fc2026..1d8ef2461fd679 100644 --- a/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp +++ b/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp @@ -209,20 +209,20 @@ CHIP_ERROR TestHarnessDACProvider::GetFirmwareInformation(MutableByteSpan & out_ return CopySpanToMutableSpan(mFirmwareInformation, out_firmware_info_buffer); } -CHIP_ERROR TestHarnessDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, +CHIP_ERROR TestHarnessDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) { Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(IsSpanUsable(digest_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); // In a non-exemplary implementation, the public key is not needed here. It is used here merely because // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. ReturnErrorOnFailure(LoadKeypairFromRaw(mDacPrivateKey, mDacPublicKey, keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digest_to_sign.data(), digest_to_sign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer); } diff --git a/src/app/tests/suites/credentials/TestHarnessDACProvider.h b/src/app/tests/suites/credentials/TestHarnessDACProvider.h index 5acd39828e4dcf..0483443fc24337 100644 --- a/src/app/tests/suites/credentials/TestHarnessDACProvider.h +++ b/src/app/tests/suites/credentials/TestHarnessDACProvider.h @@ -42,7 +42,7 @@ class TestHarnessDACProvider : public DeviceAttestationCredentialsProvider CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override; void Init(const char * filepath); void Init(const TestHarnessDACProviderData & data); diff --git a/src/credentials/DeviceAttestationCredsProvider.cpp b/src/credentials/DeviceAttestationCredsProvider.cpp index e1cc763396d637..0b5d04b17eba51 100644 --- a/src/credentials/DeviceAttestationCredsProvider.cpp +++ b/src/credentials/DeviceAttestationCredsProvider.cpp @@ -50,9 +50,9 @@ class UnimplementedDACProvider : public DeviceAttestationCredentialsProvider return CHIP_ERROR_NOT_IMPLEMENTED; } - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) override + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override { - (void) digest_to_sign; + (void) message_to_sign; (void) out_signature_buffer; return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/credentials/DeviceAttestationCredsProvider.h b/src/credentials/DeviceAttestationCredsProvider.h index 36ac029425289c..adfcc3323e4deb 100644 --- a/src/credentials/DeviceAttestationCredsProvider.h +++ b/src/credentials/DeviceAttestationCredsProvider.h @@ -80,16 +80,14 @@ class DeviceAttestationCredentialsProvider virtual CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) = 0; /** - * @brief Signs a SHA256 digest using the device attestation private key + * @brief Signs a message using the device attestation private key * - * @param[in] digest_to_sign The SHA256 digest to sign using the attestation private key. Must - * be exactly chip::Crypto::kSHA256_Hash_Length. + * @param[in] message_to_sign The message to sign using the attestation private key. * @param[in,out] out_signature_buffer Buffer to receive the signature in raw format. - * @returns CHIP_NO_ERROR on success, CHIP_ERROR_INVALID_ARGUMENT if `digest_to_sign` is wrong size, - * CHIP_ERROR_BUFFER_TOO_SMALL if `out_signature_buffer` is too small, + * @returns CHIP_NO_ERROR on success, CHIP_ERROR_BUFFER_TOO_SMALL if `out_signature_buffer` is too small, * or another CHIP_ERROR from the underlying implementation if signature fails. */ - virtual CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) = 0; + virtual CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) = 0; }; /** diff --git a/src/credentials/examples/DeviceAttestationCredsExample.cpp b/src/credentials/examples/DeviceAttestationCredsExample.cpp index 617e3463bf0d07..e96e36b59bd65b 100644 --- a/src/credentials/examples/DeviceAttestationCredsExample.cpp +++ b/src/credentials/examples/DeviceAttestationCredsExample.cpp @@ -47,7 +47,7 @@ class ExampleDACProvider : public DeviceAttestationCredentialsProvider CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override; }; CHIP_ERROR ExampleDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) @@ -121,19 +121,20 @@ CHIP_ERROR ExampleDACProvider::GetFirmwareInformation(MutableByteSpan & out_firm return CHIP_NO_ERROR; } -CHIP_ERROR ExampleDACProvider::SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_signature_buffer) +CHIP_ERROR ExampleDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, + MutableByteSpan & out_signature_buffer) { Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(IsSpanUsable(digest_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); // In a non-exemplary implementation, the public key is not needed here. It is used here merely because // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. ReturnErrorOnFailure(LoadKeypairFromRaw(DevelopmentCerts::kDacPrivateKey, DevelopmentCerts::kDacPublicKey, keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digest_to_sign.data(), digest_to_sign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer); } diff --git a/src/credentials/tests/TestDeviceAttestationCredentials.cpp b/src/credentials/tests/TestDeviceAttestationCredentials.cpp index c3576d03d7ef2f..5af5b2db5bc828 100644 --- a/src/credentials/tests/TestDeviceAttestationCredentials.cpp +++ b/src/credentials/tests/TestDeviceAttestationCredentials.cpp @@ -112,9 +112,9 @@ static void TestDACProvidersExample_Providers(nlTestSuite * inSuite, void * inCo static void TestDACProvidersExample_Signature(nlTestSuite * inSuite, void * inContext) { - constexpr uint8_t kExampleDigest[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 }; + constexpr uint8_t kExampleMessage[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 }; DeviceAttestationCredentialsProvider * example_dac_provider = Examples::GetExampleDACProvider(); NL_TEST_ASSERT(inSuite, example_dac_provider != nullptr); @@ -122,7 +122,7 @@ static void TestDACProvidersExample_Signature(nlTestSuite * inSuite, void * inCo // Sign using the example attestation private key P256ECDSASignature da_signature; MutableByteSpan out_sig_span(da_signature.Bytes(), da_signature.Capacity()); - CHIP_ERROR err = example_dac_provider->SignWithDeviceAttestationKey(ByteSpan{ kExampleDigest }, out_sig_span); + CHIP_ERROR err = example_dac_provider->SignWithDeviceAttestationKey(ByteSpan{ kExampleMessage }, out_sig_span); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, out_sig_span.size() == kP256_ECDSA_Signature_Length_Raw); @@ -144,7 +144,7 @@ static void TestDACProvidersExample_Signature(nlTestSuite * inSuite, void * inCo NL_TEST_ASSERT(inSuite, 0 == memcmp(dac_public_key.ConstBytes(), kExpectedDacPublicKey.data(), kExpectedDacPublicKey.size())); // Verify round trip signature - err = dac_public_key.ECDSA_validate_hash_signature(&kExampleDigest[0], sizeof(kExampleDigest), da_signature); + err = dac_public_key.ECDSA_validate_msg_signature(&kExampleMessage[0], sizeof(kExampleMessage), da_signature); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); } diff --git a/src/crypto/CHIPCryptoPAL.h b/src/crypto/CHIPCryptoPAL.h index eb9fb9545f27cf..077b668de55532 100644 --- a/src/crypto/CHIPCryptoPAL.h +++ b/src/crypto/CHIPCryptoPAL.h @@ -361,16 +361,6 @@ class ECPKeypair **/ virtual CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, Sig & out_signature) const = 0; - /** - * @brief A function to sign a hash using ECDSA - * @param hash Hash that needs to be signed - * @param hash_length Length of hash - * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s), - * in raw point form (see SEC1). - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ - virtual CHIP_ERROR ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, Sig & out_signature) const = 0; - /** @brief A function to derive a shared secret using ECDH * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is * ASN.1 DER encoded as padded big-endian field elements as described in SEC 1: Elliptic Curve Cryptography @@ -455,16 +445,6 @@ class P256Keypair : public P256KeypairBase **/ CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const override; - /** - * @brief A function to sign a hash using ECDSA - * @param hash Hash that needs to be signed - * @param hash_length Length of hash - * @param out_signature Buffer that will hold the output signature. The signature consists of: 2 EC elements (r and s), - * in raw point form (see SEC1). - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ - CHIP_ERROR ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, P256ECDSASignature & out_signature) const override; - /** * @brief A function to derive a shared secret using ECDH * diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index 65ec2e5f8de36f..21b20aef63735f 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -611,37 +611,31 @@ static inline const EC_KEY * to_const_EC_KEY(const P256KeypairContext * context) CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const { + CHIP_ERROR error = CHIP_NO_ERROR; + int nid = NID_undef; + EC_KEY * ec_key = nullptr; + ECDSA_SIG * sig = nullptr; + const BIGNUM * r = nullptr; + const BIGNUM * s = nullptr; + VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT); uint8_t digest[kSHA256_Hash_Length]; memset(&digest[0], 0, sizeof(digest)); ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0])); - return ECDSA_sign_hash(&digest[0], sizeof(digest), out_signature); -} -CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_length, P256ECDSASignature & out_signature) const -{ ERR_clear_error(); - CHIP_ERROR error = CHIP_NO_ERROR; - int nid = NID_undef; - EC_KEY * ec_key = nullptr; - ECDSA_SIG * sig = nullptr; - const BIGNUM * r = nullptr; - const BIGNUM * s = nullptr; - static_assert(P256ECDSASignature::Capacity() >= kP256_ECDSA_Signature_Length_Raw, "P256ECDSASignature must be large enough"); VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(hash != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(hash_length == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT); nid = _nidForCurve(MapECName(mPublicKey.Type())); VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INVALID_ARGUMENT); ec_key = to_EC_KEY(&mKeypair); VerifyOrExit(ec_key != nullptr, error = CHIP_ERROR_INTERNAL); - sig = ECDSA_do_sign(Uint8::to_const_uchar(hash), static_cast(hash_length), ec_key); + sig = ECDSA_do_sign(Uint8::to_const_uchar(&digest[0]), static_cast(sizeof(digest)), ec_key); VerifyOrExit(sig != nullptr, error = CHIP_ERROR_INTERNAL); ECDSA_SIG_get0(sig, &r, &s); diff --git a/src/crypto/CHIPCryptoPALmbedTLS.cpp b/src/crypto/CHIPCryptoPALmbedTLS.cpp index 140794d727663e..996b3625075943 100644 --- a/src/crypto/CHIPCryptoPALmbedTLS.cpp +++ b/src/crypto/CHIPCryptoPALmbedTLS.cpp @@ -553,7 +553,6 @@ static inline const mbedtls_ecp_keypair * to_const_keypair(const P256KeypairCont CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const { -#if defined(MBEDTLS_ECDSA_C) VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT); @@ -561,25 +560,13 @@ CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_len memset(&digest[0], 0, sizeof(digest)); ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0])); - return ECDSA_sign_hash(&digest[0], sizeof(digest), out_signature); -#else - return CHIP_ERROR_NOT_IMPLEMENTED; -#endif -} - -CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_length, P256ECDSASignature & out_signature) const -{ #if defined(MBEDTLS_USE_TINYCRYPT) - VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE); - VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(hash_length == kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT); - CHIP_ERROR error = CHIP_NO_ERROR; int result = UECC_FAILURE; const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair); - result = uECC_sign(keypair->private_key, hash, hash_length, out_signature.Bytes()); + result = uECC_sign(keypair->private_key, digest, sizeof(digest), out_signature.Bytes()); VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL); VerifyOrExit(out_signature.SetLength(kP256_ECDSA_Signature_Length_Raw) == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL); @@ -589,10 +576,6 @@ CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_ exit: return error; #elif defined(MBEDTLS_ECDSA_C) - VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE); - VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(hash_length == kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT); - CHIP_ERROR error = CHIP_NO_ERROR; int result = 0; mbedtls_mpi r, s; @@ -608,7 +591,7 @@ CHIP_ERROR P256Keypair::ECDSA_sign_hash(const uint8_t * hash, const size_t hash_ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); result = mbedtls_ecdsa_sign(&ecdsa_ctxt.CHIP_CRYPTO_PAL_PRIVATE(grp), &r, &s, &ecdsa_ctxt.CHIP_CRYPTO_PAL_PRIVATE(d), - Uint8::to_const_uchar(hash), hash_length, CryptoRNG, nullptr); + Uint8::to_const_uchar(digest), sizeof(digest), CryptoRNG, nullptr); VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL); diff --git a/src/crypto/hsm/CHIPCryptoPALHsm.h b/src/crypto/hsm/CHIPCryptoPALHsm.h index b8d2cb57ac3412..c981a56062b247 100644 --- a/src/crypto/hsm/CHIPCryptoPALHsm.h +++ b/src/crypto/hsm/CHIPCryptoPALHsm.h @@ -132,8 +132,6 @@ class P256KeypairHSM : public P256Keypair virtual CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) override; - virtual CHIP_ERROR ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, P256ECDSASignature & out_signature) override; - virtual CHIP_ERROR ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const override; diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp index a3e451e15429b8..1007ba2c395973 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp @@ -205,54 +205,6 @@ CHIP_ERROR P256KeypairHSM::ECDSA_sign_msg(const uint8_t * msg, size_t msg_length return error; } -CHIP_ERROR P256KeypairHSM::ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, P256ECDSASignature & out_signature) const -{ - CHIP_ERROR error = CHIP_ERROR_INTERNAL; - sss_asymmetric_t asymm_ctx = { 0 }; - sss_status_t status = kStatus_SSS_Success; - sss_object_t keyObject = { 0 }; - uint8_t signature_se05x[kMax_ECDSA_Signature_Length_Der] = { 0 }; - size_t signature_se05x_len = sizeof(signature_se05x); - MutableByteSpan out_raw_sig_span(out_signature.Bytes(), out_signature.Capacity()); - - VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(hash_length == kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(out_signature != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(keyid != kKeyId_NotInitialized, CHIP_ERROR_HSM); - - ChipLogDetail(Crypto, "ECDSA_sign_hash: Using SE05X for Ecc Sign!"); - - se05x_sessionOpen(); - VerifyOrReturnError(gex_sss_chip_ctx.ks.session != NULL, CHIP_ERROR_INTERNAL); - - status = sss_key_object_init(&keyObject, &gex_sss_chip_ctx.ks); - VerifyOrExit(status == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); - - status = sss_key_object_get_handle(&keyObject, keyid); - VerifyOrExit(status == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); - - status = sss_asymmetric_context_init(&asymm_ctx, &gex_sss_chip_ctx.session, &keyObject, kAlgorithm_SSS_SHA256, kMode_SSS_Sign); - VerifyOrExit(status == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); - - status = - sss_asymmetric_sign_digest(&asymm_ctx, const_cast(hash), hash_length, signature_se05x, &signature_se05x_len); - VerifyOrExit(status == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL); - - error = EcdsaAsn1SignatureToRaw(kP256_FE_Length, ByteSpan{ signature_se05x, signature_se05x_len }, out_raw_sig_span); - SuccessOrExit(error); - - SuccessOrExit(out_signature.SetLength(2 * kP256_FE_Length)); - - error = CHIP_NO_ERROR; -exit: - if (asymm_ctx.session != nullptr) - { - sss_asymmetric_context_free(&asymm_ctx); - } - - return error; -} - CHIP_ERROR P256KeypairHSM::Serialize(P256SerializedKeypair & output) const { const size_t len = output.Length() == 0 ? output.Capacity() : output.Length(); diff --git a/src/crypto/tests/CHIPCryptoPALTest.cpp b/src/crypto/tests/CHIPCryptoPALTest.cpp index 2ffc861df3762b..aef0d3d77c4d7f 100644 --- a/src/crypto/tests/CHIPCryptoPALTest.cpp +++ b/src/crypto/tests/CHIPCryptoPALTest.cpp @@ -994,9 +994,9 @@ static void TestECDSA_Signing_SHA256_Msg(nlTestSuite * inSuite, void * inContext static void TestECDSA_Signing_SHA256_Hash(nlTestSuite * inSuite, void * inContext) { HeapChecker heapChecker(inSuite); - const uint8_t hash[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - size_t hash_length = sizeof(hash); + const uint8_t msg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; + size_t msg_length = sizeof(msg); Test_P256Keypair keypair; NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); @@ -1010,10 +1010,14 @@ static void TestECDSA_Signing_SHA256_Hash(nlTestSuite * inSuite, void * inContex for (int i = 0; i < kNumSigningIterations; ++i) { P256ECDSASignature signature; - CHIP_ERROR signing_error = keypair.ECDSA_sign_hash(hash, hash_length, signature); + + uint8_t hash[Crypto::kSHA256_Hash_Length]; + NL_TEST_ASSERT(inSuite, Hash_SHA256(&msg[0], msg_length, &hash[0]) == CHIP_NO_ERROR); + + CHIP_ERROR signing_error = keypair.ECDSA_sign_msg(msg, msg_length, signature); NL_TEST_ASSERT(inSuite, signing_error == CHIP_NO_ERROR); - CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(hash, hash_length, signature); + CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(hash, sizeof(hash), signature); NL_TEST_ASSERT(inSuite, validation_error == CHIP_NO_ERROR); if ((signing_error != CHIP_NO_ERROR) || (validation_error != CHIP_NO_ERROR)) @@ -1044,28 +1048,6 @@ static void TestECDSA_ValidationFailsDifferentMessage(nlTestSuite * inSuite, voi NL_TEST_ASSERT(inSuite, validation_error == CHIP_ERROR_INVALID_SIGNATURE); } -static void TestECDSA_ValidationFailsDifferentHash(nlTestSuite * inSuite, void * inContext) -{ - HeapChecker heapChecker(inSuite); - const uint8_t hash[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - size_t hash_length = sizeof(hash); - - P256Keypair keypair; - NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); - - P256ECDSASignature signature; - CHIP_ERROR signing_error = keypair.ECDSA_sign_hash(hash, hash_length, signature); - NL_TEST_ASSERT(inSuite, signing_error == CHIP_NO_ERROR); - - const uint8_t diff_hash[] = { 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x00 }; - size_t diff_hash_length = sizeof(diff_hash); - - CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(diff_hash, diff_hash_length, signature); - NL_TEST_ASSERT(inSuite, validation_error == CHIP_ERROR_INVALID_SIGNATURE); -} - static void TestECDSA_ValidationFailIncorrectMsgSignature(nlTestSuite * inSuite, void * inContext) { HeapChecker heapChecker(inSuite); @@ -1088,19 +1070,22 @@ static void TestECDSA_ValidationFailIncorrectMsgSignature(nlTestSuite * inSuite, static void TestECDSA_ValidationFailIncorrectHashSignature(nlTestSuite * inSuite, void * inContext) { HeapChecker heapChecker(inSuite); - const uint8_t hash[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - size_t hash_length = sizeof(hash); + const uint8_t msg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; + size_t msg_length = sizeof(msg); + + uint8_t hash[Crypto::kSHA256_Hash_Length]; + NL_TEST_ASSERT(inSuite, Hash_SHA256(&msg[0], msg_length, &hash[0]) == CHIP_NO_ERROR); P256Keypair keypair; NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); P256ECDSASignature signature; - CHIP_ERROR signing_error = keypair.ECDSA_sign_hash(hash, hash_length, signature); + CHIP_ERROR signing_error = keypair.ECDSA_sign_msg(msg, msg_length, signature); NL_TEST_ASSERT(inSuite, signing_error == CHIP_NO_ERROR); signature[0] = static_cast(~signature[0]); // Flipping bits should invalidate the signature. - CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(hash, hash_length, signature); + CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(hash, sizeof(hash), signature); NL_TEST_ASSERT(inSuite, validation_error == CHIP_ERROR_INVALID_SIGNATURE); } @@ -1123,26 +1108,6 @@ static void TestECDSA_SigningMsgInvalidParams(nlTestSuite * inSuite, void * inCo signing_error = CHIP_NO_ERROR; } -static void TestECDSA_SigningHashInvalidParams(nlTestSuite * inSuite, void * inContext) -{ - HeapChecker heapChecker(inSuite); - const uint8_t hash[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - size_t hash_length = sizeof(hash); - - P256Keypair keypair; - NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); - - P256ECDSASignature signature; - CHIP_ERROR signing_error = keypair.ECDSA_sign_hash(nullptr, hash_length, signature); - NL_TEST_ASSERT(inSuite, signing_error == CHIP_ERROR_INVALID_ARGUMENT); - signing_error = CHIP_NO_ERROR; - - signing_error = keypair.ECDSA_sign_hash(hash, hash_length - 5, signature); - NL_TEST_ASSERT(inSuite, signing_error == CHIP_ERROR_INVALID_ARGUMENT); - signing_error = CHIP_NO_ERROR; -} - static void TestECDSA_ValidationMsgInvalidParam(nlTestSuite * inSuite, void * inContext) { HeapChecker heapChecker(inSuite); @@ -1168,22 +1133,25 @@ static void TestECDSA_ValidationMsgInvalidParam(nlTestSuite * inSuite, void * in static void TestECDSA_ValidationHashInvalidParam(nlTestSuite * inSuite, void * inContext) { HeapChecker heapChecker(inSuite); - const uint8_t hash[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - size_t hash_length = sizeof(hash); + const uint8_t msg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; + size_t msg_length = sizeof(msg); + + uint8_t hash[Crypto::kSHA256_Hash_Length]; + NL_TEST_ASSERT(inSuite, Hash_SHA256(&msg[0], msg_length, &hash[0]) == CHIP_NO_ERROR); P256Keypair keypair; NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); P256ECDSASignature signature; - CHIP_ERROR signing_error = keypair.ECDSA_sign_hash(hash, hash_length, signature); + CHIP_ERROR signing_error = keypair.ECDSA_sign_msg(msg, msg_length, signature); NL_TEST_ASSERT(inSuite, signing_error == CHIP_NO_ERROR); - CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(nullptr, hash_length, signature); + CHIP_ERROR validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(nullptr, sizeof(hash), signature); NL_TEST_ASSERT(inSuite, validation_error == CHIP_ERROR_INVALID_ARGUMENT); signing_error = CHIP_NO_ERROR; - validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(hash, hash_length - 5, signature); + validation_error = keypair.Pubkey().ECDSA_validate_hash_signature(hash, sizeof(hash) - 5, signature); NL_TEST_ASSERT(inSuite, validation_error == CHIP_ERROR_INVALID_ARGUMENT); signing_error = CHIP_NO_ERROR; } @@ -2365,11 +2333,9 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test ECDSA signing and validation message using SHA256", TestECDSA_Signing_SHA256_Msg), NL_TEST_DEF("Test ECDSA signing and validation SHA256 Hash", TestECDSA_Signing_SHA256_Hash), NL_TEST_DEF("Test ECDSA signature validation fail - Different msg", TestECDSA_ValidationFailsDifferentMessage), - NL_TEST_DEF("Test ECDSA signature validation fail - Different hash", TestECDSA_ValidationFailsDifferentHash), NL_TEST_DEF("Test ECDSA signature validation fail - Different msg signature", TestECDSA_ValidationFailIncorrectMsgSignature), NL_TEST_DEF("Test ECDSA signature validation fail - Different hash signature", TestECDSA_ValidationFailIncorrectHashSignature), NL_TEST_DEF("Test ECDSA sign msg invalid parameters", TestECDSA_SigningMsgInvalidParams), - NL_TEST_DEF("Test ECDSA sign hash invalid parameters", TestECDSA_SigningHashInvalidParams), NL_TEST_DEF("Test ECDSA msg signature validation invalid parameters", TestECDSA_ValidationMsgInvalidParam), NL_TEST_DEF("Test ECDSA hash signature validation invalid parameters", TestECDSA_ValidationHashInvalidParam), NL_TEST_DEF("Test Hash SHA 256", TestHash_SHA256), diff --git a/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.h b/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.h index 738d035eb1daf1..612a4338d7619e 100644 --- a/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.h +++ b/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.h @@ -42,9 +42,6 @@ class CHIPP256KeypairBridge : public chip::Crypto::P256KeypairBase CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, chip::Crypto::P256ECDSASignature & out_signature) const override; - CHIP_ERROR ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, - chip::Crypto::P256ECDSASignature & out_signature) const override; - CHIP_ERROR ECDH_derive_secret(const chip::Crypto::P256PublicKey & remote_public_key, chip::Crypto::P256ECDHDerivedSecret & out_secret) const override; diff --git a/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.mm b/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.mm index e51f41bc35080d..dbee9ddd9b76a3 100644 --- a/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.mm +++ b/src/darwin/Framework/CHIP/CHIPP256KeypairBridge.mm @@ -122,16 +122,6 @@ return CHIP_NO_ERROR; } -CHIP_ERROR CHIPP256KeypairBridge::ECDSA_sign_hash( - const uint8_t * hash, size_t hash_length, P256ECDSASignature & out_signature) const -{ - if (!HasKeypair()) { - return CHIP_ERROR_INCORRECT_STATE; - } - - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; -} - CHIP_ERROR CHIPP256KeypairBridge::ECDH_derive_secret( const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const { diff --git a/src/platform/Darwin/CHIPP256KeypairNativeBridge.cpp b/src/platform/Darwin/CHIPP256KeypairNativeBridge.cpp index 7a55abaee27b79..7309518b6f9d0d 100644 --- a/src/platform/Darwin/CHIPP256KeypairNativeBridge.cpp +++ b/src/platform/Darwin/CHIPP256KeypairNativeBridge.cpp @@ -42,12 +42,6 @@ CHIP_ERROR CHIPP256KeypairNativeBridge::ECDSA_sign_msg(const uint8_t * msg, size return mKeypairBase.ECDSA_sign_msg(msg, msg_length, out_signature); } -CHIP_ERROR CHIPP256KeypairNativeBridge::ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, - P256ECDSASignature & out_signature) const -{ - return mKeypairBase.ECDSA_sign_hash(hash, hash_length, out_signature); -} - CHIP_ERROR CHIPP256KeypairNativeBridge::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const { diff --git a/src/platform/Darwin/CHIPP256KeypairNativeBridge.h b/src/platform/Darwin/CHIPP256KeypairNativeBridge.h index 629006bf1e2bd9..7685d13d247e53 100644 --- a/src/platform/Darwin/CHIPP256KeypairNativeBridge.h +++ b/src/platform/Darwin/CHIPP256KeypairNativeBridge.h @@ -43,8 +43,6 @@ class CHIPP256KeypairNativeBridge : public P256Keypair CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const override; - CHIP_ERROR ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, P256ECDSASignature & out_signature) const override; - CHIP_ERROR ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const override; CHIP_ERROR NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const override; diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 4839e19867d9d1..f1ea995f5a900b 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -130,7 +130,7 @@ CHIP_ERROR ESP32FactoryDataProvider::GetProductAttestationIntermediateCert(Mutab return CHIP_NO_ERROR; } -CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) +CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) { Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; @@ -149,7 +149,7 @@ CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan ReturnErrorOnFailure(ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_DACPublicKey, pubKeyBuf, pubKeyLen, pubKeyLen)); ReturnErrorOnFailure(LoadKeypairFromRaw(ByteSpan(privKeyBuf, privKeyLen), ByteSpan(pubKeyBuf, pubKeyLen), keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digestToSign.data(), digestToSign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); } diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index 67cf2740c75e41..aa258d1d3df91f 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -58,7 +58,7 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; #if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER // ===== Members functions that implement the GenericDeviceInstanceInfoProvider diff --git a/src/platform/android/CHIPP256KeypairBridge.cpp b/src/platform/android/CHIPP256KeypairBridge.cpp index 41ebf572c70adf..f0029fd183d0e0 100644 --- a/src/platform/android/CHIPP256KeypairBridge.cpp +++ b/src/platform/android/CHIPP256KeypairBridge.cpp @@ -142,18 +142,6 @@ CHIP_ERROR CHIPP256KeypairBridge::ECDSA_sign_msg(const uint8_t * msg, size_t msg return err; } -CHIP_ERROR CHIPP256KeypairBridge::ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, - P256ECDSASignature & out_signature) const -{ - if (!HasKeypair()) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - // Not required for Java SDK. - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; -} - CHIP_ERROR CHIPP256KeypairBridge::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const { diff --git a/src/platform/android/CHIPP256KeypairBridge.h b/src/platform/android/CHIPP256KeypairBridge.h index 63b8fc3ad17a20..3cb4dd217fa8e5 100644 --- a/src/platform/android/CHIPP256KeypairBridge.h +++ b/src/platform/android/CHIPP256KeypairBridge.h @@ -55,9 +55,6 @@ class CHIPP256KeypairBridge : public chip::Crypto::P256Keypair CHIP_ERROR ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, chip::Crypto::P256ECDSASignature & out_signature) const override; - CHIP_ERROR ECDSA_sign_hash(const uint8_t * hash, size_t hash_length, - chip::Crypto::P256ECDSASignature & out_signature) const override; - CHIP_ERROR ECDH_derive_secret(const chip::Crypto::P256PublicKey & remote_public_key, chip::Crypto::P256ECDHDerivedSecret & out_secret) const override; diff --git a/src/platform/nrfconnect/FactoryDataProvider.cpp b/src/platform/nrfconnect/FactoryDataProvider.cpp index 68cf3d4952c2be..42fd8ad3eb3b2a 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.cpp +++ b/src/platform/nrfconnect/FactoryDataProvider.cpp @@ -156,7 +156,7 @@ CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermedi } template -CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & digestToSign, +CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) { Crypto::P256ECDSASignature signature; @@ -174,7 +174,7 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(c ReturnErrorOnFailure( LoadKeypairFromRaw(ByteSpan(reinterpret_cast(mFactoryData.dac_priv_key.data), mFactoryData.dac_priv_key.len), ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair)); - ReturnErrorOnFailure(keypair.ECDSA_sign_hash(digestToSign.data(), digestToSign.size(), signature)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); } diff --git a/src/platform/nrfconnect/FactoryDataProvider.h b/src/platform/nrfconnect/FactoryDataProvider.h index a027135c6fe74e..95099ba29f233e 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.h +++ b/src/platform/nrfconnect/FactoryDataProvider.h @@ -73,7 +73,7 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; // ===== Members functions that implement the CommissionableDataProvider CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; From 06dcd231d37c512b83e3ebc7781ae57f66166109 Mon Sep 17 00:00:00 2001 From: rgoliver Date: Wed, 29 Jun 2022 09:49:34 -0400 Subject: [PATCH 12/76] RPC: Support pw logging for linux rpc examples (#20057) Add a config option CHIP_USE_PW_LOGGING, which uses pw log output instead of printf on linux. This allows the logs to correctly get HDLC encoded and be piped over the socket for linux RPC builds. --- examples/chef/linux/with_pw_rpc.gni | 1 + .../rpc_console/py/chip_rpc/console.py | 8 +++-- examples/lighting-app/linux/with_pw_rpc.gni | 1 + src/lib/core/BUILD.gn | 1 + src/lib/core/core.gni | 3 ++ src/platform/Linux/BUILD.gn | 9 ++++++ src/platform/Linux/Logging.cpp | 31 +++++++++++++++++++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/examples/chef/linux/with_pw_rpc.gni b/examples/chef/linux/with_pw_rpc.gni index 9533565ecf4ce8..416733753a8909 100644 --- a/examples/chef/linux/with_pw_rpc.gni +++ b/examples/chef/linux/with_pw_rpc.gni @@ -40,3 +40,4 @@ pw_build_LINK_DEPS = [ chip_enable_pw_rpc = true chip_build_pw_trace_lib = true +chip_use_pw_logging = true diff --git a/examples/common/pigweed/rpc_console/py/chip_rpc/console.py b/examples/common/pigweed/rpc_console/py/chip_rpc/console.py index 65fdfc034f60ab..c74b6617396e59 100644 --- a/examples/common/pigweed/rpc_console/py/chip_rpc/console.py +++ b/examples/common/pigweed/rpc_console/py/chip_rpc/console.py @@ -253,7 +253,8 @@ def write_to_output(data: bytes, "E": logging.ERROR, "F": logging.FATAL, "V": logging.DEBUG, "D": logging.DEBUG, "": logging.INFO, "": logging.DEBUG, "": logging.ERROR, "": logging.INFO, "": logging.WARNING, - "": logging.ERROR, "": logging.DEBUG} + "": logging.ERROR, "": logging.DEBUG, + "ERR": logging.ERROR, "DBG": logging.DEBUG, "INF": logging.INFO} ESP_CHIP_REGEX = r"(?P[IWEFV]) \((?P