diff --git a/src/app/tests/suites/TestGroupKeyManagementCluster.yaml b/src/app/tests/suites/TestGroupKeyManagementCluster.yaml index 2c8f97e754aa6e..2562004cbf86aa 100644 --- a/src/app/tests/suites/TestGroupKeyManagementCluster.yaml +++ b/src/app/tests/suites/TestGroupKeyManagementCluster.yaml @@ -223,6 +223,35 @@ tests: EpochStartTime2: 2110002, } + - label: "Remove Group 1" + cluster: "Groups" + endpoint: 1 + command: "RemoveGroup" + arguments: + values: + - name: "groupId" + value: 0x0101 + response: + values: + - name: "status" + value: 0 + - name: "groupId" + value: 0x0101 + + - label: "Read GroupTable 2" + command: "readAttribute" + attribute: "GroupTable" + response: + value: + [ + { + FabricIndex: 1, + GroupId: 0x0102, + endpoints: [1], + GroupName: "Group #2", + }, + ] + - label: "Remove All" cluster: "Groups" endpoint: 1 diff --git a/src/credentials/GroupDataProviderImpl.cpp b/src/credentials/GroupDataProviderImpl.cpp index c5d65bfcb6e850..4c56a0943d2670 100644 --- a/src/credentials/GroupDataProviderImpl.cpp +++ b/src/credentials/GroupDataProviderImpl.cpp @@ -1187,11 +1187,15 @@ CHIP_ERROR GroupDataProviderImpl::RemoveEndpoint(chip::FabricIndex fabric_index, prev.next = endpoint.next; ReturnErrorOnFailure(prev.Save(mStorage)); } - if (group.endpoint_count > 0) + + if (group.endpoint_count > 1) { group.endpoint_count--; + return group.Save(mStorage); } - return group.Save(mStorage); + + // No more endpoints, remove the group + return RemoveGroupInfoAt(fabric_index, group.index); } CHIP_ERROR GroupDataProviderImpl::RemoveEndpoint(chip::FabricIndex fabric_index, chip::EndpointId endpoint_id) diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 5d1391e71e837c..e278dd701e1deb 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -64781,7 +64781,7 @@ class TestGroupKeyManagementClusterSuite : public TestCommand { public: TestGroupKeyManagementClusterSuite(CredentialIssuerCommands * credsIssuerConfig) : - TestCommand("TestGroupKeyManagementCluster", 18, credsIssuerConfig) + TestCommand("TestGroupKeyManagementCluster", 20, credsIssuerConfig) { AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); AddArgument("cluster", &mCluster); @@ -64962,11 +64962,40 @@ class TestGroupKeyManagementClusterSuite : public TestCommand break; case 15: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::Clusters::Groups::Commands::RemoveGroupResponse::DecodableType value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + VerifyOrReturn(CheckValue("status", value.status, 0)); + + VerifyOrReturn(CheckValue("groupId", value.groupId, 257U)); + } break; case 16: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList< + chip::app::Clusters::GroupKeyManagement::Structs::GroupInfoMapStruct::DecodableType> + value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("groupTable", iter_0, 0)); + VerifyOrReturn(CheckValue("groupTable[0].groupId", iter_0.GetValue().groupId, 258U)); + VerifyOrReturn(CheckValuePresent("groupTable[0].groupName", iter_0.GetValue().groupName)); + VerifyOrReturn(CheckValueAsString("groupTable[0].groupName.Value()", iter_0.GetValue().groupName.Value(), + chip::CharSpan("Group #2", 8))); + VerifyOrReturn(CheckValue("groupTable[0].fabricIndex", iter_0.GetValue().fabricIndex, 1)); + VerifyOrReturn(CheckNoMoreListItems("groupTable", iter_0, 1)); + } + } break; case 17: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 18: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 19: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_NOT_FOUND)); break; default: @@ -65184,7 +65213,22 @@ class TestGroupKeyManagementClusterSuite : public TestCommand ); } case 15: { - LogStep(15, "Remove All"); + LogStep(15, "Remove Group 1"); + ListFreer listFreer; + chip::app::Clusters::Groups::Commands::RemoveGroup::Type value; + value.groupId = 257U; + return SendCommand(kIdentityAlpha, GetEndpoint(1), Groups::Id, Groups::Commands::RemoveGroup::Id, value, + chip::NullOptional + + ); + } + case 16: { + LogStep(16, "Read GroupTable 2"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(0), GroupKeyManagement::Id, + GroupKeyManagement::Attributes::GroupTable::Id, true, chip::NullOptional); + } + case 17: { + LogStep(17, "Remove All"); ListFreer listFreer; chip::app::Clusters::Groups::Commands::RemoveAllGroups::Type value; return SendCommand(kIdentityAlpha, GetEndpoint(1), Groups::Id, Groups::Commands::RemoveAllGroups::Id, value, @@ -65192,8 +65236,8 @@ class TestGroupKeyManagementClusterSuite : public TestCommand ); } - case 16: { - LogStep(16, "KeySet Remove 2"); + case 18: { + LogStep(18, "KeySet Remove 2"); ListFreer listFreer; chip::app::Clusters::GroupKeyManagement::Commands::KeySetRemove::Type value; value.groupKeySetID = 418U; @@ -65202,8 +65246,8 @@ class TestGroupKeyManagementClusterSuite : public TestCommand ); } - case 17: { - LogStep(17, "KeySet Read (also removed)"); + case 19: { + LogStep(19, "KeySet Read (also removed)"); ListFreer listFreer; chip::app::Clusters::GroupKeyManagement::Commands::KeySetRead::Type value; value.groupKeySetID = 418U; 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 cb365729dc77c8..a252c1bfa4b71e 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -108178,16 +108178,24 @@ class TestGroupKeyManagementCluster : public TestCommandBridge { err = TestKeySetReadNotRemoved_14(); break; case 15: - ChipLogProgress(chipTool, " ***** Test Step 15 : Remove All\n"); - err = TestRemoveAll_15(); + ChipLogProgress(chipTool, " ***** Test Step 15 : Remove Group 1\n"); + err = TestRemoveGroup1_15(); break; case 16: - ChipLogProgress(chipTool, " ***** Test Step 16 : KeySet Remove 2\n"); - err = TestKeySetRemove2_16(); + ChipLogProgress(chipTool, " ***** Test Step 16 : Read GroupTable 2\n"); + err = TestReadGroupTable2_16(); break; case 17: - ChipLogProgress(chipTool, " ***** Test Step 17 : KeySet Read (also removed)\n"); - err = TestKeySetReadAlsoRemoved_17(); + ChipLogProgress(chipTool, " ***** Test Step 17 : Remove All\n"); + err = TestRemoveAll_17(); + break; + case 18: + ChipLogProgress(chipTool, " ***** Test Step 18 : KeySet Remove 2\n"); + err = TestKeySetRemove2_18(); + break; + case 19: + ChipLogProgress(chipTool, " ***** Test Step 19 : KeySet Read (also removed)\n"); + err = TestKeySetReadAlsoRemoved_19(); break; } @@ -108252,6 +108260,12 @@ class TestGroupKeyManagementCluster : public TestCommandBridge { VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); break; case 17: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 18: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 19: VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), EMBER_ZCL_STATUS_NOT_FOUND)); break; } @@ -108267,7 +108281,7 @@ class TestGroupKeyManagementCluster : public TestCommandBridge { private: std::atomic_uint16_t mTestIndex; - const uint16_t mTestCount = 18; + const uint16_t mTestCount = 20; chip::Optional mNodeId; chip::Optional mCluster; @@ -108757,7 +108771,71 @@ class TestGroupKeyManagementCluster : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestRemoveAll_15() + CHIP_ERROR TestRemoveGroup1_15() + { + CHIPDevice * device = GetDevice("alpha"); + CHIPTestGroups * cluster = [[CHIPTestGroups alloc] initWithDevice:device endpoint:1 queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + __auto_type * params = [[CHIPGroupsClusterRemoveGroupParams alloc] init]; + params.groupId = [NSNumber numberWithUnsignedShort:257U]; + [cluster removeGroupWithParams:params + completionHandler:^(CHIPGroupsClusterRemoveGroupResponseParams * _Nullable values, NSError * _Nullable err) { + NSLog(@"Remove Group 1 Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = values.status; + VerifyOrReturn(CheckValue("status", actualValue, 0)); + } + + { + id actualValue = values.groupId; + VerifyOrReturn(CheckValue("groupId", actualValue, 257U)); + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestReadGroupTable2_16() + { + CHIPDevice * device = GetDevice("alpha"); + CHIPTestGroupKeyManagement * cluster = [[CHIPTestGroupKeyManagement alloc] initWithDevice:device + endpoint:0 + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + CHIPReadParams * params = [[CHIPReadParams alloc] init]; + params.fabricFiltered = [NSNumber numberWithBool:true]; + [cluster readAttributeGroupTableWithParams:params + completionHandler:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read GroupTable 2 Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("GroupTable", [actualValue count], static_cast(1))); + VerifyOrReturn(CheckValue("GroupId", + ((CHIPGroupKeyManagementClusterGroupInfoMapStruct *) actualValue[0]).groupId, 258U)); + VerifyOrReturn(CheckValueAsString("GroupName", + ((CHIPGroupKeyManagementClusterGroupInfoMapStruct *) actualValue[0]).groupName, + @"Group #2")); + VerifyOrReturn(CheckValue("FabricIndex", + ((CHIPGroupKeyManagementClusterGroupInfoMapStruct *) actualValue[0]).fabricIndex, 1)); + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR TestRemoveAll_17() { CHIPDevice * device = GetDevice("alpha"); CHIPTestGroups * cluster = [[CHIPTestGroups alloc] initWithDevice:device endpoint:1 queue:mCallbackQueue]; @@ -108774,7 +108852,7 @@ class TestGroupKeyManagementCluster : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestKeySetRemove2_16() + CHIP_ERROR TestKeySetRemove2_18() { CHIPDevice * device = GetDevice("alpha"); CHIPTestGroupKeyManagement * cluster = [[CHIPTestGroupKeyManagement alloc] initWithDevice:device @@ -108796,7 +108874,7 @@ class TestGroupKeyManagementCluster : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestKeySetReadAlsoRemoved_17() + CHIP_ERROR TestKeySetReadAlsoRemoved_19() { CHIPDevice * device = GetDevice("alpha"); CHIPTestGroupKeyManagement * cluster = [[CHIPTestGroupKeyManagement alloc] initWithDevice:device