From 6da66b7d51fe79afc141160c015fb937827c0105 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 31 Jul 2024 10:48:53 -0400 Subject: [PATCH 01/21] TC-LVL-2.3: Wording tweaks / approximate first report (#34665) * TC-LVL-2.3: Wording tweaks / approximate first report * add missing skip marker --- src/python_testing/TC_LVL_2_3.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/python_testing/TC_LVL_2_3.py b/src/python_testing/TC_LVL_2_3.py index 57fbe2b7edc367..8d31b8641c3f7e 100644 --- a/src/python_testing/TC_LVL_2_3.py +++ b/src/python_testing/TC_LVL_2_3.py @@ -51,7 +51,7 @@ def steps_TC_LVL_2_3(self) -> list[TestStep]: test_plan_support.verify_success()), TestStep(6, "Set up a subscription wildcard subscription for the Level Control Cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 30 and KeepSubscriptions set to false", "Subscription successfully established"), - TestStep(7, f"{THcommand} MoveToLevel with Level field set to maxLevel, TransitionTime field set to 10 and remaining fields set to 0", + TestStep(7, f"{THcommand} MoveToLevel with Level field set to maxLevel, TransitionTime field set to 100 (10s) and remaining fields set to 0", test_plan_support.verify_success()), TestStep(8, "TH stores the reported values of CurrentLevel in all incoming reports for CurrentLevel attribute, that contains data in reportedCurrentLevelValuesList, over a period of 30 seconds."), TestStep(9, "TH verifies that reportedCurrentLevelValuesList does not contain more than 10 entries for CurrentLevel", @@ -65,18 +65,18 @@ def steps_TC_LVL_2_3(self) -> list[TestStep]: TestStep(13, "If the LT feature is not supported, skip remaining steps and end test case"), # 14 is missing in the test plan TestStep(15, "TH stores the reported values of RemainingTime in all incoming reports for RemainingTime attribute, that contains data in reportedRemainingTimeValuesList."), - TestStep(16, f" {THcommand} MoveToLevel with Level field set to startCurrentLevel, TransitionTime field set to 10 and remaining fields set to 0", + TestStep(16, f" {THcommand} MoveToLevel with Level field set to startCurrentLevel, TransitionTime field set to 100 (10s) and remaining fields set to 0", test_plan_support.verify_success()), TestStep(17, "Wait for 5 seconds"), - TestStep(18, f"{THcommand} MoveToLevel with Level field set to startCurrentLevel, TransitionTime field set to 15 and remaining fields set to 0", + TestStep(18, f"{THcommand} MoveToLevel with Level field set to startCurrentLevel, TransitionTime field set to 150 (15s) and remaining fields set to 0", test_plan_support.verify_success()), TestStep(19, "Wait for 20 seconds"), TestStep(20, "TH verifies reportedRemainingTimeValuesList contains three entries", "reportedRemainingTimeValuesList has 3 entries in the list"), - TestStep(21, "TH verifies the first entry in reportedRemainingTimeValuesList is 10", - "The first entry in reportedRemainingTimeValuesList is equal to 10"), - TestStep(22, "TH verifies the second entry in reportedRemainingTimeValuesList is 15", - "The second entry in reportedRemainingTimeValuesList is equal to 15"), + TestStep(21, "TH verifies the first entry in reportedRemainingTimeValuesList is approximately 100 (10s)", + "The first entry in reportedRemainingTimeValuesList is approximately equal to 100"), + TestStep(22, "TH verifies the second entry in reportedRemainingTimeValuesList is approximately 150", + "The second entry in reportedRemainingTimeValuesList is approximately equal to 150"), TestStep(23, "TH verifies the third entry in reportedRemainingTimeValuesList is 0", "The third entry in reportedRemainingTimeValuesList is equal to 0") ] @@ -127,6 +127,8 @@ async def test_TC_LVL_2_3(self): if count == 1: entry = sub_handler.attribute_reports[lvl.Attributes.CurrentLevel][-1] asserts.assert_equal(entry.value, max_level, "Entry is not equal to max level") + else: + self.mark_current_step_skipped() if count > 1: self.step(11) @@ -173,7 +175,7 @@ async def test_TC_LVL_2_3(self): self.step(21) remaining_time = sub_handler.attribute_reports[lvl.Attributes.RemainingTime] logging.info(f'Reamining time reports: {remaining_time}') - asserts.assert_equal(remaining_time[0].value, 100, "Unexpected first RemainingTime report") + asserts.assert_almost_equal(remaining_time[0].value, 100, delta=10, msg="Unexpected first RemainingTime report") self.step(22) asserts.assert_almost_equal(remaining_time[1].value, 150, delta=10, msg="Unexpected second RemainingTime report") From 1a7d048d75fdab47e39d828fcb2ea57fb63dccba Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 1 Aug 2024 03:35:42 +0900 Subject: [PATCH 02/21] [Darwin] Implement MTREventNameForID function (#34653) * Implement MTREventNameForID in darwin * Restyled by whitespace --------- Co-authored-by: Restyled.io --- src/darwin/Framework/CHIP/MTRClusterNames.h | 9 + .../CHIP/templates/MTRClusterNames-src.zapt | 56 + .../CHIP/zap-generated/MTRClusterNames.mm | 1854 +++++++++++++++++ 3 files changed, 1919 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRClusterNames.h b/src/darwin/Framework/CHIP/MTRClusterNames.h index 379757b5bd4a06..c13edf44e574b2 100644 --- a/src/darwin/Framework/CHIP/MTRClusterNames.h +++ b/src/darwin/Framework/CHIP/MTRClusterNames.h @@ -41,3 +41,12 @@ MTR_EXTERN MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) NSSt * will be returned. */ MTR_EXTERN MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) NSString * MTRAttributeNameForID(MTRClusterIDType clusterID, MTRAttributeIDType attributeID); + +/** + * Resolve Matter event IDs into a descriptive string. + * + * For unknown IDs, a string '' (if the cluster ID is not known) + * or '' (if the cluster ID is known but the event ID is not known) + * will be returned. + */ +MTR_EXTERN MTR_NEWLY_AVAILABLE NSString * MTREventNameForID(MTRClusterIDType clusterID, MTREventIDType eventID); diff --git a/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt index b495d79b1b4c72..1c18b6a2489b2a 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt @@ -75,6 +75,62 @@ NSString * MTRAttributeNameForID(MTRClusterIDType clusterID, MTRAttributeIDType result = [NSString stringWithFormat:@"", attributeID]; break; } + break; +{{/if}} + +{{/zcl_clusters}} + default: + result = [NSString stringWithFormat:@"", clusterID]; + break; + } + + return result; +} + + +#pragma mark - Event IDs + +NSString * MTREventNameForID(MTRClusterIDType clusterID, MTREventIDType eventID) +{ + NSString * result = nil; + + switch (clusterID) { + +{{#zcl_clusters}} +{{#if (isSupported (asUpperCamelCase label preserveAcronyms=true) isForIds=true)}} +{{~#*inline "cluster"}}{{asUpperCamelCase label preserveAcronyms=true}}{{/inline~}} + case MTRClusterIDType{{>cluster}}ID: + + switch (eventID) { + +{{/if}} + +{{#*inline "eventIDs"}} +{{#zcl_events}} +{{~#*inline "cluster"}}{{asUpperCamelCase ../clusterName preserveAcronyms=true}}{{/inline~}} +{{~#*inline "event"}}{{asUpperCamelCase name preserveAcronyms=true}}{{/inline~}} +{{#first}} +{{#if (isSupported (asUpperCamelCase ../clusterName preserveAcronyms=true) isForIds=true)}} +// Cluster {{> cluster}} events +{{/if}} +{{/first}} +{{#if (isSupported (asUpperCamelCase ../clusterName preserveAcronyms=true) event=(asUpperCamelCase name preserveAcronyms=true) isForIds=true)}} + case MTREventIDTypeCluster{{>cluster}}Event{{>event}}ID: + result = @"{{>event}}"; + break; + +{{/if}} +{{/zcl_events}} +{{/inline}} + +{{> eventIDs clusterName=label}} + +{{#if (isSupported (asUpperCamelCase label preserveAcronyms=true) isForIds=true)}} + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; {{/if}} {{/zcl_clusters}} diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 406d253ba5fb00..a46ab76ca9cc17 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -451,6 +451,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGroupsID: @@ -489,6 +490,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOnOffID: @@ -543,6 +545,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOnOffSwitchConfigurationID: @@ -585,6 +588,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLevelControlID: @@ -675,6 +679,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBinaryInputBasicID: @@ -745,6 +750,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePulseWidthModulationID: @@ -779,6 +785,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDescriptorID: @@ -833,6 +840,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBindingID: @@ -871,6 +879,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAccessControlID: @@ -933,6 +942,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeActionsID: @@ -979,6 +989,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBasicInformationID: @@ -1105,6 +1116,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOTASoftwareUpdateProviderID: @@ -1139,6 +1151,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOTASoftwareUpdateRequestorID: @@ -1189,6 +1202,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLocalizationConfigurationID: @@ -1231,6 +1245,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTimeFormatLocalizationID: @@ -1277,6 +1292,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeUnitLocalizationID: @@ -1315,6 +1331,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePowerSourceConfigurationID: @@ -1353,6 +1370,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePowerSourceID: @@ -1515,6 +1533,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGeneralCommissioningID: @@ -1585,6 +1604,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeNetworkCommissioningID: @@ -1663,6 +1683,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDiagnosticLogsID: @@ -1697,6 +1718,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGeneralDiagnosticsID: @@ -1767,6 +1789,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSoftwareDiagnosticsID: @@ -1817,6 +1840,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThreadNetworkDiagnosticsID: @@ -2103,6 +2127,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWiFiNetworkDiagnosticsID: @@ -2189,6 +2214,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEthernetNetworkDiagnosticsID: @@ -2259,6 +2285,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTimeSynchronizationID: @@ -2345,6 +2372,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBridgedDeviceBasicInformationID: @@ -2443,6 +2471,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSwitchID: @@ -2489,6 +2518,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAdministratorCommissioningID: @@ -2535,6 +2565,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOperationalCredentialsID: @@ -2593,6 +2624,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGroupKeyManagementID: @@ -2643,6 +2675,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFixedLabelID: @@ -2681,6 +2714,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeUserLabelID: @@ -2719,6 +2753,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBooleanStateID: @@ -2757,6 +2792,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeICDManagementID: @@ -2831,6 +2867,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTimerID: @@ -2877,6 +2914,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOvenCavityOperationalStateID: @@ -2935,6 +2973,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOvenModeID: @@ -2985,6 +3024,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLaundryDryerControlsID: @@ -3027,6 +3067,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeModeSelectID: @@ -3085,6 +3126,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLaundryWasherModeID: @@ -3135,6 +3177,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID: @@ -3185,6 +3228,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLaundryWasherControlsID: @@ -3235,6 +3279,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRVCRunModeID: @@ -3277,6 +3322,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRVCCleanModeID: @@ -3319,6 +3365,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTemperatureControlID: @@ -3377,6 +3424,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRefrigeratorAlarmID: @@ -3423,6 +3471,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDishwasherModeID: @@ -3473,6 +3522,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAirQualityID: @@ -3511,6 +3561,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSmokeCOAlarmID: @@ -3597,6 +3648,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDishwasherAlarmID: @@ -3647,6 +3699,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMicrowaveOvenModeID: @@ -3689,6 +3742,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMicrowaveOvenControlID: @@ -3759,6 +3813,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOperationalStateID: @@ -3817,6 +3872,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRVCOperationalStateID: @@ -3875,6 +3931,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeScenesManagementID: @@ -3921,6 +3978,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeHEPAFilterMonitoringID: @@ -3979,6 +4037,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeActivatedCarbonFilterMonitoringID: @@ -4037,6 +4096,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBooleanStateConfigurationID: @@ -4103,6 +4163,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeValveConfigurationAndControlID: @@ -4181,6 +4242,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeElectricalPowerMeasurementID: @@ -4291,6 +4353,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeElectricalEnergyMeasurementID: @@ -4349,6 +4412,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWaterHeaterManagementID: @@ -4407,6 +4471,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDemandResponseLoadControlID: @@ -4473,6 +4538,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMessagesID: @@ -4515,6 +4581,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDeviceEnergyManagementID: @@ -4581,6 +4648,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEnergyEVSEID: @@ -4707,6 +4775,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEnergyPreferenceID: @@ -4761,6 +4830,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePowerTopologyID: @@ -4803,6 +4873,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEnergyEVSEModeID: @@ -4853,6 +4924,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWaterHeaterModeID: @@ -4903,6 +4975,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDeviceEnergyManagementModeID: @@ -4953,6 +5026,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDoorLockID: @@ -5167,6 +5241,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWindowCoveringID: @@ -5289,6 +5364,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBarrierControlID: @@ -5363,6 +5439,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeServiceAreaID: @@ -5421,6 +5498,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePumpConfigurationAndControlID: @@ -5547,6 +5625,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThermostatID: @@ -5825,6 +5904,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFanControlID: @@ -5907,6 +5987,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThermostatUserInterfaceConfigurationID: @@ -5953,6 +6034,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeColorControlID: @@ -6195,6 +6277,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBallastConfigurationID: @@ -6285,6 +6368,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeIlluminanceMeasurementID: @@ -6339,6 +6423,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTemperatureMeasurementID: @@ -6389,6 +6474,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePressureMeasurementID: @@ -6459,6 +6545,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFlowMeasurementID: @@ -6509,6 +6596,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRelativeHumidityMeasurementID: @@ -6559,6 +6647,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOccupancySensingID: @@ -6649,6 +6738,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID: @@ -6727,6 +6817,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID: @@ -6805,6 +6896,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID: @@ -6883,6 +6975,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOzoneConcentrationMeasurementID: @@ -6961,6 +7054,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePM25ConcentrationMeasurementID: @@ -7039,6 +7133,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFormaldehydeConcentrationMeasurementID: @@ -7117,6 +7212,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePM1ConcentrationMeasurementID: @@ -7195,6 +7291,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePM10ConcentrationMeasurementID: @@ -7273,6 +7370,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID: @@ -7351,6 +7449,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRadonConcentrationMeasurementID: @@ -7429,6 +7528,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWiFiNetworkManagementID: @@ -7471,6 +7571,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThreadBorderRouterManagementID: @@ -7525,6 +7626,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThreadNetworkDirectoryID: @@ -7571,6 +7673,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWakeOnLANID: @@ -7613,6 +7716,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeChannelID: @@ -7659,6 +7763,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTargetNavigatorID: @@ -7701,6 +7806,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMediaPlaybackID: @@ -7779,6 +7885,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMediaInputID: @@ -7821,6 +7928,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLowPowerID: @@ -7855,6 +7963,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeKeypadInputID: @@ -7889,6 +7998,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeContentLauncherID: @@ -7931,6 +8041,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAudioOutputID: @@ -7973,6 +8084,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeApplicationLauncherID: @@ -8015,6 +8127,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeApplicationBasicID: @@ -8081,6 +8194,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAccountLoginID: @@ -8115,6 +8229,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeContentControlID: @@ -8181,6 +8296,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeContentAppObserverID: @@ -8215,6 +8331,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEcosystemInformationID: @@ -8261,6 +8378,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeCommissionerControlID: @@ -8299,6 +8417,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeElectricalMeasurementID: @@ -8845,6 +8964,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeUnitTestingID: @@ -9211,6 +9331,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSampleMEIID: @@ -9249,6 +9370,1739 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; + + default: + result = [NSString stringWithFormat:@"", clusterID]; + break; + } + + return result; +} + +#pragma mark - Event IDs + +NSString * MTREventNameForID(MTRClusterIDType clusterID, MTREventIDType eventID) +{ + NSString * result = nil; + + switch (clusterID) { + + case MTRClusterIDTypeIdentifyID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGroupsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOnOffID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOnOffSwitchConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLevelControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBinaryInputBasicID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePulseWidthModulationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDescriptorID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBindingID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAccessControlID: + + switch (eventID) { + + // Cluster AccessControl events + case MTREventIDTypeClusterAccessControlEventAccessControlEntryChangedID: + result = @"AccessControlEntryChanged"; + break; + + case MTREventIDTypeClusterAccessControlEventAccessControlExtensionChangedID: + result = @"AccessControlExtensionChanged"; + break; + + case MTREventIDTypeClusterAccessControlEventAccessRestrictionEntryChangedID: + result = @"AccessRestrictionEntryChanged"; + break; + + case MTREventIDTypeClusterAccessControlEventFabricRestrictionReviewUpdateID: + result = @"FabricRestrictionReviewUpdate"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeActionsID: + + switch (eventID) { + + // Cluster Actions events + case MTREventIDTypeClusterActionsEventStateChangedID: + result = @"StateChanged"; + break; + + case MTREventIDTypeClusterActionsEventActionFailedID: + result = @"ActionFailed"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBasicInformationID: + + switch (eventID) { + + // Cluster BasicInformation events + case MTREventIDTypeClusterBasicInformationEventStartUpID: + result = @"StartUp"; + break; + + case MTREventIDTypeClusterBasicInformationEventShutDownID: + result = @"ShutDown"; + break; + + case MTREventIDTypeClusterBasicInformationEventLeaveID: + result = @"Leave"; + break; + + case MTREventIDTypeClusterBasicInformationEventReachableChangedID: + result = @"ReachableChanged"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOTASoftwareUpdateProviderID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOTASoftwareUpdateRequestorID: + + switch (eventID) { + + // Cluster OTASoftwareUpdateRequestor events + case MTREventIDTypeClusterOTASoftwareUpdateRequestorEventStateTransitionID: + result = @"StateTransition"; + break; + + case MTREventIDTypeClusterOTASoftwareUpdateRequestorEventVersionAppliedID: + result = @"VersionApplied"; + break; + + case MTREventIDTypeClusterOTASoftwareUpdateRequestorEventDownloadErrorID: + result = @"DownloadError"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLocalizationConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTimeFormatLocalizationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeUnitLocalizationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePowerSourceConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePowerSourceID: + + switch (eventID) { + + // Cluster PowerSource events + case MTREventIDTypeClusterPowerSourceEventWiredFaultChangeID: + result = @"WiredFaultChange"; + break; + + case MTREventIDTypeClusterPowerSourceEventBatFaultChangeID: + result = @"BatFaultChange"; + break; + + case MTREventIDTypeClusterPowerSourceEventBatChargeFaultChangeID: + result = @"BatChargeFaultChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGeneralCommissioningID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeNetworkCommissioningID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDiagnosticLogsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGeneralDiagnosticsID: + + switch (eventID) { + + // Cluster GeneralDiagnostics events + case MTREventIDTypeClusterGeneralDiagnosticsEventHardwareFaultChangeID: + result = @"HardwareFaultChange"; + break; + + case MTREventIDTypeClusterGeneralDiagnosticsEventRadioFaultChangeID: + result = @"RadioFaultChange"; + break; + + case MTREventIDTypeClusterGeneralDiagnosticsEventNetworkFaultChangeID: + result = @"NetworkFaultChange"; + break; + + case MTREventIDTypeClusterGeneralDiagnosticsEventBootReasonID: + result = @"BootReason"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSoftwareDiagnosticsID: + + switch (eventID) { + + // Cluster SoftwareDiagnostics events + case MTREventIDTypeClusterSoftwareDiagnosticsEventSoftwareFaultID: + result = @"SoftwareFault"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThreadNetworkDiagnosticsID: + + switch (eventID) { + + // Cluster ThreadNetworkDiagnostics events + case MTREventIDTypeClusterThreadNetworkDiagnosticsEventConnectionStatusID: + result = @"ConnectionStatus"; + break; + + case MTREventIDTypeClusterThreadNetworkDiagnosticsEventNetworkFaultChangeID: + result = @"NetworkFaultChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWiFiNetworkDiagnosticsID: + + switch (eventID) { + + // Cluster WiFiNetworkDiagnostics events + case MTREventIDTypeClusterWiFiNetworkDiagnosticsEventDisconnectionID: + result = @"Disconnection"; + break; + + case MTREventIDTypeClusterWiFiNetworkDiagnosticsEventAssociationFailureID: + result = @"AssociationFailure"; + break; + + case MTREventIDTypeClusterWiFiNetworkDiagnosticsEventConnectionStatusID: + result = @"ConnectionStatus"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEthernetNetworkDiagnosticsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTimeSynchronizationID: + + switch (eventID) { + + // Cluster TimeSynchronization events + case MTREventIDTypeClusterTimeSynchronizationEventDSTTableEmptyID: + result = @"DSTTableEmpty"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventDSTStatusID: + result = @"DSTStatus"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventTimeZoneStatusID: + result = @"TimeZoneStatus"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventTimeFailureID: + result = @"TimeFailure"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventMissingTrustedTimeSourceID: + result = @"MissingTrustedTimeSource"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBridgedDeviceBasicInformationID: + + switch (eventID) { + + // Cluster BridgedDeviceBasicInformation events + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventStartUpID: + result = @"StartUp"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventShutDownID: + result = @"ShutDown"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventLeaveID: + result = @"Leave"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventReachableChangedID: + result = @"ReachableChanged"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventActiveChangedID: + result = @"ActiveChanged"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSwitchID: + + switch (eventID) { + + // Cluster Switch events + case MTREventIDTypeClusterSwitchEventSwitchLatchedID: + result = @"SwitchLatched"; + break; + + case MTREventIDTypeClusterSwitchEventInitialPressID: + result = @"InitialPress"; + break; + + case MTREventIDTypeClusterSwitchEventLongPressID: + result = @"LongPress"; + break; + + case MTREventIDTypeClusterSwitchEventShortReleaseID: + result = @"ShortRelease"; + break; + + case MTREventIDTypeClusterSwitchEventLongReleaseID: + result = @"LongRelease"; + break; + + case MTREventIDTypeClusterSwitchEventMultiPressOngoingID: + result = @"MultiPressOngoing"; + break; + + case MTREventIDTypeClusterSwitchEventMultiPressCompleteID: + result = @"MultiPressComplete"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAdministratorCommissioningID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOperationalCredentialsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGroupKeyManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFixedLabelID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeUserLabelID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBooleanStateID: + + switch (eventID) { + + // Cluster BooleanState events + case MTREventIDTypeClusterBooleanStateEventStateChangeID: + result = @"StateChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeICDManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTimerID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOvenCavityOperationalStateID: + + switch (eventID) { + + // Cluster OvenCavityOperationalState events + case MTREventIDTypeClusterOvenCavityOperationalStateEventOperationalErrorID: + result = @"OperationalError"; + break; + + case MTREventIDTypeClusterOvenCavityOperationalStateEventOperationCompletionID: + result = @"OperationCompletion"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOvenModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLaundryDryerControlsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeModeSelectID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLaundryWasherModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLaundryWasherControlsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRVCRunModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRVCCleanModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTemperatureControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRefrigeratorAlarmID: + + switch (eventID) { + + // Cluster RefrigeratorAlarm events + case MTREventIDTypeClusterRefrigeratorAlarmEventNotifyID: + result = @"Notify"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDishwasherModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAirQualityID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSmokeCOAlarmID: + + switch (eventID) { + + // Cluster SmokeCOAlarm events + case MTREventIDTypeClusterSmokeCOAlarmEventSmokeAlarmID: + result = @"SmokeAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventCOAlarmID: + result = @"COAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventLowBatteryID: + result = @"LowBattery"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventHardwareFaultID: + result = @"HardwareFault"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventEndOfServiceID: + result = @"EndOfService"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventSelfTestCompleteID: + result = @"SelfTestComplete"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventAlarmMutedID: + result = @"AlarmMuted"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventMuteEndedID: + result = @"MuteEnded"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventInterconnectSmokeAlarmID: + result = @"InterconnectSmokeAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventInterconnectCOAlarmID: + result = @"InterconnectCOAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventAllClearID: + result = @"AllClear"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDishwasherAlarmID: + + switch (eventID) { + + // Cluster DishwasherAlarm events + case MTREventIDTypeClusterDishwasherAlarmEventNotifyID: + result = @"Notify"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMicrowaveOvenModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMicrowaveOvenControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOperationalStateID: + + switch (eventID) { + + // Cluster OperationalState events + case MTREventIDTypeClusterOperationalStateEventOperationalErrorID: + result = @"OperationalError"; + break; + + case MTREventIDTypeClusterOperationalStateEventOperationCompletionID: + result = @"OperationCompletion"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRVCOperationalStateID: + + switch (eventID) { + + // Cluster RVCOperationalState events + case MTREventIDTypeClusterRVCOperationalStateEventOperationalErrorID: + result = @"OperationalError"; + break; + + case MTREventIDTypeClusterRVCOperationalStateEventOperationCompletionID: + result = @"OperationCompletion"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeScenesManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeHEPAFilterMonitoringID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeActivatedCarbonFilterMonitoringID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBooleanStateConfigurationID: + + switch (eventID) { + + // Cluster BooleanStateConfiguration events + case MTREventIDTypeClusterBooleanStateConfigurationEventAlarmsStateChangedID: + result = @"AlarmsStateChanged"; + break; + + case MTREventIDTypeClusterBooleanStateConfigurationEventSensorFaultID: + result = @"SensorFault"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeValveConfigurationAndControlID: + + switch (eventID) { + + // Cluster ValveConfigurationAndControl events + case MTREventIDTypeClusterValveConfigurationAndControlEventValveStateChangedID: + result = @"ValveStateChanged"; + break; + + case MTREventIDTypeClusterValveConfigurationAndControlEventValveFaultID: + result = @"ValveFault"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeElectricalPowerMeasurementID: + + switch (eventID) { + + // Cluster ElectricalPowerMeasurement events + case MTREventIDTypeClusterElectricalPowerMeasurementEventMeasurementPeriodRangesID: + result = @"MeasurementPeriodRanges"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeElectricalEnergyMeasurementID: + + switch (eventID) { + + // Cluster ElectricalEnergyMeasurement events + case MTREventIDTypeClusterElectricalEnergyMeasurementEventCumulativeEnergyMeasuredID: + result = @"CumulativeEnergyMeasured"; + break; + + case MTREventIDTypeClusterElectricalEnergyMeasurementEventPeriodicEnergyMeasuredID: + result = @"PeriodicEnergyMeasured"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWaterHeaterManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDemandResponseLoadControlID: + + switch (eventID) { + + // Cluster DemandResponseLoadControl events + case MTREventIDTypeClusterDemandResponseLoadControlEventLoadControlEventStatusChangeID: + result = @"LoadControlEventStatusChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMessagesID: + + switch (eventID) { + + // Cluster Messages events + case MTREventIDTypeClusterMessagesEventMessageQueuedID: + result = @"MessageQueued"; + break; + + case MTREventIDTypeClusterMessagesEventMessagePresentedID: + result = @"MessagePresented"; + break; + + case MTREventIDTypeClusterMessagesEventMessageCompleteID: + result = @"MessageComplete"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDeviceEnergyManagementID: + + switch (eventID) { + + // Cluster DeviceEnergyManagement events + case MTREventIDTypeClusterDeviceEnergyManagementEventPowerAdjustStartID: + result = @"PowerAdjustStart"; + break; + + case MTREventIDTypeClusterDeviceEnergyManagementEventPowerAdjustEndID: + result = @"PowerAdjustEnd"; + break; + + case MTREventIDTypeClusterDeviceEnergyManagementEventPausedID: + result = @"Paused"; + break; + + case MTREventIDTypeClusterDeviceEnergyManagementEventResumedID: + result = @"Resumed"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEnergyEVSEID: + + switch (eventID) { + + // Cluster EnergyEVSE events + case MTREventIDTypeClusterEnergyEVSEEventEVConnectedID: + result = @"EVConnected"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventEVNotDetectedID: + result = @"EVNotDetected"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventEnergyTransferStartedID: + result = @"EnergyTransferStarted"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventEnergyTransferStoppedID: + result = @"EnergyTransferStopped"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventFaultID: + result = @"Fault"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventRFIDID: + result = @"RFID"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEnergyPreferenceID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePowerTopologyID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEnergyEVSEModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWaterHeaterModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDeviceEnergyManagementModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDoorLockID: + + switch (eventID) { + + // Cluster DoorLock events + case MTREventIDTypeClusterDoorLockEventDoorLockAlarmID: + result = @"DoorLockAlarm"; + break; + + case MTREventIDTypeClusterDoorLockEventDoorStateChangeID: + result = @"DoorStateChange"; + break; + + case MTREventIDTypeClusterDoorLockEventLockOperationID: + result = @"LockOperation"; + break; + + case MTREventIDTypeClusterDoorLockEventLockOperationErrorID: + result = @"LockOperationError"; + break; + + case MTREventIDTypeClusterDoorLockEventLockUserChangeID: + result = @"LockUserChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWindowCoveringID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBarrierControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeServiceAreaID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePumpConfigurationAndControlID: + + switch (eventID) { + + // Cluster PumpConfigurationAndControl events + case MTREventIDTypeClusterPumpConfigurationAndControlEventSupplyVoltageLowID: + result = @"SupplyVoltageLow"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSupplyVoltageHighID: + result = @"SupplyVoltageHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventPowerMissingPhaseID: + result = @"PowerMissingPhase"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSystemPressureLowID: + result = @"SystemPressureLow"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSystemPressureHighID: + result = @"SystemPressureHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventDryRunningID: + result = @"DryRunning"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventMotorTemperatureHighID: + result = @"MotorTemperatureHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventPumpMotorFatalFailureID: + result = @"PumpMotorFatalFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventElectronicTemperatureHighID: + result = @"ElectronicTemperatureHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventPumpBlockedID: + result = @"PumpBlocked"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSensorFailureID: + result = @"SensorFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventElectronicNonFatalFailureID: + result = @"ElectronicNonFatalFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventElectronicFatalFailureID: + result = @"ElectronicFatalFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventGeneralFaultID: + result = @"GeneralFault"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventLeakageID: + result = @"Leakage"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventAirDetectionID: + result = @"AirDetection"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventTurbineOperationID: + result = @"TurbineOperation"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThermostatID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFanControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThermostatUserInterfaceConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeColorControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBallastConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeIlluminanceMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTemperatureMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePressureMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFlowMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRelativeHumidityMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOccupancySensingID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOzoneConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePM25ConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFormaldehydeConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePM1ConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePM10ConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRadonConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWiFiNetworkManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThreadBorderRouterManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThreadNetworkDirectoryID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWakeOnLANID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeChannelID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTargetNavigatorID: + + switch (eventID) { + + // Cluster TargetNavigator events + case MTREventIDTypeClusterTargetNavigatorEventTargetUpdatedID: + result = @"TargetUpdated"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMediaPlaybackID: + + switch (eventID) { + + // Cluster MediaPlayback events + case MTREventIDTypeClusterMediaPlaybackEventStateChangedID: + result = @"StateChanged"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMediaInputID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLowPowerID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeKeypadInputID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeContentLauncherID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAudioOutputID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeApplicationLauncherID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeApplicationBasicID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAccountLoginID: + + switch (eventID) { + + // Cluster AccountLogin events + case MTREventIDTypeClusterAccountLoginEventLoggedOutID: + result = @"LoggedOut"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeContentControlID: + + switch (eventID) { + + // Cluster ContentControl events + case MTREventIDTypeClusterContentControlEventRemainingScreenTimeExpiredID: + result = @"RemainingScreenTimeExpired"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeContentAppObserverID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEcosystemInformationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeCommissionerControlID: + + switch (eventID) { + + // Cluster CommissionerControl events + case MTREventIDTypeClusterCommissionerControlEventCommissioningRequestResultID: + result = @"CommissioningRequestResult"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeElectricalMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeUnitTestingID: + + switch (eventID) { + + // Cluster UnitTesting events + case MTREventIDTypeClusterUnitTestingEventTestEventID: + result = @"TestEvent"; + break; + + case MTREventIDTypeClusterUnitTestingEventTestFabricScopedEventID: + result = @"TestFabricScopedEvent"; + break; + + case MTREventIDTypeClusterUnitTestingEventTestDifferentVendorMeiEventID: + result = @"TestDifferentVendorMeiEvent"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSampleMEIID: + + switch (eventID) { + + // Cluster SampleMEI events + case MTREventIDTypeClusterSampleMEIEventPingCountEventID: + result = @"PingCountEvent"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; default: result = [NSString stringWithFormat:@"", clusterID]; From f2f3d0eb03ba5bea32b22f19982c402a8c1c9063 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Wed, 31 Jul 2024 15:06:04 -0400 Subject: [PATCH 03/21] Add TC_MCORE_FS_1_3.py test implementation (#34650) --- src/python_testing/TC_MCORE_FS_1_3.py | 175 ++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/python_testing/TC_MCORE_FS_1_3.py diff --git a/src/python_testing/TC_MCORE_FS_1_3.py b/src/python_testing/TC_MCORE_FS_1_3.py new file mode 100644 index 00000000000000..791d3785f28395 --- /dev/null +++ b/src/python_testing/TC_MCORE_FS_1_3.py @@ -0,0 +1,175 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This test requires a TH_SERVER application that returns UnsupportedAttribute when reading UniqueID from BasicInformation Cluster. Please specify with --string-arg th_server_app_path: + +import logging +import os +import random +import signal +import subprocess +import time +import uuid + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.interaction_model import Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + + +class TC_MCORE_FS_1_3(MatterBaseTest): + @async_test_body + async def setup_class(self): + super().setup_class() + self.device_for_th_eco_nodeid = 1111 + self.device_for_th_eco_kvs = None + self.device_for_th_eco_port = 5543 + self.app_process_for_th_eco = None + + self.device_for_dut_eco_nodeid = 1112 + self.device_for_dut_eco_kvs = None + self.device_for_dut_eco_port = 5544 + self.app_process_for_dut_eco = None + + # Create a second controller on a new fabric to communicate to the server + new_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() + new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=2) + paa_path = str(self.matter_test_config.paa_trust_store_path) + self.TH_server_controller = new_fabric_admin.NewController(nodeId=112233, paaTrustStorePath=paa_path) + + def teardown_class(self): + if self.app_process_for_dut_eco is not None: + logging.warning("Stopping app with SIGTERM") + self.app_process_for_dut_eco.send_signal(signal.SIGTERM.value) + self.app_process_for_dut_eco.wait() + if self.app_process_for_th_eco is not None: + logging.warning("Stopping app with SIGTERM") + self.app_process_for_th_eco.send_signal(signal.SIGTERM.value) + self.app_process_for_th_eco.wait() + + os.remove(self.device_for_dut_eco_kvs) + if self.device_for_th_eco_kvs is not None: + os.remove(self.device_for_th_eco_kvs) + super().teardown_class() + + async def create_device_and_commission_to_th_fabric(self, kvs, port, node_id_for_th, device_info): + # TODO: confirm whether we can open processes like this on the TH + app = self.user_params.get("th_server_app_path", None) + if not app: + asserts.fail('This test requires a TH_SERVER app. Specify app path with --string-arg th_server_app_path:') + + discriminator = random.randint(0, 4095) + passcode = 20202021 + app_args = f'--secured-device-port {port} --discriminator {discriminator} --passcode {passcode} --KVS {kvs}' + cmd = f'{app} {app_args}' + # TODO: Determine if we want these logs cooked or pushed to somewhere else + logging.info(f"Starting TH device for {device_info}") + self.app_process_for_dut_eco = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info(f"Started TH device for {device_info}") + time.sleep(3) + + logging.info("Commissioning from separate fabric") + await self.TH_server_controller.CommissionOnNetwork(nodeId=node_id_for_th, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + logging.info("Commissioning device for DUT ecosystem onto TH for managing") + + async def create_and_commission_device_for_th_ecosystem(self): + # TODO: confirm whether we can open processes like this on the TH + app = self.user_params.get("th_server_app_path", None) + + self.device_for_th_eco_kvs = f'kvs_{str(uuid.uuid4())}' + discriminator = random.randint(0, 4095) + passcode = 20202021 + app_args = f'--secured-device-port {self.device_for_th_eco_port} --discriminator {discriminator} --passcode {passcode} --KVS {self.device_for_th_eco_kvs}' + cmd = f'{app} {app_args}' + # TODO: Determine if we want these logs cooked or pushed to somewhere else + logging.info("Starting TH device for TH ecosystem") + self.app_process_for_th_eco = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info("Started TH device for TH ecosystem") + time.sleep(3) + + logging.info("Commissioning from separate fabric") + self.server_nodeid = 1112 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.server_nodeid, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + logging.info("Commissioning TH device for TH ecosystem") + + def steps_TC_MCORE_FS_1_3(self) -> list[TestStep]: + steps = [TestStep(1, "DUT_FSA commissions TH_SED_DUT to DUT_FSAs fabric and generates a UniqueID", is_commissioning=True), + TestStep(2, "TH_FSA commissions TH_SED_TH onto TH_FSAs fabric and generates a UniqueID."), + TestStep(3, "Follow manufacturer provided instructions to enable DUT_FSA to synchronize TH_SED_TH onto DUT_FSAs fabric."), + TestStep(4, "DUT_FSA synchronizes TH_SED_TH onto DUT_FSAs fabric and copies the UniqueID presented by TH_FSAs Bridged Device Basic Information Cluster.")] + return steps + + @async_test_body + async def test_TC_MCORE_FS_1_3(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + self.print_step(0, "Commissioning DUT to TH, already done") + self.step(1) + # These steps are not explicitly in step 1, but they help identify the dynamically added endpoint in step 1. + root_node_endpoint = 0 + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=root_node_endpoint) + set_of_endpoints_before_adding_device = set(root_part_list) + + kvs = f'kvs_{str(uuid.uuid4())}' + device_info = "for DUT ecosystem" + await self.create_device_and_commission_to_th_fabric(kvs, self.device_for_dut_eco_port, self.device_for_dut_eco_nodeid, device_info) + self.device_for_dut_eco_kvs = kvs + read_result = await self.TH_server_controller.ReadAttribute(self.device_for_dut_eco_nodeid, [(root_node_endpoint, Clusters.BasicInformation.Attributes.UniqueID)]) + result = read_result[root_node_endpoint][Clusters.BasicInformation][Clusters.BasicInformation.Attributes.UniqueID] + asserts.assert_true(type_matches(result, Clusters.Attribute.ValueDecodeFailure), "We were expecting a value decode failure") + asserts.assert_equal(result.Reason.status, Status.UnsupportedAttribute, "Incorrect error returned from reading UniqueID") + + params = await self.openCommissioningWindow(dev_ctrl=self.TH_server_controller, node_id=self.device_for_dut_eco_nodeid) + + self.wait_for_user_input( + prompt_msg=f"Using the DUT vendor's provided interface, commission the device using the following parameters:\n" + f"- discriminator: {params.randomDiscriminator}\n" + f"- setupPinCode: {params.commissioningParameters.setupPinCode}\n" + f"- setupQRCode: {params.commissioningParameters.setupQRCode}\n" + f"- setupManualcode: {params.commissioningParameters.setupManualCode}\n" + f"If using FabricSync Admin, you may type:\n" + f">>> pairing onnetwork {params.commissioningParameters.setupPinCode}") + + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=root_node_endpoint) + set_of_endpoints_after_adding_device = set(root_part_list) + + asserts.assert_true(set_of_endpoints_after_adding_device.issuperset( + set_of_endpoints_before_adding_device), "Expected only new endpoints to be added") + unique_endpoints_set = set_of_endpoints_after_adding_device - set_of_endpoints_before_adding_device + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") + newly_added_endpoint = list(unique_endpoints_set)[0] + + th_sed_dut_unique_id = await self.read_single_attribute_check_success(cluster=Clusters.BridgedDeviceBasicInformation, attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, endpoint=newly_added_endpoint) + asserts.assert_true(type_matches(th_sed_dut_unique_id, str), "UniqueID should be a string") + asserts.assert_true(th_sed_dut_unique_id, "UniqueID should not be an empty string") + + self.step(2) + kvs = f'kvs_{str(uuid.uuid4())}' + device_info = "for TH_FSA ecosystem" + await self.create_device_and_commission_to_th_fabric(kvs, self.device_for_th_eco_port, self.device_for_th_eco_nodeid, device_info) + self.device_for_th_eco_kvs = kvs + # TODO(https://github.com/CHIP-Specifications/chip-test-plans/issues/4375) During setup we need to create the TH_FSA device + # where we would commission device created in create_device_and_commission_to_th_fabric to be commissioned into TH_FSA. + + # TODO(https://github.com/CHIP-Specifications/chip-test-plans/issues/4375) Because we cannot create a TH_FSA and there is + # no way to mock it the following 2 test steps are skipped for now. + self.skip_step(3) + self.skip_step(4) + + +if __name__ == "__main__": + default_matter_test_main() From fbbcc7d9b6ec580a6c2c14c1d9c7f4386e5a1552 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Wed, 31 Jul 2024 15:37:08 -0400 Subject: [PATCH 04/21] Fix most TC-SWTCH-2.4 remaining issues (#34677) - Move 2.4 in a better place in the file - Add test steps properly - Allow default button press position override Issue #34656 Testing done: - Test still passes on DUT with automation --- src/python_testing/TC_SWTCH.py | 255 +++++++++++++++++---------------- 1 file changed, 132 insertions(+), 123 deletions(-) diff --git a/src/python_testing/TC_SWTCH.py b/src/python_testing/TC_SWTCH.py index 6da5c7a229e0b7..08bf23d91c30d4 100644 --- a/src/python_testing/TC_SWTCH.py +++ b/src/python_testing/TC_SWTCH.py @@ -45,22 +45,28 @@ logger = logging.getLogger(__name__) -class TC_SwitchTests(MatterBaseTest): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) +def bump_substep(step: str) -> str: + """Given a string like "5a", bump it to "5b", or "6c" to "6d" """ + if len(step) == 0: + raise ValueError("Can't bump empty steps!") - def desc_TC_SWTCH_2_4(self) -> str: - """Returns a description of this test""" - return "[TC-SWTCH-2.4] Momentary Switch Long Press Verification" + end_char = step[-1] + if not end_char.isalpha(): + return step + "a" - # TODO(#34656): Fill test steps - # def steps_TC_SWTCH_2_4(self) -> list[TestStep]: - # steps = [ - # TestStep("0", "Commissioning, already done", is_commissioning=True), - # # TODO: fill when test is done - # ] + step_prefix = step[:-1] + next_end_char = chr(ord(end_char) + 1) + if ord(next_end_char) > ord('z'): + raise ValueError(f"Reached max substep for step '{step}'") + next_step = step_prefix + next_end_char - # return steps + return next_step + + +class TC_SwitchTests(MatterBaseTest): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._default_pressed_position = self.user_params.get("default_pressed_position", 1) def _send_named_pipe_command(self, command_dict: dict[str, Any]): app_pid = self.matter_test_config.app_pid @@ -164,14 +170,6 @@ def _ask_for_release(self): else: time.sleep(self.keep_pressed_delay/1000) - def _placeholder_for_step(self, step_id: str): - # TODO(#34656): Global search an replace of `self._placeholder_for_step` with `self.step` when done. - logging.info(f"Step {step_id}") - pass - - def _placeholder_for_skip(self, step_id: str): - logging.info(f"Skipped step {step_id}") - def _await_sequence_of_reports(self, report_queue: queue.Queue, endpoint_id: int, attribute: TypedAttributePath, sequence: list[Any], timeout_sec: float): start_time = time.time() elapsed = 0.0 @@ -269,93 +267,6 @@ def _expect_no_events_for_cluster(self, event_queue: queue.Queue, endpoint_id: i logging.info(f"Successfully waited for no further events on {expected_cluster} for {elapsed:.1f} seconds") - @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) - async def test_TC_SWTCH_2_4(self): - # TODO(#34656): Make this come from PIXIT - switch_pressed_position = 1 - post_prompt_settle_delay_seconds = 10.0 - - # Commission DUT - already done - - # Read feature map to set bool markers - cluster = Clusters.Objects.Switch - feature_map = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.FeatureMap) - - has_ms_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitch) != 0 - has_msr_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchRelease) != 0 - has_msl_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchLongPress) != 0 - has_as_feature = (feature_map & cluster.Bitmaps.Feature.kActionSwitch) != 0 - # has_msm_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchMultiPress) != 0 - - if not has_ms_feature: - logging.info("Skipping rest of test: SWTCH.S.F01(MS) feature not present") - self.skip_all_remaining_steps("2") - - endpoint_id = self.matter_test_config.endpoint - - # Step 1: Set up subscription to all Switch cluster events - self._placeholder_for_step("1") - event_listener = EventChangeCallback(cluster) - attrib_listener = ClusterAttributeChangeAccumulator(cluster) - await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) - await attrib_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) - - # Step 2: Operator does not operate switch on the DUT - self._placeholder_for_step("2") - self._ask_for_switch_idle() - - # Step 3: TH reads the CurrentPosition attribute from the DUT - self._placeholder_for_step("3") - - # Verify that the value is 0 - current_position = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.CurrentPosition) - asserts.assert_equal(current_position, 0) - - # Step 4a: Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it - self._placeholder_for_step("4a") - self._ask_for_long_press(endpoint_id, switch_pressed_position, feature_map) - - # Step 4b: TH expects report of CurrentPosition 1, followed by a report of Current Position 0. - self._placeholder_for_step("4b") - logging.info( - f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for CurrentPosition to go {switch_pressed_position}, then 0.") - self._await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.CurrentPosition, sequence=[ - switch_pressed_position, 0], timeout_sec=post_prompt_settle_delay_seconds) - - # Step 4c: TH expects at least InitialPress with NewPosition = 1 - self._placeholder_for_step("4c") - logging.info(f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for InitialPress event.") - expected_events = [cluster.Events.InitialPress(newPosition=switch_pressed_position)] - self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, - sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) - - # Step 4d: For MSL/AS, expect to see LongPress/LongRelease in that order - if not has_msl_feature and not has_as_feature: - logging.info("Skipping Step 4d due to missing MSL and AS features") - self._placeholder_for_skip("4d") - else: - # Steb 4d: TH expects report of LongPress, LongRelease in that order. - self._placeholder_for_step("4d") - logging.info(f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for LongPress then LongRelease.") - expected_events = [] - expected_events.append(cluster.Events.LongPress(newPosition=switch_pressed_position)) - expected_events.append(cluster.Events.LongRelease(previousPosition=switch_pressed_position)) - self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, - sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) - - # Step 4e: For MS & (!MSL & !AS & !MSR), expect no further events for 10 seconds. - if not has_msl_feature and not has_as_feature and not has_msr_feature: - self._placeholder_for_step("4e") - self._expect_no_events_for_cluster(event_queue=event_listener.event_queue, - endpoint_id=endpoint_id, expected_cluster=cluster, timeout_sec=10.0) - - # Step 4f: For MSR & not MSL, expect to see ShortRelease. - if not has_msl_feature and has_msr_feature: - self._placeholder_for_step("4f") - expected_events = [cluster.Events.ShortRelease(previousPosition=switch_pressed_position)] - self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, - sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) - def _received_event(self, event_listener: EventChangeCallback, target_event: ClusterObjects.ClusterEvent, timeout_s: int) -> bool: """ Returns true if this event was received, false otherwise @@ -534,6 +445,104 @@ async def test_TC_SWTCH_2_3(self): button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) asserts.assert_equal(button_val, 0, "Button value is not 0") + def desc_TC_SWTCH_2_4(self) -> str: + return "[TC-SWTCH-2.4] Momentary Switch Long Press Verification" + + def steps_TC_SWTCH_2_4(self): + return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), + TestStep(2, "Set up subscription to all events of Switch cluster on the endpoint"), + TestStep(3, "Operator does not operate switch on the DUT"), + TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + TestStep(5, "Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it", + """ + * TH expects receiving a subscription report of CurrentPosition 1, followed by a report of Current Position 0. + * TH expects receiving at InitialPress event with NewPosition = 1. + * if MSL or AS feature is supported, TH expect receiving LongPress/LongRelease in that order. + * if MS & (!MSL & !AS & !MSR) features present, TH expects receiving no further events for 10 seconds after release. + * if (MSR & !MSL) features present, TH expects receiving ShortRelease event. + """) + ] + + @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) + async def test_TC_SWTCH_2_4(self): + switch_pressed_position = self._default_pressed_position + post_prompt_settle_delay_seconds = 10.0 + + endpoint_id = self.matter_test_config.endpoint + cluster = Clusters.Objects.Switch + + # Step 1: Commission DUT - already done + self.step(1) + + # Read feature map to set bool markers + feature_map = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.FeatureMap) + + has_ms_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitch) != 0 + has_msr_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchRelease) != 0 + has_msl_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchLongPress) != 0 + has_as_feature = (feature_map & cluster.Bitmaps.Feature.kActionSwitch) != 0 + + if not has_ms_feature: + logging.info("Skipping rest of test: SWTCH.S.F01(MS) feature not present") + self.skip_all_remaining_steps("2") + + # Step 2: Set up subscription to all events of Switch cluster on the endpoint + self.step(2) + event_listener = EventChangeCallback(cluster) + attrib_listener = ClusterAttributeChangeAccumulator(cluster) + await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + await attrib_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + + # Step 3: Operator does not operate switch on the DUT + self.step(3) + self._ask_for_switch_idle() + + # Step 4: TH reads the CurrentPosition attribute from the DUT + self.step(4) + + # Verify that the value is 0 + current_position = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(current_position, 0) + + # Step 5: Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it + self.step(5) + self._ask_for_long_press(endpoint_id, switch_pressed_position, feature_map) + + # - TH expects report of CurrentPosition 1, followed by a report of Current Position 0. + logging.info( + f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for CurrentPosition to go {switch_pressed_position}, then 0.") + self._await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.CurrentPosition, sequence=[ + switch_pressed_position, 0], timeout_sec=post_prompt_settle_delay_seconds) + + # - TH expects at least InitialPress with NewPosition = 1 + logging.info(f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for InitialPress event.") + expected_events = [cluster.Events.InitialPress(newPosition=switch_pressed_position)] + self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, + sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) + + # - if MSL or AS feature is supported, expect to see LongPress/LongRelease in that order. + if not has_msl_feature and not has_as_feature: + logging.info("Since MSL and AS features both unsupported, skipping check for LongPress/LongRelease") + else: + # - TH expects report of LongPress, LongRelease in that order. + logging.info(f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for LongPress then LongRelease.") + expected_events = [] + expected_events.append(cluster.Events.LongPress(newPosition=switch_pressed_position)) + expected_events.append(cluster.Events.LongRelease(previousPosition=switch_pressed_position)) + self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, + sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) + + # - if MS & (!MSL & !AS & !MSR) features present, expect no further events for 10 seconds after release. + if not has_msl_feature and not has_as_feature and not has_msr_feature: + self._expect_no_events_for_cluster(event_queue=event_listener.event_queue, + endpoint_id=endpoint_id, expected_cluster=cluster, timeout_sec=10.0) + + # - if (MSR & !MSL) features present, expect to see ShortRelease event. + if not has_msl_feature and has_msr_feature: + expected_events = [cluster.Events.ShortRelease(previousPosition=switch_pressed_position)] + self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, + sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) + def steps_TC_SWTCH_2_5(self): return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), TestStep(2, "Set up a subscription to all Switch cluster events"), @@ -638,7 +647,7 @@ async def test_TC_SWTCH_2_5(self): multi_press_max = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.MultiPressMax) endpoint_id = self.matter_test_config.endpoint - pressed_position = 1 + pressed_position = self._default_pressed_position self.step(2) event_listener = EventChangeCallback(cluster) @@ -657,27 +666,27 @@ def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = else: self._ask_for_multi_press(endpoint_id, number_of_presses=count, pressed_position=pressed_position, feature_map=feature_map, multi_press_max=multi_press_max) - for i in range(count): + for pos_idx in range(count): event = event_listener.wait_for_event_report(cluster.Events.InitialPress) asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") - if i > 0: + if pos_idx > 0: event = event_listener.wait_for_event_report(cluster.Events.MultiPressOngoing) asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on MultiPressOngoing") - asserts.assert_equal(event.currentNumberOfPressesCounted, i+1, + asserts.assert_equal(event.currentNumberOfPressesCounted, pos_idx + 1, "Unexpected CurrentNumberOfPressesCounted on MultiPressOngoing") event = event_listener.wait_for_event_report(cluster.Events.ShortRelease) asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on ShortRelease") - step = step[:-1] + chr(ord(step[-1])+1) + step = bump_substep(step) self.step(step) self._ask_for_switch_idle() event = event_listener.wait_for_event_report(cluster.Events.MultiPressComplete) asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on MultiPressComplete") asserts.assert_equal(event.totalNumberOfPressesCounted, count, "Unexpected count on MultiPressComplete") - test_multi_press_sequence("4a", 1) + test_multi_press_sequence("4a", count=1) - test_multi_press_sequence("5a", 2) + test_multi_press_sequence("5a", count=2) self.step("6a") multi_press_max = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.MultiPressMax) @@ -685,7 +694,7 @@ def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = self.skip_step("6b") self.skip_step("6c") else: - test_multi_press_sequence("6b", 3) + test_multi_press_sequence("6b", count=3) if not has_msl_feature: self.skip_all_remaining_steps(7) @@ -694,7 +703,7 @@ def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = self.step(7) # subscription is already set up - test_multi_press_sequence("8a", 2, short_long=True) + test_multi_press_sequence("8a", count=2, short_long=True) self.step("9a") self._ask_for_multi_press_long_short(endpoint_id, pressed_position, feature_map) @@ -813,7 +822,7 @@ async def test_TC_SWTCH_2_6(self): multi_press_max = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.MultiPressMax) endpoint_id = self.matter_test_config.endpoint - pressed_position = 1 + pressed_position = self._default_pressed_position self.step(2) event_listener = EventChangeCallback(cluster) @@ -836,7 +845,7 @@ def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = event = event_listener.wait_for_event_report(cluster.Events.InitialPress) asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") - step = step[:-1] + chr(ord(step[-1])+1) + step = bump_substep(step) self.step(step) self._ask_for_switch_idle() event = event_listener.wait_for_event_report(cluster.Events.MultiPressComplete) @@ -844,11 +853,11 @@ def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = expected_count = 0 if count > multi_press_max else count asserts.assert_equal(event.totalNumberOfPressesCounted, expected_count, "Unexpected count on MultiPressComplete") - test_multi_press_sequence("4a", 1) + test_multi_press_sequence("4a", count=1) - test_multi_press_sequence("5a", 2) + test_multi_press_sequence("5a", count=2) - test_multi_press_sequence("6a", multi_press_max + 1) + test_multi_press_sequence("6a", count=(multi_press_max + 1)) self.step("7a") if not has_msl_feature: @@ -857,7 +866,7 @@ def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = # subscription is already established self.step("7b") - test_multi_press_sequence("8a", 2, short_long=True) + test_multi_press_sequence("8a", count=2, short_long=True) self.step("9a") self._ask_for_multi_press_long_short(endpoint_id, pressed_position, feature_map) From e1137ebfbe90ae16a8be6c5dbd128391ed112534 Mon Sep 17 00:00:00 2001 From: Chris Letnick Date: Wed, 31 Jul 2024 13:17:01 -0700 Subject: [PATCH 05/21] Initial test script for Fabric Sync TC_MCORE_FS_1_2 (#34675) * Initial test script for Fabric Sync TC_MCORE_FS_1_2 * Apply suggestions from code review Co-authored-by: C Freeman * Address Review Comments * Address review comments * Fix default timeout after other timeouts changed * Restyled by autopep8 * Fix linter error --------- Co-authored-by: C Freeman Co-authored-by: Restyled.io --- src/python_testing/TC_MCORE_FS_1_2.py | 176 ++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 src/python_testing/TC_MCORE_FS_1_2.py diff --git a/src/python_testing/TC_MCORE_FS_1_2.py b/src/python_testing/TC_MCORE_FS_1_2.py new file mode 100644 index 00000000000000..0af8cbedb30345 --- /dev/null +++ b/src/python_testing/TC_MCORE_FS_1_2.py @@ -0,0 +1,176 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# TODO: add to CI. See https://github.com/project-chip/connectedhomeip/issues/34676 +# for details about the block below. +# + +import base64 +import logging +import queue +import time + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_SC_3_6 import AttributeChangeAccumulator + + +class TC_MCORE_FS_1_2(MatterBaseTest): + def steps_TC_MCORE_FS_1_2(self) -> list[TestStep]: + steps = [TestStep(1, "TH_FSA subscribes to all the Bridged Device Basic Information clusters provided by DUT_FSA to identify the presence of a Bridged Node endpoint with a UniqueID matching the UniqueID provided by the BasicInformationCluster of the TH_SED_DUT."), + TestStep(2, "TH_FSA initiates commissioning of TH_SED_DUT by sending the OpenCommissioningWindow command to the Administrator Commissioning Cluster on the endpoint with the uniqueID matching that of TH_SED_DUT."), + TestStep(3, "TH_FSA completes commissioning of TH_SED_DUT using the Enhanced Commissioning Method."), + TestStep(4, "Commission TH_SED_L onto DUT_FSA’s fabric using the manufacturer specified mechanism."), + TestStep(5, "TH_FSA waits for subscription report from a the Bridged Device Basic Information clusters provided by DUT_FSA to identify the presence of a Bridged Node endpoint with a UniqueID matching the UniqueID provided by the BasicInformationCluster of the TH_SED_L."), + TestStep(6, "TH_FSA initiates commissions of TH_SED_L by sending the OpenCommissioningWindow command to the Administrator Commissioning Cluster on the endpoint with the uniqueID matching that of TH_SED_L."), + TestStep(7, "TH_FSA completes commissioning of TH_SED_L using the Enhanced Commissioning Method.")] + return steps + + @property + def default_timeout(self) -> int: + return self.user_params.get("report_waiting_timeout_delay_sec", 10)*2 + 60 + + @async_test_body + async def test_TC_MCORE_FS_1_2(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + min_report_interval_sec = self.user_params.get("min_report_interval_sec", 0) + max_report_interval_sec = self.user_params.get("max_report_interval_sec", 2) + report_waiting_timeout_delay_sec = self.user_params.get("report_waiting_timeout_delay_sec", 10) + + self.step(1) + + # Subscribe to the UniqueIDs + unique_id_queue = queue.Queue() + subscription_contents = [ + (Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID) # On all endpoints + ] + sub = await self.default_controller.ReadAttribute( + nodeid=self.dut_node_id, + attributes=subscription_contents, + reportInterval=(min_report_interval_sec, max_report_interval_sec), + keepSubscriptions=False + ) + attribute_handler = AttributeChangeAccumulator( + name=self.default_controller.name, expected_attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, output=unique_id_queue) + sub.SetAttributeUpdateCallback(attribute_handler) + + logging.info("Waiting for First BridgedDeviceBasicInformation.") + start_time = time.time() + elapsed = 0 + time_remaining = report_waiting_timeout_delay_sec + + th_sed_dut_bdbi_endpoint = -1 + th_sed_dut_unique_id = -1 + + while time_remaining > 0 and th_sed_dut_bdbi_endpoint < 0: + try: + item = unique_id_queue.get(block=True, timeout=time_remaining) + endpoint, attribute, value = item['endpoint'], item['attribute'], item['value'] + + # Record arrival of an expected subscription change when seen + if attribute == Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID: + th_sed_dut_bdbi_endpoint = endpoint + th_sed_dut_unique_id = value + + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = report_waiting_timeout_delay_sec - elapsed + + asserts.assert_greater(th_sed_dut_bdbi_endpoint, 0, "Failed to find any BDBI instances with UniqueID present.") + logging.info("Found BDBI with UniqueID (%d) on endpoint %d." % th_sed_dut_unique_id, th_sed_dut_bdbi_endpoint) + + self.step(2) + + self.sync_passcode = 20202024 + self.th_sed_dut_discriminator = 2222 + cmd = Clusters.AdministratorCommissioning.Commands.OpenCommissioningWindow(commissioningTimeout=3*60, + PAKEPasscodeVerifier=b"+w1qZQR05Zn0bc2LDyNaDAhsrhDS5iRHPTN10+EmNx8E2OpIPC4SjWRDQVOgqcbnXdYMlpiZ168xLBqn1fx9659gGK/7f9Yc6GxpoJH8kwAUYAYyLGsYeEBt1kL6kpXjgA==", + discriminator=self.th_sed_dut_discriminator, + iterations=10000, salt=base64.b64encode(bytes('SaltyMcSalterson', 'utf-8'))) + await self.send_single_cmd(cmd, endpoint=th_sed_dut_bdbi_endpoint, timedRequestTimeoutMs=5000) + + logging.info("Commissioning Window open for TH_SED_DUT.") + + self.step(3) + + self.th_sed_dut_nodeid = 1111 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.th_sed_dut_nodeid, setupPinCode=self.sync_passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.th_sed_dut_discriminator) + logging.info("Commissioning TH_SED_DUT complete") + + self.step(4) + if not self.is_ci: + self.wait_for_use_input( + "Commission TH_SED_DUT onto DUT_FSA’s fabric using the manufacturer specified mechanism. (ensure Synchronization is enabled.)") + else: + logging.info("Stopping after step 3 while running in CI to avoid manual steps.") + return + + self.step(5) + + th_sed_later_bdbi_endpoint = -1 + th_sed_later_unique_id = -1 + logging.info("Waiting for Second BridgedDeviceBasicInformation.") + start_time = time.time() + elapsed = 0 + time_remaining = report_waiting_timeout_delay_sec + + while time_remaining > 0 and th_sed_later_bdbi_endpoint < 0: + try: + item = unique_id_queue.get(block=True, timeout=time_remaining) + endpoint, attribute, value = item['endpoint'], item['attribute'], item['value'] + + # Record arrival of an expected subscription change when seen + if attribute == Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID and endpoint != th_sed_dut_bdbi_endpoint and th_sed_later_unique_id != th_sed_dut_unique_id: + th_sed_later_bdbi_endpoint = endpoint + th_sed_later_unique_id = value + + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = report_waiting_timeout_delay_sec - elapsed + + asserts.assert_greater(th_sed_later_bdbi_endpoint, 0, "Failed to find any BDBI instances with UniqueID present.") + logging.info("Found another BDBI with UniqueID (%d) on endpoint %d." % th_sed_later_unique_id, th_sed_later_bdbi_endpoint) + + self.step(6) + + self.th_sed_later_discriminator = 3333 + # min commissioning timeout is 3*60 seconds, so use that even though the command said 30. + cmd = Clusters.AdministratorCommissioning.Commands.OpenCommissioningWindow(commissioningTimeout=3*60, + PAKEPasscodeVerifier=b"+w1qZQR05Zn0bc2LDyNaDAhsrhDS5iRHPTN10+EmNx8E2OpIPC4SjWRDQVOgqcbnXdYMlpiZ168xLBqn1fx9659gGK/7f9Yc6GxpoJH8kwAUYAYyLGsYeEBt1kL6kpXjgA==", + discriminator=self.th_sed_later_discriminator, + iterations=10000, salt=base64.b64encode(bytes('SaltyMcSalterson', 'utf-8'))) + await self.send_single_cmd(cmd, endpoint=th_sed_later_bdbi_endpoint, timedRequestTimeoutMs=5000) + + logging.info("Commissioning Window open for TH_SED_L.") + + self.step(7) + + self.th_sed_later_nodeid = 2222 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.th_sed_later_nodeid, setupPinCode=self.sync_passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.th_sed_later_discriminator) + logging.info("Commissioning TH_SED_L complete") + + +if __name__ == "__main__": + default_matter_test_main() From 884360a66546ccbfc5474f0a70a69a9ed52d40cb Mon Sep 17 00:00:00 2001 From: Douglas Rocha Ferraz Date: Wed, 31 Jul 2024 16:19:41 -0400 Subject: [PATCH 06/21] Test automation for FabricSync ICD BridgedDeviceBasicInfoCluster (#34628) * WIP Bridged ICD, commissioning to both fabrics * wip testing sending KeepActive * wip most steps implemented * using SIGSTOP and SIGCONT to control ICD server pausing * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson * comments addressed * more comments addressed * lint pass * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: C Freeman * comments addressed, incl TH_SERVER configurable * added setupQRCode and setupManualCode as options for DUT commissioning * Restyled by autopep8 * Restyled by isort * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson * comments addressed * Restyled by autopep8 --------- Co-authored-by: Terence Hampson Co-authored-by: C Freeman Co-authored-by: Restyled.io --- src/python_testing/TC_BRBINFO_4_1.py | 275 +++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 src/python_testing/TC_BRBINFO_4_1.py diff --git a/src/python_testing/TC_BRBINFO_4_1.py b/src/python_testing/TC_BRBINFO_4_1.py new file mode 100644 index 00000000000000..6c65f634bb6a7b --- /dev/null +++ b/src/python_testing/TC_BRBINFO_4_1.py @@ -0,0 +1,275 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This test requires a TH_SERVER application. Please specify with --string-arg th_server_app_path: +# TH_SERVER must support following arguments: --secured-device-port --discriminator --passcode --KVS +# E.g: python3 src/python_testing/TC_BRBINFO_4_1.py --commissioning-method on-network --qr-code MT:-24J042C00KA0648G00 \ +# --string-arg th_server_app_path:out/linux-x64-lit-icd/lit-icd-app + +import logging +import os +import queue +import signal +import subprocess +import time +import uuid + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from matter_testing_support import MatterBaseTest, SimpleEventCallback, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) +_ROOT_ENDPOINT_ID = 0 + + +class TC_BRBINFO_4_1(MatterBaseTest): + + # + # Class Helper functions + # + + async def _read_attribute_expect_success(self, endpoint, cluster, attribute, node_id): + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute, node_id=node_id) + + # Override default timeout to support a 60 min wait + @property + def default_timeout(self) -> int: + return 63*60 + + def desc_TC_BRBINFO_4_1(self) -> str: + """Returns a description of this test""" + return "[TC_BRBINFO_4_1] Verification of KeepActive Command [DUT-Server]" + + def steps_TC_BRBINFO_4_1(self) -> list[TestStep]: + steps = [ + TestStep("0", "Preconditions"), + TestStep("1a", "TH reads from the ICD the A_IDLE_MODE_DURATION, A_ACTIVE_MODE_DURATION, and ACTIVE_MODE_THRESHOLD attributes"), + TestStep("1b", "Simple KeepActive command w/ subscription. ActiveChanged event received by TH contains PromisedActiveDuration"), + TestStep("2", "Sends 3x KeepActive commands w/ subscription. ActiveChanged event received ONCE and contains PromisedActiveDuration"), + TestStep("3", "KeepActive not returned after 60 minutes of offline ICD"), + ] + return steps + + def _ask_for_vendor_commissioniong_ux_operation(self, discriminator, setupPinCode, setupManualCode, setupQRCode): + self.wait_for_user_input( + prompt_msg=f"Using the DUT vendor's provided interface, commission the ICD device using the following parameters:\n" + f"- discriminator: {discriminator}\n" + f"- setupPinCode: {setupPinCode}\n" + f"- setupQRCode: {setupQRCode}\n" + f"- setupManualcode: {setupManualCode}\n" + f"If using FabricSync Admin test app, you may type:\n" + f">>> pairing onnetwork 111 {setupPinCode}") + + async def _send_keep_active_command(self, duration, endpoint_id) -> int: + logging.info("Sending keep active command") + keep_active = await self.default_controller.SendCommand(nodeid=self.dut_node_id, endpoint=endpoint_id, payload=Clusters.Objects.BridgedDeviceBasicInformation.Commands.KeepActive(stayActiveDuration=duration)) + return keep_active + + async def _wait_for_active_changed_event(self, timeout) -> int: + try: + promised_active_duration = self.q.get(block=True, timeout=timeout) + logging.info(f"PromisedActiveDuration: {promised_active_duration}") + return promised_active_duration + except queue.Empty: + asserts.fail("Timeout on event ActiveChanged") + + async def _get_dynamic_endpoint(self) -> int: + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=_ROOT_ENDPOINT_ID) + set_of_endpoints_after_adding_device = set(root_part_list) + + asserts.assert_true(set_of_endpoints_after_adding_device.issuperset( + self.set_of_dut_endpoints_before_adding_device), "Expected only new endpoints to be added") + unique_endpoints_set = set_of_endpoints_after_adding_device - self.set_of_dut_endpoints_before_adding_device + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") + newly_added_endpoint = list(unique_endpoints_set)[0] + return newly_added_endpoint + + @async_test_body + async def setup_class(self): + # These steps are not explicitly, but they help identify the dynamically added endpoint + # The second part of this process happens on _get_dynamic_endpoint() + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=_ROOT_ENDPOINT_ID) + self.set_of_dut_endpoints_before_adding_device = set(root_part_list) + + super().setup_class() + app = self.user_params.get("th_server_app_path", None) + if not app: + asserts.fail('This test requires a TH_SERVER app. Specify app path with --string-arg th_server_app_path:') + + self.kvs = f'kvs_{str(uuid.uuid4())}' + self.port = 5543 + discriminator = 3850 + passcode = 20202021 + app_args = f'--secured-device-port {self.port} --discriminator {discriminator} --passcode {passcode} --KVS {self.kvs} ' + cmd = f'{app} {app_args}' + + logging.info("Starting ICD Server App") + self.app_process = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info("ICD started") + time.sleep(3) + + logging.info("Commissioning of ICD to fabric one (TH)") + self.icd_nodeid = 1111 + + await self.default_controller.CommissionOnNetwork(nodeId=self.icd_nodeid, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + + logging.info("Commissioning of ICD to fabric two (DUT)") + params = await self.openCommissioningWindow(dev_ctrl=self.default_controller, node_id=self.icd_nodeid) + + self._ask_for_vendor_commissioniong_ux_operation(params.randomDiscriminator, params.commissioningParameters.setupPinCode, + params.commissioningParameters.setupManualCode, params.commissioningParameters.setupQRCode) + + def teardown_class(self): + logging.warning("Stopping app with SIGTERM") + self.app_process.send_signal(signal.SIGTERM.value) + self.app_process.wait() + os.remove(self.kvs) + super().teardown_class() + + # + # BRBINFO 4.1 Test Body + # + + @async_test_body + async def test_TC_BRBINFO_4_1(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + icdm_cluster = Clusters.Objects.IcdManagement + icdm_attributes = icdm_cluster.Attributes + brb_info_cluster = Clusters.Objects.BridgedDeviceBasicInformation + basic_info_cluster = Clusters.Objects.BasicInformation + basic_info_attributes = basic_info_cluster.Attributes + + dynamic_endpoint_id = await self._get_dynamic_endpoint() + logging.info(f"Dynamic endpoint is {dynamic_endpoint_id}") + + # Preconditions + self.step("0") + + logging.info("Ensuring DUT is commissioned to TH") + + # Confirms commissioning of DUT on TH as it reads its fature map + await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + basic_info_cluster, + basic_info_attributes.FeatureMap, + self.dut_node_id + ) + + logging.info("Ensuring ICD is commissioned to TH") + + # Confirms commissioning of ICD on TH as it reads its feature map + await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + basic_info_cluster, + basic_info_attributes.FeatureMap, + self.icd_nodeid + ) + + self.step("1a") + + idle_mode_duration = await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + icdm_cluster, + icdm_attributes.IdleModeDuration, + self.icd_nodeid + ) + logging.info(f"IdleModeDuration: {idle_mode_duration}") + + active_mode_duration = await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + icdm_cluster, + icdm_attributes.ActiveModeDuration, + self.icd_nodeid + ) + logging.info(f"ActiveModeDuration: {active_mode_duration}") + + self.step("1b") + + # Subscription to ActiveChanged + event = brb_info_cluster.Events.ActiveChanged + self.q = queue.Queue() + urgent = 1 + cb = SimpleEventCallback("ActiveChanged", event.cluster_id, event.event_id, self.q) + subscription = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=[(dynamic_endpoint_id, event, urgent)], reportInterval=[1, 3]) + subscription.SetEventUpdateCallback(callback=cb) + + stay_active_duration = 1000 + logging.info(f"Sending KeepActiveCommand({stay_active_duration}ms)") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + + logging.info("Waiting for ActiveChanged from DUT...") + promised_active_duration = await self._wait_for_active_changed_event((idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000) + + asserts.assert_greater_equal(promised_active_duration, stay_active_duration, "PromisedActiveDuration < StayActiveDuration") + + self.step("2") + + stay_active_duration = 1500 + logging.info(f"Sending KeepActiveCommand({stay_active_duration}ms)") + self._send_keep_active_command(stay_active_duration) + + logging.info("Waiting for ActiveChanged from DUT...") + promised_active_duration = await self._wait_for_active_changed_event((idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000) + + # wait for active time duration + time.sleep(max(stay_active_duration/1000, promised_active_duration)) + # ICD now should be in idle mode + + # sends 3x keep active commands + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + time.sleep(100) + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + time.sleep(100) + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + time.sleep(100) + + logging.info("Waiting for ActiveChanged from DUT...") + promised_active_duration = await self._wait_for_active_changed_event((idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000) + + asserts.assert_equal(self.q.qSize(), 0, "More than one event received from DUT") + + self.step("3") + + stay_active_duration = 10000 + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + + # stops (halts) the ICD server process by sending a SIGTOP signal + self.app_process.send_signal(signal.SIGSTOP.value) + + if not self.is_ci: + logging.info("Waiting for 60 minutes") + self._timeout + time.sleep(60*60) + + # resumes (continues) the ICD server process by sending a SIGCONT signal + self.app_process.send_signal(signal.SIGCONT.value) + + # wait for active changed event, expect no event will be sent + event_timeout = (idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000 + try: + promised_active_duration = self.q.get(block=True, timeout=event_timeout) + finally: + asserts.assert_true(queue.Empty(), "ActiveChanged event received when not expected") + + +if __name__ == "__main__": + default_matter_test_main() From d88dee09ad40cb82ac3ec215e035b0388d96e7ef Mon Sep 17 00:00:00 2001 From: Petru Lauric <81822411+plauric@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:24:17 -0400 Subject: [PATCH 07/21] ServiceArea test scripts (#34548) * initial commit * fix bugs * fix issues reported by the linter * fix bug in checking for unique areaDesc * add TC 1.5 * Update src/python_testing/TC_SEAR_1_2.py Co-authored-by: William * Update src/python_testing/TC_SEAR_1_2.py Co-authored-by: William * address code review comments * fix issue introduced by the previous commit * address code review feedback * Update src/python_testing/TC_SEAR_1_2.py Co-authored-by: Kiel Oleson * address code review feedback * remove PICS checked by the TC_SEAR_1.6 * more code review updates * Restyled by autopep8 --------- Co-authored-by: William Co-authored-by: Kiel Oleson Co-authored-by: Restyled.io --- src/python_testing/TC_SEAR_1_2.py | 368 ++++++++++++++++++++++++++++++ src/python_testing/TC_SEAR_1_3.py | 155 +++++++++++++ src/python_testing/TC_SEAR_1_4.py | 84 +++++++ src/python_testing/TC_SEAR_1_5.py | 283 +++++++++++++++++++++++ src/python_testing/TC_SEAR_1_6.py | 148 ++++++++++++ 5 files changed, 1038 insertions(+) create mode 100644 src/python_testing/TC_SEAR_1_2.py create mode 100644 src/python_testing/TC_SEAR_1_3.py create mode 100644 src/python_testing/TC_SEAR_1_4.py create mode 100644 src/python_testing/TC_SEAR_1_5.py create mode 100644 src/python_testing/TC_SEAR_1_6.py diff --git a/src/python_testing/TC_SEAR_1_2.py b/src/python_testing/TC_SEAR_1_2.py new file mode 100644 index 00000000000000..4ebb3342ee9bfc --- /dev/null +++ b/src/python_testing/TC_SEAR_1_2.py @@ -0,0 +1,368 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# TODO - this was copied/pasted from another test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_2(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + self.mapid_list = [] + + # this must be kept in sync with the definitions from the Common Landmark Semantic Tag Namespace + self.MAX_LANDMARK_ID = 0x33 + + # this must be kept in sync with the definitions from the Common Relative Position Semantic Tag Namespace + self.MAX_RELPOS_ID = 0x07 + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_and_validate_supported_maps(self, step): + self.print_step(step, "Read SupportedMaps attribute") + supported_maps = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedMaps) + logging.info("SupportedMaps: %s" % (supported_maps)) + asserts.assert_less_equal(len(supported_maps), 255, + "SupportedMaps should have max 255 entries") + + mapid_list = [m.mapID for m in supported_maps] + asserts.assert_true(len(set(mapid_list)) == len(mapid_list), "SupportedMaps must have unique MapID values!") + + name_list = [m.name for m in supported_maps] + asserts.assert_true(len(set(name_list)) == len(name_list), "SupportedMaps must have unique Name values!") + + # save so other methods can use this if neeeded + self.mapid_list = mapid_list + + async def read_and_validate_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + asserts.assert_less_equal(len(supported_areas), 255, + "SupportedAreas should have max 255 entries") + areaid_list = [] + areadesc_s = set() + for a in supported_areas: + asserts.assert_true(a.areaID not in areaid_list, "SupportedAreas must have unique AreaID values!") + + areaid_list.append(a.areaID) + + if len(self.mapid_list) > 0: + asserts.assert_is_not(a.mapID, NullValue, + f"SupportedAreas entry with AreaID({a.areaID}) should not have null MapID") + asserts.assert_is(a.mapID in self.mapid_list, + f"SupportedAreas entry with AreaID({a.areaID}) has unknown MapID({a.mapID})") + k = f"mapID:{a.mapID} areaDesc:{a.areaDesc}" + asserts.assert_true(k not in areadesc_s, + f"SupportedAreas must have unique MapID({a.mapID}) + AreaDesc({a.areaDesc}) values!") + areadesc_s.add(k) + else: + # empty SupportedMaps + asserts.assert_is(a.mapID, NullValue, + f"SupportedAreas entry with AreaID({a.areaID}) should have null MapID") + k = f"areaDesc:{a.areaDesc}" + asserts.assert_true(k not in areadesc_s, f"SupportedAreas must have unique AreaDesc({a.areaDesc}) values!") + areadesc_s.add(k) + + if a.locationInfo is NullValue and a.landmarkTag is NullValue: + asserts.assert_true( + f"SupportedAreas entry with AreaID({a.areaID}) should not have null LocationInfo and null LandmarkTag") + if a.landmarkTag is not NullValue: + asserts.assert_true(a.landmarkTag <= self.MAX_LANDMARK_ID, + f"SupportedAreas entry with AreaID({a.areaID}) has invalid LandmarkTag({a.landmarkTag})") + asserts.assert_true(a.positionTag is NullValue or a.positionTag in range(0, self.MAX_RELPOS_ID), + f"SupportedAreas entry with AreaID({a.areaID}) has invalid PositionTag({a.positionTag})") + # save so other methods can use this if neeeded + self.areaid_list = areaid_list + + async def read_and_validate_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + # TODO how to check if all entries are uint32? + + asserts.assert_true(len(selected_areas) <= len(self.areaid_list), + f"SelectedAreas(len {len(selected_areas)}) should have at most {len(self.areaid_list)} entries") + + asserts.assert_true(len(set(selected_areas)) == len(selected_areas), "SelectedAreas must have unique AreaID values!") + + for a in selected_areas: + asserts.assert_true(a in self.areaid_list, + f"SelectedAreas entry {a} has invalid value") + # save so other methods can use this if neeeded + self.selareaid_list = selected_areas + + async def read_and_validate_current_area(self, step): + self.print_step(step, "Read CurrentArea attribute") + current_area = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.CurrentArea) + logging.info(f"CurrentArea {current_area}") + + asserts.assert_true((len(self.selareaid_list) == 0 and current_area is NullValue) + or + current_area in self.selareaid_list, + f"CurrentArea {current_area} is invalid. SelectedAreas is {self.selareaid_list}.") + # save so other methods can use this if neeeded + self.current_area = current_area + + async def read_and_validate_estimated_end_time(self, step): + import time + read_time = int(time.time()) + self.print_step(step, "Read EstimatedEndTime attribute") + estimated_end_time = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.EstimatedEndTime) + logging.info(f"EstimatedEndTime {estimated_end_time}") + + if self.current_area is NullValue: + asserts.assert_true(estimated_end_time is NullValue, + "EstimatedEndTime should be null if CurrentArea is null.") + else: + # allow for some clock skew + asserts.assert_true(estimated_end_time >= read_time - 3*60, + f"EstimatedEndTime({estimated_end_time}) should be greater than the time when it was read({read_time})") + + async def read_and_validate_progress(self, step): + self.print_step(step, "Read Progress attribute") + progress = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.Progress) + logging.info(f"Progress {progress}") + + asserts.assert_true(len(progress) <= len(self.areaid_list), + f"Progress(len {len(progress)}) should have at most {len(self.areaid_list)} entries") + + progareaid_list = [] + for p in progress: + if p.areaID in progareaid_list: + asserts.fail("Progress must have unique AreaID values!") + else: + progareaid_list.append(p.areaID) + asserts.assert_true(p.areaID in self.areaid_list, + f"Progress entry has invalid AreaID value ({p.areaID})") + asserts.assert_true(p.status in (Clusters.ServiceArea.OperationalStatusEnum.kPending, + Clusters.ServiceArea.OperationalStatusEnum.kOperating, + Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + Clusters.ServiceArea.OperationalStatusEnum.kCompleted), + f"Progress entry has invalid Status value ({p.status})") + if p.status not in (Clusters.ServiceArea.OperationalStatusEnum.kSkipped, Clusters.ServiceArea.OperationalStatusEnum.kCompleted): + asserts.assert_true(p.totalOperationalTime is NullValue, + f"Progress entry should have a null TotalOperationalTime value (Status is {p.status})") + # TODO how to check that InitialTimeEstimate is either null or uint32? + + # Sends and out-of-band command to the rvc-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_2(self) -> list[str]: + return ["SEAR.S"] + + @async_test_body + async def test_TC_SEAR_1_2(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + if self.check_pics("SEAR.S.F02"): + await self.read_and_validate_supported_maps(step=2) + + await self.read_and_validate_supported_areas(step=3) + + await self.read_and_validate_selected_areas(step=4) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=5) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=6) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=7) + + if self.check_pics("SEAR.S.F02") and self.check_pics("SEAR.S.M.REMOVE_MAP"): + test_step = "Manually ensure the SupportedMaps attribute is not empty and that the device is not operating" + self.print_step("8", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=9) + old_supported_maps = self.mapid_list + + test_step = "Manually intervene to remove one or more entries in the SupportedMaps list" + self.print_step("10", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=11) + new_supported_maps = self.mapid_list + asserts.assert_true(len(old_supported_maps) > len(new_supported_maps), "Failed to remove map(s)") + + # NOTE the following operations are all part of step 11 - read all these attributes and check the data consistency + # after removing map(s) + await self.read_and_validate_supported_areas(step=11) + + await self.read_and_validate_selected_areas(step=11) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=11) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=11) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=11) + + if self.check_pics("SEAR.S.F02") and self.check_pics("SEAR.S.M.ADD_MAP"): + test_step = "Manually ensure the SupportedMaps attribute has less than 255 entries and that the device is not operating" + self.print_step("12", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=13) + old_supported_maps = self.mapid_list + + test_step = "Manually intervene to add one or more entries to the SupportedMaps list" + self.print_step("14", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=15) + new_supported_maps = self.mapid_list + asserts.assert_true(len(old_supported_maps) < len(new_supported_maps), "Failed to add map(s)") + + # NOTE the following operations are all part of step 15 - read all these attributes and check the data consistency + # after adding map(s) + await self.read_and_validate_supported_areas(step=15) + + await self.read_and_validate_selected_areas(step=15) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=15) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=15) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=15) + + if self.check_pics("SEAR.S.M.REMOVE_AREA"): + test_step = "Manually ensure the SupportedAreas attribute is not empty and that the device is not operating" + self.print_step("16", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=17) + old_supported_areas = self.areaid_list + + test_step = "Manually intervene to remove one or more entries from the SupportedAreas list" + self.print_step("18", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=19) + new_supported_areas = self.areaid_list + asserts.assert_true(len(old_supported_areas) > len(new_supported_areas), "Failed to remove area(s)") + + # NOTE the following operations are all part of step 19 - read all these attributes and check the data consistency + # after removing areas(s) + + await self.read_and_validate_selected_areas(step=19) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=19) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=19) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=19) + + if self.check_pics("SEAR.S.M.ADD_AREA"): + test_step = "Manually ensure the SupportedAreas attribute has less than 255 entries and that the device is not operating" + self.print_step("20", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=21) + old_supported_areas = self.areaid_list + + test_step = "Manually intervene to add one or more entries to the SupportedAreas list" + self.print_step("22", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=23) + new_supported_areas = self.areaid_list + asserts.assert_true(len(old_supported_areas) < len(new_supported_areas), "Failed to add area(s)") + + # NOTE the following operations are all part of step 23 - read all these attributes and check the data consistency + # after removing areas(s) + + await self.read_and_validate_selected_areas(step=23) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=23) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=23) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=23) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_3.py b/src/python_testing/TC_SEAR_1_3.py new file mode 100644 index 00000000000000..0acee1b34cdeb8 --- /dev/null +++ b/src/python_testing/TC_SEAR_1_3.py @@ -0,0 +1,155 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_3(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + + return [a.areaID for a in supported_areas] + + async def read_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + return selected_areas + + async def send_cmd_select_areas_expect_response(self, step, new_areas, expected_response): + self.print_step(step, f"Send SelectAreas command with NewAreas({new_areas})") + ret = await self.send_single_cmd(cmd=Clusters.Objects.ServiceArea.Commands.SelectAreas(newAreas=new_areas), + endpoint=self.endpoint) + + asserts.assert_equal(ret.commandResponseState.errorStateID, + expected_response, + f"Command response ({ret.commandResponseState}) doesn't match the expected one") + + # Sends and out-of-band command to the rvc-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_3(self) -> list[str]: + return ["SEAR.S"] + + @async_test_body + async def test_TC_SEAR_1_3(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + supported_area_ids = await self.read_supported_areas(step=2) + asserts.assert_true(len(self.supported_areas) > 0, "SupportedAreas is empty") + valid_area_id = supported_area_ids[0] + invalid_area_id = 1 + max(supported_area_ids) + + duplicated_areas = [valid_area_id, valid_area_id] + + # FIXME need to check if this is the correct name of this status code + await self.send_cmd_select_areas_expect_response(step=3, new_areas=duplicated_areas, expected_response=Clusters.ServiceArea.SelectAreasStatus.kDuplicatedAreas) + + await self.send_cmd_select_areas_expect_response(step=4, new_areas=[], expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + + selected_areas = await self.read_selected_areas(step=5) + asserts.assert_true(len(selected_areas) == 0, "SelectedAreas should be empty") + + await self.send_cmd_select_areas_expect_response(step=6, new_areas=[invalid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kUnsupportedArea) + + if self.check_pics("SEAR.S.M.INVALID_STATE_FOR_SELECT_AREAS") and self.check_pics("SEAR.S.M.HAS_MANUAL_SELAREA_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that prevents it from executing the SelectAreas command" + self.print_step("7", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_select_areas_expect_response(step=8, new_areas=[valid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kInvalidInMode) + + if self.check_pics("SEAR.S.M.VALID_STATE_FOR_SELECT_AREAS") and self.check_pics("SEAR.S.M.HAS_MANUAL_SELAREA_STATE_CONTROL"): + test_step = f"Manually intervene to put the device in a state that allows it to execute the SelectAreas({supported_area_ids}) command" + self.print_step("9", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_select_areas_expect_response(step=10, new_areas=supported_area_ids, expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + + selected_areas = await self.read_selected_areas(step=11) + asserts.assert_true(len(selected_areas) == len(supported_area_ids), + f"SelectedAreas({selected_areas}) should match SupportedAreas({supported_area_ids})") + + await self.send_cmd_select_areas_expect_response(step=12, new_areas=supported_area_ids, expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + + if self.check_pics("SEAR.S.M.VALID_STATE_FOR_SELECT_AREAS") and self.check_pics("SEAR.S.M.HAS_MANUAL_SELAREA_STATE_CONTROL") and self.check_pics("SEAR.S.M.SELECT_AREAS_WHILE_NON_IDLE"): + test_step = f"Manually intervene to put the device in a state that allows it to execute the SelectAreas({valid_area_id}) command, and put the device in a non-idle state" + self.print_step("13", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + if self.check_pics("SEAR.S.F00"): + await self.send_cmd_select_areas_expect_response(step=14, new_areas=[valid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + else: + await self.send_cmd_select_areas_expect_response(step=14, new_areas=[valid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kInvalidInMode) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_4.py b/src/python_testing/TC_SEAR_1_4.py new file mode 100644 index 00000000000000..a6326559beaa20 --- /dev/null +++ b/src/python_testing/TC_SEAR_1_4.py @@ -0,0 +1,84 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_4(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def TC_SEAR_1_4(self) -> list[str]: + return ["SEAR.S"] + + @async_test_body + async def test_TC_SEAR_1_4(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + attribute_list = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.AttributeList) + logging.info("AttributeList: %s" % (attribute_list)) + + if Clusters.ServiceArea.Attributes.CurrentArea not in attribute_list \ + and Clusters.ServiceArea.Attributes.Progress not in attribute_list: + + cmd_list = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.AcceptedCommandList) + logging.info("AcceptedCommandList: %s" % (cmd_list)) + asserts.assert_true(Clusters.ServiceArea.Commands.SkipArea not in cmd_list, + "SkipArea command should not be implemented if both CurrentArea and Progress are not") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_5.py b/src/python_testing/TC_SEAR_1_5.py new file mode 100644 index 00000000000000..adcf8341c93389 --- /dev/null +++ b/src/python_testing/TC_SEAR_1_5.py @@ -0,0 +1,283 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_5(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + + return [a.areaID for a in supported_areas] + + async def read_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + return selected_areas + + async def read_progress(self, step): + self.print_step(step, "Read Progress attribute") + progress = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.Progress) + logging.info(f"Progress {progress}") + + return progress + + async def read_current_area(self, step): + self.print_step(step, "Read CurrentArea attribute") + current_area = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.CurrentArea) + logging.info(f"CurrentArea {current_area}") + + return current_area + + async def send_cmd_skip_area_expect_response(self, step, skipped_area, expected_response): + self.print_step(step, f"Send SkipArea command with SkippedArea({skipped_area})") + ret = await self.send_single_cmd(cmd=Clusters.Objects.ServiceArea.Commands.SkipArea(skippedArea=skipped_area), + endpoint=self.endpoint) + + asserts.assert_equal(ret.commandResponseState.errorStateID, + expected_response, + f"Command response ({ret.commandResponseState}) doesn't match the expected one") + + # Sends and out-of-band command to the rvc-app + + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_5(self) -> list[str]: + return ["SEAR.S", "SEAR.S.C02.Rsp"] + + @async_test_body + async def test_TC_SEAR_1_5(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + supported_area_ids = await self.read_supported_areas(step=2) + asserts.assert_true(len(supported_area_ids) > 0, "SupportedAreas is empty") + valid_area_id = supported_area_ids[0] + invalid_area_id = 1 + max(supported_area_ids) + + if self.check_pics("SEAR.S.M.INVALID_STATE_FOR_SKIP") and self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that prevents it from executing the SkipArea command \ + (e.g. set CurrentArea to null or make it not operate, i.e. be in the idle state)" + self.print_step("3", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_skip_area_expect_response(step=4, skipped_area=valid_area_id, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kInvalidInMode) + + if self.check_pics("SEAR.S.M.NO_SELAREA_FOR_SKIP") and self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state where the state would allow it to execute the SkipArea command, \ + if SelectedAreas wasn't empty, and SelectedAreas is empty" + self.print_step("5", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_skip_area_expect_response(step=6, skipped_area=valid_area_id, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kInvalidAreaList) + + if self.check_pics("SEAR.S.M.VALID_STATE_FOR_SKIP") and self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that allows it to execute the SkipArea command" + self.print_step("7", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_skip_area_expect_response(step=8, skipped_area=invalid_area_id, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kInvalidSkippedArea) + + if not self.check_pics("SEAR.S.M.VALID_STATE_FOR_SKIP"): + return + + if self.check_pics("SEAR.S.A0005"): + old_progress_list = await self.read_progress(step=9) + asserts.assert_true(len(old_progress_list) > 0, f"len of Progress({len(old_progress_list)}) should not be zero)") + + selected_areas = await self.read_selected_areas(step=10) + asserts.assert_true(len(selected_areas) > 0, "SelectedAreas is empty") + + old_current_area = NullValue + if self.check_pics("SEAR.S.A0003"): + old_current_area = await self.read_current_area(step=11) + + self.print_step("12", "") + if old_current_area is not NullValue: + await self.send_cmd_skip_area_expect_response(step=13, skipped_area=old_current_area, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kSuccess) + if self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "(Manual operation) wait for the device to skip the current area, and start operating at\ + the next one it should process, or stop operating" + self.print_step("14", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + if self.check_pics("SEAR.S.A0005"): + new_progress_list = await self.read_progress(step=15) + asserts.assert_true(len(new_progress_list) > 0, + f"len of Progress({len(new_progress_list)}) should not be zero)") + + prog_areas = [p.areaID for p in new_progress_list] + + asserts.assert_true(old_current_area in prog_areas, f"Progress should include area {old_current_area}") + + new_current_area = await self.read_current_area(step=16) + for p in new_progress_list: + if p.areaID == old_current_area: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + "Progress for areaID({old_current_area}) should be Skipped") + break + test_step = "Indicate whether the device has stopped operating (y/n)" + ret = self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + # Verify that if the device hasn't stopped operating, the `new_progress_list`'s entry matching `new_current_area` shows the Operating status + if ret != "y": + for p in new_progress_list: + if p.areaID == new_current_area: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kOperating, + "Progress for areaID({new_current_area}) should be Operating") + break + + # next, we need to check for something else (so the condition of the 'if' above becomes part of the 'then' statement below): + # if before skipping all areas, except the current one, were Skipped or Completed, the device MUST have stopped operating + was_only_skipped_or_completed = True + for p in old_progress_list: + if p.areaID != old_current_area: + if p.status not in (Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + Clusters.ServiceArea.OperationalStatusEnum.kCompleted): + was_only_skipped_or_completed = False + break + if was_only_skipped_or_completed: + asserts.assert_true(ret == "y", "The device should not be operating") + + self.print_step("17", "") + return + + if not self.check_pics("SEAR.S.A0005"): + return + + if self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that allows it to execute the SkipArea command" + self.print_step("18", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + self.print_step("19", "") + if len(old_progress_list) == 0: + return + + area_to_skip = NullValue + self.print_step("20", "") + for p in old_progress_list: + if p.status in (Clusters.ServiceArea.OperationalStatusEnum.kPending, + Clusters.ServiceArea.OperationalStatusEnum.kOperating): + area_to_skip = p.areaID + break + + if area_to_skip is NullValue: + return + + await self.send_cmd_skip_area_expect_response(step=21, skipped_area=area_to_skip, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kSuccess) + + if self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "(Manual operation) wait for the device to update Progress or to stop operating" + self.print_step("22", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + new_progress_list = await self.read_progress(step=23) + asserts.assert_true(len(new_progress_list) > 0, f"len of Progress({len(new_progress_list)}) should not be zero)") + + for p in new_progress_list: + if p.areaID == area_to_skip: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + "Progress for areaID({new_current_area}) should be Skipped") + break + + test_step = "Indicate whether the device has stopped operating (y/n)" + ret = self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + was_only_skipped_or_completed = True + for p in old_progress_list: + if p.areaID != area_to_skip: + if p.status not in (Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + Clusters.ServiceArea.OperationalStatusEnum.kCompleted): + was_only_skipped_or_completed = False + break + if was_only_skipped_or_completed: + asserts.assert_true(ret == "y", "The device should not be operating") + for p in new_progress_list: + if p.areaID == old_current_area: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + "Progress for areaID({old_current_area}) should be Skipped") + break + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_6.py b/src/python_testing/TC_SEAR_1_6.py new file mode 100644 index 00000000000000..02a0fcdd33133a --- /dev/null +++ b/src/python_testing/TC_SEAR_1_6.py @@ -0,0 +1,148 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_6(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + + return [a.areaID for a in supported_areas] + + async def read_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + return selected_areas + + async def read_progress(self, step): + self.print_step(step, "Read Progress attribute") + progress = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.Progress) + logging.info(f"Progress {progress}") + + return progress + + # Sends and out-of-band command to the rvc-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_6(self) -> list[str]: + return ["SEAR.S", "SEAR.S.A0005", "SEAR.S.A0000", "SEAR.S.A0002", "SEAR.S.M.HAS_MANUAL_OPERATING_STATE_CONTROL"] + + @async_test_body + async def test_TC_SEAR_1_6(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + test_step = "Manually intervene to put the device in the idle state and ensure SupportedAreas and SelectedAreas are not empty" + self.print_step("2", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + supported_area_ids = await self.read_supported_areas(step=3) + asserts.assert_true(len(supported_area_ids) > 0, "SupportedAreas is empty") + + selected_areas = await self.read_selected_areas(step=4) + asserts.assert_true(len(selected_areas) > 0, "SelectedAreas is empty") + + test_step = "Manually intervene to put the device in the operating state" + self.print_step("5", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + progress_list_operating = await self.read_progress(step=6) + asserts.assert_true(len(selected_areas) == len(progress_list_operating), + f"len of SelectedAreas({len(selected_areas)}) should be equal to len of Progress({len(progress_list_operating)})") + + for p in progress_list_operating: + asserts.assert_true(p.areaID in selected_areas, f"Progress entry with unknown AreaID({p.areaID})") + asserts.assert_true(p.status in (Clusters.ServiceArea.OperationalStatusEnum.kPending, + Clusters.ServiceArea.OperationalStatusEnum.kOperating), + f"Progress entry with unexpected Status({p.status})") + asserts.assert_true(p.TotalOperationalTime is NullValue, "Progress entry with non-null TotalOperationalTime") + + test_step = "While all entries in Progress show the Pending or Operating status (i.e. \ + before any area is skipped or completed), manually intervene to put the device \ + in the idle state, by ending the operation unexpectedly (e.g. force an error)" + self.print_step("7", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + progress_list_idle = await self.read_progress(step=8) + asserts.assert_true(len(selected_areas) == len(progress_list_idle), + f"len of SelectedAreas({len(selected_areas)}) should be equal to len of Progress({len(progress_list_idle)})") + + for p in progress_list_idle: + asserts.assert_true(p.areaID in selected_areas, f"Progress entry with unknown AreaID({p.areaID})") + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + f"Progress entry with unexpected Status({p.status})") + + +if __name__ == "__main__": + default_matter_test_main() From 7a129d8334c6a3304b97a1129b48e8c8d11bb5a8 Mon Sep 17 00:00:00 2001 From: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:49:12 -0700 Subject: [PATCH 08/21] Remove manual tests for Thermostat presets (#34679) --- .../certification/Test_TC_TSTAT_4_2.yaml | 2228 ----------------- 1 file changed, 2228 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_TSTAT_4_2.yaml diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_4_2.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_4_2.yaml deleted file mode 100644 index b813eafd402606..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_4_2.yaml +++ /dev/null @@ -1,2228 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 42.4.2. [TC-TSTAT-4.2] Preset Test Cases with server as DUT - -PICS: - - TSTAT.S - -config: - nodeId: 0x12344321 - cluster: "Thermostat" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Step 2: Test Harness writes to the Presets attribute without calling - the StartPresetsSchedulesEditRequest" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #2 Test Harness Client attempts to write Presets and gets an INVALID_IN_STATE error since the client didn't send a request to edit the presets by calling StartPresetsSchedulesEditRequest command. - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": null, "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a INVALID_IN_STATE (0xCB) - - [1722285385.263] [53729:5380292] [DMG] WriteClient moving to [AwaitingDe] - [1722285385.263] [53729:5380292] [TOO] Response Failure: IM Error 0x000005CB: General error: 0xcb (INVALID_IN_STATE) - [1722285385.263] [53729:5380292] [EM] <<< [E:42658i S:21691 M:14088666 (Ack:20978215)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722285385.263] [53729:5380292] [EM] Flushed pending ack for MessageCounter:20978215 on exchange 42658i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3a: Test Harness writes to the Presets attribute after calling - the StartPresetsSchedulesEditRequest command" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #3a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3b: Test Harness writes to the Presets attribute adding 3 - presets for Sleep, Wake and GoingToSleep" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #3b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": null, "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": null, "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": null, "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286250.503] [54321:5397545] [DMG] WriteClient moving to [ResponseRe] - [1722286250.503] [54321:5397545] [DMG] WriteResponseMessage = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] AttributeStatusIBs = - [1722286250.503] [54321:5397545] [DMG] [ - [1722286250.503] [54321:5397545] [DMG] AttributeStatusIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] AttributePathIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] Endpoint = 0x1, - [1722286250.503] [54321:5397545] [DMG] Cluster = 0x201, - [1722286250.503] [54321:5397545] [DMG] Attribute = 0x0000_0050, - [1722286250.503] [54321:5397545] [DMG] } - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] StatusIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] status = 0x00 (SUCCESS), - [1722286250.503] [54321:5397545] [DMG] }, - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] }, - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] AttributeStatusIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] AttributePathIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] Endpoint = 0x1, - [1722286250.503] [54321:5397545] [DMG] Cluster = 0x201, - [1722286250.503] [54321:5397545] [DMG] Attribute = 0x0000_0050, - [1722286250.503] [54321:5397545] [DMG] ListIndex = Null, - [1722286250.503] [54321:5397545] [DMG] } - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] StatusIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] status = 0x00 (SUCCESS), - [1722286250.503] [54321:5397545] [DMG] }, - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] }, - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] AttributeStatusIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] AttributePathIB = - [1722286250.503] [54321:5397545] [DMG] { - [1722286250.503] [54321:5397545] [DMG] Endpoint = 0x1, - [1722286250.503] [54321:5397545] [DMG] Cluster = 0x201, - [1722286250.503] [54321:5397545] [DMG] Attribute = 0x0000_0050, - [1722286250.503] [54321:5397545] [DMG] ListIndex = Null, - [1722286250.503] [54321:5397545] [DMG] } - [1722286250.503] [54321:5397545] [DMG] - [1722286250.503] [54321:5397545] [DMG] StatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] status = 0x00 (SUCCESS), - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] AttributeStatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] AttributePathIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] Endpoint = 0x1, - [1722286250.504] [54321:5397545] [DMG] Cluster = 0x201, - [1722286250.504] [54321:5397545] [DMG] Attribute = 0x0000_0050, - [1722286250.504] [54321:5397545] [DMG] ListIndex = Null, - [1722286250.504] [54321:5397545] [DMG] } - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] StatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] status = 0x00 (SUCCESS), - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] AttributeStatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] AttributePathIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] Endpoint = 0x1, - [1722286250.504] [54321:5397545] [DMG] Cluster = 0x201, - [1722286250.504] [54321:5397545] [DMG] Attribute = 0x0000_0050, - [1722286250.504] [54321:5397545] [DMG] ListIndex = Null, - [1722286250.504] [54321:5397545] [DMG] } - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] StatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] status = 0x00 (SUCCESS), - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] AttributeStatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] AttributePathIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] Endpoint = 0x1, - [1722286250.504] [54321:5397545] [DMG] Cluster = 0x201, - [1722286250.504] [54321:5397545] [DMG] Attribute = 0x0000_0050, - [1722286250.504] [54321:5397545] [DMG] ListIndex = Null, - [1722286250.504] [54321:5397545] [DMG] } - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] StatusIB = - [1722286250.504] [54321:5397545] [DMG] { - [1722286250.504] [54321:5397545] [DMG] status = 0x00 (SUCCESS), - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] }, - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] ], - [1722286250.504] [54321:5397545] [DMG] - [1722286250.504] [54321:5397545] [DMG] InteractionModelRevision = 11 - [1722286250.504] [54321:5397545] [DMG] } - [1722286250.504] [54321:5397545] [DMG] WriteClient moving to [AwaitingDe] - [1722286250.504] [54321:5397545] [EM] <<< [E:14426i S:42250 M:116961408 (Ack:156984778)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286250.504] [54321:5397545] [EM] Flushed pending ack for MessageCounter:156984778 on exchange 14426i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3c: Test Harness reads the Presets attribute without calling - the CommitPresetsSchedulesRequest command" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #3c Test Harness Client reads Presets attribute but the new additions are not committed since the client didn't call the CommitPresetsSchedulesRequest command - - ./chip-tool thermostat read presets 0x12344321 1 - On TH(chip-tool) verify that DUT successfully read Presets (but without the new changes) - [1722286701.424] [54699:5406692] [TOO] Endpoint: 1 Cluster: 0x0000_0201 Attribute 0x0000_0050 DataVersion: 3807987049 - [1722286701.425] [54699:5406692] [TOO] Presets: 2 entries - [1722286701.425] [54699:5406692] [TOO] [1]: { - [1722286701.425] [54699:5406692] [TOO] PresetHandle: 01 - [1722286701.425] [54699:5406692] [TOO] PresetScenario: 1 - [1722286701.425] [54699:5406692] [TOO] CoolingSetpoint: 2500 - [1722286701.425] [54699:5406692] [TOO] HeatingSetpoint: 2100 - [1722286701.426] [54699:5406692] [TOO] BuiltIn: TRUE - [1722286701.426] [54699:5406692] [TOO] } - [1722286701.426] [54699:5406692] [TOO] [2]: { - [1722286701.426] [54699:5406692] [TOO] PresetHandle: 02 - [1722286701.426] [54699:5406692] [TOO] PresetScenario: 2 - [1722286701.426] [54699:5406692] [TOO] CoolingSetpoint: 2600 - [1722286701.426] [54699:5406692] [TOO] HeatingSetpoint: 2000 - [1722286701.426] [54699:5406692] [TOO] BuiltIn: TRUE - [1722286701.426] [54699:5406692] [TOO] } - [1722286701.426] [54699:5406692] [EM] <<< [E:49759i S:37002 M:67372150 (Ack:254131025)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3d: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #3d Test Harness Client calls CommitPresetsSchedulesRequest command - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722287841.505] [55282:5425045] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x0 - [1722287841.505] [55282:5425045] [DMG] ICR moving to [AwaitingDe] - [1722287841.505] [55282:5425045] [EM] <<< [E:46441i S:57071 M:61366563 (Ack:138534230)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3e: Test Harness reads the Presets attribute after calling the - CommitPresetsSchedulesRequest command" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #3e Test Harness Client reads Presets attribute and can see the added Presets. - - ./chip-tool thermostat read presets 0x12344321 1 - On TH(chip-tool) verify that DUT successfully read Presets (with the new changes) - [1722288101.757] [55446:5430009] [TOO] Endpoint: 1 Cluster: 0x0000_0201 Attribute 0x0000_0050 DataVersion: 3807987055 - [1722288101.757] [55446:5430009] [TOO] Presets: 5 entries - [1722288101.758] [55446:5430009] [TOO] [1]: { - [1722288101.759] [55446:5430009] [TOO] PresetHandle: 01 - [1722288101.759] [55446:5430009] [TOO] PresetScenario: 1 - [1722288101.759] [55446:5430009] [TOO] CoolingSetpoint: 2500 - [1722288101.759] [55446:5430009] [TOO] HeatingSetpoint: 2600 - [1722288101.759] [55446:5430009] [TOO] BuiltIn: TRUE - [1722288101.759] [55446:5430009] [TOO] } - [1722288101.759] [55446:5430009] [TOO] [2]: { - [1722288101.759] [55446:5430009] [TOO] PresetHandle: 02 - [1722288101.759] [55446:5430009] [TOO] PresetScenario: 2 - [1722288101.759] [55446:5430009] [TOO] CoolingSetpoint: 2600 - [1722288101.759] [55446:5430009] [TOO] HeatingSetpoint: 2500 - [1722288101.759] [55446:5430009] [TOO] BuiltIn: TRUE - [1722288101.759] [55446:5430009] [TOO] } - [1722288101.759] [55446:5430009] [TOO] [3]: { - [1722288101.759] [55446:5430009] [TOO] PresetHandle: 03 - [1722288101.759] [55446:5430009] [TOO] PresetScenario: 3 - [1722288101.759] [55446:5430009] [TOO] Name: Sleep - [1722288101.759] [55446:5430009] [TOO] CoolingSetpoint: 2500 - [1722288101.759] [55446:5430009] [TOO] HeatingSetpoint: 2600 - [1722288101.759] [55446:5430009] [TOO] BuiltIn: FALSE - [1722288101.759] [55446:5430009] [TOO] } - [1722288101.759] [55446:5430009] [TOO] [4]: { - [1722288101.759] [55446:5430009] [TOO] PresetHandle: 04 - [1722288101.759] [55446:5430009] [TOO] PresetScenario: 4 - [1722288101.759] [55446:5430009] [TOO] Name: Wake - [1722288101.759] [55446:5430009] [TOO] CoolingSetpoint: 2200 - [1722288101.759] [55446:5430009] [TOO] HeatingSetpoint: 2900 - [1722288101.759] [55446:5430009] [TOO] BuiltIn: FALSE - [1722288101.759] [55446:5430009] [TOO] } - [1722288101.759] [55446:5430009] [TOO] [5]: { - [1722288101.759] [55446:5430009] [TOO] PresetHandle: 06 - [1722288101.759] [55446:5430009] [TOO] PresetScenario: 6 - [1722288101.759] [55446:5430009] [TOO] Name: GoingToSleep - [1722288101.759] [55446:5430009] [TOO] CoolingSetpoint: 2100 - [1722288101.759] [55446:5430009] [TOO] HeatingSetpoint: 2500 - [1722288101.759] [55446:5430009] [TOO] BuiltIn: FALSE - [1722288101.759] [55446:5430009] [TOO] } - [1722288101.759] [55446:5430009] [EM] <<< [E:64397i S:21821 M:262922240 (Ack:37271345)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722288101.760] [55446:5430009] [EM] Flushed pending ack for MessageCounter:37271345 on exchange 64397i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #4a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4b: Test Harness writes to the Presets attribute with a - built-in preset having preset handle hex:01 removed" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #4b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722288460.741] [55752:5437815] [DMG] WriteClient moving to [ResponseRe] - [1722288460.741] [55752:5437815] [DMG] WriteResponseMessage = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] AttributeStatusIBs = - [1722288460.741] [55752:5437815] [DMG] [ - [1722288460.741] [55752:5437815] [DMG] AttributeStatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] AttributePathIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] Endpoint = 0x1, - [1722288460.741] [55752:5437815] [DMG] Cluster = 0x201, - [1722288460.741] [55752:5437815] [DMG] Attribute = 0x0000_0050, - [1722288460.741] [55752:5437815] [DMG] } - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] StatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] status = 0x00 (SUCCESS), - [1722288460.741] [55752:5437815] [DMG] }, - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] }, - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] AttributeStatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] AttributePathIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] Endpoint = 0x1, - [1722288460.741] [55752:5437815] [DMG] Cluster = 0x201, - [1722288460.741] [55752:5437815] [DMG] Attribute = 0x0000_0050, - [1722288460.741] [55752:5437815] [DMG] ListIndex = Null, - [1722288460.741] [55752:5437815] [DMG] } - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] StatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] status = 0x00 (SUCCESS), - [1722288460.741] [55752:5437815] [DMG] }, - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] }, - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] AttributeStatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] AttributePathIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] Endpoint = 0x1, - [1722288460.741] [55752:5437815] [DMG] Cluster = 0x201, - [1722288460.741] [55752:5437815] [DMG] Attribute = 0x0000_0050, - [1722288460.741] [55752:5437815] [DMG] ListIndex = Null, - [1722288460.741] [55752:5437815] [DMG] } - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] StatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] status = 0x00 (SUCCESS), - [1722288460.741] [55752:5437815] [DMG] }, - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] }, - [1722288460.741] [55752:5437815] [DMG] - [1722288460.741] [55752:5437815] [DMG] AttributeStatusIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.741] [55752:5437815] [DMG] AttributePathIB = - [1722288460.741] [55752:5437815] [DMG] { - [1722288460.742] [55752:5437815] [DMG] Endpoint = 0x1, - [1722288460.742] [55752:5437815] [DMG] Cluster = 0x201, - [1722288460.742] [55752:5437815] [DMG] Attribute = 0x0000_0050, - [1722288460.742] [55752:5437815] [DMG] ListIndex = Null, - [1722288460.742] [55752:5437815] [DMG] } - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] StatusIB = - [1722288460.742] [55752:5437815] [DMG] { - [1722288460.742] [55752:5437815] [DMG] status = 0x00 (SUCCESS), - [1722288460.742] [55752:5437815] [DMG] }, - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] }, - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] AttributeStatusIB = - [1722288460.742] [55752:5437815] [DMG] { - [1722288460.742] [55752:5437815] [DMG] AttributePathIB = - [1722288460.742] [55752:5437815] [DMG] { - [1722288460.742] [55752:5437815] [DMG] Endpoint = 0x1, - [1722288460.742] [55752:5437815] [DMG] Cluster = 0x201, - [1722288460.742] [55752:5437815] [DMG] Attribute = 0x0000_0050, - [1722288460.742] [55752:5437815] [DMG] ListIndex = Null, - [1722288460.742] [55752:5437815] [DMG] } - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] StatusIB = - [1722288460.742] [55752:5437815] [DMG] { - [1722288460.742] [55752:5437815] [DMG] status = 0x00 (SUCCESS), - [1722288460.742] [55752:5437815] [DMG] }, - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] }, - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] ], - [1722288460.742] [55752:5437815] [DMG] - [1722288460.742] [55752:5437815] [DMG] InteractionModelRevision = 11 - [1722288460.742] [55752:5437815] [DMG] } - [1722288460.742] [55752:5437815] [DMG] WriteClient moving to [AwaitingDe] - [1722288460.742] [55752:5437815] [EM] <<< [E:10991i S:19292 M:9249657 (Ack:153811994)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #4c Test Harness Client calls CommitPresetsSchedulesRequest command and gets UNSUPPORTED_ACCESS since a built-in preset was attempted to be removed. - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an UNSUPPORTED_ACCESS (0x7E) error - [1722288464.392] [55754:5437857] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x7e - [1722288464.392] [55754:5437857] [TOO] Error: IM Error 0x0000057E: General error: 0x7e (UNSUPPORTED_ACCESS) - [1722288464.392] [55754:5437857] [DMG] ICR moving to [AwaitingDe] - [1722288464.392] [55754:5437857] [EM] <<< [E:45905i S:14600 M:175519796 (Ack:248690311)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5a: Test Harness calls the SetActivePresetRequest command to - set the active preset handle" - PICS: TSTAT.S.F08 && TSTAT.S.C06.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #5a Test Harness Client calls SetActivePresetRequest command to set the active preset handle - - ./chip-tool thermostat set-active-preset-request "hex:03" 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722292538.299] [58873:5523668] [TOO] Endpoint: 1 Cluster: 0x0000_0201 Attribute 0x0000_004E DataVersion: 3470253931 - [1722292538.300] [58873:5523668] [TOO] ActivePresetHandle: 03 - [1722292538.300] [58873:5523668] [EM] <<< [E:63772i S:58620 M:79797990 (Ack:248773669)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 5b: Test Harness reads the ActivePresetHandle attribute" - PICS: TSTAT.S.F08 && TSTAT.S.A004e - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #5b Test Harness Client reads ActivePresetHandle attribute - - ./chip-tool thermostat read active-preset-handle 0x12344321 1 - On TH(chip-tool) verify that DUT successfully read ActivePresetHandle - [1722299898.382] [62999:5632512] [TOO] Endpoint: 1 Cluster: 0x0000_0201 Attribute 0x0000_004E DataVersion: 3098962545 - [1722299898.382] [62999:5632512] [TOO] ActivePresetHandle: 03 - [1722299898.382] [62999:5632512] [EM] <<< [E:27648i S:55804 M:2686999 (Ack:191947351)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5c: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #5b Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5d: Test Harness writes to the Presets attribute without the - preset with handle hex:03 matching the ActivePresetHandle attribute - removed" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #5c Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets ./out/debug/chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5e: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #5e Test Harness Client calls CommitPresetsSchedulesRequest command ans gets INVALID_IN_STATE since the preset with its handle matching the active preset handle was attempted to be removed. - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an INVALID_IN_STATE (0xCB) error - [1722293312.795] [59386:5538858] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0xcb - [1722293312.795] [59386:5538858] [TOO] Error: IM Error 0x000005CB: General error: 0xcb (INVALID_IN_STATE) - [1722293312.795] [59386:5538858] [DMG] ICR moving to [AwaitingDe] - [1722293312.795] [59386:5538858] [EM] <<< [E:4647i S:21966 M:58651952 (Ack:80870764)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #6a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6b: Test Harness writes to the Presets attribute with a - built-in preset having preset handle hex:01 modified to be not - built-in." - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #6b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #6c Test Harness Client calls CommitPresetsSchedulesRequest command gets UNSUPPORTED_ACCESS since a built-in preset was attempted to be modified to a non built-in preset - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an UNSUPPORTED_ACCESS (0x7E) error - [1722289468.881] [56642:5458641] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x7e - [1722289468.881] [56642:5458641] [TOO] Error: IM Error 0x0000057E: General error: 0x7e (UNSUPPORTED_ACCESS) - [1722289468.881] [56642:5458641] [DMG] ICR moving to [AwaitingDe] - [1722289468.881] [56642:5458641] [EM] <<< [E:20464i S:35105 M:91065475 (Ack:114933900)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #6a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7b: Test Harness writes to the Presets attribute with a new - preset having builtIn set to true" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #7b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": null, "name": "Vacation", "presetScenario": 5, "coolingSetpoint": 2900, "heatingSetpoint": 2000, "builtIn": true }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #6c Test Harness Client calls CommitPresetsSchedulesRequest command and gets CONSTRAINT_ERROR since a new preset was attempted to be added as a built-in preset. - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an CONSTRAINT_ERROR (0x87) error - [1722289998.305] [56996:5468872] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x87 - [1722289998.305] [56996:5468872] [TOO] Error: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1722289998.305] [56996:5468872] [DMG] ICR moving to [AwaitingDe] - [1722289998.305] [56996:5468872] [EM] <<< [E:44500i S:62829 M:76436393 (Ack:145233702)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 8a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #8a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 8b: Test Harness writes to the Presets attribute with a preset - having preset handle hex:08 that doesn't exist in the Presets - attribute" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #8b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:08", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 8c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #8c Test Harness Client calls CommitPresetsSchedulesRequest command gets NOT_FOUND since an existing preset was attempted to be added with a preset handle that doesn't exist in the Presets attribute - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an NOT_FOUND (0x8B) error - [1722290436.980] [57434:5479429] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x8b - [1722290436.980] [57434:5479429] [TOO] Error: IM Error 0x0000058B: General error: 0x8b (NOT_FOUND) - [1722290436.980] [57434:5479429] [DMG] ICR moving to [AwaitingDe] - [1722290436.980] [57434:5479429] [EM] <<< [E:54210i S:10110 M:158287615 (Ack:73923062)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 9a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #9a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 9b: Test Harness writes to the Presets attribute" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #8b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 9c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #8c Test Harness Client calls CommitPresetsSchedulesRequest command gets CONSTRAINT_ERROR since preset with preset handle hex:03 is duplicated - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) error - [1722302289.994] [63677:5670818] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x87 - [1722302289.994] [63677:5670818] [TOO] Error: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1722302289.994] [63677:5670818] [DMG] ICR moving to [AwaitingDe] - [1722302289.994] [63677:5670818] [EM] <<< [E:25209i S:7768 M:264197735 (Ack:106550461)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 10a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #10a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 10b: Test Harness writes to the Presets attribute wherein a - built-in preset is modified to a non built-in preset" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #10b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 10c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #10c Test Harness Client calls CommitPresetsSchedulesRequest command gets UNSUPPORTED_ACCESS since built-in preset with handle hex:01 was attempted to be modified to a not built-in preset - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an UNSUPPORTED_ACCESS (0x7E) error - [1722289468.881] [56642:5458641] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x7e - [1722289468.881] [56642:5458641] [TOO] Error: IM Error 0x0000057E: General error: 0x7e (UNSUPPORTED_ACCESS) - [1722289468.881] [56642:5458641] [DMG] ICR moving to [AwaitingDe] - [1722289468.881] [56642:5458641] [EM] <<< [E:20464i S:35105 M:91065475 (Ack:114933900)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 11a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #11a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 11b: Test Harness writes to the Presets attribute wherein a non - built-in preset is modified to a built-in preset" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #11b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 11c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #11c Test Harness Client calls CommitPresetsSchedulesRequest command gets UNSUPPORTED_ACCESS since non built-in preset with handle hex:03 was attempted to be modified to be built-in - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an UNSUPPORTED_ACCESS (0x7E) error - [1722297542.066] [60654:5591651] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x7e - [1722297542.066] [60654:5591651] [TOO] Error: IM Error 0x0000057E: General error: 0x7e (UNSUPPORTED_ACCESS) - [1722297542.066] [60654:5591651] [DMG] ICR moving to [AwaitingDe] - [1722297542.066] [60654:5591651] [EM] <<< [E:11999i S:35595 M:148057801 (Ack:14642826)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 12a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #12a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 12b: Test Harness writes to the Presets attribute with a preset - that doesn't support names in the PresetTypeFeatures bitmap but has a - name" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #11b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "name": "Occupied", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "hex:03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }, {"presetHandle": "hex:06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 2100, "heatingSetpoint": 2500, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722289461.377] [56636:5458560] [EM] <<< [E:23635i S:58282 M:220756286 (Ack:5366080)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 12c: Test Harness calls the CommitPresetsSchedulesRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C09.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #11c Test Harness Client calls CommitPresetsSchedulesRequest command gets CONSTRAINT_ERROR since we attempted to add a name to a preset with handle hex:01 that doesn't support names. - - ./chip-tool thermostat commit-presets-schedules-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends an CONSTRAINT_ERROR (0x87) error - [1722298150.233] [60910:5602100] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x87 - [1722298150.233] [60910:5602100] [TOO] Error: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1722298150.233] [60910:5602100] [DMG] ICR moving to [AwaitingDe] - [1722298150.233] [60910:5602100] [EM] <<< [E:44287i S:42687 M:5072557 (Ack:66989213)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - #TODO: Add tests for the total number of Presets exceeds the NumberOfPresets supported. Also Add tests for adding presets with preset scenario not present in PresetTypes. - - - label: - "Step 13a: Test Harness calls the StartPresetsSchedulesEditRequest - command to edit presets" - PICS: TSTAT.S.F08 && TSTAT.S.C07.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #13a Test Harness Client calls StartPresetsSchedulesEditRequest command - - ./chip-tool thermostat start-presets-schedules-edit-request 180 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722286001.805] [54149:5392862] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0007 Status=0x0 - [1722286001.805] [54149:5392862] [DMG] ICR moving to [AwaitingDe] - [1722286001.805] [54149:5392862] [EM] <<< [E:7545i S:16937 M:144975449 (Ack:93571372)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286001.806] [54149:5392862] [EM] Flushed pending ack for MessageCounter:93571372 on exchange 7545i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 13b: Test Harness writes to the Presets attribute but calls - CancelPresetsSchedulesEditRequest command to cancel the edit request" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #13b Test Harness Client attempts to write Presets and gets SUCCESS - - ./chip-tool thermostat write presets '[ {"presetHandle": "hex:01", "presetScenario": 1, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": true }, {"presetHandle": "hex:02", "presetScenario": 2, "coolingSetpoint": 2600, "heatingSetpoint": 2500, "builtIn": true }, {"presetHandle": "03", "name": "Sleep", "presetScenario": 3, "coolingSetpoint": 2500, "heatingSetpoint": 2600, "builtIn": false }, {"presetHandle": "04", "name": "Wake", "presetScenario": 4, "coolingSetpoint": 2200, "heatingSetpoint": 2900, "builtIn": false }, {"presetHandle": null, "name": "Vacation", "presetScenario": 5, "coolingSetpoint": 2900, "heatingSetpoint": 2000, "builtIn": false }, {"presetHandle": "06", "name": "GoingToSleep", "presetScenario": 6, "coolingSetpoint": 3000, "heatingSetpoint": 1900, "builtIn": false }]' 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722289461.376] [56636:5458560] [DMG] WriteClient moving to [ResponseRe] - [1722289461.376] [56636:5458560] [DMG] WriteResponseMessage = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIBs = - [1722289461.376] [56636:5458560] [DMG] [ - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.376] [56636:5458560] [DMG] } - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] StatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] }, - [1722289461.376] [56636:5458560] [DMG] - [1722289461.376] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] AttributePathIB = - [1722289461.376] [56636:5458560] [DMG] { - [1722289461.376] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.376] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.376] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.376] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] AttributeStatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] AttributePathIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] Endpoint = 0x1, - [1722289461.377] [56636:5458560] [DMG] Cluster = 0x201, - [1722289461.377] [56636:5458560] [DMG] Attribute = 0x0000_0050, - [1722289461.377] [56636:5458560] [DMG] ListIndex = Null, - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] StatusIB = - [1722289461.377] [56636:5458560] [DMG] { - [1722289461.377] [56636:5458560] [DMG] status = 0x00 (SUCCESS), - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] }, - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] ], - [1722289461.377] [56636:5458560] [DMG] - [1722289461.377] [56636:5458560] [DMG] InteractionModelRevision = 11 - [1722289461.377] [56636:5458560] [DMG] } - [1722289461.377] [56636:5458560] [DMG] WriteClient moving to [AwaitingDe] - [1722286250.504] [54321:5397545] [EM] <<< [E:14426i S:42250 M:116961408 (Ack:156984778)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - [1722286250.504] [54321:5397545] [EM] Flushed pending ack for MessageCounter:156984778 on exchange 14426i - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 13c: Test Harness calls the CancelPresetsSchedulesEditRequest - command" - PICS: TSTAT.S.F08 && TSTAT.S.C08.Rsp - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #13c Test Harness Client calls CancelPresetsSchedulesEditRequest command - - ./chip-tool thermostat cancel-presets-schedules-edit-request 0x12344321 1 - On TH(chip-tool) verify that DUT sends a success response - [1722287841.505] [55282:5425045] [DMG] Received Command Response Status for Endpoint=1 Cluster=0x0000_0201 Command=0x0000_0009 Status=0x0 - [1722287841.505] [55282:5425045] [DMG] ICR moving to [AwaitingDe] - [1722287841.505] [55282:5425045] [EM] <<< [E:46441i S:57071 M:61366563 (Ack:138534230)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 13d: Test Harness reads the Presets attribute after calling the - CancelPresetsSchedulesEditRequest command" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #3c Test Harness Client reads Presets attribute - - ./chip-tool thermostat read presets 0x12344321 1 - On TH(chip-tool) verify that DUT successfully read Presets (but without the Vacation preset added) - [1722299465.497] [62905:5625656] [TOO] Endpoint: 1 Cluster: 0x0000_0201 Attribute 0x0000_0050 DataVersion: 3098962545 - [1722299465.497] [62905:5625656] [TOO] Presets: 5 entries - [1722299465.498] [62905:5625656] [TOO] [1]: { - [1722299465.498] [62905:5625656] [TOO] PresetHandle: 01 - [1722299465.498] [62905:5625656] [TOO] PresetScenario: 1 - [1722299465.498] [62905:5625656] [TOO] CoolingSetpoint: 2500 - [1722299465.498] [62905:5625656] [TOO] HeatingSetpoint: 2600 - [1722299465.498] [62905:5625656] [TOO] BuiltIn: TRUE - [1722299465.498] [62905:5625656] [TOO] } - [1722299465.498] [62905:5625656] [TOO] [2]: { - [1722299465.498] [62905:5625656] [TOO] PresetHandle: 02 - [1722299465.498] [62905:5625656] [TOO] PresetScenario: 2 - [1722299465.498] [62905:5625656] [TOO] CoolingSetpoint: 2600 - [1722299465.498] [62905:5625656] [TOO] HeatingSetpoint: 2500 - [1722299465.498] [62905:5625656] [TOO] BuiltIn: TRUE - [1722299465.498] [62905:5625656] [TOO] } - [1722299465.498] [62905:5625656] [TOO] [3]: { - [1722299465.498] [62905:5625656] [TOO] PresetHandle: 03 - [1722299465.498] [62905:5625656] [TOO] PresetScenario: 3 - [1722299465.498] [62905:5625656] [TOO] Name: Sleep - [1722299465.498] [62905:5625656] [TOO] CoolingSetpoint: 2500 - [1722299465.498] [62905:5625656] [TOO] HeatingSetpoint: 2600 - [1722299465.498] [62905:5625656] [TOO] BuiltIn: FALSE - [1722299465.498] [62905:5625656] [TOO] } - [1722299465.498] [62905:5625656] [TOO] [4]: { - [1722299465.498] [62905:5625656] [TOO] PresetHandle: 04 - [1722299465.498] [62905:5625656] [TOO] PresetScenario: 4 - [1722299465.498] [62905:5625656] [TOO] Name: Wake - [1722299465.498] [62905:5625656] [TOO] CoolingSetpoint: 2200 - [1722299465.498] [62905:5625656] [TOO] HeatingSetpoint: 2900 - [1722299465.498] [62905:5625656] [TOO] BuiltIn: FALSE - [1722299465.498] [62905:5625656] [TOO] } - [1722299465.498] [62905:5625656] [TOO] [5]: { - [1722299465.498] [62905:5625656] [TOO] PresetHandle: 06 - [1722299465.498] [62905:5625656] [TOO] PresetScenario: 6 - [1722299465.498] [62905:5625656] [TOO] Name: Vacationleep - [1722299465.498] [62905:5625656] [TOO] CoolingSetpoint: 2100 - [1722299465.498] [62905:5625656] [TOO] HeatingSetpoint: 2500 - [1722299465.498] [62905:5625656] [TOO] BuiltIn: FALSE - [1722299465.498] [62905:5625656] [TOO] } - [1722299465.498] [62905:5625656] [EM] <<< [E:53084i S:11903 M:249395534 (Ack:245071987)] (S) Msg TX to 1:000000000000006E [FEC4] [UDP:[fe80::1%lo0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck) (B:34) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" From 6c0923661c312db4923404f91c6603bbfa1d5898 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Thu, 1 Aug 2024 09:28:53 +1200 Subject: [PATCH 09/21] Dump details about leaked ExchangeContexts before aborting (#34617) * Dump details about leaked ExchangeContexts before aborting This is implemented via a VerifyOrDieWithObject() variant of the existing VerifyOrDie() macro that calls a DumpToLog() method on the provided object if it exists (otherwise this is simply a no-op). If CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE is not enabled, VerifyOrDieWithObject() simply behaves like a plain VerifyOrDie(). DumpToLog() implementations can use ChipLogFormatRtti to log type information about an object (usually a delegate); if RTTI is disabled this simply outputs whether the object was null or not. * Address review comments * Make gcc happy and improve documentation * Remove unused include * Fix compile error without CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE * Avoid unused parameter warning --- src/lib/support/BUILD.gn | 6 ++- src/lib/support/CodeUtils.h | 16 +++++++ src/lib/support/Compiler.h | 24 ++++++++++ src/lib/support/ObjectDump.h | 57 +++++++++++++++++++++++ src/lib/support/Pool.h | 29 +++++++++++- src/lib/support/logging/TextOnlyLogging.h | 20 ++++++++ src/messaging/ExchangeContext.cpp | 8 ++-- src/messaging/ExchangeContext.h | 8 +++- src/messaging/tests/TestExchange.cpp | 12 +++++ 9 files changed, 172 insertions(+), 8 deletions(-) create mode 100644 src/lib/support/Compiler.h create mode 100644 src/lib/support/ObjectDump.h diff --git a/src/lib/support/BUILD.gn b/src/lib/support/BUILD.gn index 27f52465858b1d..0b1d353821dabf 100644 --- a/src/lib/support/BUILD.gn +++ b/src/lib/support/BUILD.gn @@ -68,6 +68,7 @@ source_set("logging_constants") { source_set("attributes") { sources = [ + "Compiler.h", "DLLUtil.h", "EnforceFormat.h", ] @@ -132,7 +133,10 @@ source_set("text_only_logging") { } source_set("verifymacros") { - sources = [ "CodeUtils.h" ] + sources = [ + "CodeUtils.h", + "ObjectDump.h", + ] public_deps = [ ":attributes", diff --git a/src/lib/support/CodeUtils.h b/src/lib/support/CodeUtils.h index 800123aa456851..fb659c47939afd 100644 --- a/src/lib/support/CodeUtils.h +++ b/src/lib/support/CodeUtils.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -547,6 +548,21 @@ inline void chipDie(void) #define VerifyOrDie(aCondition) VerifyOrDieWithoutLogging(aCondition) #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE +/** + * @def VerifyOrDieWithObject(aCondition, aObject) + * + * Like VerifyOrDie(), but calls DumpObjectToLog() + * on the provided object on failure before aborting + * if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE is enabled. + */ +#if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE +#define VerifyOrDieWithObject(aCondition, aObject) \ + nlABORT_ACTION(aCondition, ::chip::DumpObjectToLog(aObject); \ + ChipLogError(Support, "VerifyOrDie failure at %s:%d: %s", __FILE__, __LINE__, #aCondition)) +#else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE +#define VerifyOrDieWithObject(aCondition, aObject) VerifyOrDieWithoutLogging(aCondition) +#endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE + /** * @def VerifyOrDieWithMsg(aCondition, aModule, aMessage, ...) * diff --git a/src/lib/support/Compiler.h b/src/lib/support/Compiler.h new file mode 100644 index 00000000000000..0c26e185a23349 --- /dev/null +++ b/src/lib/support/Compiler.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// CHIP_HAVE_RTTI: Is C++ RTTI enabled? +#if defined(__clang__) +#define CHIP_HAVE_RTTI __has_feature(cxx_rtti) +#elif defined(__GNUC__) && defined(__GXX_RTTI) +#define CHIP_HAVE_RTTI 1 +#else +#define CHIP_HAVE_RTTI 0 +#endif diff --git a/src/lib/support/ObjectDump.h b/src/lib/support/ObjectDump.h new file mode 100644 index 00000000000000..d297cd5b590141 --- /dev/null +++ b/src/lib/support/ObjectDump.h @@ -0,0 +1,57 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { + +/** + * A dumpable object that can log some useful state for debugging in fatal + * error scenarios by exposing a `void DumpToLog() const` method. The method + * should log key details about the state of object using ChipLogError(). + */ +template +struct IsDumpable : std::false_type +{ +}; +template +struct IsDumpable().DumpToLog())>> : std::true_type +{ +}; + +struct DumpableTypeExample +{ + void DumpToLog() const {}; +}; +static_assert(IsDumpable::value); + +/** + * Calls DumpToLog() on the object, if supported. + */ +template +void DumpObjectToLog([[maybe_unused]] const T * object) +{ + if constexpr (IsDumpable::value) + { + object->DumpToLog(); + } +} + +} // namespace chip diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index e4fb31769f4193..3ab4b8db6713ba 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -263,7 +264,7 @@ class BitMapObjectPool : public internal::StaticAllocatorBitmap { public: BitMapObjectPool() : StaticAllocatorBitmap(mData.mMemory, mUsage, N, sizeof(T)) {} - ~BitMapObjectPool() { VerifyOrDie(Allocated() == 0); } + ~BitMapObjectPool() { VerifyOrDieWithObject(Allocated() == 0, this); } BitmapActiveObjectIterator begin() { return BitmapActiveObjectIterator(this, FirstActiveIndex()); } BitmapActiveObjectIterator end() { return BitmapActiveObjectIterator(this, N); } @@ -323,6 +324,18 @@ class BitMapObjectPool : public internal::StaticAllocatorBitmap return ForEachActiveObjectInner(&proxy, &internal::LambdaProxy::ConstCall); } + void DumpToLog() const + { + ChipLogError(Support, "BitMapObjectPool: %lu allocated", static_cast(Allocated())); + if constexpr (IsDumpable::value) + { + ForEachActiveObject([](const T * object) { + object->DumpToLog(); + return Loop::Continue; + }); + } + } + private: static Loop ReleaseObject(void * context, void * object) { @@ -389,7 +402,7 @@ class HeapObjectPool : public internal::Statistics, public HeapObjectPoolExitHan if (!sIgnoringLeaksOnExit) { // Verify that no live objects remain, to prevent potential use-after-free. - VerifyOrDie(Allocated() == 0); + VerifyOrDieWithObject(Allocated() == 0, this); } #endif // __SANITIZE_ADDRESS__ } @@ -570,6 +583,18 @@ class HeapObjectPool : public internal::Statistics, public HeapObjectPoolExitHan return mObjects.ForEachNode(&proxy, &internal::LambdaProxy::ConstCall); } + void DumpToLog() const + { + ChipLogError(Support, "HeapObjectPool: %lu allocated", static_cast(Allocated())); + if constexpr (IsDumpable::value) + { + ForEachActiveObject([](const T * object) { + object->DumpToLog(); + return Loop::Continue; + }); + } + } + private: static Loop ReleaseObject(void * context, void * object) { diff --git a/src/lib/support/logging/TextOnlyLogging.h b/src/lib/support/logging/TextOnlyLogging.h index dd9e73d0f5aeed..903624183a7d6c 100644 --- a/src/lib/support/logging/TextOnlyLogging.h +++ b/src/lib/support/logging/TextOnlyLogging.h @@ -36,6 +36,7 @@ #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include #if CHIP_SYSTEM_CONFIG_PLATFORM_LOG && defined(CHIP_SYSTEM_CONFIG_PLATFORM_LOG_INCLUDE) #include CHIP_SYSTEM_CONFIG_PLATFORM_LOG_INCLUDE @@ -292,6 +294,24 @@ using LogRedirectCallback_t = void (*)(const char * module, uint8_t category, co #define ChipLogValueExchangeIdFromReceivedHeader(payloadHeader) \ ChipLogValueExchangeId((payloadHeader).GetExchangeID(), !(payloadHeader).IsInitiator()) +/** + * Logging helpers for logging the dynamic type of an object, if possible. + * + * Primarily useful when logging the type of delegates or similar objects when + * performing logging for a fatal error in DumpToLog(). + * + * Example: + * @code + * ChipLogError(Foo, "Delegate=" ChipLogFormatRtti, ChipLogValueRtti(mDelegate)); + * @endcode + */ +#define ChipLogFormatRtti "%s" +#if CHIP_HAVE_RTTI +#define ChipLogValueRtti(ptr) ((ptr) != nullptr ? typeid(*(ptr)).name() : "null") +#else +#define ChipLogValueRtti(ptr) ((ptr) != nullptr ? "?" : "null") +#endif + /** * Logging helpers for protocol ids. A protocol id is a (vendor-id, * protocol-id) pair. diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index 554e5fbce9482d..62c5206f7b272e 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -294,7 +294,7 @@ ExchangeContext::ExchangeContext(ExchangeManager * em, uint16_t ExchangeId, cons mDispatch(GetMessageDispatch(isEphemeralExchange, delegate)), mSession(*this) { - VerifyOrDie(mExchangeMgr == nullptr); + VerifyOrDieWithObject(mExchangeMgr == nullptr, this); mExchangeMgr = em; mExchangeId = ExchangeId; @@ -334,12 +334,12 @@ ExchangeContext::ExchangeContext(ExchangeManager * em, uint16_t ExchangeId, cons ExchangeContext::~ExchangeContext() { - VerifyOrDie(mExchangeMgr != nullptr && GetReferenceCount() == 0); + VerifyOrDieWithObject(mExchangeMgr != nullptr && GetReferenceCount() == 0, this); // // Ensure that DoClose has been called by the time we get here. If not, we have a leak somewhere. // - VerifyOrDie(mFlags.Has(Flags::kFlagClosed)); + VerifyOrDieWithObject(mFlags.Has(Flags::kFlagClosed), this); #if CHIP_CONFIG_ENABLE_ICD_SERVER // TODO(#33075) : Add check for group context to not a req since it serves no purpose @@ -666,7 +666,7 @@ void ExchangeContext::AbortAllOtherCommunicationOnFabric() void ExchangeContext::ExchangeSessionHolder::GrabExpiredSession(const SessionHandle & session) { - VerifyOrDie(session->AsSecureSession()->IsPendingEviction()); + VerifyOrDieWithObject(session->AsSecureSession()->IsPendingEviction(), this); GrabUnchecked(session); } diff --git a/src/messaging/ExchangeContext.h b/src/messaging/ExchangeContext.h index 47cf0ddbef2783..e10ef84ce911be 100644 --- a/src/messaging/ExchangeContext.h +++ b/src/messaging/ExchangeContext.h @@ -158,7 +158,7 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext, SessionHandle GetSessionHandle() const { - VerifyOrDie(mSession); + VerifyOrDieWithObject(mSession, this); auto sessionHandle = mSession.Get(); return std::move(sessionHandle.Value()); } @@ -238,6 +238,12 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext, void ClearInjectedFailures() { mInjectedFailures.ClearAll(); } #endif + void DumpToLog() const + { + ChipLogError(ExchangeManager, "ExchangeContext: " ChipLogFormatExchangeId " delegate=" ChipLogFormatRtti, + ChipLogValueExchangeId(GetExchangeId(), IsInitiator()), ChipLogValueRtti(mDelegate)); + } + private: #if CONFIG_BUILD_FOR_HOST_UNIT_TEST BitFlags mInjectedFailures; diff --git a/src/messaging/tests/TestExchange.cpp b/src/messaging/tests/TestExchange.cpp index f221c999ac4e22..20df66f9d143d9 100644 --- a/src/messaging/tests/TestExchange.cpp +++ b/src/messaging/tests/TestExchange.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -219,4 +220,15 @@ TEST_F(TestExchange, CheckBasicExchangeMessageDispatch) }); } } + +// A crude test to exercise VerifyOrDieWithObject() in ObjectPool and +// the resulting DumpToLog() call on the ExchangeContext. +// TODO: Find a way to automate this test without killing the process. +// TEST_F(TestExchange, DumpExchangePoolToLog) +// { +// MockExchangeDelegate delegate; +// ObjectPool pool; +// pool.CreateObject(&GetExchangeManager(), static_cast(1234), GetSessionAliceToBob(), true, &delegate); +// } + } // namespace From b74eadbbef7ff9c5c2cf7f52dda8943281fcb03a Mon Sep 17 00:00:00 2001 From: Anu Biradar <104591549+abiradarti@users.noreply.github.com> Date: Wed, 31 Jul 2024 19:21:21 -0500 Subject: [PATCH 10/21] [TI] CC13x4_26x4 build fixes (#34682) * lwip pbuf, map file, and hex creation when OTA is disabled * added cc13x4 family define around the non OTA hex creation * whitespace fix * reversed custom factoy data flash with cc13x4 check * more whitespace fixes --- examples/all-clusters-app/cc13x4_26x4/README.md | 2 +- .../all-clusters-app/cc13x4_26x4/main/AppTask.cpp | 8 +++++++- examples/lighting-app/cc13x4_26x4/README.md | 2 +- examples/lighting-app/cc13x4_26x4/src/AppTask.cpp | 8 +++++++- examples/lock-app/cc13x4_26x4/README.md | 2 +- examples/lock-app/cc13x4_26x4/src/AppTask.cpp | 11 ++++++++++- examples/pump-app/cc13x4_26x4/README.md | 2 +- examples/pump-app/cc13x4_26x4/main/AppTask.cpp | 10 +++++++++- examples/pump-controller-app/cc13x4_26x4/README.md | 2 +- .../pump-controller-app/cc13x4_26x4/main/AppTask.cpp | 11 ++++++++++- examples/shell/cc13x4_26x4/README.md | 2 +- src/lwip/cc13xx_26xx/lwipopts.h | 2 +- .../ti_simplelink_sdk/ti_simplelink_executable.gni | 3 +++ 13 files changed, 53 insertions(+), 12 deletions(-) diff --git a/examples/all-clusters-app/cc13x4_26x4/README.md b/examples/all-clusters-app/cc13x4_26x4/README.md index be6a38277edafc..b90e3933c351e5 100644 --- a/examples/all-clusters-app/cc13x4_26x4/README.md +++ b/examples/all-clusters-app/cc13x4_26x4/README.md @@ -109,7 +109,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp index 98926214c4cb36..88099f009f2dac 100644 --- a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp @@ -76,8 +76,10 @@ AppTask AppTask::sAppTask; constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -100,9 +102,9 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask @@ -176,10 +178,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) #endif } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::StartAppTask() { @@ -224,6 +228,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -240,6 +245,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) diff --git a/examples/lighting-app/cc13x4_26x4/README.md b/examples/lighting-app/cc13x4_26x4/README.md index 73718a0bf76a86..5a6f6efb6a53ae 100644 --- a/examples/lighting-app/cc13x4_26x4/README.md +++ b/examples/lighting-app/cc13x4_26x4/README.md @@ -108,7 +108,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp index aa9bdbccefa3c3..6c4ffacdda2565 100644 --- a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp @@ -126,9 +126,9 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask @@ -215,10 +215,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::Init() { @@ -239,6 +241,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -255,6 +258,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -371,6 +375,7 @@ void AppTask::AppTaskMain(void * pvParameter) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -396,6 +401,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { diff --git a/examples/lock-app/cc13x4_26x4/README.md b/examples/lock-app/cc13x4_26x4/README.md index 7ff622a8e14f90..c7d15dcc8533fe 100644 --- a/examples/lock-app/cc13x4_26x4/README.md +++ b/examples/lock-app/cc13x4_26x4/README.md @@ -109,7 +109,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp index b26bd6ae43f8c1..f210aaf1a6e1de 100644 --- a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp @@ -94,8 +94,10 @@ void uiLocked(void); void uiUnlocking(void); void uiUnlocked(void); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -118,10 +120,11 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif + // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask // Init sequence if the device is not yet on a Thread Network. Once the timer @@ -207,10 +210,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::Init() { @@ -230,6 +235,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -246,6 +252,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -418,6 +425,7 @@ void AppTask::AppTaskMain(void * pvParameter) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -443,6 +451,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(LockManager::Action_t aAction) { diff --git a/examples/pump-app/cc13x4_26x4/README.md b/examples/pump-app/cc13x4_26x4/README.md index 1e7e0c33b2136a..5cd2e3c367be79 100644 --- a/examples/pump-app/cc13x4_26x4/README.md +++ b/examples/pump-app/cc13x4_26x4/README.md @@ -108,7 +108,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp index 9ec109313d3ad1..9c409b09256d8b 100644 --- a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp @@ -96,8 +96,10 @@ AppTask AppTask::sAppTask; static DeviceCallbacks sDeviceCallbacks; +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -120,9 +122,9 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask @@ -171,10 +173,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::StartAppTask() { @@ -217,6 +221,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -233,6 +238,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -353,6 +359,7 @@ void AppTask::PostEvent(const AppEvent * aEvent) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -378,6 +385,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) { diff --git a/examples/pump-controller-app/cc13x4_26x4/README.md b/examples/pump-controller-app/cc13x4_26x4/README.md index bd357fb25f2961..9b5eb0e693426d 100644 --- a/examples/pump-controller-app/cc13x4_26x4/README.md +++ b/examples/pump-controller-app/cc13x4_26x4/README.md @@ -110,7 +110,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp index a8d1e1d88f5cd3..d437da1c06d304 100644 --- a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp @@ -83,8 +83,10 @@ static Button_Handle sAppRightHandle; AppTask AppTask::sAppTask; +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -107,10 +109,11 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif + // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask // Init sequence if the device is not yet on a Thread Network. Once the timer @@ -199,10 +202,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::Init() { @@ -222,6 +227,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -238,6 +244,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -352,6 +359,7 @@ void AppTask::PostEvent(const AppEvent * aEvent) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -377,6 +385,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) { diff --git a/examples/shell/cc13x4_26x4/README.md b/examples/shell/cc13x4_26x4/README.md index 3f1923f3db33af..2d5e53d5ec1b18 100644 --- a/examples/shell/cc13x4_26x4/README.md +++ b/examples/shell/cc13x4_26x4/README.md @@ -63,7 +63,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/src/lwip/cc13xx_26xx/lwipopts.h b/src/lwip/cc13xx_26xx/lwipopts.h index d89c33afb5ed84..26a1bb6641cb00 100644 --- a/src/lwip/cc13xx_26xx/lwipopts.h +++ b/src/lwip/cc13xx_26xx/lwipopts.h @@ -89,7 +89,7 @@ #define MEMP_SEPARATE_POOLS (1) #define LWIP_PBUF_FROM_CUSTOM_POOLS (0) #define MEMP_USE_CUSTOM_POOLS (0) -#define PBUF_POOL_SIZE (12) +#define PBUF_POOL_SIZE (18) #define PBUF_POOL_BUFSIZE (1280) #define PBUF_CUSTOM_POOL_IDX_START (MEMP_PBUF_POOL_SMALL) #define PBUF_CUSTOM_POOL_IDX_END (MEMP_PBUF_POOL_LARGE) diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni b/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni index 3df24854297f49..76a59df16bc370 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni @@ -484,6 +484,9 @@ template("ti_simplelink_executable") { } else { # The executable is the final target. data_deps = [ ":${simplelink_target_name}.out" ] + if (ti_simplelink_device_family == "cc13x4_26x4" && custom_factory_data) { + data_deps += [ ":${simplelink_target_name}-and-factory-data.hex" ] + } } if (defined(invoker.data_deps)) { From d938a28d3b81d14c17ef40260302697c94a60dd8 Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:22:33 -0400 Subject: [PATCH 11/21] [ICD] Add missing polling function to NoWifi connectivity manager (#34684) * Add missing polling function to NoWifi connectivity manager * Update GenericConnectivityManagerImpl_NoWiFi.h Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- .../GenericConnectivityManagerImpl_NoWiFi.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h b/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h index e7d29ee4965a85..552603b492f115 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h @@ -78,6 +78,10 @@ class GenericConnectivityManagerImpl_NoWiFi static const char * _WiFiAPModeToStr(ConnectivityManager::WiFiAPMode mode); static const char * _WiFiStationStateToStr(ConnectivityManager::WiFiStationState state); static const char * _WiFiAPStateToStr(ConnectivityManager::WiFiAPState state); + // TODO ICD rework: ambiguous declaration of _SetPollingInterval when thread and no-wifi are both built together +#if CHIP_CONFIG_ENABLE_ICD_SERVER && !CHIP_DEVICE_CONFIG_ENABLE_THREAD + CHIP_ERROR _SetPollingInterval(System::Clock::Milliseconds32 pollingInterval); +#endif private: ImplClass * Impl() { return static_cast(this); } @@ -221,6 +225,15 @@ inline const char * GenericConnectivityManagerImpl_NoWiFi::_WiFiAPSta return nullptr; } +#if CHIP_CONFIG_ENABLE_ICD_SERVER && !CHIP_DEVICE_CONFIG_ENABLE_THREAD +template +inline CHIP_ERROR +GenericConnectivityManagerImpl_NoWiFi::_SetPollingInterval(System::Clock::Milliseconds32 pollingInterval) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#endif + } // namespace Internal } // namespace DeviceLayer } // namespace chip From 43661ab85e1fa64427c05ebc94088f6ef2f10372 Mon Sep 17 00:00:00 2001 From: Rob Bultman Date: Wed, 31 Jul 2024 21:03:32 -0400 Subject: [PATCH 12/21] [OPSTATE] Add Q test script for CountdownTime (#34632) * Add Q test * Added test to test set * Remove unused var * Restyled by autopep8 * Restyled by isort * Fix name * Use pics over other method * Removed unused stuff * Added pipe commands * Fix reset * Get example to report appropriate changes. * WiP * Added some comments * Changes to make things work * Removed dev msgs * Missed some * Removed dev msgs * Straggler * Restyled by clang-format * Restyled by autopep8 * Restyled by isort * Commented unused var * Update examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp * Fix bug --------- Co-authored-by: Restyled.io --- .github/workflows/tests.yaml | 1 + .../include/operational-state-delegate-impl.h | 1 + .../src/operational-state-delegate-impl.cpp | 15 +++ .../linux/AllClustersCommandDelegate.cpp | 50 +++++++- .../linux/AllClustersCommandDelegate.h | 10 ++ src/python_testing/TC_OPSTATE_2_6.py | 62 ++++++++++ src/python_testing/TC_OpstateCommon.py | 112 +++++++++++++++++- 7 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 src/python_testing/TC_OPSTATE_2_6.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 8284b5a9abd284..5e38c6c341bea6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -578,6 +578,7 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OPSTATE_2_3.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OPSTATE_2_4.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OPSTATE_2_5.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OPSTATE_2_6.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OVENOPSTATE_2_1.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OVENOPSTATE_2_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_OVENOPSTATE_2_3.py' diff --git a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h index 60b6b09e9b6511..badadd68cd30a9 100644 --- a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h +++ b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h @@ -138,6 +138,7 @@ class OperationalStateDelegate : public GenericOperationalStateDelegateImpl }; Instance * GetOperationalStateInstance(); +OperationalStateDelegate * GetOperationalStateDelegate(); void Shutdown(); diff --git a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp index d258b8261a1aed..d4a91cf259a2a7 100644 --- a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp @@ -59,6 +59,7 @@ void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperat auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); if (error == CHIP_NO_ERROR) { + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(ErrorStateEnum::kNoError)); } else @@ -73,6 +74,7 @@ void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOpera auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(ErrorStateEnum::kNoError)); } else @@ -96,6 +98,7 @@ void GenericOperationalStateDelegateImpl::HandleStartStateCallback(GenericOperat auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { + GetInstance()->UpdateCountdownTimeFromDelegate(); (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, this); err.Set(to_underlying(ErrorStateEnum::kNoError)); } @@ -113,6 +116,8 @@ void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperati { (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, this); + GetInstance()->UpdateCountdownTimeFromDelegate(); + OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); GetInstance()->GetCurrentOperationalError(current_err); @@ -152,6 +157,11 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data delegate->mPausedTime++; } } + else if (!countdown_time.IsNull() && countdown_time.Value() <= 0) + { + OperationalState::GenericOperationalError noError(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + delegate->HandleStopStateCallback(noError); + } if (state == OperationalState::OperationalStateEnum::kRunning || state == OperationalState::OperationalStateEnum::kPaused) { @@ -173,6 +183,11 @@ OperationalState::Instance * OperationalState::GetOperationalStateInstance() return gOperationalStateInstance; } +OperationalStateDelegate * OperationalState::GetOperationalStateDelegate() +{ + return gOperationalStateDelegate; +} + void OperationalState::Shutdown() { if (gOperationalStateInstance != nullptr) diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index d620731e93dc5c..6c1467fc62a145 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -667,21 +667,65 @@ void AllClustersAppCommandHandler::OnModeChangeHandler(std::string device, std:: void AllClustersAppCommandHandler::OnOperationalStateChange(std::string device, std::string operation, Json::Value param) { - OperationalState::Instance * operationalStateInstance = nullptr; if (device == "Generic") { - operationalStateInstance = OperationalState::GetOperationalStateInstance(); + OnGenericOperationalStateChange(device, operation, param); } else if (device == "Oven") { - operationalStateInstance = OvenCavityOperationalState::GetOperationalStateInstance(); + OnOvenOperationalStateChange(device, operation, param); } else { ChipLogDetail(NotSpecified, "Invalid device type : %s", device.c_str()); return; } +} + +void AllClustersAppCommandHandler::OnGenericOperationalStateChange(std::string device, std::string operation, Json::Value param) +{ + OperationalState::Instance * operationalStateInstance = OperationalState::GetOperationalStateInstance(); + OperationalState::OperationalStateDelegate * operationalStateDelegate = OperationalState::GetOperationalStateDelegate(); + OperationalState::GenericOperationalError noError(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + OperationalState::OperationalStateEnum state = + static_cast(operationalStateInstance->GetCurrentOperationalState()); + if (operation == "Start") + { + operationalStateDelegate->HandleStartStateCallback(noError); + } + else if (operation == "Resume") + { + operationalStateDelegate->HandleResumeStateCallback(noError); + } + else if (operation == "Pause") + { + operationalStateDelegate->HandlePauseStateCallback(noError); + } + else if (operation == "Stop" && state == OperationalState::OperationalStateEnum::kRunning) + { + operationalStateDelegate->HandleStopStateCallback(noError); + } + else if (operation == "OnFault") + { + uint8_t event_id = to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation); + if (!param.isNull()) + { + event_id = to_underlying(static_cast(param.asUInt())); + } + OperationalState::GenericOperationalError err(event_id); + operationalStateInstance->OnOperationalErrorDetected(err); + } + else + { + ChipLogDetail(NotSpecified, "Invalid operation : %s", operation.c_str()); + return; + } +} + +void AllClustersAppCommandHandler::OnOvenOperationalStateChange(std::string device, std::string operation, Json::Value param) +{ + OperationalState::Instance * operationalStateInstance = OvenCavityOperationalState::GetOperationalStateInstance(); if (operation == "Start" || operation == "Resume") { operationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.h b/examples/all-clusters-app/linux/AllClustersCommandDelegate.h index f097c539b54fb6..f1b873fc0d69c4 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.h +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.h @@ -105,6 +105,16 @@ class AllClustersAppCommandHandler * Should be called when it is necessary to change the operational state as a manual operation. */ void OnOperationalStateChange(std::string device, std::string operation, Json::Value param); + + /** + * Should be called when it is necessary to change the operational state as a manual operation. + */ + void OnGenericOperationalStateChange(std::string device, std::string operation, Json::Value param); + + /** + * Should be called when it is necessary to change the operational state as a manual operation. + */ + void OnOvenOperationalStateChange(std::string device, std::string operation, Json::Value param); }; class AllClustersCommandDelegate : public NamedPipeCommandDelegate diff --git a/src/python_testing/TC_OPSTATE_2_6.py b/src/python_testing/TC_OPSTATE_2_6.py new file mode 100644 index 00000000000000..8560452b327712 --- /dev/null +++ b/src/python_testing/TC_OPSTATE_2_6.py @@ -0,0 +1,62 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OPSTATE_2_6(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OPSTATE_2_6(self) -> list[TestStep]: + return self.steps_TC_OPSTATE_BASE_2_6() + + def pics_TC_OPSTATE_2_6(self) -> list[str]: + return ["OPSTATE.S", "OPSTATE.S.A0002"] + + @async_test_body + async def test_TC_OPSTATE_2_6(self): + # endpoint = self.matter_test_config.endpoint + + # await self.TEST_TC_OPSTATE_BASE_2_6(endpoint=endpoint) + await self.TEST_TC_OPSTATE_BASE_2_6(endpoint=1) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OpstateCommon.py b/src/python_testing/TC_OpstateCommon.py index 09dc73e3344c1f..ece50ac90c65b6 100644 --- a/src/python_testing/TC_OpstateCommon.py +++ b/src/python_testing/TC_OpstateCommon.py @@ -28,7 +28,7 @@ from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import EventChangeCallback, TestStep +from matter_testing_support import ClusterAttributeChangeAccumulator, EventChangeCallback, TestStep from mobly import asserts @@ -1082,6 +1082,7 @@ async def TEST_TC_OPSTATE_BASE_2_5(self, endpoint=1): # STEP 7: TH waits for initial-countdown-time self.step(7) + logging.info(f'Sleeping for {initial_countdown_time:.1f} seconds.') time.sleep(initial_countdown_time) # STEP 8: TH sends Stop command to the DUT @@ -1221,3 +1222,112 @@ async def TEST_TC_OPSTATE_BASE_2_5(self, endpoint=1): self.skip_step(20) self.skip_step(21) self.skip_step(22) + + ############################ + # TEST CASE 2.6 - Optional Reports with DUT as Server + ############################ + def steps_TC_OPSTATE_BASE_2_6(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Subscribe to CountdownTime attribute"), + TestStep(3, "Manually put the DUT into a state where it will use the CountdownTime attribute, " + "the initial value of the CountdownTime is greater than 30, " + "and it will begin counting down the CountdownTime attribute."), + TestStep(4, "Over a period of 30 seconds, TH counts all report transactions with an attribute " + "report for the CountdownTime attribute in numberOfReportsReceived"), + TestStep(5, "Until the current operation finishes, TH counts all report transactions with " + "an attribute report for the CountdownTime attribute in numberOfReportsReceived and saves up to 5 such reports."), + TestStep(6, "Manually put the DUT into a state where it will use the CountdownTime attribute, " + "the initial value of the CountdownTime is greater than 30, and it will begin counting down the CountdownTime attribute."), + TestStep(7, "TH reads from the DUT the OperationalState attribute"), + TestStep(8, "Manually put the device in the Paused(0x02) operational state") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_6(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + + self.init_test() + + # commission + self.step(1) + + # Note that this does a subscribe-all instead of subscribing only to the CountdownTime attribute. + # To-Do: Update the TP to subscribe-all. + self.step(2) + sub_handler = ClusterAttributeChangeAccumulator(cluster) + await sub_handler.start(self.default_controller, self.dut_node_id, endpoint) + + self.step(3) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_RUNNING")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Start") + time.sleep(1) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(3) + + sub_handler.reset() + self.step(4) + logging.info('Test will now collect data for 30 seconds') + time.sleep(30) + + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + sub_handler.reset() + asserts.assert_less_equal(count, 5, "Received more than 5 reports for CountdownTime") + asserts.assert_greater_equal(count, 0, "Did not receive any reports for CountdownTime") + + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attributes.OperationalState) + if attr_value == cluster.Enums.OperationalStateEnum.kRunning: + self.step(5) + wait_count = 0 + while (attr_value != cluster.Enums.OperationalStateEnum.kStopped) and (wait_count < 20): + time.sleep(1) + wait_count = wait_count + 1 + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attributes.OperationalState) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_less_equal(count, 5, "Received more than 5 reports for CountdownTime") + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(5) + + sub_handler.reset() + self.step(6) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_RUNNING")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Start") + time.sleep(1) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(6) + + self.step(7) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + sub_handler.reset() + self.step(8) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_PAUSED")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Pause") + time.sleep(1) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(8) From d7872bc66b5c9d1a7896edfda9e5f3697d5cd487 Mon Sep 17 00:00:00 2001 From: Douglas Rocha Ferraz Date: Wed, 31 Jul 2024 21:09:23 -0400 Subject: [PATCH 13/21] YAML update to BRBINFO, ProductId (#34513) * Bridged Device Information Cluster, Attribute ProductID test reflects marking as O, not X * Update src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml Co-authored-by: Terence Hampson * corrected pics * corrected pics * WIP Bridged ICD, commissioning to both fabrics * wip testing sending KeepActive * update to bridged-device-basic-information.xml and zap generated files * removed unrelated file --------- Co-authored-by: Terence Hampson Co-authored-by: Andrei Litvin --- .../placeholder/linux/apps/app1/config.matter | 1 + .../placeholder/linux/apps/app2/config.matter | 1 + .../certification/Test_TC_BRBINFO_2_1.yaml | 22 ++--- .../chip/bridged-device-basic-information.xml | 1 + .../data_model/controller-clusters.matter | 1 + .../chip/devicecontroller/ChipClusters.java | 27 ++++++ .../devicecontroller/ClusterIDMapping.java | 1 + .../devicecontroller/ClusterReadMapping.java | 11 +++ .../BridgedDeviceBasicInformationCluster.kt | 91 +++++++++++++++++++ .../CHIPAttributeTLVValueDecoder.cpp | 16 ++++ .../python/chip/clusters/CHIPClusters.py | 6 ++ .../python/chip/clusters/Objects.py | 18 ++++ .../MTRAttributeSpecifiedCheck.mm | 3 + .../MTRAttributeTLVValueDecoder.mm | 11 +++ .../CHIP/zap-generated/MTRBaseClusters.h | 6 ++ .../CHIP/zap-generated/MTRBaseClusters.mm | 36 ++++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 1 + .../CHIP/zap-generated/MTRClusterNames.mm | 4 + .../CHIP/zap-generated/MTRClusters.h | 2 + .../CHIP/zap-generated/MTRClusters.mm | 5 + .../zap-generated/attributes/Accessors.cpp | 47 ++++++++++ .../zap-generated/attributes/Accessors.h | 6 ++ .../zap-generated/cluster-objects.cpp | 2 + .../zap-generated/cluster-objects.h | 13 +++ .../app-common/zap-generated/ids/Attributes.h | 4 + .../zap-generated/cluster/Commands.h | 5 + .../cluster/logging/DataModelLogger.cpp | 5 + .../zap-generated/cluster/Commands.h | 91 +++++++++++++++++++ 28 files changed, 423 insertions(+), 14 deletions(-) diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 665714e076ed91..d956aee9081628 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -2465,6 +2465,7 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute optional char_string<32> vendorName = 1; readonly attribute optional vendor_id vendorID = 2; readonly attribute optional char_string<32> productName = 3; + readonly attribute optional int16u productID = 4; attribute optional char_string<32> nodeLabel = 5; readonly attribute optional int16u hardwareVersion = 7; readonly attribute optional char_string<64> hardwareVersionString = 8; diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index d1fd025cef5bff..e892c7ebcf9e1e 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -2422,6 +2422,7 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute optional char_string<32> vendorName = 1; readonly attribute optional vendor_id vendorID = 2; readonly attribute optional char_string<32> productName = 3; + readonly attribute optional int16u productID = 4; attribute optional char_string<32> nodeLabel = 5; readonly attribute optional int16u hardwareVersion = 7; readonly attribute optional char_string<64> hardwareVersionString = 8; diff --git a/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml b/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml index a0b87e6c3897b9..b869f2d99ee8f0 100644 --- a/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml @@ -140,21 +140,15 @@ tests: response: value: ProductNameValue - - label: - "Step 14: TH reads attribute ID 4 from the DUT (matches in ID to - ProductID in the parent cluster, but is absent on the - BridgedDeviceBasicInformation cluster)." - PICS: BRBINFO.S - cluster: "AnyCommands" - command: "ReadById" - arguments: - values: - - name: "ClusterId" - value: BRBINFO.ClusterId - - name: "AttributeId" - value: 0x0004 + - label: "Step 14: TH reads ProductID from the DUT" + PICS: BRBINFO.S.A0004 + command: "readAttribute" + attribute: "ProductID" response: - error: UNSUPPORTED_ATTRIBUTE + constraints: + type: int16u + minValue: 1 + maxValue: 65534 - label: "Step 17: TH reads NodeLabel from the DUT" PICS: BRBINFO.S.A0005 diff --git a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml index 74f88bea39e623..b33ccb740f9a54 100644 --- a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml +++ b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml @@ -80,6 +80,7 @@ limitations under the License. VendorName VendorID ProductName + ProductID NodeLabel HardwareVersion HardwareVersionString diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index eb9999da242c69..24a9e2fb45c2b0 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -2348,6 +2348,7 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute optional char_string<32> vendorName = 1; readonly attribute optional vendor_id vendorID = 2; readonly attribute optional char_string<32> productName = 3; + readonly attribute optional int16u productID = 4; attribute optional char_string<32> nodeLabel = 5; readonly attribute optional int16u hardwareVersion = 7; readonly attribute optional char_string<64> hardwareVersionString = 8; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 950e7f818d0db3..f7fc1ea6955305 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -15166,6 +15166,7 @@ public static class BridgedDeviceBasicInformationCluster extends BaseChipCluster private static final long VENDOR_NAME_ATTRIBUTE_ID = 1L; private static final long VENDOR_I_D_ATTRIBUTE_ID = 2L; private static final long PRODUCT_NAME_ATTRIBUTE_ID = 3L; + private static final long PRODUCT_I_D_ATTRIBUTE_ID = 4L; private static final long NODE_LABEL_ATTRIBUTE_ID = 5L; private static final long HARDWARE_VERSION_ATTRIBUTE_ID = 7L; private static final long HARDWARE_VERSION_STRING_ATTRIBUTE_ID = 8L; @@ -15314,6 +15315,32 @@ public void onSuccess(byte[] tlv) { }, PRODUCT_NAME_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readProductIDAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PRODUCT_I_D_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PRODUCT_I_D_ATTRIBUTE_ID, true); + } + + public void subscribeProductIDAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PRODUCT_I_D_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PRODUCT_I_D_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readNodeLabelAttribute( CharStringAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NODE_LABEL_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 6c8fccf1cdeda1..37936a56fba6a6 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -4460,6 +4460,7 @@ public enum Attribute { VendorName(1L), VendorID(2L), ProductName(3L), + ProductID(4L), NodeLabel(5L), HardwareVersion(7L), HardwareVersionString(8L), diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index c6a6f189ba36eb..417ecce949fdc9 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -4659,6 +4659,17 @@ private static Map readBridgedDeviceBasicInformationInt readBridgedDeviceBasicInformationProductNameCommandParams ); result.put("readProductNameAttribute", readBridgedDeviceBasicInformationProductNameAttributeInteractionInfo); + Map readBridgedDeviceBasicInformationProductIDCommandParams = new LinkedHashMap(); + InteractionInfo readBridgedDeviceBasicInformationProductIDAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.BridgedDeviceBasicInformationCluster) cluster).readProductIDAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readBridgedDeviceBasicInformationProductIDCommandParams + ); + result.put("readProductIDAttribute", readBridgedDeviceBasicInformationProductIDAttributeInteractionInfo); Map readBridgedDeviceBasicInformationNodeLabelCommandParams = new LinkedHashMap(); InteractionInfo readBridgedDeviceBasicInformationNodeLabelAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt index 64742323eec50c..8e56362d8da349 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt @@ -395,6 +395,97 @@ class BridgedDeviceBasicInformationCluster( } } + suspend fun readProductIDAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun subscribeProductIDAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 4u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Productid attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UShortSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readNodeLabelAttribute(): String? { val ATTRIBUTE_ID: UInt = 5u diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 49af03e873c702..33c041e5bbe85f 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -10140,6 +10140,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue, value)); return value; } + case Attributes::ProductID::Id: { + using TypeInfo = Attributes::ProductID::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } case Attributes::NodeLabel::Id: { using TypeInfo = Attributes::NodeLabel::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 275e2e6b63f099..588c3da4f020eb 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -3324,6 +3324,12 @@ class ChipClusters: "type": "str", "reportable": True, }, + 0x00000004: { + "attributeName": "ProductID", + "attributeId": 0x00000004, + "type": "int", + "reportable": True, + }, 0x00000005: { "attributeName": "NodeLabel", "attributeId": 0x00000005, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 9ef896538fb595..b84ad31879c1d5 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -11660,6 +11660,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="vendorName", Tag=0x00000001, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="vendorID", Tag=0x00000002, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="productName", Tag=0x00000003, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="productID", Tag=0x00000004, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="nodeLabel", Tag=0x00000005, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="hardwareVersion", Tag=0x00000007, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="hardwareVersionString", Tag=0x00000008, Type=typing.Optional[str]), @@ -11684,6 +11685,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: vendorName: 'typing.Optional[str]' = None vendorID: 'typing.Optional[uint]' = None productName: 'typing.Optional[str]' = None + productID: 'typing.Optional[uint]' = None nodeLabel: 'typing.Optional[str]' = None hardwareVersion: 'typing.Optional[uint]' = None hardwareVersionString: 'typing.Optional[str]' = None @@ -11830,6 +11832,22 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[str]' = None + @dataclass + class ProductID(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000039 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000004 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + @dataclass class NodeLabel(ClusterAttributeDescriptor): @ChipUtility.classproperty diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 241c006a7074fd..d214e061ec9f65 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -1530,6 +1530,9 @@ static BOOL AttributeIsSpecifiedInBridgedDeviceBasicInformationCluster(Attribute case Attributes::ProductName::Id: { return YES; } + case Attributes::ProductID::Id: { + return YES; + } case Attributes::NodeLabel::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index a13bd2f3f40433..7920a04dc597b1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -4450,6 +4450,17 @@ static id _Nullable DecodeAttributeValueForBridgedDeviceBasicInformationCluster( } return value; } + case Attributes::ProductID::Id: { + using TypeInfo = Attributes::ProductID::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedShort:cppValue]; + return value; + } case Attributes::NodeLabel::Id: { using TypeInfo = Attributes::NodeLabel::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 615dbceadcdf57..bdd3bcf1f78a2f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -3744,6 +3744,12 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeProductNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeProductIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeProductIDWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeProductIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeNodeLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index ddbcc431e5dd86..e2bb0e376dffe1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -31056,6 +31056,42 @@ + (void)readAttributeProductNameWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } +- (void)readAttributeProductIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductID::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeProductIDWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductID::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeProductIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductID::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + - (void)readAttributeNodeLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BridgedDeviceBasicInformation::Attributes::NodeLabel::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index caec13ea1b284f..98ca2f96263d50 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -1945,6 +1945,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeVendorNameID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeVendorIDID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductNameID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, + MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeNodeLabelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000005, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeHardwareVersionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000007, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeHardwareVersionStringID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000008, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index a46ab76ca9cc17..5f9d1b8e510ed6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -2391,6 +2391,10 @@ result = @"ProductName"; break; + case MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductIDID: + result = @"ProductID"; + break; + case MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeNodeLabelID: result = @"NodeLabel"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index eb27ead337eda9..8da2b1f2ec4f2b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -1722,6 +1722,8 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeProductNameWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeProductIDWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeNodeLabelWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index fe261fb6825dc8..ec6f0c49b74d73 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -5070,6 +5070,11 @@ - (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveP return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductNameID) params:params]; } +- (NSDictionary * _Nullable)readAttributeProductIDWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductIDID) params:params]; +} + - (NSDictionary * _Nullable)readAttributeNodeLabelWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeNodeLabelID) params:params]; diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 81744d5c6994ff..1ba55467d670af 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -7697,6 +7697,53 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpa } // namespace ProductName +namespace ProductID { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ProductID + namespace NodeLabel { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index cd73287e99b4ca..53e24c079fc4bd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -1225,6 +1225,12 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpa Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty); } // namespace ProductName +namespace ProductID { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ProductID + namespace NodeLabel { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value); // char_string Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value); diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 881ec25faa191d..af49e0617caa1f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -8228,6 +8228,8 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, vendorID); case Attributes::ProductName::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, productName); + case Attributes::ProductID::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, productID); case Attributes::NodeLabel::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, nodeLabel); case Attributes::HardwareVersion::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index c52692f1ad4591..25ded74c85a287 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -11134,6 +11134,18 @@ struct TypeInfo static constexpr size_t MaxLength() { return 32; } }; } // namespace ProductName +namespace ProductID { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ProductID::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ProductID namespace NodeLabel { struct TypeInfo { @@ -11348,6 +11360,7 @@ struct TypeInfo Attributes::VendorName::TypeInfo::DecodableType vendorName; Attributes::VendorID::TypeInfo::DecodableType vendorID = static_cast(0); Attributes::ProductName::TypeInfo::DecodableType productName; + Attributes::ProductID::TypeInfo::DecodableType productID = static_cast(0); Attributes::NodeLabel::TypeInfo::DecodableType nodeLabel; Attributes::HardwareVersion::TypeInfo::DecodableType hardwareVersion = static_cast(0); Attributes::HardwareVersionString::TypeInfo::DecodableType hardwareVersionString; diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index b6e3a64e1bcfc7..0a144da9030e42 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -1894,6 +1894,10 @@ namespace ProductName { static constexpr AttributeId Id = 0x00000003; } // namespace ProductName +namespace ProductID { +static constexpr AttributeId Id = 0x00000004; +} // namespace ProductID + namespace NodeLabel { static constexpr AttributeId Id = 0x00000005; } // namespace NodeLabel diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 01d9f7edc46758..9367f844d3c16b 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -3489,6 +3489,7 @@ class TimeSynchronizationSetDefaultNTP : public ClusterCommand | * VendorName | 0x0001 | | * VendorID | 0x0002 | | * ProductName | 0x0003 | +| * ProductID | 0x0004 | | * NodeLabel | 0x0005 | | * HardwareVersion | 0x0007 | | * HardwareVersionString | 0x0008 | @@ -18274,6 +18275,7 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "vendor-name", Attributes::VendorName::Id, credsIssuerConfig), // make_unique(Id, "vendor-id", Attributes::VendorID::Id, credsIssuerConfig), // make_unique(Id, "product-name", Attributes::ProductName::Id, credsIssuerConfig), // + make_unique(Id, "product-id", Attributes::ProductID::Id, credsIssuerConfig), // make_unique(Id, "node-label", Attributes::NodeLabel::Id, credsIssuerConfig), // make_unique(Id, "hardware-version", Attributes::HardwareVersion::Id, credsIssuerConfig), // make_unique(Id, "hardware-version-string", Attributes::HardwareVersionString::Id, credsIssuerConfig), // @@ -18300,6 +18302,8 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "product-name", Attributes::ProductName::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "product-id", 0, UINT16_MAX, Attributes::ProductID::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "node-label", Attributes::NodeLabel::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "hardware-version", 0, UINT16_MAX, Attributes::HardwareVersion::Id, @@ -18344,6 +18348,7 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "vendor-name", Attributes::VendorName::Id, credsIssuerConfig), // make_unique(Id, "vendor-id", Attributes::VendorID::Id, credsIssuerConfig), // make_unique(Id, "product-name", Attributes::ProductName::Id, credsIssuerConfig), // + make_unique(Id, "product-id", Attributes::ProductID::Id, credsIssuerConfig), // make_unique(Id, "node-label", Attributes::NodeLabel::Id, credsIssuerConfig), // make_unique(Id, "hardware-version", Attributes::HardwareVersion::Id, credsIssuerConfig), // make_unique(Id, "hardware-version-string", Attributes::HardwareVersionString::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index d34bbe31914c4a..fb156dee2d45dc 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -11066,6 +11066,11 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("ProductName", 1, value); } + case BridgedDeviceBasicInformation::Attributes::ProductID::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ProductID", 1, value); + } case BridgedDeviceBasicInformation::Attributes::NodeLabel::Id: { chip::CharSpan value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 59410234dd7589..d31a6b22803f88 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -40149,6 +40149,7 @@ class SubscribeAttributeTimeSynchronizationClusterRevision : public SubscribeAtt | * VendorName | 0x0001 | | * VendorID | 0x0002 | | * ProductName | 0x0003 | +| * ProductID | 0x0004 | | * NodeLabel | 0x0005 | | * HardwareVersion | 0x0007 | | * HardwareVersionString | 0x0008 | @@ -40477,6 +40478,92 @@ class SubscribeAttributeBridgedDeviceBasicInformationProductName : public Subscr } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ProductID + */ +class ReadBridgedDeviceBasicInformationProductID : public ReadAttribute { +public: + ReadBridgedDeviceBasicInformationProductID() + : ReadAttribute("product-id") + { + } + + ~ReadBridgedDeviceBasicInformationProductID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::ProductID::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeProductIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"BridgedDeviceBasicInformation.ProductID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("BridgedDeviceBasicInformation ProductID read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeBridgedDeviceBasicInformationProductID : public SubscribeAttribute { +public: + SubscribeAttributeBridgedDeviceBasicInformationProductID() + : SubscribeAttribute("product-id") + { + } + + ~SubscribeAttributeBridgedDeviceBasicInformationProductID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::ProductID::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeProductIDWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"BridgedDeviceBasicInformation.ProductID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute NodeLabel */ @@ -192407,6 +192494,10 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // From 9a55b3eddac9c9cdb4dda75ab41ee803ca7eb3e8 Mon Sep 17 00:00:00 2001 From: Shao Ling Tan <161761051+shaoltan-amazon@users.noreply.github.com> Date: Wed, 31 Jul 2024 19:25:28 -0700 Subject: [PATCH 14/21] Fix simplified Linux tv-casting-app gn build error. (#34692) --- examples/tv-casting-app/linux/BUILD.gn | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/tv-casting-app/linux/BUILD.gn b/examples/tv-casting-app/linux/BUILD.gn index 0e4b9820538412..3a6cfb1e6f82f6 100644 --- a/examples/tv-casting-app/linux/BUILD.gn +++ b/examples/tv-casting-app/linux/BUILD.gn @@ -58,10 +58,12 @@ executable("chip-tv-casting-app") { if (chip_build_libshell) { defines += [ "ENABLE_CHIP_SHELL" ] - sources += [ - "CastingShellCommands.cpp", - "CastingShellCommands.h", - ] + if (!chip_casting_simplified) { + sources += [ + "CastingShellCommands.cpp", + "CastingShellCommands.h", + ] + } } output_dir = root_out_dir From 27501d48fd4f1dbc8bbb49ae7a767fe46429af6f Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Thu, 1 Aug 2024 04:27:52 +0200 Subject: [PATCH 15/21] adding parallel execution to restyle-diff (#34663) * adding parallel execution to restyle-diff * using xargs to call restyle-paths * fixing Copyright year * restyle the restyler --- scripts/helpers/restyle-diff.sh | 66 +++++++++++++++++---------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/scripts/helpers/restyle-diff.sh b/scripts/helpers/restyle-diff.sh index 5cc9ffa6b081fc..5f37c69762e281 100755 --- a/scripts/helpers/restyle-diff.sh +++ b/scripts/helpers/restyle-diff.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2020-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,57 +21,54 @@ # you've written is kosher to CI # # Usage: -# restyle-diff.sh [-d] [ref] +# restyle-diff.sh [-d] [-p] [ref] # # if unspecified, ref defaults to upstream/master (or master) # -d sets container's log level to DEBUG, if unspecified the default log level will remain (info level) +# -p pulls the Docker image before running the restyle paths # here=${0%/*} set -e +MAX_ARGS=256 +pull_image=0 + CHIP_ROOT=$(cd "$here/../.." && pwd) cd "$CHIP_ROOT" -docker_run() { - if [ -t 0 ]; then - exec docker run --tty "$@" - - else - exec docker run "$@" - - fi -} - restyle-paths() { - image=restyled/restyler:edge - for path in "$@"; do - ( - docker_run --tty --interactive --rm \ - --env LOG_LEVEL \ - --env LOG_DESTINATION \ - --env LOG_FORMAT \ - --env LOG_COLOR \ - --env HOST_DIRECTORY="$PWD" \ - --env UNRESTRICTED=1 \ - --volume "$PWD":/code \ - --volume /tmp:/tmp \ - --volume /var/run/docker.sock:/var/run/docker.sock \ - --entrypoint restyle-path \ - "$image" "$path" - ) - done + docker run \ + --env LOG_LEVEL \ + --env LOG_DESTINATION \ + --env LOG_FORMAT \ + --env LOG_COLOR \ + --env HOST_DIRECTORY="$PWD" \ + --env UNRESTRICTED=1 \ + --volume "$PWD":/code \ + --volume /tmp:/tmp \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + --entrypoint restyle-path \ + "$image" "$@" + } +#This was added to be able to use xargs to call the function restyle-paths +export -f restyle-paths + while [[ $# -gt 0 ]]; do case "$1" in -d) export LOG_LEVEL="DEBUG" shift ;; + -p) + pull_image=1 + shift + ;; *) ref="$1" shift @@ -81,8 +78,13 @@ done if [[ -z "$ref" ]]; then ref="master" - git remote | grep -qxF upstream && ref="upstream/master" + git remote | grep -qxF upstream && ref="upstream/master" && git fetch upstream fi -mapfile -t paths < <(git diff --ignore-submodules --name-only --merge-base "$ref") -restyle-paths "${paths[@]}" +if [[ $pull_image -eq 1 ]]; then + docker pull restyled/restyler:edge +fi + +paths=$(git diff --ignore-submodules --name-only --merge-base "$ref") + +echo "$paths" | xargs -n "$MAX_ARGS" bash -c 'restyle-paths "$@"' From 22c65cbb5d3b22b23242fa1c71c97e7744c11cc9 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 31 Jul 2024 22:29:18 -0400 Subject: [PATCH 16/21] Add some bits to exercise global structs/enums to Unit Testing cluster. (#34540) * Adds things to the Unit Testing cluster XML. * This requires those things to be enabled in all-clusters-app, all-clusters-minimal-app, and one of the chef contact sensors to pass CI. * That requires an implementation in test-cluster-server * At which point might as well add a YAML test to exercise it all. --- .../all-clusters-app.matter | 25 + .../all-clusters-common/all-clusters-app.zap | 80 ++ .../all-clusters-minimal-app.matter | 25 + .../all-clusters-minimal-app.zap | 80 ++ .../rootnode_contactsensor_27f76aeaf5.matter | 25 + .../rootnode_contactsensor_27f76aeaf5.zap | 80 ++ .../test-cluster-server.cpp | 66 ++ src/app/tests/suites/TestCluster.yaml | 75 +- .../zcl/data-model/chip/test-cluster.xml | 29 + .../zcl/zcl-with-test-extensions.json | 4 +- src/app/zap-templates/zcl/zcl.json | 4 +- .../data_model/controller-clusters.matter | 19 + .../chip/devicecontroller/ChipClusters.java | 201 ++++ .../chip/devicecontroller/ChipStructs.java | 114 ++- .../devicecontroller/ClusterIDMapping.java | 22 + .../devicecontroller/ClusterInfoMapping.java | 109 +++ .../devicecontroller/ClusterReadMapping.java | 22 + .../devicecontroller/ClusterWriteMapping.java | 44 + .../chip/devicecontroller/cluster/files.gni | 1 + .../structs/UnitTestingClusterNestedStruct.kt | 18 +- .../structs/UnitTestingClusterSimpleStruct.kt | 16 +- .../UnitTestingClusterTestGlobalStruct.kt | 92 ++ .../cluster/clusters/UnitTestingCluster.kt | 866 +++++++++++++++--- .../java/matter/controller/cluster/files.gni | 1 + .../structs/UnitTestingClusterNestedStruct.kt | 18 +- .../structs/UnitTestingClusterSimpleStruct.kt | 16 +- .../UnitTestingClusterTestGlobalStruct.kt | 92 ++ .../cluster/ChipClusterEventStructTest.kt | 25 +- .../cluster/ChipClusterStructTest.kt | 120 ++- .../CHIPAttributeTLVValueDecoder.cpp | 336 ++++++- .../CHIPEventTLVValueDecoder.cpp | 47 +- .../python/chip/clusters/CHIPClusters.py | 36 + .../python/chip/clusters/Objects.py | 112 +++ .../CHIP/templates/availability.yaml | 37 +- .../MTRAttributeSpecifiedCheck.mm | 12 + .../MTRAttributeTLVValueDecoder.mm | 122 +++ .../CHIP/zap-generated/MTRBaseClusters.h | 39 + .../CHIP/zap-generated/MTRBaseClusters.mm | 344 +++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 6 + .../CHIP/zap-generated/MTRClusterNames.mm | 16 + .../CHIP/zap-generated/MTRClusters.h | 17 + .../CHIP/zap-generated/MTRClusters.mm | 91 ++ .../zap-generated/MTRCommandPayloadsObjc.h | 53 ++ .../zap-generated/MTRCommandPayloadsObjc.mm | 314 +++++++ .../MTRCommandPayloads_Internal.h | 12 + .../zap-generated/MTREventTLVValueDecoder.mm | 10 + .../CHIP/zap-generated/MTRStructsObjc.h | 2 + .../CHIP/zap-generated/MTRStructsObjc.mm | 10 +- .../zap-generated/attributes/Accessors.cpp | 139 +++ .../zap-generated/attributes/Accessors.h | 23 + .../app-common/zap-generated/callback.h | 6 + .../zap-generated/cluster-objects.cpp | 96 ++ .../zap-generated/cluster-objects.h | 139 ++- .../app-common/zap-generated/ids/Attributes.h | 16 + .../app-common/zap-generated/ids/Commands.h | 8 + .../zap-generated/cluster/Commands.h | 64 ++ .../cluster/ComplexArgumentParser.cpp | 92 +- .../cluster/ComplexArgumentParser.h | 10 +- .../cluster/logging/DataModelLogger.cpp | 116 ++- .../cluster/logging/DataModelLogger.h | 8 +- .../zap-generated/cluster/Commands.h | 815 +++++++++++++++- 61 files changed, 5155 insertions(+), 282 deletions(-) create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 3dd2b0f99fb439..f69ed20583379c 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -6949,6 +6949,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -6981,6 +6982,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -7066,6 +7068,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -7101,6 +7105,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -7252,6 +7258,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -7305,6 +7316,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -7388,6 +7404,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } @@ -9283,6 +9302,8 @@ endpoint 1 { ram attribute timedWriteBoolean; callback attribute generalErrorBoolean; callback attribute clusterErrorBoolean; + ram attribute globalEnum; + callback attribute globalStruct; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; @@ -9317,6 +9338,8 @@ endpoint 1 { ram attribute nullableRangeRestrictedInt16u default = 200; ram attribute nullableRangeRestrictedInt16s default = -100; callback attribute writeOnlyInt8u default = 0; + ram attribute nullableGlobalEnum; + callback attribute nullableGlobalStruct; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; ram attribute meiInt8u default = 0; @@ -9342,6 +9365,7 @@ endpoint 1 { handle command TestListInt8UReverseRequest; handle command StringEchoResponse; handle command TestEnumsRequest; + handle command GlobalEchoResponse; handle command TestNullableOptionalRequest; handle command SimpleStructEchoRequest; handle command TimedInvokeRequest; @@ -9351,6 +9375,7 @@ endpoint 1 { handle command TestBatchHelperRequest; handle command TestSecondBatchHelperRequest; handle command StringEchoRequest; + handle command GlobalEchoRequest; handle command TestDifferentVendorMeiRequest; handle command TestDifferentVendorMeiResponse; } diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index a052433002d237..7b3ccf977dbc2b 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -22341,6 +22341,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestNullableOptionalRequest", "code": 15, @@ -22413,6 +22421,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoRequest", + "code": 25, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "TestDifferentVendorMeiRequest", "code": 4294049962, @@ -23183,6 +23199,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "global_enum", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "global_struct", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, @@ -23727,6 +23775,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "nullable_global_enum", + "code": 16435, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "nullable_global_struct", + "code": 16436, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 4bf0d15e54f799..7db7a1c97c61b0 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -5540,6 +5540,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -5572,6 +5573,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -5657,6 +5659,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -5692,6 +5696,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -5843,6 +5849,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -5896,6 +5907,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -5979,6 +5995,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } @@ -6840,6 +6859,8 @@ endpoint 1 { ram attribute timedWriteBoolean; callback attribute generalErrorBoolean; callback attribute clusterErrorBoolean; + ram attribute globalEnum; + callback attribute globalStruct; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; @@ -6874,6 +6895,8 @@ endpoint 1 { ram attribute nullableRangeRestrictedInt16u default = 200; ram attribute nullableRangeRestrictedInt16s default = -100; callback attribute writeOnlyInt8u default = 0; + ram attribute nullableGlobalEnum; + callback attribute nullableGlobalStruct; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; ram attribute meiInt8u default = 0; @@ -6899,6 +6922,7 @@ endpoint 1 { handle command TestListInt8UReverseRequest; handle command StringEchoResponse; handle command TestEnumsRequest; + handle command GlobalEchoResponse; handle command TestNullableOptionalRequest; handle command SimpleStructEchoRequest; handle command TimedInvokeRequest; @@ -6908,6 +6932,7 @@ endpoint 1 { handle command TestBatchHelperRequest; handle command TestSecondBatchHelperRequest; handle command StringEchoRequest; + handle command GlobalEchoRequest; handle command TestDifferentVendorMeiRequest; handle command TestDifferentVendorMeiResponse; } diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap index 57f2c0412fca55..560e95a7ec180a 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap @@ -9081,6 +9081,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestNullableOptionalRequest", "code": 15, @@ -9153,6 +9161,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoRequest", + "code": 25, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "TestDifferentVendorMeiRequest", "code": 4294049962, @@ -9923,6 +9939,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "global_enum", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "global_struct", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, @@ -10467,6 +10515,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "nullable_global_enum", + "code": 16435, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "nullable_global_struct", + "code": 16436, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter index 5735b2cf936ff4..6e7ce6b18132ea 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -1570,6 +1570,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -1602,6 +1603,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -1687,6 +1689,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -1722,6 +1726,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -1873,6 +1879,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -1926,6 +1937,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -2009,6 +2025,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } @@ -2332,6 +2351,8 @@ endpoint 1 { ram attribute timedWriteBoolean; callback attribute generalErrorBoolean; callback attribute clusterErrorBoolean; + ram attribute globalEnum; + callback attribute globalStruct; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; @@ -2366,6 +2387,8 @@ endpoint 1 { ram attribute nullableRangeRestrictedInt16u default = 200; ram attribute nullableRangeRestrictedInt16s default = -100; callback attribute writeOnlyInt8u default = 0; + ram attribute nullableGlobalEnum; + callback attribute nullableGlobalStruct; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; ram attribute meiInt8u default = 0; @@ -2390,6 +2413,7 @@ endpoint 1 { handle command TestListNestedStructListArgumentRequest; handle command TestListInt8UReverseRequest; handle command TestEnumsRequest; + handle command GlobalEchoResponse; handle command TestNullableOptionalRequest; handle command SimpleStructEchoRequest; handle command TimedInvokeRequest; @@ -2398,6 +2422,7 @@ endpoint 1 { handle command TestEmitTestFabricScopedEventRequest; handle command TestBatchHelperRequest; handle command TestSecondBatchHelperRequest; + handle command GlobalEchoRequest; handle command TestDifferentVendorMeiRequest; handle command TestDifferentVendorMeiResponse; } diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap index 590dea9f9f3c8e..02a553e03f9cd1 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap @@ -3252,6 +3252,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestNullableOptionalRequest", "code": 15, @@ -3316,6 +3324,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoRequest", + "code": 25, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "TestDifferentVendorMeiRequest", "code": 4294049962, @@ -4086,6 +4102,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "global_enum", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "global_struct", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, @@ -4630,6 +4678,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "nullable_global_enum", + "code": 16435, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "nullable_global_struct", + "code": 16436, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/src/app/clusters/test-cluster-server/test-cluster-server.cpp b/src/app/clusters/test-cluster-server/test-cluster-server.cpp index 4b6fc979336ab3..9bd925780524eb 100644 --- a/src/app/clusters/test-cluster-server/test-cluster-server.cpp +++ b/src/app/clusters/test-cluster-server/test-cluster-server.cpp @@ -101,8 +101,12 @@ class TestAttrAccess : public AttributeAccessInterface AttributeValueDecoder & aDecoder); CHIP_ERROR ReadStructAttribute(AttributeValueEncoder & aEncoder); CHIP_ERROR WriteStructAttribute(AttributeValueDecoder & aDecoder); + CHIP_ERROR ReadGlobalStruct(AttributeValueEncoder & aEncoder); + CHIP_ERROR WriteGlobalStruct(AttributeValueDecoder & aDecoder); CHIP_ERROR ReadNullableStruct(AttributeValueEncoder & aEncoder); CHIP_ERROR WriteNullableStruct(AttributeValueDecoder & aDecoder); + CHIP_ERROR ReadNullableGlobalStruct(AttributeValueEncoder & aEncoder); + CHIP_ERROR WriteNullableGlobalStruct(AttributeValueDecoder & aDecoder); CHIP_ERROR ReadListFabricScopedAttribute(AttributeValueEncoder & aEncoder); CHIP_ERROR WriteListFabricScopedAttribute(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder); }; @@ -126,7 +130,9 @@ size_t gListLongOctetStringLen = kAttributeListLength; Structs::TestListStructOctet::Type listStructOctetStringData[kAttributeListLength]; OctetStringData gStructAttributeByteSpanData; Structs::SimpleStruct::Type gStructAttributeValue; +Globals::Structs::TestGlobalStruct::Type gGlobalStructAttributeValue; NullableStruct::TypeInfo::Type gNullableStructAttributeValue; +DataModel::Nullable gNullableGlobalStructAttributeValue; chip::app::Clusters::UnitTesting::Structs::TestFabricScoped::Type gListFabricScopedAttributeValue[kAttributeListLength]; uint8_t gListFabricScoped_fabricSensitiveInt8uList[kAttributeListLength][kFabricSensitiveIntListLength]; @@ -198,6 +204,9 @@ CHIP_ERROR TestAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attribu case StructAttr::Id: { return ReadStructAttribute(aEncoder); } + case GlobalStruct::Id: { + return ReadGlobalStruct(aEncoder); + } case ListLongOctetString::Id: { return ReadListLongOctetStringAttribute(aEncoder); } @@ -207,6 +216,9 @@ CHIP_ERROR TestAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attribu case NullableStruct::Id: { return ReadNullableStruct(aEncoder); } + case NullableGlobalStruct::Id: { + return ReadNullableGlobalStruct(aEncoder); + } case GeneralErrorBoolean::Id: { return StatusIB(Protocols::InteractionModel::Status::InvalidDataType).ToChipError(); } @@ -249,9 +261,15 @@ CHIP_ERROR TestAttrAccess::Write(const ConcreteDataAttributePath & aPath, Attrib case StructAttr::Id: { return WriteStructAttribute(aDecoder); } + case GlobalStruct::Id: { + return WriteGlobalStruct(aDecoder); + } case NullableStruct::Id: { return WriteNullableStruct(aDecoder); } + case NullableGlobalStruct::Id: { + return WriteNullableGlobalStruct(aDecoder); + } case GeneralErrorBoolean::Id: { return StatusIB(Protocols::InteractionModel::Status::InvalidDataType).ToChipError(); } @@ -276,6 +294,26 @@ CHIP_ERROR TestAttrAccess::WriteNullableStruct(AttributeValueDecoder & aDecoder) return aDecoder.Decode(gNullableStructAttributeValue); } +CHIP_ERROR TestAttrAccess::ReadNullableGlobalStruct(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(gNullableGlobalStructAttributeValue); +} + +CHIP_ERROR TestAttrAccess::WriteNullableGlobalStruct(AttributeValueDecoder & aDecoder) +{ + Attributes::NullableGlobalStruct::TypeInfo::DecodableType temp; + ReturnErrorOnFailure(aDecoder.Decode(temp)); + + if (!temp.IsNull()) + { + // We don't support a nonempty charspan here for now. + VerifyOrReturnError(temp.Value().name.empty(), CHIP_ERROR_BUFFER_TOO_SMALL); + } + + gNullableGlobalStructAttributeValue = temp; + return CHIP_NO_ERROR; +} + CHIP_ERROR TestAttrAccess::ReadListInt8uAttribute(AttributeValueEncoder & aEncoder) { return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { @@ -588,6 +626,23 @@ CHIP_ERROR TestAttrAccess::WriteStructAttribute(AttributeValueDecoder & aDecoder return CHIP_NO_ERROR; } +CHIP_ERROR TestAttrAccess::ReadGlobalStruct(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(gGlobalStructAttributeValue); +} + +CHIP_ERROR TestAttrAccess::WriteGlobalStruct(AttributeValueDecoder & aDecoder) +{ + // We don't support a nonempty charspan here for now. + Attributes::GlobalStruct::TypeInfo::DecodableType temp; + ReturnErrorOnFailure(aDecoder.Decode(temp)); + + VerifyOrReturnError(temp.name.empty(), CHIP_ERROR_BUFFER_TOO_SMALL); + + gGlobalStructAttributeValue = temp; + return CHIP_NO_ERROR; +} + CHIP_ERROR TestAttrAccess::ReadListFabricScopedAttribute(AttributeValueEncoder & aEncoder) { return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { @@ -1114,6 +1169,17 @@ bool emberAfUnitTestingClusterTestSecondBatchHelperRequestCallback( commandData.fillCharacter); } +bool emberAfUnitTestingClusterGlobalEchoRequestCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const Commands::GlobalEchoRequest::DecodableType & commandData) +{ + Commands::GlobalEchoResponse::Type response; + response.field1 = commandData.field1; + response.field2 = commandData.field2; + + commandObj->AddResponse(commandPath, response); + return true; +} + // ----------------------------------------------------------------------------- // Plugin initialization diff --git a/src/app/tests/suites/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index 308240a0dd537d..d2ff0cb2d0f27e 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -3912,6 +3912,7 @@ tests: 22, 23, 24, + 25, 4294049962, ] @@ -3919,7 +3920,7 @@ tests: command: "readAttribute" attribute: "GeneratedCommandList" response: - value: [0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 4294049979] + value: [0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 4294049979] - label: "Validate presence of MEI attribute" command: "readAttribute" @@ -3960,3 +3961,75 @@ tests: g: 1.5, h: 3.14159265358979, } + + # Globals testing + - label: "Write global-struct-typed attribute" + command: "writeAttribute" + attribute: "global_struct" + arguments: + value: + { + Name: "", + MyBitmap: 0x02, + MyEnum: TestGlobalEnum.SomeOtherValue, + } + + - label: "Read global-struct-typed attribute" + command: "readAttribute" + attribute: "global_struct" + response: + value: { + # Purposefully using non-symbolic values to make sure things work right. + Name: "", + MyBitmap: 0x02, + MyEnum: 1, + } + + - label: "Write nullable global-struct-typed attribute" + command: "writeAttribute" + attribute: "nullable_global_struct" + arguments: + value: { Name: "", MyBitmap: 0x01, MyEnum: TestGlobalEnum.SomeValue } + + - label: "Read nullable global-struct-typed attribute" + command: "readAttribute" + attribute: "nullable_global_struct" + response: + value: { Name: "", MyBitmap: 0x01, MyEnum: 0 } + + - label: "Write nullable global-struct-typed attribute as null" + command: "writeAttribute" + attribute: "nullable_global_struct" + arguments: + value: null + + - label: "Read nullable global-struct-typed attribute a second time" + command: "readAttribute" + attribute: "nullable_global_struct" + response: + value: null + + - label: "Send a command with global types" + command: "GlobalEchoRequest" + arguments: + values: + - name: "field1" + value: + { + Name: "", + MyBitmap: 0x02, + MyEnum: TestGlobalEnum.FinalValue, + } + - name: "field2" + value: TestGlobalEnum.SomeOtherValue + response: + values: + - name: "field1" + value: + { + Name: "", + MyBitmap: 0x02, + MyEnum: TestGlobalEnum.FinalValue, + } + - name: "field2" + value: TestGlobalEnum.SomeOtherValue diff --git a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml index f010838f933b03..c289ee9f1c4338 100644 --- a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml @@ -58,6 +58,7 @@ limitations under the License. + @@ -65,6 +66,7 @@ limitations under the License. + @@ -198,6 +200,9 @@ limitations under the License. cluster_error_boolean + global_enum + global_struct + nullable_boolean nullable_bitmap8 nullable_bitmap16 @@ -232,8 +237,14 @@ limitations under the License. nullable_range_restricted_int16u nullable_range_restricted_int16s + write_only_int8u + nullable_global_enum + nullable_global_struct + mei_int8u @@ -474,6 +485,16 @@ limitations under the License. + + + Command that takes arguments that are global structs/enums and the + response just echoes them back. + + + + + @@ -622,6 +643,14 @@ limitations under the License. + + + Response to GlobalEchoRequest. + + + + + Response to TestDifferentVendorMeiRequest, which is a command having a different MEI vendor ID than the cluster. diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 4c5a59200e7d49..44de496f06f544 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -299,7 +299,9 @@ "struct_attr", "nullable_struct", "general_error_boolean", - "cluster_error_boolean" + "cluster_error_boolean", + "global_struct", + "nullable_global_struct" ], "Thread Border Router Management": [ "BorderRouterName", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 777847fb7f06ad..a72b44ee03084a 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -297,7 +297,9 @@ "struct_attr", "nullable_struct", "general_error_boolean", - "cluster_error_boolean" + "cluster_error_boolean", + "global_struct", + "nullable_global_struct" ], "Thread Border Router Management": [ "BorderRouterName", diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 24a9e2fb45c2b0..c0e1f7cb0f2eb7 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9747,6 +9747,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -9779,6 +9780,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -9864,6 +9866,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -9899,6 +9903,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -10050,6 +10056,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -10103,6 +10114,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -10186,6 +10202,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index f7fc1ea6955305..e8ba5badd39616 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -65210,6 +65210,8 @@ public static class UnitTestingCluster extends BaseChipCluster { private static final long TIMED_WRITE_BOOLEAN_ATTRIBUTE_ID = 48L; private static final long GENERAL_ERROR_BOOLEAN_ATTRIBUTE_ID = 49L; private static final long CLUSTER_ERROR_BOOLEAN_ATTRIBUTE_ID = 50L; + private static final long GLOBAL_ENUM_ATTRIBUTE_ID = 51L; + private static final long GLOBAL_STRUCT_ATTRIBUTE_ID = 52L; private static final long UNSUPPORTED_ATTRIBUTE_ID = 255L; private static final long NULLABLE_BOOLEAN_ATTRIBUTE_ID = 16384L; private static final long NULLABLE_BITMAP8_ATTRIBUTE_ID = 16385L; @@ -65245,6 +65247,8 @@ public static class UnitTestingCluster extends BaseChipCluster { private static final long NULLABLE_RANGE_RESTRICTED_INT16U_ATTRIBUTE_ID = 16424L; private static final long NULLABLE_RANGE_RESTRICTED_INT16S_ATTRIBUTE_ID = 16425L; private static final long WRITE_ONLY_INT8U_ATTRIBUTE_ID = 16426L; + private static final long NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID = 16435L; + private static final long NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID = 16436L; private static final long MEI_INT8U_ATTRIBUTE_ID = 4294070017L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; @@ -66288,6 +66292,47 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } + public void globalEchoRequest(GlobalEchoResponseCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2) { + globalEchoRequest(callback, field1, field2, 0); + } + + public void globalEchoRequest(GlobalEchoResponseCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2, int timedInvokeTimeoutMs) { + final long commandId = 25L; + + ArrayList elements = new ArrayList<>(); + final long field1FieldID = 0L; + BaseTLVType field1tlvValue = field1.encodeTlv(); + elements.add(new StructElement(field1FieldID, field1tlvValue)); + + final long field2FieldID = 1L; + BaseTLVType field2tlvValue = new UIntType(field2); + elements.add(new StructElement(field2FieldID, field2tlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long field1FieldID = 0L; + ChipStructs.UnitTestingClusterTestGlobalStruct field1 = null; + final long field2FieldID = 1L; + Integer field2 = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == field1FieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + field1 = ChipStructs.UnitTestingClusterTestGlobalStruct.decodeTlv(castingValue); + } + } else if (element.contextTagNum() == field2FieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + field2 = castingValue.value(Integer.class); + } + } + } + callback.onSuccess(field1, field2); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + public void testDifferentVendorMeiRequest(TestDifferentVendorMeiResponseCallback callback, Integer arg1) { testDifferentVendorMeiRequest(callback, arg1, 0); } @@ -66381,6 +66426,10 @@ public interface StringEchoResponseCallback extends BaseClusterCallback { void onSuccess(byte[] payload); } + public interface GlobalEchoResponseCallback extends BaseClusterCallback { + void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2); + } + public interface TestDifferentVendorMeiResponseCallback extends BaseClusterCallback { void onSuccess(Integer arg1, Long eventNumber); } @@ -66413,6 +66462,10 @@ public interface ListFabricScopedAttributeCallback extends BaseAttributeCallback void onSuccess(List value); } + public interface GlobalStructAttributeCallback extends BaseAttributeCallback { + void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct value); + } + public interface NullableBooleanAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable Boolean value); } @@ -66545,6 +66598,14 @@ public interface NullableRangeRestrictedInt16sAttributeCallback extends BaseAttr void onSuccess(@Nullable Integer value); } + public interface NullableGlobalEnumAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Integer value); + } + + public interface NullableGlobalStructAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value); + } + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -68207,6 +68268,76 @@ public void onSuccess(byte[] tlv) { }, CLUSTER_ERROR_BOOLEAN_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readGlobalEnumAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_ENUM_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_ENUM_ATTRIBUTE_ID, true); + } + + public void writeGlobalEnumAttribute(DefaultClusterCallback callback, Integer value) { + writeGlobalEnumAttribute(callback, value, 0); + } + + public void writeGlobalEnumAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), GLOBAL_ENUM_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeGlobalEnumAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_ENUM_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_ENUM_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGlobalStructAttribute( + GlobalStructAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_STRUCT_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_STRUCT_ATTRIBUTE_ID, true); + } + + public void writeGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value) { + writeGlobalStructAttribute(callback, value, 0); + } + + public void writeGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value.encodeTlv(); + writeAttribute(new WriteAttributesCallbackImpl(callback), GLOBAL_STRUCT_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeGlobalStructAttribute( + GlobalStructAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_STRUCT_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_STRUCT_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readUnsupportedAttribute( BooleanAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, UNSUPPORTED_ATTRIBUTE_ID); @@ -69432,6 +69563,76 @@ public void onSuccess(byte[] tlv) { }, WRITE_ONLY_INT8U_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readNullableGlobalEnumAttribute( + NullableGlobalEnumAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID, true); + } + + public void writeNullableGlobalEnumAttribute(DefaultClusterCallback callback, Integer value) { + writeNullableGlobalEnumAttribute(callback, value, 0); + } + + public void writeNullableGlobalEnumAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeNullableGlobalEnumAttribute( + NullableGlobalEnumAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readNullableGlobalStructAttribute( + NullableGlobalStructAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID, true); + } + + public void writeNullableGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value) { + writeNullableGlobalStructAttribute(callback, value, 0); + } + + public void writeNullableGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? value.encodeTlv() : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeNullableGlobalStructAttribute( + NullableGlobalStructAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readMeiInt8uAttribute( IntegerAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MEI_INT8U_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index df78372f96c945..5ab4c29beb623b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -12899,6 +12899,7 @@ public static class UnitTestingClusterSimpleStruct { public Integer f; public Float g; public Double h; + public Optional i; private static final long A_ID = 0L; private static final long B_ID = 1L; private static final long C_ID = 2L; @@ -12907,6 +12908,7 @@ public static class UnitTestingClusterSimpleStruct { private static final long F_ID = 5L; private static final long G_ID = 6L; private static final long H_ID = 7L; + private static final long I_ID = 8L; public UnitTestingClusterSimpleStruct( Integer a, @@ -12916,7 +12918,8 @@ public UnitTestingClusterSimpleStruct( String e, Integer f, Float g, - Double h + Double h, + Optional i ) { this.a = a; this.b = b; @@ -12926,6 +12929,7 @@ public UnitTestingClusterSimpleStruct( this.f = f; this.g = g; this.h = h; + this.i = i; } public StructType encodeTlv() { @@ -12938,6 +12942,7 @@ public StructType encodeTlv() { values.add(new StructElement(F_ID, new UIntType(f))); values.add(new StructElement(G_ID, new FloatType(g))); values.add(new StructElement(H_ID, new DoubleType(h))); + values.add(new StructElement(I_ID, i.map((nonOptionali) -> new UIntType(nonOptionali)).orElse(new EmptyType()))); return new StructType(values); } @@ -12954,6 +12959,7 @@ public static UnitTestingClusterSimpleStruct decodeTlv(BaseTLVType tlvValue) { Integer f = null; Float g = null; Double h = null; + Optional i = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == A_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -12995,6 +13001,11 @@ public static UnitTestingClusterSimpleStruct decodeTlv(BaseTLVType tlvValue) { DoubleType castingValue = element.value(DoubleType.class); h = castingValue.value(Double.class); } + } else if (element.contextTagNum() == I_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + i = Optional.of(castingValue.value(Integer.class)); + } } } return new UnitTestingClusterSimpleStruct( @@ -13005,7 +13016,8 @@ public static UnitTestingClusterSimpleStruct decodeTlv(BaseTLVType tlvValue) { e, f, g, - h + h, + i ); } @@ -13037,6 +13049,9 @@ public String toString() { output.append("\th: "); output.append(h); output.append("\n"); + output.append("\ti: "); + output.append(i); + output.append("\n"); output.append("}\n"); return output.toString(); } @@ -13407,18 +13422,22 @@ public static class UnitTestingClusterNestedStruct { public Integer a; public Boolean b; public ChipStructs.UnitTestingClusterSimpleStruct c; + public Optional d; private static final long A_ID = 0L; private static final long B_ID = 1L; private static final long C_ID = 2L; + private static final long D_ID = 3L; public UnitTestingClusterNestedStruct( Integer a, Boolean b, - ChipStructs.UnitTestingClusterSimpleStruct c + ChipStructs.UnitTestingClusterSimpleStruct c, + Optional d ) { this.a = a; this.b = b; this.c = c; + this.d = d; } public StructType encodeTlv() { @@ -13426,6 +13445,7 @@ public StructType encodeTlv() { values.add(new StructElement(A_ID, new UIntType(a))); values.add(new StructElement(B_ID, new BooleanType(b))); values.add(new StructElement(C_ID, c.encodeTlv())); + values.add(new StructElement(D_ID, d.map((nonOptionald) -> nonOptionald.encodeTlv()).orElse(new EmptyType()))); return new StructType(values); } @@ -13437,6 +13457,7 @@ public static UnitTestingClusterNestedStruct decodeTlv(BaseTLVType tlvValue) { Integer a = null; Boolean b = null; ChipStructs.UnitTestingClusterSimpleStruct c = null; + Optional d = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == A_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -13453,12 +13474,18 @@ public static UnitTestingClusterNestedStruct decodeTlv(BaseTLVType tlvValue) { StructType castingValue = element.value(StructType.class); c = ChipStructs.UnitTestingClusterSimpleStruct.decodeTlv(castingValue); } + } else if (element.contextTagNum() == D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + d = Optional.of(ChipStructs.UnitTestingClusterTestGlobalStruct.decodeTlv(castingValue)); + } } } return new UnitTestingClusterNestedStruct( a, b, - c + c, + d ); } @@ -13475,6 +13502,9 @@ public String toString() { output.append("\tc: "); output.append(c); output.append("\n"); + output.append("\td: "); + output.append(d); + output.append("\n"); output.append("}\n"); return output.toString(); } @@ -13722,4 +13752,80 @@ public String toString() { return output.toString(); } } +public static class UnitTestingClusterTestGlobalStruct { + public String name; + public @Nullable Long myBitmap; + public @Nullable Optional myEnum; + private static final long NAME_ID = 0L; + private static final long MY_BITMAP_ID = 1L; + private static final long MY_ENUM_ID = 2L; + + public UnitTestingClusterTestGlobalStruct( + String name, + @Nullable Long myBitmap, + @Nullable Optional myEnum + ) { + this.name = name; + this.myBitmap = myBitmap; + this.myEnum = myEnum; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(NAME_ID, new StringType(name))); + values.add(new StructElement(MY_BITMAP_ID, myBitmap != null ? new UIntType(myBitmap) : new NullType())); + values.add(new StructElement(MY_ENUM_ID, myEnum != null ? myEnum.map((nonOptionalmyEnum) -> new UIntType(nonOptionalmyEnum)).orElse(new EmptyType()) : new NullType())); + + return new StructType(values); + } + + public static UnitTestingClusterTestGlobalStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String name = null; + @Nullable Long myBitmap = null; + @Nullable Optional myEnum = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + name = castingValue.value(String.class); + } + } else if (element.contextTagNum() == MY_BITMAP_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + myBitmap = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == MY_ENUM_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + myEnum = Optional.of(castingValue.value(Integer.class)); + } + } + } + return new UnitTestingClusterTestGlobalStruct( + name, + myBitmap, + myEnum + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("UnitTestingClusterTestGlobalStruct {\n"); + output.append("\tname: "); + output.append(name); + output.append("\n"); + output.append("\tmyBitmap: "); + output.append(myBitmap); + output.append("\n"); + output.append("\tmyEnum: "); + output.append(myEnum); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 37936a56fba6a6..bad71209a40272 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -17755,6 +17755,8 @@ public enum Attribute { TimedWriteBoolean(48L), GeneralErrorBoolean(49L), ClusterErrorBoolean(50L), + GlobalEnum(51L), + GlobalStruct(52L), Unsupported(255L), NullableBoolean(16384L), NullableBitmap8(16385L), @@ -17790,6 +17792,8 @@ public enum Attribute { NullableRangeRestrictedInt16u(16424L), NullableRangeRestrictedInt16s(16425L), WriteOnlyInt8u(16426L), + NullableGlobalEnum(16435L), + NullableGlobalStruct(16436L), MeiInt8u(4294070017L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), @@ -17865,6 +17869,7 @@ public enum Command { TestBatchHelperRequest(22L), TestSecondBatchHelperRequest(23L), StringEchoRequest(24L), + GlobalEchoRequest(25L), TestDifferentVendorMeiRequest(4294049962L),; private final long id; Command(long id) { @@ -18223,6 +18228,23 @@ public static StringEchoRequestCommandField value(int id) throws NoSuchFieldErro } throw new NoSuchFieldError(); } + }public enum GlobalEchoRequestCommandField {Field1(0),Field2(1),; + private final int id; + GlobalEchoRequestCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static GlobalEchoRequestCommandField value(int id) throws NoSuchFieldError { + for (GlobalEchoRequestCommandField field : GlobalEchoRequestCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } }public enum TestDifferentVendorMeiRequestCommandField {Arg1(0),; private final int id; TestDifferentVendorMeiRequestCommandField(int id) { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 2ba2e50bb11ee8..1d398ff42e2c9d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -20908,6 +20908,30 @@ public void onError(Exception error) { } } + public static class DelegatedUnitTestingClusterGlobalEchoResponseCallback implements ChipClusters.UnitTestingCluster.GlobalEchoResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2) { + Map responseValues = new LinkedHashMap<>(); + + // field1: Struct TestGlobalStruct + // Conversion from this type to Java is not properly implemented yet + CommandResponseInfo field2ResponseValue = new CommandResponseInfo("field2", "Integer"); + responseValues.put(field2ResponseValue, field2); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedUnitTestingClusterTestDifferentVendorMeiResponseCallback implements ChipClusters.UnitTestingCluster.TestDifferentVendorMeiResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21078,6 +21102,27 @@ public void onError(Exception ex) { } } + public static class DelegatedUnitTestingClusterGlobalStructAttributeCallback implements ChipClusters.UnitTestingCluster.GlobalStructAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.UnitTestingClusterTestGlobalStruct"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedUnitTestingClusterNullableBooleanAttributeCallback implements ChipClusters.UnitTestingCluster.NullableBooleanAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21771,6 +21816,48 @@ public void onError(Exception ex) { } } + public static class DelegatedUnitTestingClusterNullableGlobalEnumAttributeCallback implements ChipClusters.UnitTestingCluster.NullableGlobalEnumAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Integer value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedUnitTestingClusterNullableGlobalStructAttributeCallback implements ChipClusters.UnitTestingCluster.NullableGlobalStructAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.UnitTestingClusterTestGlobalStruct"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedUnitTestingClusterGeneratedCommandListAttributeCallback implements ChipClusters.UnitTestingCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -29576,6 +29663,28 @@ public Map> getCommandMap() { ); unitTestingClusterInteractionInfoMap.put("stringEchoRequest", unitTestingstringEchoRequestInteractionInfo); + Map unitTestingglobalEchoRequestCommandParams = new LinkedHashMap(); + + + CommandParameterInfo unitTestingglobalEchoRequestfield2CommandParameterInfo = new CommandParameterInfo("field2", Integer.class, Integer.class); + unitTestingglobalEchoRequestCommandParams.put("field2",unitTestingglobalEchoRequestfield2CommandParameterInfo); + InteractionInfo unitTestingglobalEchoRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster) + .globalEchoRequest((ChipClusters.UnitTestingCluster.GlobalEchoResponseCallback) callback + , (ChipStructs.UnitTestingClusterTestGlobalStruct) + commandArguments.get("field1") + + , (Integer) + commandArguments.get("field2") + + ); + }, + () -> new DelegatedUnitTestingClusterGlobalEchoResponseCallback(), + unitTestingglobalEchoRequestCommandParams + ); + unitTestingClusterInteractionInfoMap.put("globalEchoRequest", unitTestingglobalEchoRequestInteractionInfo); + Map unitTestingtestDifferentVendorMeiRequestCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingtestDifferentVendorMeiRequestarg1CommandParameterInfo = new CommandParameterInfo("arg1", Integer.class, Integer.class); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 417ecce949fdc9..32d3d4f1a51756 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -20846,6 +20846,17 @@ private static Map readUnitTestingInteractionInfo() { readUnitTestingClusterErrorBooleanCommandParams ); result.put("readClusterErrorBooleanAttribute", readUnitTestingClusterErrorBooleanAttributeInteractionInfo); + Map readUnitTestingGlobalEnumCommandParams = new LinkedHashMap(); + InteractionInfo readUnitTestingGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).readGlobalEnumAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readUnitTestingGlobalEnumCommandParams + ); + result.put("readGlobalEnumAttribute", readUnitTestingGlobalEnumAttributeInteractionInfo); Map readUnitTestingUnsupportedCommandParams = new LinkedHashMap(); InteractionInfo readUnitTestingUnsupportedAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -21220,6 +21231,17 @@ private static Map readUnitTestingInteractionInfo() { readUnitTestingWriteOnlyInt8uCommandParams ); result.put("readWriteOnlyInt8uAttribute", readUnitTestingWriteOnlyInt8uAttributeInteractionInfo); + Map readUnitTestingNullableGlobalEnumCommandParams = new LinkedHashMap(); + InteractionInfo readUnitTestingNullableGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).readNullableGlobalEnumAttribute( + (ChipClusters.UnitTestingCluster.NullableGlobalEnumAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedUnitTestingClusterNullableGlobalEnumAttributeCallback(), + readUnitTestingNullableGlobalEnumCommandParams + ); + result.put("readNullableGlobalEnumAttribute", readUnitTestingNullableGlobalEnumAttributeInteractionInfo); Map readUnitTestingMeiInt8uCommandParams = new LinkedHashMap(); InteractionInfo readUnitTestingMeiInt8uAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 32759bb97af64c..93a48d76bf61dc 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -4827,6 +4827,28 @@ public Map> getWriteAttributeMap() { writeUnitTestingClusterErrorBooleanCommandParams ); writeUnitTestingInteractionInfo.put("writeClusterErrorBooleanAttribute", writeUnitTestingClusterErrorBooleanAttributeInteractionInfo); + Map writeUnitTestingGlobalEnumCommandParams = new LinkedHashMap(); + CommandParameterInfo unitTestingglobalEnumCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeUnitTestingGlobalEnumCommandParams.put( + "value", + unitTestingglobalEnumCommandParameterInfo + ); + InteractionInfo writeUnitTestingGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).writeGlobalEnumAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeUnitTestingGlobalEnumCommandParams + ); + writeUnitTestingInteractionInfo.put("writeGlobalEnumAttribute", writeUnitTestingGlobalEnumAttributeInteractionInfo); Map writeUnitTestingUnsupportedCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingunsupportedCommandParameterInfo = new CommandParameterInfo( @@ -5575,6 +5597,28 @@ public Map> getWriteAttributeMap() { writeUnitTestingWriteOnlyInt8uCommandParams ); writeUnitTestingInteractionInfo.put("writeWriteOnlyInt8uAttribute", writeUnitTestingWriteOnlyInt8uAttributeInteractionInfo); + Map writeUnitTestingNullableGlobalEnumCommandParams = new LinkedHashMap(); + CommandParameterInfo unitTestingnullableGlobalEnumCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeUnitTestingNullableGlobalEnumCommandParams.put( + "value", + unitTestingnullableGlobalEnumCommandParameterInfo + ); + InteractionInfo writeUnitTestingNullableGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).writeNullableGlobalEnumAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeUnitTestingNullableGlobalEnumCommandParams + ); + writeUnitTestingInteractionInfo.put("writeNullableGlobalEnumAttribute", writeUnitTestingNullableGlobalEnumAttributeInteractionInfo); Map writeUnitTestingMeiInt8uCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingmeiInt8uCommandParameterInfo = new CommandParameterInfo( diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index e101562093412c..3cbd5cb52ce17a 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -151,6 +151,7 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UserLabelClusterLabelStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt index 6ec856c422029a..74cfa88e79291f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.structs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -26,12 +27,14 @@ class UnitTestingClusterNestedStruct( val a: UInt, val b: Boolean, val c: UnitTestingClusterSimpleStruct, + val d: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterNestedStruct {\n") append("\ta : $a\n") append("\tb : $b\n") append("\tc : $c\n") + append("\td : $d\n") append("}\n") } @@ -41,6 +44,10 @@ class UnitTestingClusterNestedStruct( put(ContextSpecificTag(TAG_A), a) put(ContextSpecificTag(TAG_B), b) c.toTlv(ContextSpecificTag(TAG_C), this) + if (d.isPresent) { + val optd = d.get() + optd.toTlv(ContextSpecificTag(TAG_D), this) + } endStructure() } } @@ -49,16 +56,25 @@ class UnitTestingClusterNestedStruct( private const val TAG_A = 0 private const val TAG_B = 1 private const val TAG_C = 2 + private const val TAG_D = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterNestedStruct { tlvReader.enterStructure(tlvTag) val a = tlvReader.getUInt(ContextSpecificTag(TAG_A)) val b = tlvReader.getBoolean(ContextSpecificTag(TAG_B)) val c = UnitTestingClusterSimpleStruct.fromTlv(ContextSpecificTag(TAG_C), tlvReader) + val d = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_D))) { + Optional.of( + UnitTestingClusterTestGlobalStruct.fromTlv(ContextSpecificTag(TAG_D), tlvReader) + ) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterNestedStruct(a, b, c) + return UnitTestingClusterNestedStruct(a, b, c, d) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt index 24f06fb8752b6c..8a6d89c228c11d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.structs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -31,6 +32,7 @@ class UnitTestingClusterSimpleStruct( val f: UInt, val g: Float, val h: Double, + val i: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterSimpleStruct {\n") @@ -42,6 +44,7 @@ class UnitTestingClusterSimpleStruct( append("\tf : $f\n") append("\tg : $g\n") append("\th : $h\n") + append("\ti : $i\n") append("}\n") } @@ -56,6 +59,10 @@ class UnitTestingClusterSimpleStruct( put(ContextSpecificTag(TAG_F), f) put(ContextSpecificTag(TAG_G), g) put(ContextSpecificTag(TAG_H), h) + if (i.isPresent) { + val opti = i.get() + put(ContextSpecificTag(TAG_I), opti) + } endStructure() } } @@ -69,6 +76,7 @@ class UnitTestingClusterSimpleStruct( private const val TAG_F = 5 private const val TAG_G = 6 private const val TAG_H = 7 + private const val TAG_I = 8 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterSimpleStruct { tlvReader.enterStructure(tlvTag) @@ -80,10 +88,16 @@ class UnitTestingClusterSimpleStruct( val f = tlvReader.getUInt(ContextSpecificTag(TAG_F)) val g = tlvReader.getFloat(ContextSpecificTag(TAG_G)) val h = tlvReader.getDouble(ContextSpecificTag(TAG_H)) + val i = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_I))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_I))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h) + return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h, i) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt new file mode 100644 index 00000000000000..aa66049b549524 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class UnitTestingClusterTestGlobalStruct( + val name: String, + val myBitmap: ULong?, + val myEnum: Optional?, +) { + override fun toString(): String = buildString { + append("UnitTestingClusterTestGlobalStruct {\n") + append("\tname : $name\n") + append("\tmyBitmap : $myBitmap\n") + append("\tmyEnum : $myEnum\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_NAME), name) + if (myBitmap != null) { + put(ContextSpecificTag(TAG_MY_BITMAP), myBitmap) + } else { + putNull(ContextSpecificTag(TAG_MY_BITMAP)) + } + if (myEnum != null) { + if (myEnum.isPresent) { + val optmyEnum = myEnum.get() + put(ContextSpecificTag(TAG_MY_ENUM), optmyEnum) + } + } else { + putNull(ContextSpecificTag(TAG_MY_ENUM)) + } + endStructure() + } + } + + companion object { + private const val TAG_NAME = 0 + private const val TAG_MY_BITMAP = 1 + private const val TAG_MY_ENUM = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterTestGlobalStruct { + tlvReader.enterStructure(tlvTag) + val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) + val myBitmap = + if (!tlvReader.isNull()) { + tlvReader.getULong(ContextSpecificTag(TAG_MY_BITMAP)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_BITMAP)) + null + } + val myEnum = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MY_ENUM))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_MY_ENUM))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_ENUM)) + null + } + + tlvReader.exitContainer() + + return UnitTestingClusterTestGlobalStruct(name, myBitmap, myEnum) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt index b50ab4468820d1..74402b19dcfdf3 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt @@ -123,6 +123,8 @@ class UnitTestingCluster(private val controller: MatterController, private val e class StringEchoResponse(val payload: ByteArray) + class GlobalEchoResponse(val field1: UnitTestingClusterTestGlobalStruct, val field2: UByte) + class TestDifferentVendorMeiResponse(val arg1: UByte, val eventNumber: ULong) class ListInt8uAttribute(val value: List) @@ -203,6 +205,17 @@ class UnitTestingCluster(private val controller: MatterController, private val e object SubscriptionEstablished : ListFabricScopedAttributeSubscriptionState() } + class GlobalStructAttribute(val value: UnitTestingClusterTestGlobalStruct) + + sealed class GlobalStructAttributeSubscriptionState { + data class Success(val value: UnitTestingClusterTestGlobalStruct) : + GlobalStructAttributeSubscriptionState() + + data class Error(val exception: Exception) : GlobalStructAttributeSubscriptionState() + + object SubscriptionEstablished : GlobalStructAttributeSubscriptionState() + } + class NullableBooleanAttribute(val value: Boolean?) sealed class NullableBooleanAttributeSubscriptionState { @@ -541,6 +554,27 @@ class UnitTestingCluster(private val controller: MatterController, private val e object SubscriptionEstablished : NullableRangeRestrictedInt16sAttributeSubscriptionState() } + class NullableGlobalEnumAttribute(val value: UByte?) + + sealed class NullableGlobalEnumAttributeSubscriptionState { + data class Success(val value: UByte?) : NullableGlobalEnumAttributeSubscriptionState() + + data class Error(val exception: Exception) : NullableGlobalEnumAttributeSubscriptionState() + + object SubscriptionEstablished : NullableGlobalEnumAttributeSubscriptionState() + } + + class NullableGlobalStructAttribute(val value: UnitTestingClusterTestGlobalStruct?) + + sealed class NullableGlobalStructAttributeSubscriptionState { + data class Success(val value: UnitTestingClusterTestGlobalStruct?) : + NullableGlobalStructAttributeSubscriptionState() + + data class Error(val exception: Exception) : NullableGlobalStructAttributeSubscriptionState() + + object SubscriptionEstablished : NullableGlobalStructAttributeSubscriptionState() + } + class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -2386,6 +2420,68 @@ class UnitTestingCluster(private val controller: MatterController, private val e return StringEchoResponse(payload_decoded) } + suspend fun globalEchoRequest( + field1: UnitTestingClusterTestGlobalStruct, + field2: UByte, + timedInvokeTimeout: Duration? = null, + ): GlobalEchoResponse { + val commandId: UInt = 25u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_FIELD1_REQ: Int = 0 + field1.toTlv(ContextSpecificTag(TAG_FIELD1_REQ), tlvWriter) + + val TAG_FIELD2_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_FIELD2_REQ), field2) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_FIELD1: Int = 0 + var field1_decoded: UnitTestingClusterTestGlobalStruct? = null + + val TAG_FIELD2: Int = 1 + var field2_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_FIELD1)) { + field1_decoded = UnitTestingClusterTestGlobalStruct.fromTlv(tag, tlvReader) + } + + if (tag == ContextSpecificTag(TAG_FIELD2)) { + field2_decoded = tlvReader.getUByte(tag) + } else { + tlvReader.skipElement() + } + } + + if (field1_decoded == null) { + throw IllegalStateException("field1 not found in TLV") + } + + if (field2_decoded == null) { + throw IllegalStateException("field2 not found in TLV") + } + + tlvReader.exitContainer() + + return GlobalEchoResponse(field1_decoded, field2_decoded) + } + suspend fun testDifferentVendorMeiRequest( arg1: UByte, timedInvokeTimeout: Duration? = null, @@ -8305,8 +8401,8 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun readUnsupportedAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 255u + suspend fun readGlobalEnumAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 51u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8327,22 +8423,17 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Unsupported attribute not found in response" } + requireNotNull(attributeData) { "Globalenum attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: Boolean? = - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getBoolean(AnonymousTag) - } else { - null - } + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) return decodedValue } - suspend fun writeUnsupportedAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 255u + suspend fun writeGlobalEnumAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 51u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8381,11 +8472,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeUnsupportedAttribute( + suspend fun subscribeGlobalEnumAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 255u + ): Flow { + val ATTRIBUTE_ID: UInt = 51u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8403,7 +8494,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - BooleanSubscriptionState.Error( + UByteSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8416,28 +8507,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Unsupported attribute not found in Node State update" } + requireNotNull(attributeData) { "Globalenum attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: Boolean? = - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getBoolean(AnonymousTag) - } else { - null - } + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - decodedValue?.let { emit(BooleanSubscriptionState.Success(it)) } + emit(UByteSubscriptionState.Success(decodedValue)) } SubscriptionState.SubscriptionEstablished -> { - emit(BooleanSubscriptionState.SubscriptionEstablished) + emit(UByteSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { - val ATTRIBUTE_ID: UInt = 16384u + suspend fun readGlobalStructAttribute(): GlobalStructAttribute { + val ATTRIBUTE_ID: UInt = 52u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8458,26 +8544,24 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullableboolean attribute not found in response" } + requireNotNull(attributeData) { "Globalstruct attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: Boolean? = - if (!tlvReader.isNull()) { - tlvReader.getBoolean(AnonymousTag) - } else { - tlvReader.getNull(AnonymousTag) - null - } + val decodedValue: UnitTestingClusterTestGlobalStruct = + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) - return NullableBooleanAttribute(decodedValue) + return GlobalStructAttribute(decodedValue) } - suspend fun writeNullableBooleanAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16384u + suspend fun writeGlobalStructAttribute( + value: UnitTestingClusterTestGlobalStruct, + timedWriteTimeout: Duration? = null, + ) { + val ATTRIBUTE_ID: UInt = 52u val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) + value.toTlv(AnonymousTag, tlvWriter) val writeRequests: WriteRequests = WriteRequests( @@ -8513,11 +8597,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBooleanAttribute( + suspend fun subscribeGlobalStructAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16384u + ): Flow { + val ATTRIBUTE_ID: UInt = 52u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8535,7 +8619,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBooleanAttributeSubscriptionState.Error( + GlobalStructAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8548,31 +8632,24 @@ class UnitTestingCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Nullableboolean attribute not found in Node State update" - } + requireNotNull(attributeData) { "Globalstruct attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: Boolean? = - if (!tlvReader.isNull()) { - tlvReader.getBoolean(AnonymousTag) - } else { - tlvReader.getNull(AnonymousTag) - null - } + val decodedValue: UnitTestingClusterTestGlobalStruct = + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) - decodedValue?.let { emit(NullableBooleanAttributeSubscriptionState.Success(it)) } + emit(GlobalStructAttributeSubscriptionState.Success(decodedValue)) } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBooleanAttributeSubscriptionState.SubscriptionEstablished) + emit(GlobalStructAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap8Attribute(): NullableBitmap8Attribute { - val ATTRIBUTE_ID: UInt = 16385u + suspend fun readUnsupportedAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 255u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8593,23 +8670,22 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap8 attribute not found in response" } + requireNotNull(attributeData) { "Unsupported attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - tlvReader.getUByte(AnonymousTag) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) } else { - tlvReader.getNull(AnonymousTag) null } - return NullableBitmap8Attribute(decodedValue) + return decodedValue } - suspend fun writeNullableBitmap8Attribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16385u + suspend fun writeUnsupportedAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 255u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8648,11 +8724,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap8Attribute( + suspend fun subscribeUnsupportedAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16385u + ): Flow { + val ATTRIBUTE_ID: UInt = 255u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8670,7 +8746,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap8AttributeSubscriptionState.Error( + BooleanSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8683,31 +8759,28 @@ class UnitTestingCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Nullablebitmap8 attribute not found in Node State update" - } + requireNotNull(attributeData) { "Unsupported attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - tlvReader.getUByte(AnonymousTag) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) } else { - tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(NullableBitmap8AttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(BooleanSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBitmap8AttributeSubscriptionState.SubscriptionEstablished) + emit(BooleanSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap16Attribute(): NullableBitmap16Attribute { - val ATTRIBUTE_ID: UInt = 16386u + suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { + val ATTRIBUTE_ID: UInt = 16384u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8728,23 +8801,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap16 attribute not found in response" } + requireNotNull(attributeData) { "Nullableboolean attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UShort? = + val decodedValue: Boolean? = if (!tlvReader.isNull()) { - tlvReader.getUShort(AnonymousTag) + tlvReader.getBoolean(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return NullableBitmap16Attribute(decodedValue) + return NullableBooleanAttribute(decodedValue) } - suspend fun writeNullableBitmap16Attribute(value: UShort, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16386u + suspend fun writeNullableBooleanAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16384u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8783,11 +8856,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap16Attribute( + suspend fun subscribeNullableBooleanAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16386u + ): Flow { + val ATTRIBUTE_ID: UInt = 16384u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8805,7 +8878,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap16AttributeSubscriptionState.Error( + NullableBooleanAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8819,30 +8892,30 @@ class UnitTestingCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Nullablebitmap16 attribute not found in Node State update" + "Nullableboolean attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UShort? = + val decodedValue: Boolean? = if (!tlvReader.isNull()) { - tlvReader.getUShort(AnonymousTag) + tlvReader.getBoolean(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(NullableBitmap16AttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(NullableBooleanAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBitmap16AttributeSubscriptionState.SubscriptionEstablished) + emit(NullableBooleanAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap32Attribute(): NullableBitmap32Attribute { - val ATTRIBUTE_ID: UInt = 16387u + suspend fun readNullableBitmap8Attribute(): NullableBitmap8Attribute { + val ATTRIBUTE_ID: UInt = 16385u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8863,23 +8936,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap32 attribute not found in response" } + requireNotNull(attributeData) { "Nullablebitmap8 attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UInt? = + val decodedValue: UByte? = if (!tlvReader.isNull()) { - tlvReader.getUInt(AnonymousTag) + tlvReader.getUByte(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return NullableBitmap32Attribute(decodedValue) + return NullableBitmap8Attribute(decodedValue) } - suspend fun writeNullableBitmap32Attribute(value: UInt, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16387u + suspend fun writeNullableBitmap8Attribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16385u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8918,11 +8991,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap32Attribute( + suspend fun subscribeNullableBitmap8Attribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16387u + ): Flow { + val ATTRIBUTE_ID: UInt = 16385u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8940,7 +9013,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap32AttributeSubscriptionState.Error( + NullableBitmap8AttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8954,30 +9027,30 @@ class UnitTestingCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Nullablebitmap32 attribute not found in Node State update" + "Nullablebitmap8 attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UInt? = + val decodedValue: UByte? = if (!tlvReader.isNull()) { - tlvReader.getUInt(AnonymousTag) + tlvReader.getUByte(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(NullableBitmap32AttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(NullableBitmap8AttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBitmap32AttributeSubscriptionState.SubscriptionEstablished) + emit(NullableBitmap8AttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap64Attribute(): NullableBitmap64Attribute { - val ATTRIBUTE_ID: UInt = 16388u + suspend fun readNullableBitmap16Attribute(): NullableBitmap16Attribute { + val ATTRIBUTE_ID: UInt = 16386u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8998,23 +9071,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap64 attribute not found in response" } + requireNotNull(attributeData) { "Nullablebitmap16 attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: ULong? = + val decodedValue: UShort? = if (!tlvReader.isNull()) { - tlvReader.getULong(AnonymousTag) + tlvReader.getUShort(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return NullableBitmap64Attribute(decodedValue) + return NullableBitmap16Attribute(decodedValue) } - suspend fun writeNullableBitmap64Attribute(value: ULong, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16388u + suspend fun writeNullableBitmap16Attribute(value: UShort, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16386u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -9053,11 +9126,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap64Attribute( + suspend fun subscribeNullableBitmap16Attribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16388u + ): Flow { + val ATTRIBUTE_ID: UInt = 16386u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -9075,7 +9148,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap64AttributeSubscriptionState.Error( + NullableBitmap16AttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -9089,12 +9162,282 @@ class UnitTestingCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Nullablebitmap64 attribute not found in Node State update" + "Nullablebitmap16 attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: ULong? = + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableBitmap16AttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableBitmap16AttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readNullableBitmap32Attribute(): NullableBitmap32Attribute { + val ATTRIBUTE_ID: UInt = 16387u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablebitmap32 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap32Attribute(decodedValue) + } + + suspend fun writeNullableBitmap32Attribute(value: UInt, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16387u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableBitmap32Attribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16387u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + NullableBitmap32AttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Nullablebitmap32 attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableBitmap32AttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableBitmap32AttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readNullableBitmap64Attribute(): NullableBitmap64Attribute { + val ATTRIBUTE_ID: UInt = 16388u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablebitmap64 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap64Attribute(decodedValue) + } + + suspend fun writeNullableBitmap64Attribute(value: ULong, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16388u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableBitmap64Attribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16388u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + NullableBitmap64AttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Nullablebitmap64 attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = if (!tlvReader.isNull()) { tlvReader.getULong(AnonymousTag) } else { @@ -13051,6 +13394,279 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } + suspend fun readNullableGlobalEnumAttribute(): NullableGlobalEnumAttribute { + val ATTRIBUTE_ID: UInt = 16435u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableglobalenum attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableGlobalEnumAttribute(decodedValue) + } + + suspend fun writeNullableGlobalEnumAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16435u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableGlobalEnumAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16435u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + NullableGlobalEnumAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Nullableglobalenum attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableGlobalEnumAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableGlobalEnumAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readNullableGlobalStructAttribute(): NullableGlobalStructAttribute { + val ATTRIBUTE_ID: UInt = 16436u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableglobalstruct attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UnitTestingClusterTestGlobalStruct? = + if (!tlvReader.isNull()) { + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableGlobalStructAttribute(decodedValue) + } + + suspend fun writeNullableGlobalStructAttribute( + value: UnitTestingClusterTestGlobalStruct, + timedWriteTimeout: Duration? = null, + ) { + val ATTRIBUTE_ID: UInt = 16436u + + val tlvWriter = TlvWriter() + value.toTlv(AnonymousTag, tlvWriter) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableGlobalStructAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16436u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + NullableGlobalStructAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Nullableglobalstruct attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UnitTestingClusterTestGlobalStruct? = + if (!tlvReader.isNull()) { + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableGlobalStructAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableGlobalStructAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readMeiInt8uAttribute(): UByte { val ATTRIBUTE_ID: UInt = 4294070017u diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index dc0b4b09ec96f6..021d82d5e5b25a 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -151,6 +151,7 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UserLabelClusterLabelStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt index 3552ec2a5fc075..d57a0432a7c7ed 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.structs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -26,12 +27,14 @@ class UnitTestingClusterNestedStruct( val a: UByte, val b: Boolean, val c: UnitTestingClusterSimpleStruct, + val d: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterNestedStruct {\n") append("\ta : $a\n") append("\tb : $b\n") append("\tc : $c\n") + append("\td : $d\n") append("}\n") } @@ -41,6 +44,10 @@ class UnitTestingClusterNestedStruct( put(ContextSpecificTag(TAG_A), a) put(ContextSpecificTag(TAG_B), b) c.toTlv(ContextSpecificTag(TAG_C), this) + if (d.isPresent) { + val optd = d.get() + optd.toTlv(ContextSpecificTag(TAG_D), this) + } endStructure() } } @@ -49,16 +56,25 @@ class UnitTestingClusterNestedStruct( private const val TAG_A = 0 private const val TAG_B = 1 private const val TAG_C = 2 + private const val TAG_D = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterNestedStruct { tlvReader.enterStructure(tlvTag) val a = tlvReader.getUByte(ContextSpecificTag(TAG_A)) val b = tlvReader.getBoolean(ContextSpecificTag(TAG_B)) val c = UnitTestingClusterSimpleStruct.fromTlv(ContextSpecificTag(TAG_C), tlvReader) + val d = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_D))) { + Optional.of( + UnitTestingClusterTestGlobalStruct.fromTlv(ContextSpecificTag(TAG_D), tlvReader) + ) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterNestedStruct(a, b, c) + return UnitTestingClusterNestedStruct(a, b, c, d) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt index 864a28ffd7defc..722445efea8504 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.structs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -31,6 +32,7 @@ class UnitTestingClusterSimpleStruct( val f: UByte, val g: Float, val h: Double, + val i: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterSimpleStruct {\n") @@ -42,6 +44,7 @@ class UnitTestingClusterSimpleStruct( append("\tf : $f\n") append("\tg : $g\n") append("\th : $h\n") + append("\ti : $i\n") append("}\n") } @@ -56,6 +59,10 @@ class UnitTestingClusterSimpleStruct( put(ContextSpecificTag(TAG_F), f) put(ContextSpecificTag(TAG_G), g) put(ContextSpecificTag(TAG_H), h) + if (i.isPresent) { + val opti = i.get() + put(ContextSpecificTag(TAG_I), opti) + } endStructure() } } @@ -69,6 +76,7 @@ class UnitTestingClusterSimpleStruct( private const val TAG_F = 5 private const val TAG_G = 6 private const val TAG_H = 7 + private const val TAG_I = 8 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterSimpleStruct { tlvReader.enterStructure(tlvTag) @@ -80,10 +88,16 @@ class UnitTestingClusterSimpleStruct( val f = tlvReader.getUByte(ContextSpecificTag(TAG_F)) val g = tlvReader.getFloat(ContextSpecificTag(TAG_G)) val h = tlvReader.getDouble(ContextSpecificTag(TAG_H)) + val i = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_I))) { + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_I))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h) + return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h, i) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt new file mode 100644 index 00000000000000..66caded2c08ab3 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package matter.controller.cluster.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class UnitTestingClusterTestGlobalStruct( + val name: String, + val myBitmap: UInt?, + val myEnum: Optional?, +) { + override fun toString(): String = buildString { + append("UnitTestingClusterTestGlobalStruct {\n") + append("\tname : $name\n") + append("\tmyBitmap : $myBitmap\n") + append("\tmyEnum : $myEnum\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_NAME), name) + if (myBitmap != null) { + put(ContextSpecificTag(TAG_MY_BITMAP), myBitmap) + } else { + putNull(ContextSpecificTag(TAG_MY_BITMAP)) + } + if (myEnum != null) { + if (myEnum.isPresent) { + val optmyEnum = myEnum.get() + put(ContextSpecificTag(TAG_MY_ENUM), optmyEnum) + } + } else { + putNull(ContextSpecificTag(TAG_MY_ENUM)) + } + endStructure() + } + } + + companion object { + private const val TAG_NAME = 0 + private const val TAG_MY_BITMAP = 1 + private const val TAG_MY_ENUM = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterTestGlobalStruct { + tlvReader.enterStructure(tlvTag) + val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) + val myBitmap = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_MY_BITMAP)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_BITMAP)) + null + } + val myEnum = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MY_ENUM))) { + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_MY_ENUM))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_ENUM)) + null + } + + tlvReader.exitContainer() + + return UnitTestingClusterTestGlobalStruct(name, myBitmap, myEnum) + } + } +} diff --git a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt index 55c880e02e4bf2..bfee37f38f5437 100644 --- a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt +++ b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt @@ -19,6 +19,7 @@ package chip.devicecontroller.cluster import chip.devicecontroller.cluster.eventstructs.UnitTestingClusterTestEventEvent import chip.devicecontroller.cluster.eventstructs.UnitTestingClusterTestFabricScopedEventEvent import chip.devicecontroller.cluster.structs.UnitTestingClusterSimpleStruct +import java.util.Optional import matter.tlv.AnonymousTag import matter.tlv.TlvReader import matter.tlv.TlvWriter @@ -28,9 +29,29 @@ class ChipClusterEventStructTest { @Test fun testEventEventTlvTest() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val simpleStruct2 = - UnitTestingClusterSimpleStruct(8U, false, 9U, byteArrayOf(0x02, 0x03), "test2", 4U, 5.6f, 7.8) + UnitTestingClusterSimpleStruct( + 8U, + false, + 9U, + byteArrayOf(0x02, 0x03), + "test2", + 4U, + 5.6f, + 7.8, + Optional.empty() + ) val struct = UnitTestingClusterTestEventEvent( 1U, diff --git a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt index ffa0044569e0af..a38a71d63141ee 100644 --- a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt +++ b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt @@ -35,9 +35,29 @@ class ChipClusterStructTest { @Test fun doubleNestedStructTlvTest() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val simpleStruct2 = - UnitTestingClusterSimpleStruct(8U, false, 9U, byteArrayOf(0x02, 0x03), "test2", 4U, 5.6f, 7.8) + UnitTestingClusterSimpleStruct( + 8U, + false, + 9U, + byteArrayOf(0x02, 0x03), + "test2", + 4U, + 5.6f, + 7.8, + Optional.empty() + ) val nestedStructList = UnitTestingClusterNestedStructList( 1U, @@ -82,7 +102,17 @@ class ChipClusterStructTest { @Test fun nullablesAndOptionalsStructTlvTest1() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -121,7 +151,17 @@ class ChipClusterStructTest { // Optional Check - 1 fun nullablesAndOptionalsStructTlvTest2() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -160,7 +200,17 @@ class ChipClusterStructTest { // Optional Check - 2 fun nullablesAndOptionalsStructTlvTest3() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -199,7 +249,17 @@ class ChipClusterStructTest { // Nullable check - 1 fun nullablesAndOptionalsStructTlvTest4() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -238,7 +298,17 @@ class ChipClusterStructTest { // Nullable check - 2 fun nullablesAndOptionalsStructTlvTest5() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( null, @@ -276,7 +346,17 @@ class ChipClusterStructTest { @Test fun testFabricScopedTlvTest1() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterTestFabricScoped( 1U, @@ -309,7 +389,17 @@ class ChipClusterStructTest { @Test fun testFabricScopedTlvTest2() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterTestFabricScoped( 1U, @@ -342,7 +432,17 @@ class ChipClusterStructTest { @Test fun testFabricScopedTlvTest3() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterTestFabricScoped( 1U, diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 33c041e5bbe85f..81e24a4bc9dcd7 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -46578,6 +46578,25 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR chip::JniReferences::GetInstance().CreateBoxedObject( newElement_0_nullableStruct_hClassName.c_str(), newElement_0_nullableStruct_hCtorSignature.c_str(), jninewElement_0_nullableStruct_h, newElement_0_nullableStruct_h); + jobject newElement_0_nullableStruct_i; + if (!entry_0.nullableStruct.Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableStruct_i); + } + else + { + jobject newElement_0_nullableStruct_iInsideOptional; + std::string newElement_0_nullableStruct_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_nullableStruct_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_nullableStruct_iInsideOptional = + static_cast(entry_0.nullableStruct.Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_nullableStruct_iInsideOptionalClassName.c_str(), + newElement_0_nullableStruct_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_nullableStruct_iInsideOptional, newElement_0_nullableStruct_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableStruct_iInsideOptional, + newElement_0_nullableStruct_i); + } jclass simpleStructStructClass_3; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -46592,7 +46611,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_3, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/" - "lang/Float;Ljava/lang/Double;)V", + "lang/Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_3); if (err != CHIP_NO_ERROR || simpleStructStructCtor_3 == nullptr) { @@ -46604,7 +46623,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR env->NewObject(simpleStructStructClass_3, simpleStructStructCtor_3, newElement_0_nullableStruct_a, newElement_0_nullableStruct_b, newElement_0_nullableStruct_c, newElement_0_nullableStruct_d, newElement_0_nullableStruct_e, newElement_0_nullableStruct_f, newElement_0_nullableStruct_g, - newElement_0_nullableStruct_h); + newElement_0_nullableStruct_h, newElement_0_nullableStruct_i); } jobject newElement_0_optionalStruct; if (!entry_0.optionalStruct.HasValue()) @@ -46673,6 +46692,26 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_optionalStructInsideOptional_hClassName.c_str(), newElement_0_optionalStructInsideOptional_hCtorSignature.c_str(), jninewElement_0_optionalStructInsideOptional_h, newElement_0_optionalStructInsideOptional_h); + jobject newElement_0_optionalStructInsideOptional_i; + if (!entry_0.optionalStruct.Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalStructInsideOptional_i); + } + else + { + jobject newElement_0_optionalStructInsideOptional_iInsideOptional; + std::string newElement_0_optionalStructInsideOptional_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_optionalStructInsideOptional_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_optionalStructInsideOptional_iInsideOptional = + static_cast(entry_0.optionalStruct.Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_optionalStructInsideOptional_iInsideOptionalClassName.c_str(), + newElement_0_optionalStructInsideOptional_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_optionalStructInsideOptional_iInsideOptional, + newElement_0_optionalStructInsideOptional_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalStructInsideOptional_iInsideOptional, + newElement_0_optionalStructInsideOptional_i); + } jclass simpleStructStructClass_3; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -46687,7 +46726,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_3, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/" - "lang/Float;Ljava/lang/Double;)V", + "lang/Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_3); if (err != CHIP_NO_ERROR || simpleStructStructCtor_3 == nullptr) { @@ -46695,12 +46734,12 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } - newElement_0_optionalStructInsideOptional = - env->NewObject(simpleStructStructClass_3, simpleStructStructCtor_3, - newElement_0_optionalStructInsideOptional_a, newElement_0_optionalStructInsideOptional_b, - newElement_0_optionalStructInsideOptional_c, newElement_0_optionalStructInsideOptional_d, - newElement_0_optionalStructInsideOptional_e, newElement_0_optionalStructInsideOptional_f, - newElement_0_optionalStructInsideOptional_g, newElement_0_optionalStructInsideOptional_h); + newElement_0_optionalStructInsideOptional = env->NewObject( + simpleStructStructClass_3, simpleStructStructCtor_3, newElement_0_optionalStructInsideOptional_a, + newElement_0_optionalStructInsideOptional_b, newElement_0_optionalStructInsideOptional_c, + newElement_0_optionalStructInsideOptional_d, newElement_0_optionalStructInsideOptional_e, + newElement_0_optionalStructInsideOptional_f, newElement_0_optionalStructInsideOptional_g, + newElement_0_optionalStructInsideOptional_h, newElement_0_optionalStructInsideOptional_i); chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalStructInsideOptional, newElement_0_optionalStruct); } @@ -46790,6 +46829,29 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_nullableOptionalStructInsideOptional_hCtorSignature.c_str(), jninewElement_0_nullableOptionalStructInsideOptional_h, newElement_0_nullableOptionalStructInsideOptional_h); + jobject newElement_0_nullableOptionalStructInsideOptional_i; + if (!entry_0.nullableOptionalStruct.Value().Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, + newElement_0_nullableOptionalStructInsideOptional_i); + } + else + { + jobject newElement_0_nullableOptionalStructInsideOptional_iInsideOptional; + std::string newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalClassName = + "java/lang/Integer"; + std::string newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_nullableOptionalStructInsideOptional_iInsideOptional = + static_cast(entry_0.nullableOptionalStruct.Value().Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalClassName.c_str(), + newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_nullableOptionalStructInsideOptional_iInsideOptional, + newElement_0_nullableOptionalStructInsideOptional_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional( + newElement_0_nullableOptionalStructInsideOptional_iInsideOptional, + newElement_0_nullableOptionalStructInsideOptional_i); + } jclass simpleStructStructClass_4; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -46804,7 +46866,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_4, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/" - "Integer;Ljava/lang/Float;Ljava/lang/Double;)V", + "Integer;Ljava/lang/Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_4); if (err != CHIP_NO_ERROR || simpleStructStructCtor_4 == nullptr) { @@ -46821,7 +46883,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_nullableOptionalStructInsideOptional_e, newElement_0_nullableOptionalStructInsideOptional_f, newElement_0_nullableOptionalStructInsideOptional_g, - newElement_0_nullableOptionalStructInsideOptional_h); + newElement_0_nullableOptionalStructInsideOptional_h, + newElement_0_nullableOptionalStructInsideOptional_i); } chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalStructInsideOptional, newElement_0_nullableOptionalStruct); @@ -47009,6 +47072,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jdouble jnivalue_h = static_cast(cppValue.h); chip::JniReferences::GetInstance().CreateBoxedObject(value_hClassName.c_str(), value_hCtorSignature.c_str(), jnivalue_h, value_h); + jobject value_i; + if (!cppValue.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_i); + } + else + { + jobject value_iInsideOptional; + std::string value_iInsideOptionalClassName = "java/lang/Integer"; + std::string value_iInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_iInsideOptional = static_cast(cppValue.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(value_iInsideOptionalClassName.c_str(), + value_iInsideOptionalCtorSignature.c_str(), + jnivalue_iInsideOptional, value_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_iInsideOptional, value_i); + } jclass simpleStructStructClass_0; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -47023,7 +47102,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_0, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_0); if (err != CHIP_NO_ERROR || simpleStructStructCtor_0 == nullptr) { @@ -47032,7 +47111,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } value = env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, value_a, value_b, value_c, value_d, value_e, - value_f, value_g, value_h); + value_f, value_g, value_h, value_i); return value; } case Attributes::RangeRestrictedInt8u::Id: { @@ -47272,6 +47351,25 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_fabricSensitiveStruct_hClassName.c_str(), newElement_0_fabricSensitiveStruct_hCtorSignature.c_str(), jninewElement_0_fabricSensitiveStruct_h, newElement_0_fabricSensitiveStruct_h); + jobject newElement_0_fabricSensitiveStruct_i; + if (!entry_0.fabricSensitiveStruct.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_fabricSensitiveStruct_i); + } + else + { + jobject newElement_0_fabricSensitiveStruct_iInsideOptional; + std::string newElement_0_fabricSensitiveStruct_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_fabricSensitiveStruct_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_fabricSensitiveStruct_iInsideOptional = + static_cast(entry_0.fabricSensitiveStruct.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_fabricSensitiveStruct_iInsideOptionalClassName.c_str(), + newElement_0_fabricSensitiveStruct_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_fabricSensitiveStruct_iInsideOptional, newElement_0_fabricSensitiveStruct_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_fabricSensitiveStruct_iInsideOptional, + newElement_0_fabricSensitiveStruct_i); + } jclass simpleStructStructClass_2; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -47286,7 +47384,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_2, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_2); if (err != CHIP_NO_ERROR || simpleStructStructCtor_2 == nullptr) { @@ -47299,7 +47397,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_fabricSensitiveStruct_b, newElement_0_fabricSensitiveStruct_c, newElement_0_fabricSensitiveStruct_d, newElement_0_fabricSensitiveStruct_e, newElement_0_fabricSensitiveStruct_f, newElement_0_fabricSensitiveStruct_g, - newElement_0_fabricSensitiveStruct_h); + newElement_0_fabricSensitiveStruct_h, newElement_0_fabricSensitiveStruct_i); jobject newElement_0_fabricSensitiveInt8uList; chip::JniReferences::GetInstance().CreateArrayList(newElement_0_fabricSensitiveInt8uList); @@ -47401,6 +47499,93 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } + case Attributes::GlobalEnum::Id: { + using TypeInfo = Attributes::GlobalEnum::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::GlobalStruct::Id: { + using TypeInfo = Attributes::GlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + jobject value_name; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.name, value_name)); + jobject value_myBitmap; + if (cppValue.myBitmap.IsNull()) + { + value_myBitmap = nullptr; + } + else + { + std::string value_myBitmapClassName = "java/lang/Long"; + std::string value_myBitmapCtorSignature = "(J)V"; + jlong jnivalue_myBitmap = static_cast(cppValue.myBitmap.Value().Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myBitmapClassName.c_str(), value_myBitmapCtorSignature.c_str(), jnivalue_myBitmap, value_myBitmap); + } + jobject value_myEnum; + if (!cppValue.myEnum.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_myEnum); + } + else + { + jobject value_myEnumInsideOptional; + if (cppValue.myEnum.Value().IsNull()) + { + value_myEnumInsideOptional = nullptr; + } + else + { + std::string value_myEnumInsideOptionalClassName = "java/lang/Integer"; + std::string value_myEnumInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_myEnumInsideOptional = static_cast(cppValue.myEnum.Value().Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myEnumInsideOptionalClassName.c_str(), value_myEnumInsideOptionalCtorSignature.c_str(), + jnivalue_myEnumInsideOptional, value_myEnumInsideOptional); + } + chip::JniReferences::GetInstance().CreateOptional(value_myEnumInsideOptional, value_myEnum); + } + + jclass testGlobalStructStructClass_0; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$UnitTestingClusterTestGlobalStruct", testGlobalStructStructClass_0); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterTestGlobalStruct"); + return nullptr; + } + + jmethodID testGlobalStructStructCtor_0; + err = chip::JniReferences::GetInstance().FindMethod(env, testGlobalStructStructClass_0, "", + "(Ljava/lang/String;Ljava/lang/Long;Ljava/util/Optional;)V", + &testGlobalStructStructCtor_0); + if (err != CHIP_NO_ERROR || testGlobalStructStructCtor_0 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterTestGlobalStruct constructor"); + return nullptr; + } + + value = env->NewObject(testGlobalStructStructClass_0, testGlobalStructStructCtor_0, value_name, value_myBitmap, + value_myEnum); + return value; + } case Attributes::Unsupported::Id: { using TypeInfo = Attributes::Unsupported::TypeInfo; TypeInfo::DecodableType cppValue; @@ -48114,6 +48299,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jdouble jnivalue_h = static_cast(cppValue.Value().h); chip::JniReferences::GetInstance().CreateBoxedObject(value_hClassName.c_str(), value_hCtorSignature.c_str(), jnivalue_h, value_h); + jobject value_i; + if (!cppValue.Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_i); + } + else + { + jobject value_iInsideOptional; + std::string value_iInsideOptionalClassName = "java/lang/Integer"; + std::string value_iInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_iInsideOptional = static_cast(cppValue.Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(value_iInsideOptionalClassName.c_str(), + value_iInsideOptionalCtorSignature.c_str(), + jnivalue_iInsideOptional, value_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_iInsideOptional, value_i); + } jclass simpleStructStructClass_1; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -48128,7 +48329,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_1); if (err != CHIP_NO_ERROR || simpleStructStructCtor_1 == nullptr) { @@ -48137,7 +48338,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } value = env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, value_a, value_b, value_c, value_d, - value_e, value_f, value_g, value_h); + value_e, value_f, value_g, value_h, value_i); } return value; } @@ -48249,6 +48450,107 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } + case Attributes::NullableGlobalEnum::Id: { + using TypeInfo = Attributes::NullableGlobalEnum::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::NullableGlobalStruct::Id: { + using TypeInfo = Attributes::NullableGlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + jobject value_name; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.Value().name, value_name)); + jobject value_myBitmap; + if (cppValue.Value().myBitmap.IsNull()) + { + value_myBitmap = nullptr; + } + else + { + std::string value_myBitmapClassName = "java/lang/Long"; + std::string value_myBitmapCtorSignature = "(J)V"; + jlong jnivalue_myBitmap = static_cast(cppValue.Value().myBitmap.Value().Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myBitmapClassName.c_str(), value_myBitmapCtorSignature.c_str(), jnivalue_myBitmap, value_myBitmap); + } + jobject value_myEnum; + if (!cppValue.Value().myEnum.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_myEnum); + } + else + { + jobject value_myEnumInsideOptional; + if (cppValue.Value().myEnum.Value().IsNull()) + { + value_myEnumInsideOptional = nullptr; + } + else + { + std::string value_myEnumInsideOptionalClassName = "java/lang/Integer"; + std::string value_myEnumInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_myEnumInsideOptional = static_cast(cppValue.Value().myEnum.Value().Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myEnumInsideOptionalClassName.c_str(), value_myEnumInsideOptionalCtorSignature.c_str(), + jnivalue_myEnumInsideOptional, value_myEnumInsideOptional); + } + chip::JniReferences::GetInstance().CreateOptional(value_myEnumInsideOptional, value_myEnum); + } + + jclass testGlobalStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$UnitTestingClusterTestGlobalStruct", testGlobalStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterTestGlobalStruct"); + return nullptr; + } + + jmethodID testGlobalStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, testGlobalStructStructClass_1, "", + "(Ljava/lang/String;Ljava/lang/Long;Ljava/util/Optional;)V", + &testGlobalStructStructCtor_1); + if (err != CHIP_NO_ERROR || testGlobalStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterTestGlobalStruct constructor"); + return nullptr; + } + + value = env->NewObject(testGlobalStructStructClass_1, testGlobalStructStructCtor_1, value_name, value_myBitmap, + value_myEnum); + } + return value; + } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 7f3c03f9e8ab05..89a4a256880158 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -8260,6 +8260,22 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & jdouble jnivalue_arg4_h = static_cast(cppValue.arg4.h); chip::JniReferences::GetInstance().CreateBoxedObject( value_arg4_hClassName.c_str(), value_arg4_hCtorSignature.c_str(), jnivalue_arg4_h, value_arg4_h); + jobject value_arg4_i; + if (!cppValue.arg4.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_arg4_i); + } + else + { + jobject value_arg4_iInsideOptional; + std::string value_arg4_iInsideOptionalClassName = "java/lang/Integer"; + std::string value_arg4_iInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_arg4_iInsideOptional = static_cast(cppValue.arg4.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_arg4_iInsideOptionalClassName.c_str(), value_arg4_iInsideOptionalCtorSignature.c_str(), + jnivalue_arg4_iInsideOptional, value_arg4_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_arg4_iInsideOptional, value_arg4_i); + } jclass simpleStructStructClass_0; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -8274,7 +8290,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_0, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_0); if (err != CHIP_NO_ERROR || simpleStructStructCtor_0 == nullptr) { @@ -8282,8 +8298,9 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } - value_arg4 = env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, value_arg4_a, value_arg4_b, - value_arg4_c, value_arg4_d, value_arg4_e, value_arg4_f, value_arg4_g, value_arg4_h); + value_arg4 = + env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, value_arg4_a, value_arg4_b, value_arg4_c, + value_arg4_d, value_arg4_e, value_arg4_f, value_arg4_g, value_arg4_h, value_arg4_i); jobject value_arg5; chip::JniReferences::GetInstance().CreateArrayList(value_arg5); @@ -8336,6 +8353,22 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & jdouble jninewElement_0_h = static_cast(entry_0.h); chip::JniReferences::GetInstance().CreateBoxedObject( newElement_0_hClassName.c_str(), newElement_0_hCtorSignature.c_str(), jninewElement_0_h, newElement_0_h); + jobject newElement_0_i; + if (!entry_0.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_i); + } + else + { + jobject newElement_0_iInsideOptional; + std::string newElement_0_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_iInsideOptional = static_cast(entry_0.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_iInsideOptionalClassName.c_str(), newElement_0_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_iInsideOptional, newElement_0_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_iInsideOptional, newElement_0_i); + } jclass simpleStructStructClass_1; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -8350,7 +8383,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_1); if (err != CHIP_NO_ERROR || simpleStructStructCtor_1 == nullptr) { @@ -8358,9 +8391,9 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } - newElement_0 = - env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, newElement_0_a, newElement_0_b, - newElement_0_c, newElement_0_d, newElement_0_e, newElement_0_f, newElement_0_g, newElement_0_h); + newElement_0 = env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, newElement_0_a, newElement_0_b, + newElement_0_c, newElement_0_d, newElement_0_e, newElement_0_f, newElement_0_g, + newElement_0_h, newElement_0_i); chip::JniReferences::GetInstance().AddToList(value_arg5, newElement_0); } diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 588c3da4f020eb..cc0b5aaa65a4b2 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -14491,6 +14491,14 @@ class ChipClusters: "payload": "bytes", }, }, + 0x00000019: { + "commandId": 0x00000019, + "commandName": "GlobalEchoRequest", + "args": { + "field1": "TestGlobalStruct", + "field2": "int", + }, + }, 0xFFF200AA: { "commandId": 0xFFF200AA, "commandName": "TestDifferentVendorMeiRequest", @@ -14829,6 +14837,20 @@ class ChipClusters: "reportable": True, "writable": True, }, + 0x00000033: { + "attributeName": "GlobalEnum", + "attributeId": 0x00000033, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00000034: { + "attributeName": "GlobalStruct", + "attributeId": 0x00000034, + "type": "", + "reportable": True, + "writable": True, + }, 0x000000FF: { "attributeName": "Unsupported", "attributeId": 0x000000FF, @@ -15074,6 +15096,20 @@ class ChipClusters: "reportable": True, "writable": True, }, + 0x00004033: { + "attributeName": "NullableGlobalEnum", + "attributeId": 0x00004033, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00004034: { + "attributeName": "NullableGlobalStruct", + "attributeId": 0x00004034, + "type": "", + "reportable": True, + "writable": True, + }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index b84ad31879c1d5..3795b08dd230e3 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -50101,6 +50101,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timedWriteBoolean", Tag=0x00000030, Type=bool), ClusterObjectFieldDescriptor(Label="generalErrorBoolean", Tag=0x00000031, Type=bool), ClusterObjectFieldDescriptor(Label="clusterErrorBoolean", Tag=0x00000032, Type=bool), + ClusterObjectFieldDescriptor(Label="globalEnum", Tag=0x00000033, Type=Globals.Enums.TestGlobalEnum), + ClusterObjectFieldDescriptor(Label="globalStruct", Tag=0x00000034, Type=Globals.Structs.TestGlobalStruct), ClusterObjectFieldDescriptor(Label="unsupported", Tag=0x000000FF, Type=typing.Optional[bool]), ClusterObjectFieldDescriptor(Label="nullableBoolean", Tag=0x00004000, Type=typing.Union[Nullable, bool]), ClusterObjectFieldDescriptor(Label="nullableBitmap8", Tag=0x00004001, Type=typing.Union[Nullable, uint]), @@ -50136,6 +50138,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nullableRangeRestrictedInt16u", Tag=0x00004028, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="nullableRangeRestrictedInt16s", Tag=0x00004029, Type=typing.Union[Nullable, int]), ClusterObjectFieldDescriptor(Label="writeOnlyInt8u", Tag=0x0000402A, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="nullableGlobalEnum", Tag=0x00004033, Type=typing.Union[Nullable, Globals.Enums.TestGlobalEnum]), + ClusterObjectFieldDescriptor(Label="nullableGlobalStruct", Tag=0x00004034, Type=typing.Union[Nullable, Globals.Structs.TestGlobalStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), @@ -50192,6 +50196,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: timedWriteBoolean: 'bool' = None generalErrorBoolean: 'bool' = None clusterErrorBoolean: 'bool' = None + globalEnum: 'Globals.Enums.TestGlobalEnum' = None + globalStruct: 'Globals.Structs.TestGlobalStruct' = None unsupported: 'typing.Optional[bool]' = None nullableBoolean: 'typing.Union[Nullable, bool]' = None nullableBitmap8: 'typing.Union[Nullable, uint]' = None @@ -50227,6 +50233,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: nullableRangeRestrictedInt16u: 'typing.Union[Nullable, uint]' = None nullableRangeRestrictedInt16s: 'typing.Union[Nullable, int]' = None writeOnlyInt8u: 'typing.Optional[uint]' = None + nullableGlobalEnum: 'typing.Union[Nullable, Globals.Enums.TestGlobalEnum]' = None + nullableGlobalStruct: 'typing.Union[Nullable, Globals.Structs.TestGlobalStruct]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -50292,6 +50300,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="f", Tag=5, Type=uint), ClusterObjectFieldDescriptor(Label="g", Tag=6, Type=float32), ClusterObjectFieldDescriptor(Label="h", Tag=7, Type=float), + ClusterObjectFieldDescriptor(Label="i", Tag=8, Type=typing.Optional[Globals.Enums.TestGlobalEnum]), ]) a: 'uint' = 0 @@ -50302,6 +50311,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: f: 'uint' = 0 g: 'float32' = 0.0 h: 'float' = 0.0 + i: 'typing.Optional[Globals.Enums.TestGlobalEnum]' = None @dataclass class TestFabricScoped(ClusterObject): @@ -50370,11 +50380,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="a", Tag=0, Type=uint), ClusterObjectFieldDescriptor(Label="b", Tag=1, Type=bool), ClusterObjectFieldDescriptor(Label="c", Tag=2, Type=UnitTesting.Structs.SimpleStruct), + ClusterObjectFieldDescriptor(Label="d", Tag=3, Type=typing.Optional[Globals.Structs.TestGlobalStruct]), ]) a: 'uint' = 0 b: 'bool' = False c: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + d: 'typing.Optional[Globals.Structs.TestGlobalStruct]' = None @dataclass class NestedStructList(ClusterObject): @@ -50962,6 +50974,24 @@ def descriptor(cls) -> ClusterObjectDescriptor: arg1: 'uint' = 0 arg2: 'UnitTesting.Enums.SimpleEnum' = 0 + @dataclass + class GlobalEchoResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0xFFF1FC05 + command_id: typing.ClassVar[int] = 0x0000000E + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="field1", Tag=0, Type=Globals.Structs.TestGlobalStruct), + ClusterObjectFieldDescriptor(Label="field2", Tag=1, Type=Globals.Enums.TestGlobalEnum), + ]) + + field1: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: UnitTesting.Structs.TestGlobalStruct()) + field2: 'Globals.Enums.TestGlobalEnum' = 0 + @dataclass class TestNullableOptionalRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 @@ -51157,6 +51187,24 @@ def descriptor(cls) -> ClusterObjectDescriptor: payload: 'bytes' = b"" + @dataclass + class GlobalEchoRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0xFFF1FC05 + command_id: typing.ClassVar[int] = 0x00000019 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'GlobalEchoResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="field1", Tag=0, Type=Globals.Structs.TestGlobalStruct), + ClusterObjectFieldDescriptor(Label="field2", Tag=1, Type=Globals.Enums.TestGlobalEnum), + ]) + + field1: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: UnitTesting.Structs.TestGlobalStruct()) + field2: 'Globals.Enums.TestGlobalEnum' = 0 + @dataclass class TestDifferentVendorMeiRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 @@ -51948,6 +51996,38 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'bool' = False + @dataclass + class GlobalEnum(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000033 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=Globals.Enums.TestGlobalEnum) + + value: 'Globals.Enums.TestGlobalEnum' = 0 + + @dataclass + class GlobalStruct(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000034 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=Globals.Structs.TestGlobalStruct) + + value: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: UnitTesting.Structs.TestGlobalStruct()) + @dataclass class Unsupported(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -52508,6 +52588,38 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[uint]' = None + @dataclass + class NullableGlobalEnum(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00004033 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, Globals.Enums.TestGlobalEnum]) + + value: 'typing.Union[Nullable, Globals.Enums.TestGlobalEnum]' = NullValue + + @dataclass + class NullableGlobalStruct(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00004034 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, Globals.Structs.TestGlobalStruct]) + + value: 'typing.Union[Nullable, Globals.Structs.TestGlobalStruct]' = NullValue + @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index aed4d52a4c4b3c..ee6351b3c6793e 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -9695,29 +9695,38 @@ - WaterHeaterMode - WiFiNetworkManagement attributes: - OccupancySensing: - # Targeting 1.4 - - HoldTime - - HoldTimeLimits GeneralCommissioning: # Targeting 1.4 - TCAcceptedVersion - TCMinRequiredVersion - TCAcknowledgements - TCAcknowledgementsRequired + OccupancySensing: + # Targeting 1.4 + - HoldTime + - HoldTimeLimits + UnitTesting: + # Ideally none of UnitTesting would be exposed as public API, but + # for now just start doing that for new additions to it. + - GlobalEnum + - GlobalStruct + - NullableGlobalEnum + - NullableGlobalStruct commands: BridgedDeviceBasicInformation: # Targeting 1.4 - KeepActive + GeneralCommissioning: + # Targeting 1.4 + - SetTCAcknowledgements + - SetTCAcknowledgementsResponse UnitTesting: # Ideally none of UnitTesting would be exposed as public API, but # for now just start doing that for new additions to it. + - GlobalEchoRequest + - GlobalEchoResponse - StringEchoRequest - StringEchoResponse - GeneralCommissioning: - # Targeting 1.4 - - SetTCAcknowledgements - - SetTCAcknowledgementsResponse structs: Globals: # Test-only value @@ -9725,6 +9734,14 @@ OccupancySensing: # Targeting 1.4 - HoldTimeLimitsStruct + struct fields: + UnitTesting: + # Ideally none of UnitTesting would be exposed as public API, but + # for now just start doing that for new additions to it. + SimpleStruct: + - i + NestedStruct: + - d events: BridgedDeviceBasicInformation: # Targeting 1.4 @@ -9744,10 +9761,10 @@ BridgedDeviceBasicInformation: # Targeting 1.4 - Feature - OccupancySensing: + GeneralCommissioning: # Targeting 1.4 - Feature - GeneralCommissioning: + OccupancySensing: # Targeting 1.4 - Feature bitmap values: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index d214e061ec9f65..d0ea9a364af749 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -6678,6 +6678,12 @@ static BOOL AttributeIsSpecifiedInUnitTestingCluster(AttributeId aAttributeId) case Attributes::ClusterErrorBoolean::Id: { return YES; } + case Attributes::GlobalEnum::Id: { + return YES; + } + case Attributes::GlobalStruct::Id: { + return YES; + } case Attributes::Unsupported::Id: { return YES; } @@ -6783,6 +6789,12 @@ static BOOL AttributeIsSpecifiedInUnitTestingCluster(AttributeId aAttributeId) case Attributes::WriteOnlyInt8u::Id: { return YES; } + case Attributes::NullableGlobalEnum::Id: { + return YES; + } + case Attributes::NullableGlobalStruct::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 7920a04dc597b1..c6d743173044cd 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -19333,6 +19333,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.nullableStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableStruct.Value().f.Raw()]; newElement_0.nullableStruct.g = [NSNumber numberWithFloat:entry_0.nullableStruct.Value().g]; newElement_0.nullableStruct.h = [NSNumber numberWithDouble:entry_0.nullableStruct.Value().h]; + if (entry_0.nullableStruct.Value().i.HasValue()) { + newElement_0.nullableStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableStruct.Value().i.Value())]; + } else { + newElement_0.nullableStruct.i = nil; + } } if (entry_0.optionalStruct.HasValue()) { newElement_0.optionalStruct = [MTRUnitTestingClusterSimpleStruct new]; @@ -19349,6 +19354,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.optionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.optionalStruct.Value().f.Raw()]; newElement_0.optionalStruct.g = [NSNumber numberWithFloat:entry_0.optionalStruct.Value().g]; newElement_0.optionalStruct.h = [NSNumber numberWithDouble:entry_0.optionalStruct.Value().h]; + if (entry_0.optionalStruct.Value().i.HasValue()) { + newElement_0.optionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.optionalStruct.Value().i.Value())]; + } else { + newElement_0.optionalStruct.i = nil; + } } else { newElement_0.optionalStruct = nil; } @@ -19370,6 +19380,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.nullableOptionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalStruct.Value().Value().f.Raw()]; newElement_0.nullableOptionalStruct.g = [NSNumber numberWithFloat:entry_0.nullableOptionalStruct.Value().Value().g]; newElement_0.nullableOptionalStruct.h = [NSNumber numberWithDouble:entry_0.nullableOptionalStruct.Value().Value().h]; + if (entry_0.nullableOptionalStruct.Value().Value().i.HasValue()) { + newElement_0.nullableOptionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableOptionalStruct.Value().Value().i.Value())]; + } else { + newElement_0.nullableOptionalStruct.i = nil; + } } } else { newElement_0.nullableOptionalStruct = nil; @@ -19482,6 +19497,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value.f = [NSNumber numberWithUnsignedChar:cppValue.f.Raw()]; value.g = [NSNumber numberWithFloat:cppValue.g]; value.h = [NSNumber numberWithDouble:cppValue.h]; + if (cppValue.i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.i.Value())]; + } else { + value.i = nil; + } return value; } case Attributes::RangeRestrictedInt8u::Id: { @@ -19609,6 +19629,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.fabricSensitiveStruct.f = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveStruct.f.Raw()]; newElement_0.fabricSensitiveStruct.g = [NSNumber numberWithFloat:entry_0.fabricSensitiveStruct.g]; newElement_0.fabricSensitiveStruct.h = [NSNumber numberWithDouble:entry_0.fabricSensitiveStruct.h]; + if (entry_0.fabricSensitiveStruct.i.HasValue()) { + newElement_0.fabricSensitiveStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.fabricSensitiveStruct.i.Value())]; + } else { + newElement_0.fabricSensitiveStruct.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; auto iter_2 = entry_0.fabricSensitiveInt8uList.begin(); @@ -19670,6 +19695,48 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value = [NSNumber numberWithBool:cppValue]; return value; } + case Attributes::GlobalEnum::Id: { + using TypeInfo = Attributes::GlobalEnum::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue)]; + return value; + } + case Attributes::GlobalStruct::Id: { + using TypeInfo = Attributes::GlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + MTRDataTypeTestGlobalStruct * _Nonnull value; + value = [MTRDataTypeTestGlobalStruct new]; + value.name = AsString(cppValue.name); + if (value.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + if (cppValue.myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:cppValue.myBitmap.Value().Raw()]; + } + if (cppValue.myEnum.HasValue()) { + if (cppValue.myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + return value; + } case Attributes::Unsupported::Id: { using TypeInfo = Attributes::Unsupported::TypeInfo; TypeInfo::DecodableType cppValue; @@ -20131,6 +20198,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value.f = [NSNumber numberWithUnsignedChar:cppValue.Value().f.Raw()]; value.g = [NSNumber numberWithFloat:cppValue.Value().g]; value.h = [NSNumber numberWithDouble:cppValue.Value().h]; + if (cppValue.Value().i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value().i.Value())]; + } else { + value.i = nil; + } } return value; } @@ -20205,6 +20277,56 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value = [NSNumber numberWithUnsignedChar:cppValue]; return value; } + case Attributes::NullableGlobalEnum::Id: { + using TypeInfo = Attributes::NullableGlobalEnum::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value())]; + } + return value; + } + case Attributes::NullableGlobalStruct::Id: { + using TypeInfo = Attributes::NullableGlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + MTRDataTypeTestGlobalStruct * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [MTRDataTypeTestGlobalStruct new]; + value.name = AsString(cppValue.Value().name); + if (value.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + if (cppValue.Value().myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:cppValue.Value().myBitmap.Value().Raw()]; + } + if (cppValue.Value().myEnum.HasValue()) { + if (cppValue.Value().myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value().myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + } + return value; + } case Attributes::MeiInt8u::Id: { using TypeInfo = Attributes::MeiInt8u::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index bdd3bcf1f78a2f..0f17934d1ee74f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -16339,6 +16339,13 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) supports large payloads. */ - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParams *)params completion:(void (^)(MTRUnitTestingClusterStringEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command GlobalEchoRequest + * + * Command that takes arguments that are global structs/enums and the + response just echoes them back. + */ +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; /** * Command TestDifferentVendorMeiRequest * @@ -16722,6 +16729,22 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeClusterErrorBooleanWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGlobalEnumWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGlobalStructWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeUnsupportedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -17002,6 +17025,22 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeWriteOnlyInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeNullableGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeNullableGlobalEnumWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeNullableGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeNullableGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeNullableGlobalStructWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeNullableGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index e2bb0e376dffe1..3ca3bfe55708dd 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -116509,6 +116509,30 @@ - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParam queue:self.callbackQueue completion:responseHandler]; } +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRUnitTestingClusterGlobalEchoRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = UnitTesting::Commands::GlobalEchoRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRUnitTestingClusterGlobalEchoResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} - (void)testDifferentVendorMeiRequestWithParams:(MTRUnitTestingClusterTestDifferentVendorMeiRequestParams *)params completion:(void (^)(MTRUnitTestingClusterTestDifferentVendorMeiResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -118935,6 +118959,10 @@ - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnu nonNullValue_2.f = static_cast>(element_0.nullableStruct.f.unsignedCharValue); nonNullValue_2.g = element_0.nullableStruct.g.floatValue; nonNullValue_2.h = element_0.nullableStruct.h.doubleValue; + if (element_0.nullableStruct.i != nil) { + auto & definedValue_4 = nonNullValue_2.i.Emplace(); + definedValue_4 = static_cast>(element_0.nullableStruct.i.unsignedCharValue); + } } if (element_0.optionalStruct != nil) { auto & definedValue_2 = listHolder_0->mList[i_0].optionalStruct.Emplace(); @@ -118946,6 +118974,10 @@ - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnu definedValue_2.f = static_cast>(element_0.optionalStruct.f.unsignedCharValue); definedValue_2.g = element_0.optionalStruct.g.floatValue; definedValue_2.h = element_0.optionalStruct.h.doubleValue; + if (element_0.optionalStruct.i != nil) { + auto & definedValue_4 = definedValue_2.i.Emplace(); + definedValue_4 = static_cast>(element_0.optionalStruct.i.unsignedCharValue); + } } if (element_0.nullableOptionalStruct != nil) { auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalStruct.Emplace(); @@ -118961,6 +118993,10 @@ - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnu nonNullValue_3.f = static_cast>(element_0.nullableOptionalStruct.f.unsignedCharValue); nonNullValue_3.g = element_0.nullableOptionalStruct.g.floatValue; nonNullValue_3.h = element_0.nullableOptionalStruct.h.doubleValue; + if (element_0.nullableOptionalStruct.i != nil) { + auto & definedValue_5 = nonNullValue_3.i.Emplace(); + definedValue_5 = static_cast>(element_0.nullableOptionalStruct.i.unsignedCharValue); + } } } if (element_0.nullableList == nil) { @@ -119186,6 +119222,10 @@ - (void)writeAttributeStructAttrWithValue:(MTRUnitTestingClusterSimpleStruct * _ cppValue.f = static_cast>(value.f.unsignedCharValue); cppValue.g = value.g.floatValue; cppValue.h = value.h.doubleValue; + if (value.i != nil) { + auto & definedValue_1 = cppValue.i.Emplace(); + definedValue_1 = static_cast>(value.i.unsignedCharValue); + } chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); @@ -119634,6 +119674,10 @@ - (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value params listHolder_0->mList[i_0].fabricSensitiveStruct.f = static_castmList[i_0].fabricSensitiveStruct.f)>>(element_0.fabricSensitiveStruct.f.unsignedCharValue); listHolder_0->mList[i_0].fabricSensitiveStruct.g = element_0.fabricSensitiveStruct.g.floatValue; listHolder_0->mList[i_0].fabricSensitiveStruct.h = element_0.fabricSensitiveStruct.h.doubleValue; + if (element_0.fabricSensitiveStruct.i != nil) { + auto & definedValue_3 = listHolder_0->mList[i_0].fabricSensitiveStruct.i.Emplace(); + definedValue_3 = static_cast>(element_0.fabricSensitiveStruct.i.unsignedCharValue); + } { using ListType_2 = std::remove_reference_tmList[i_0].fabricSensitiveInt8uList)>; using ListMemberType_2 = ListMemberTypeGetter::Type; @@ -119889,6 +119933,149 @@ + (void)readAttributeClusterErrorBooleanWithClusterStateCache:(MTRClusterStateCa completion:completion]; } +- (void)readAttributeGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + TypeInfo::Type cppValue; + cppValue = static_cast>(value.unsignedCharValue); + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeGlobalEnumWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + TypeInfo::Type cppValue; + cppValue.name = AsCharSpan(value.name); + if (value.myBitmap == nil) { + cppValue.myBitmap.SetNull(); + } else { + auto & nonNullValue_1 = cppValue.myBitmap.SetNonNull(); + nonNullValue_1 = static_cast>(value.myBitmap.unsignedIntValue); + } + if (value.myEnum != nil) { + auto & definedValue_1 = cppValue.myEnum.Emplace(); + if (value.myEnum == nil) { + definedValue_1.SetNull(); + } else { + auto & nonNullValue_2 = definedValue_1.SetNonNull(); + nonNullValue_2 = static_cast>(value.myEnum.unsignedCharValue); + } + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeGlobalStructWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + - (void)readAttributeUnsupportedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UnitTesting::Attributes::Unsupported::TypeInfo; @@ -121929,6 +122116,10 @@ - (void)writeAttributeNullableStructWithValue:(MTRUnitTestingClusterSimpleStruct nonNullValue_0.f = static_cast>(value.f.unsignedCharValue); nonNullValue_0.g = value.g.floatValue; nonNullValue_0.h = value.h.doubleValue; + if (value.i != nil) { + auto & definedValue_2 = nonNullValue_0.i.Emplace(); + definedValue_2 = static_cast>(value.i.unsignedCharValue); + } } chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); @@ -122301,6 +122492,159 @@ + (void)readAttributeWriteOnlyInt8uWithClusterStateCache:(MTRClusterStateCacheCo completion:completion]; } +- (void)readAttributeNullableGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = static_cast>(value.unsignedCharValue); + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeNullableGlobalEnumWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeNullableGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeNullableGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0.name = AsCharSpan(value.name); + if (value.myBitmap == nil) { + nonNullValue_0.myBitmap.SetNull(); + } else { + auto & nonNullValue_2 = nonNullValue_0.myBitmap.SetNonNull(); + nonNullValue_2 = static_cast>(value.myBitmap.unsignedIntValue); + } + if (value.myEnum != nil) { + auto & definedValue_2 = nonNullValue_0.myEnum.Emplace(); + if (value.myEnum == nil) { + definedValue_2.SetNull(); + } else { + auto & nonNullValue_3 = definedValue_2.SetNonNull(); + nonNullValue_3 = static_cast>(value.myEnum.unsignedCharValue); + } + } + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeNullableGlobalStructWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeNullableGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UnitTesting::Attributes::GeneratedCommandList::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 98ca2f96263d50..f920a8e336cd92 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -5764,6 +5764,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitTestingAttributeTimedWriteBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000030, MTRAttributeIDTypeClusterUnitTestingAttributeGeneralErrorBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000031, MTRAttributeIDTypeClusterUnitTestingAttributeClusterErrorBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000032, + MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID MTR_PROVISIONALLY_AVAILABLE = 0x00000033, + MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID MTR_PROVISIONALLY_AVAILABLE = 0x00000034, MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x000000FF, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004000, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBitmap8ID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004001, @@ -5799,6 +5801,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitTestingAttributeNullableRangeRestrictedInt16uID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004028, MTRAttributeIDTypeClusterUnitTestingAttributeNullableRangeRestrictedInt16sID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004029, MTRAttributeIDTypeClusterUnitTestingAttributeWriteOnlyInt8uID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000402A, + MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID MTR_PROVISIONALLY_AVAILABLE = 0x00004033, + MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID MTR_PROVISIONALLY_AVAILABLE = 0x00004034, MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterUnitTestingAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterUnitTestingAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -7102,6 +7106,7 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterUnitTestingCommandTestListInt8UReverseRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000D, MTRCommandIDTypeClusterUnitTestingCommandStringEchoResponseID MTR_PROVISIONALLY_AVAILABLE = 0x0000000D, MTRCommandIDTypeClusterUnitTestingCommandTestEnumsRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000E, + MTRCommandIDTypeClusterUnitTestingCommandGlobalEchoResponseID MTR_PROVISIONALLY_AVAILABLE = 0x0000000E, MTRCommandIDTypeClusterUnitTestingCommandTestNullableOptionalRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000F, MTRCommandIDTypeClusterUnitTestingCommandTestComplexNullableOptionalRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000010, MTRCommandIDTypeClusterUnitTestingCommandSimpleStructEchoRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000011, @@ -7112,6 +7117,7 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterUnitTestingCommandTestBatchHelperRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000016, MTRCommandIDTypeClusterUnitTestingCommandTestSecondBatchHelperRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000017, MTRCommandIDTypeClusterUnitTestingCommandStringEchoRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000018, + MTRCommandIDTypeClusterUnitTestingCommandGlobalEchoRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000019, MTRCommandIDTypeClusterUnitTestingCommandTestDifferentVendorMeiRequestID MTR_PROVISIONALLY_AVAILABLE = 0xFFF200AA, MTRCommandIDTypeClusterUnitTestingCommandTestDifferentVendorMeiResponseID MTR_PROVISIONALLY_AVAILABLE = 0xFFF200BB, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 5f9d1b8e510ed6..6191e7c60d53eb 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -9163,6 +9163,14 @@ result = @"ClusterErrorBoolean"; break; + case MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID: + result = @"GlobalEnum"; + break; + + case MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID: + result = @"GlobalStruct"; + break; + case MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID: result = @"Unsupported"; break; @@ -9303,6 +9311,14 @@ result = @"WriteOnlyInt8u"; break; + case MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID: + result = @"NullableGlobalEnum"; + break; + + case MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID: + result = @"NullableGlobalStruct"; + break; + case MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 8da2b1f2ec4f2b..44ecc1e0119c46 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -7455,6 +7455,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)testBatchHelperRequestWithParams:(MTRUnitTestingClusterTestBatchHelperRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestBatchHelperResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)testSecondBatchHelperRequestWithParams:(MTRUnitTestingClusterTestSecondBatchHelperRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestBatchHelperResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterStringEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)testDifferentVendorMeiRequestWithParams:(MTRUnitTestingClusterTestDifferentVendorMeiRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestDifferentVendorMeiResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeBooleanWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7645,6 +7646,14 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)writeAttributeClusterErrorBooleanWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeClusterErrorBooleanWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeGlobalEnumWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGlobalStructWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeUnsupportedWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7785,6 +7794,14 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)writeAttributeWriteOnlyInt8uWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeWriteOnlyInt8uWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeNullableGlobalEnumWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeNullableGlobalStructWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index ec6f0c49b74d73..8e06c4d288084f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -21757,6 +21757,33 @@ - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParam completion:responseHandler]; } +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRUnitTestingClusterGlobalEchoRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = UnitTesting::Commands::GlobalEchoRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRUnitTestingClusterGlobalEchoResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + - (void)testDifferentVendorMeiRequestWithParams:(MTRUnitTestingClusterTestDifferentVendorMeiRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestDifferentVendorMeiResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -22539,6 +22566,38 @@ - (void)writeAttributeClusterErrorBooleanWithValue:(NSDictionary [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeClusterErrorBooleanID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } +- (NSDictionary * _Nullable)readAttributeGlobalEnumWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID) params:params]; +} + +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeGlobalEnumWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeGlobalStructWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID) params:params]; +} + +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeGlobalStructWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + - (NSDictionary * _Nullable)readAttributeUnsupportedWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID) params:params]; @@ -23099,6 +23158,38 @@ - (void)writeAttributeWriteOnlyInt8uWithValue:(NSDictionary *)da [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeWriteOnlyInt8uID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } +- (NSDictionary * _Nullable)readAttributeNullableGlobalEnumWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID) params:params]; +} + +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeNullableGlobalEnumWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeNullableGlobalStructWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID) params:params]; +} + +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeNullableGlobalStructWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID) params:params]; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 54073ac579e846..62f200fe8623f7 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -12925,6 +12925,27 @@ MTR_DEPRECATED("Please use MTRUnitTestingClusterTestEnumsRequestParams", ios(16. @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRUnitTestingClusterGlobalEchoResponseParams : NSObject + +@property (nonatomic, copy) MTRDataTypeTestGlobalStruct * _Nonnull field1 MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull field2 MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRUnitTestingClusterGlobalEchoResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRUnitTestingClusterTestNullableOptionalRequestParams : NSObject @@ -13491,6 +13512,38 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRUnitTestingClusterGlobalEchoRequestParams : NSObject + +@property (nonatomic, copy) MTRDataTypeTestGlobalStruct * _Nonnull field1 MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull field2 MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRUnitTestingClusterTestDifferentVendorMeiRequestParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index c49195ce1016eb..6b10028ec18d78 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -32884,6 +32884,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()]; newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g]; newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h]; + if (entry_0.c.i.HasValue()) { + newElement_0.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.i.Value())]; + } else { + newElement_0.c.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; auto iter_2 = entry_0.d.begin(); @@ -32903,6 +32908,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()]; newElement_2.g = [NSNumber numberWithFloat:entry_2.g]; newElement_2.h = [NSNumber numberWithDouble:entry_2.h]; + if (entry_2.i.HasValue()) { + newElement_2.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.i.Value())]; + } else { + newElement_2.i = nil; + } [array_2 addObject:newElement_2]; } CHIP_ERROR err = iter_2.GetStatus(); @@ -32985,6 +32995,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } CHIP_ERROR err = iter_0.GetStatus(); @@ -33497,6 +33512,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].c.f = static_castmList[i_0].c.f)>>(element_0.c.f.unsignedCharValue); listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue; listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue; + if (element_0.c.i != nil) { + auto & definedValue_3 = listHolder_0->mList[i_0].c.i.Emplace(); + definedValue_3 = static_cast>(element_0.c.i.unsignedCharValue); + } { using ListType_2 = std::remove_reference_tmList[i_0].d)>; using ListMemberType_2 = ListMemberTypeGetter::Type; @@ -33520,6 +33539,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_2->mList[i_2].f = static_castmList[i_2].f)>>(element_2.f.unsignedCharValue); listHolder_2->mList[i_2].g = element_2.g.floatValue; listHolder_2->mList[i_2].h = element_2.h.doubleValue; + if (element_2.i != nil) { + auto & definedValue_4 = listHolder_2->mList[i_2].i.Emplace(); + definedValue_4 = static_cast>(element_2.i.unsignedCharValue); + } } listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count); } else { @@ -33623,6 +33646,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].f = static_castmList[i_0].f)>>(element_0.f.unsignedCharValue); listHolder_0->mList[i_0].g = element_0.g.floatValue; listHolder_0->mList[i_0].h = element_0.h.doubleValue; + if (element_0.i != nil) { + auto & definedValue_2 = listHolder_0->mList[i_0].i.Emplace(); + definedValue_2 = static_cast>(element_0.i.unsignedCharValue); + } } encodableStruct.arg2 = ListType_0(listHolder_0->mList, self.arg2.count); } else { @@ -33903,6 +33930,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.f = static_cast>(self.arg1.f.unsignedCharValue); encodableStruct.arg1.g = self.arg1.g.floatValue; encodableStruct.arg1.h = self.arg1.h.doubleValue; + if (self.arg1.i != nil) { + auto & definedValue_1 = encodableStruct.arg1.i.Emplace(); + definedValue_1 = static_cast>(self.arg1.i.unsignedCharValue); + } } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -34207,6 +34238,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.nullableStructValue.f = [NSNumber numberWithUnsignedChar:decodableStruct.nullableStructValue.Value().f.Raw()]; self.nullableStructValue.g = [NSNumber numberWithFloat:decodableStruct.nullableStructValue.Value().g]; self.nullableStructValue.h = [NSNumber numberWithDouble:decodableStruct.nullableStructValue.Value().h]; + if (decodableStruct.nullableStructValue.Value().i.HasValue()) { + self.nullableStructValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.nullableStructValue.Value().i.Value())]; + } else { + self.nullableStructValue.i = nil; + } } else { self.nullableStructValue = nil; } @@ -34229,6 +34265,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.optionalStructValue.f = [NSNumber numberWithUnsignedChar:decodableStruct.optionalStructValue.Value().f.Raw()]; self.optionalStructValue.g = [NSNumber numberWithFloat:decodableStruct.optionalStructValue.Value().g]; self.optionalStructValue.h = [NSNumber numberWithDouble:decodableStruct.optionalStructValue.Value().h]; + if (decodableStruct.optionalStructValue.Value().i.HasValue()) { + self.optionalStructValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.optionalStructValue.Value().i.Value())]; + } else { + self.optionalStructValue.i = nil; + } } else { self.optionalStructValue = nil; } @@ -34258,6 +34299,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.nullableOptionalStructValue.f = [NSNumber numberWithUnsignedChar:decodableStruct.nullableOptionalStructValue.Value().f.Raw()]; self.nullableOptionalStructValue.g = [NSNumber numberWithFloat:decodableStruct.nullableOptionalStructValue.Value().g]; self.nullableOptionalStructValue.h = [NSNumber numberWithDouble:decodableStruct.nullableOptionalStructValue.Value().h]; + if (decodableStruct.nullableOptionalStructValue.Value().i.HasValue()) { + self.nullableOptionalStructValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.nullableOptionalStructValue.Value().i.Value())]; + } else { + self.nullableOptionalStructValue.i = nil; + } } else { self.nullableOptionalStructValue = nil; } @@ -34426,6 +34472,29 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.c.f = static_cast>(self.arg1.c.f.unsignedCharValue); encodableStruct.arg1.c.g = self.arg1.c.g.floatValue; encodableStruct.arg1.c.h = self.arg1.c.h.doubleValue; + if (self.arg1.c.i != nil) { + auto & definedValue_2 = encodableStruct.arg1.c.i.Emplace(); + definedValue_2 = static_cast>(self.arg1.c.i.unsignedCharValue); + } + if (self.arg1.d != nil) { + auto & definedValue_1 = encodableStruct.arg1.d.Emplace(); + definedValue_1.name = AsCharSpan(self.arg1.d.name); + if (self.arg1.d.myBitmap == nil) { + definedValue_1.myBitmap.SetNull(); + } else { + auto & nonNullValue_3 = definedValue_1.myBitmap.SetNonNull(); + nonNullValue_3 = static_cast>(self.arg1.d.myBitmap.unsignedIntValue); + } + if (self.arg1.d.myEnum != nil) { + auto & definedValue_3 = definedValue_1.myEnum.Emplace(); + if (self.arg1.d.myEnum == nil) { + definedValue_3.SetNull(); + } else { + auto & nonNullValue_4 = definedValue_3.SetNonNull(); + nonNullValue_4 = static_cast>(self.arg1.d.myEnum.unsignedCharValue); + } + } + } } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -34619,6 +34688,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].f = static_castmList[i_0].f)>>(element_0.f.unsignedCharValue); listHolder_0->mList[i_0].g = element_0.g.floatValue; listHolder_0->mList[i_0].h = element_0.h.doubleValue; + if (element_0.i != nil) { + auto & definedValue_2 = listHolder_0->mList[i_0].i.Emplace(); + definedValue_2 = static_cast>(element_0.i.unsignedCharValue); + } } encodableStruct.arg1 = ListType_0(listHolder_0->mList, self.arg1.count); } else { @@ -34758,6 +34831,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.arg1.f = [NSNumber numberWithUnsignedChar:decodableStruct.arg1.f.Raw()]; self.arg1.g = [NSNumber numberWithFloat:decodableStruct.arg1.g]; self.arg1.h = [NSNumber numberWithDouble:decodableStruct.arg1.h]; + if (decodableStruct.arg1.i.HasValue()) { + self.arg1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.arg1.i.Value())]; + } else { + self.arg1.i = nil; + } } return CHIP_NO_ERROR; } @@ -35009,6 +35087,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.c.f = static_cast>(self.arg1.c.f.unsignedCharValue); encodableStruct.arg1.c.g = self.arg1.c.g.floatValue; encodableStruct.arg1.c.h = self.arg1.c.h.doubleValue; + if (self.arg1.c.i != nil) { + auto & definedValue_2 = encodableStruct.arg1.c.i.Emplace(); + definedValue_2 = static_cast>(self.arg1.c.i.unsignedCharValue); + } { using ListType_1 = std::remove_reference_t; using ListMemberType_1 = ListMemberTypeGetter::Type; @@ -35032,6 +35114,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_1->mList[i_1].f = static_castmList[i_1].f)>>(element_1.f.unsignedCharValue); listHolder_1->mList[i_1].g = element_1.g.floatValue; listHolder_1->mList[i_1].h = element_1.h.doubleValue; + if (element_1.i != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].i.Emplace(); + definedValue_3 = static_cast>(element_1.i.unsignedCharValue); + } } encodableStruct.arg1.d = ListType_1(listHolder_1->mList, self.arg1.d.count); } else { @@ -35299,6 +35385,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].c.f = static_castmList[i_0].c.f)>>(element_0.c.f.unsignedCharValue); listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue; listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue; + if (element_0.c.i != nil) { + auto & definedValue_3 = listHolder_0->mList[i_0].c.i.Emplace(); + definedValue_3 = static_cast>(element_0.c.i.unsignedCharValue); + } { using ListType_2 = std::remove_reference_tmList[i_0].d)>; using ListMemberType_2 = ListMemberTypeGetter::Type; @@ -35322,6 +35412,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_2->mList[i_2].f = static_castmList[i_2].f)>>(element_2.f.unsignedCharValue); listHolder_2->mList[i_2].g = element_2.g.floatValue; listHolder_2->mList[i_2].h = element_2.h.doubleValue; + if (element_2.i != nil) { + auto & definedValue_4 = listHolder_2->mList[i_2].i.Emplace(); + definedValue_4 = static_cast>(element_2.i.unsignedCharValue); + } } listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count); } else { @@ -35802,6 +35896,110 @@ @implementation MTRTestClusterClusterTestEnumsRequestParams @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; @end +@implementation MTRUnitTestingClusterGlobalEchoResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _field1 = [MTRDataTypeTestGlobalStruct new]; + + _field2 = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRUnitTestingClusterGlobalEchoResponseParams alloc] init]; + + other.field1 = self.field1; + other.field2 = self.field2; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: field1:%@; field2:%@; >", NSStringFromClass([self class]), _field1, _field2]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRUnitTestingClusterGlobalEchoResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType &)decodableStruct +{ + { + self.field1 = [MTRDataTypeTestGlobalStruct new]; + self.field1.name = AsString(decodableStruct.field1.name); + if (self.field1.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + if (decodableStruct.field1.myBitmap.IsNull()) { + self.field1.myBitmap = nil; + } else { + self.field1.myBitmap = [NSNumber numberWithUnsignedInt:decodableStruct.field1.myBitmap.Value().Raw()]; + } + if (decodableStruct.field1.myEnum.HasValue()) { + if (decodableStruct.field1.myEnum.Value().IsNull()) { + self.field1.myEnum = nil; + } else { + self.field1.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.field1.myEnum.Value().Value())]; + } + } else { + self.field1.myEnum = nil; + } + } + { + self.field2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.field2)]; + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRUnitTestingClusterTestNullableOptionalRequestParams - (instancetype)init { @@ -36028,6 +36226,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader nonNullValue_0.f = static_cast>(self.nullableStruct.f.unsignedCharValue); nonNullValue_0.g = self.nullableStruct.g.floatValue; nonNullValue_0.h = self.nullableStruct.h.doubleValue; + if (self.nullableStruct.i != nil) { + auto & definedValue_2 = nonNullValue_0.i.Emplace(); + definedValue_2 = static_cast>(self.nullableStruct.i.unsignedCharValue); + } } } { @@ -36041,6 +36243,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader definedValue_0.f = static_cast>(self.optionalStruct.f.unsignedCharValue); definedValue_0.g = self.optionalStruct.g.floatValue; definedValue_0.h = self.optionalStruct.h.doubleValue; + if (self.optionalStruct.i != nil) { + auto & definedValue_2 = definedValue_0.i.Emplace(); + definedValue_2 = static_cast>(self.optionalStruct.i.unsignedCharValue); + } } } { @@ -36058,6 +36264,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader nonNullValue_1.f = static_cast>(self.nullableOptionalStruct.f.unsignedCharValue); nonNullValue_1.g = self.nullableOptionalStruct.g.floatValue; nonNullValue_1.h = self.nullableOptionalStruct.h.doubleValue; + if (self.nullableOptionalStruct.i != nil) { + auto & definedValue_3 = nonNullValue_1.i.Emplace(); + definedValue_3 = static_cast>(self.nullableOptionalStruct.i.unsignedCharValue); + } } } } @@ -36251,6 +36461,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.f = static_cast>(self.arg1.f.unsignedCharValue); encodableStruct.arg1.g = self.arg1.g.floatValue; encodableStruct.arg1.h = self.arg1.h.doubleValue; + if (self.arg1.i != nil) { + auto & definedValue_1 = encodableStruct.arg1.i.Emplace(); + definedValue_1 = static_cast>(self.arg1.i.unsignedCharValue); + } } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -36908,6 +37122,106 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRUnitTestingClusterGlobalEchoRequestParams +- (instancetype)init +{ + if (self = [super init]) { + + _field1 = [MTRDataTypeTestGlobalStruct new]; + + _field2 = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRUnitTestingClusterGlobalEchoRequestParams alloc] init]; + + other.field1 = self.field1; + other.field2 = self.field2; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: field1:%@; field2:%@; >", NSStringFromClass([self class]), _field1, _field2]; + return descriptionString; +} + +@end + +@implementation MTRUnitTestingClusterGlobalEchoRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.field1.name = AsCharSpan(self.field1.name); + if (self.field1.myBitmap == nil) { + encodableStruct.field1.myBitmap.SetNull(); + } else { + auto & nonNullValue_1 = encodableStruct.field1.myBitmap.SetNonNull(); + nonNullValue_1 = static_cast>(self.field1.myBitmap.unsignedIntValue); + } + if (self.field1.myEnum != nil) { + auto & definedValue_1 = encodableStruct.field1.myEnum.Emplace(); + if (self.field1.myEnum == nil) { + definedValue_1.SetNull(); + } else { + auto & nonNullValue_2 = definedValue_1.SetNonNull(); + nonNullValue_2 = static_cast>(self.field1.myEnum.unsignedCharValue); + } + } + } + { + encodableStruct.field2 = static_cast>(self.field2.unsignedCharValue); + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + @implementation MTRUnitTestingClusterTestDifferentVendorMeiRequestParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index d3058d649ee710..93191eb3caa64d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -2266,6 +2266,12 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRUnitTestingClusterGlobalEchoResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType &)decodableStruct; + +@end + @interface MTRUnitTestingClusterTestNullableOptionalRequestParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -2326,6 +2332,12 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRUnitTestingClusterGlobalEchoRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + @interface MTRUnitTestingClusterTestDifferentVendorMeiRequestParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 4d70a00ee32937..821b8f6d58173d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -4637,6 +4637,11 @@ static id _Nullable DecodeEventPayloadForUnitTestingCluster(EventId aEventId, TL memberValue.f = [NSNumber numberWithUnsignedChar:cppValue.arg4.f.Raw()]; memberValue.g = [NSNumber numberWithFloat:cppValue.arg4.g]; memberValue.h = [NSNumber numberWithDouble:cppValue.arg4.h]; + if (cppValue.arg4.i.HasValue()) { + memberValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.arg4.i.Value())]; + } else { + memberValue.i = nil; + } value.arg4 = memberValue; } while (0); do { @@ -4661,6 +4666,11 @@ static id _Nullable DecodeEventPayloadForUnitTestingCluster(EventId aEventId, TL newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } CHIP_ERROR err = iter_0.GetStatus(); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 3a11fc91e44536..d73fc257e6bcd6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -2139,6 +2139,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @property (nonatomic, copy) NSNumber * _Nonnull f MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) NSNumber * _Nonnull g MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) NSNumber * _Nonnull h MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@property (nonatomic, copy) NSNumber * _Nullable i MTR_PROVISIONALLY_AVAILABLE; @end MTR_DEPRECATED("Please use MTRUnitTestingClusterSimpleStruct", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -2214,6 +2215,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @property (nonatomic, copy) NSNumber * _Nonnull a MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) NSNumber * _Nonnull b MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) MTRUnitTestingClusterSimpleStruct * _Nonnull c MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@property (nonatomic, copy) MTRDataTypeTestGlobalStruct * _Nullable d MTR_PROVISIONALLY_AVAILABLE; @end MTR_DEPRECATED("Please use MTRUnitTestingClusterNestedStruct", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 94a6b90dfeac88..632b70647eb6d0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -8825,6 +8825,8 @@ - (instancetype)init _g = @(0); _h = @(0); + + _i = nil; } return self; } @@ -8841,13 +8843,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.f = self.f; other.g = self.g; other.h = self.h; + other.i = self.i; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; d:%@; e:%@; f:%@; g:%@; h:%@; >", NSStringFromClass([self class]), _a, _b, _c, [_d base64EncodedStringWithOptions:0], _e, _f, _g, _h]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; d:%@; e:%@; f:%@; g:%@; h:%@; i:%@; >", NSStringFromClass([self class]), _a, _b, _c, [_d base64EncodedStringWithOptions:0], _e, _f, _g, _h, _i]; return descriptionString; } @@ -9008,6 +9011,8 @@ - (instancetype)init _b = @(0); _c = [MTRUnitTestingClusterSimpleStruct new]; + + _d = nil; } return self; } @@ -9019,13 +9024,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.a = self.a; other.b = self.b; other.c = self.c; + other.d = self.d; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; >", NSStringFromClass([self class]), _a, _b, _c]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; d:%@; >", NSStringFromClass([self class]), _a, _b, _c, _d]; return descriptionString; } diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 1ba55467d670af..ca6df3d1c72e99 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -46078,6 +46078,53 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) } // namespace TimedWriteBoolean +namespace GlobalEnum { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); +} + +} // namespace GlobalEnum + namespace Unsupported { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) @@ -49016,6 +49063,98 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value, + MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace NullableGlobalEnum + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 53e24c079fc4bd..ea344fcc49b7cd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -6957,6 +6957,14 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); } // namespace TimedWriteBoolean +namespace GlobalEnum { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::Globals::TestGlobalEnum * value); // TestGlobalEnum +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value, + MarkAttributeDirty markDirty); +} // namespace GlobalEnum + namespace Unsupported { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value); // boolean Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); @@ -7362,6 +7370,21 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { +Protocols::InteractionModel::Status +Get(chip::EndpointId endpoint, DataModel::Nullable & value); // TestGlobalEnum +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value, + MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace NullableGlobalEnum + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 60cdf13689cf10..d1f11db1e93cc5 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -6929,6 +6929,12 @@ bool emberAfUnitTestingClusterTestSecondBatchHelperRequestCallback( bool emberAfUnitTestingClusterStringEchoRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::DecodableType & commandData); +/** + * @brief Unit Testing Cluster GlobalEchoRequest Command callback (from client) + */ +bool emberAfUnitTestingClusterGlobalEchoRequestCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::DecodableType & commandData); /** * @brief Unit Testing Cluster TestDifferentVendorMeiRequest Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index af49e0617caa1f..f206178484a6c3 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -29391,6 +29391,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const encoder.Encode(to_underlying(Fields::kF), f); encoder.Encode(to_underlying(Fields::kG), g); encoder.Encode(to_underlying(Fields::kH), h); + encoder.Encode(to_underlying(Fields::kI), i); return encoder.Finalize(); } @@ -29440,6 +29441,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, h); } + else if (__context_tag == to_underlying(Fields::kI)) + { + err = DataModel::Decode(reader, i); + } else { } @@ -29657,6 +29662,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const encoder.Encode(to_underlying(Fields::kA), a); encoder.Encode(to_underlying(Fields::kB), b); encoder.Encode(to_underlying(Fields::kC), c); + encoder.Encode(to_underlying(Fields::kD), d); return encoder.Finalize(); } @@ -29686,6 +29692,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, c); } + else if (__context_tag == to_underlying(Fields::kD)) + { + err = DataModel::Decode(reader, d); + } else { } @@ -30986,6 +30996,45 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace TestEnumsRequest. +namespace GlobalEchoResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kField1), field1); + encoder.Encode(to_underlying(Fields::kField2), field2); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kField1)) + { + err = DataModel::Decode(reader, field1); + } + else if (__context_tag == to_underlying(Fields::kField2)) + { + err = DataModel::Decode(reader, field2); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace GlobalEchoResponse. namespace TestNullableOptionalRequest { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -31397,6 +31446,45 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace StringEchoRequest. +namespace GlobalEchoRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kField1), field1); + encoder.Encode(to_underlying(Fields::kField2), field2); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kField1)) + { + err = DataModel::Decode(reader, field1); + } + else if (__context_tag == to_underlying(Fields::kField2)) + { + err = DataModel::Decode(reader, field2); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace GlobalEchoRequest. namespace TestDifferentVendorMeiRequest { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -31571,6 +31659,10 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generalErrorBoolean); case Attributes::ClusterErrorBoolean::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, clusterErrorBoolean); + case Attributes::GlobalEnum::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, globalEnum); + case Attributes::GlobalStruct::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, globalStruct); case Attributes::Unsupported::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, unsupported); case Attributes::NullableBoolean::TypeInfo::GetAttributeId(): @@ -31641,6 +31733,10 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, nullableRangeRestrictedInt16s); case Attributes::WriteOnlyInt8u::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, writeOnlyInt8u); + case Attributes::NullableGlobalEnum::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, nullableGlobalEnum); + case Attributes::NullableGlobalStruct::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, nullableGlobalStruct); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 25ded74c85a287..719c1de9e28975 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -44013,6 +44013,7 @@ enum class Fields : uint8_t kF = 5, kG = 6, kH = 7, + kI = 8, }; struct Type @@ -44026,6 +44027,7 @@ struct Type chip::BitMask f = static_cast>(0); float g = static_cast(0); double h = static_cast(0); + Optional i; CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -44163,6 +44165,7 @@ enum class Fields : uint8_t kA = 0, kB = 1, kC = 2, + kD = 3, }; struct Type @@ -44171,6 +44174,7 @@ struct Type uint8_t a = static_cast(0); bool b = static_cast(0); Structs::SimpleStruct::Type c; + Optional d; CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -44427,6 +44431,11 @@ struct Type; struct DecodableType; } // namespace TestEnumsRequest +namespace GlobalEchoResponse { +struct Type; +struct DecodableType; +} // namespace GlobalEchoResponse + namespace TestNullableOptionalRequest { struct Type; struct DecodableType; @@ -44477,6 +44486,11 @@ struct Type; struct DecodableType; } // namespace StringEchoRequest +namespace GlobalEchoRequest { +struct Type; +struct DecodableType; +} // namespace GlobalEchoRequest + namespace TestDifferentVendorMeiRequest { struct Type; struct DecodableType; @@ -45531,6 +45545,41 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace TestEnumsRequest +namespace GlobalEchoResponse { +enum class Fields : uint8_t +{ + kField1 = 0, + kField2 = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::Type field1; + Globals::TestGlobalEnum field2 = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::DecodableType field1; + Globals::TestGlobalEnum field2 = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GlobalEchoResponse namespace TestNullableOptionalRequest { enum class Fields : uint8_t { @@ -45898,6 +45947,41 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace StringEchoRequest +namespace GlobalEchoRequest { +enum class Fields : uint8_t +{ + kField1 = 0, + kField2 = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::Type field1; + Globals::TestGlobalEnum field2 = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::DecodableType field1; + Globals::TestGlobalEnum field2 = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GlobalEchoRequest namespace TestDifferentVendorMeiRequest { enum class Fields : uint8_t { @@ -46543,6 +46627,30 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace ClusterErrorBoolean +namespace GlobalEnum { +struct TypeInfo +{ + using Type = chip::app::Clusters::Globals::TestGlobalEnum; + using DecodableType = chip::app::Clusters::Globals::TestGlobalEnum; + using DecodableArgType = chip::app::Clusters::Globals::TestGlobalEnum; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::GlobalEnum::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace GlobalEnum +namespace GlobalStruct { +struct TypeInfo +{ + using Type = chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type; + using DecodableType = chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType; + using DecodableArgType = const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType &; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::GlobalStruct::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace GlobalStruct namespace Unsupported { struct TypeInfo { @@ -46970,6 +47078,31 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::NullableGlobalEnum::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace NullableGlobalEnum +namespace NullableGlobalStruct { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = + const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::NullableGlobalStruct::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace NullableGlobalStruct namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -47078,7 +47211,9 @@ struct TypeInfo Attributes::TimedWriteBoolean::TypeInfo::DecodableType timedWriteBoolean = static_cast(0); Attributes::GeneralErrorBoolean::TypeInfo::DecodableType generalErrorBoolean = static_cast(0); Attributes::ClusterErrorBoolean::TypeInfo::DecodableType clusterErrorBoolean = static_cast(0); - Attributes::Unsupported::TypeInfo::DecodableType unsupported = static_cast(0); + Attributes::GlobalEnum::TypeInfo::DecodableType globalEnum = static_cast(0); + Attributes::GlobalStruct::TypeInfo::DecodableType globalStruct; + Attributes::Unsupported::TypeInfo::DecodableType unsupported = static_cast(0); Attributes::NullableBoolean::TypeInfo::DecodableType nullableBoolean; Attributes::NullableBitmap8::TypeInfo::DecodableType nullableBitmap8; Attributes::NullableBitmap16::TypeInfo::DecodableType nullableBitmap16; @@ -47113,6 +47248,8 @@ struct TypeInfo Attributes::NullableRangeRestrictedInt16u::TypeInfo::DecodableType nullableRangeRestrictedInt16u; Attributes::NullableRangeRestrictedInt16s::TypeInfo::DecodableType nullableRangeRestrictedInt16s; Attributes::WriteOnlyInt8u::TypeInfo::DecodableType writeOnlyInt8u = static_cast(0); + Attributes::NullableGlobalEnum::TypeInfo::DecodableType nullableGlobalEnum; + Attributes::NullableGlobalStruct::TypeInfo::DecodableType nullableGlobalStruct; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 0a144da9030e42..5deab64ef504fc 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -8296,6 +8296,14 @@ namespace ClusterErrorBoolean { static constexpr AttributeId Id = 0x00000032; } // namespace ClusterErrorBoolean +namespace GlobalEnum { +static constexpr AttributeId Id = 0x00000033; +} // namespace GlobalEnum + +namespace GlobalStruct { +static constexpr AttributeId Id = 0x00000034; +} // namespace GlobalStruct + namespace Unsupported { static constexpr AttributeId Id = 0x000000FF; } // namespace Unsupported @@ -8436,6 +8444,14 @@ namespace WriteOnlyInt8u { static constexpr AttributeId Id = 0x0000402A; } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { +static constexpr AttributeId Id = 0x00004033; +} // namespace NullableGlobalEnum + +namespace NullableGlobalStruct { +static constexpr AttributeId Id = 0x00004034; +} // namespace NullableGlobalStruct + namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index 68b11f130dcb4c..e9210638315112 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1980,6 +1980,10 @@ namespace TestEnumsRequest { static constexpr CommandId Id = 0x0000000E; } // namespace TestEnumsRequest +namespace GlobalEchoResponse { +static constexpr CommandId Id = 0x0000000E; +} // namespace GlobalEchoResponse + namespace TestNullableOptionalRequest { static constexpr CommandId Id = 0x0000000F; } // namespace TestNullableOptionalRequest @@ -2020,6 +2024,10 @@ namespace StringEchoRequest { static constexpr CommandId Id = 0x00000018; } // namespace StringEchoRequest +namespace GlobalEchoRequest { +static constexpr CommandId Id = 0x00000019; +} // namespace GlobalEchoRequest + namespace TestDifferentVendorMeiRequest { static constexpr CommandId Id = 0xFFF200AA; } // namespace TestDifferentVendorMeiRequest diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 9367f844d3c16b..a48a4b5376f2b7 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -14243,6 +14243,7 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * TestBatchHelperRequest | 0x16 | | * TestSecondBatchHelperRequest | 0x17 | | * StringEchoRequest | 0x18 | +| * GlobalEchoRequest | 0x19 | | * TestDifferentVendorMeiRequest | 0xFFF200AA| |------------------------------------------------------------------------------| | Attributes: | | @@ -14293,6 +14294,8 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * TimedWriteBoolean | 0x0030 | | * GeneralErrorBoolean | 0x0031 | | * ClusterErrorBoolean | 0x0032 | +| * GlobalEnum | 0x0033 | +| * GlobalStruct | 0x0034 | | * Unsupported | 0x00FF | | * NullableBoolean | 0x4000 | | * NullableBitmap8 | 0x4001 | @@ -14328,6 +14331,8 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * NullableRangeRestrictedInt16u | 0x4028 | | * NullableRangeRestrictedInt16s | 0x4029 | | * WriteOnlyInt8u | 0x402A | +| * NullableGlobalEnum | 0x4033 | +| * NullableGlobalStruct | 0x4034 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -15344,6 +15349,46 @@ class UnitTestingStringEchoRequest : public ClusterCommand chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::Type mRequest; }; +/* + * Command GlobalEchoRequest + */ +class UnitTestingGlobalEchoRequest : public ClusterCommand +{ +public: + UnitTestingGlobalEchoRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("global-echo-request", credsIssuerConfig), mComplex_Field1(&mRequest.field1) + { + AddArgument("Field1", &mComplex_Field1); + AddArgument("Field2", 0, UINT8_MAX, &mRequest.field2); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Type mRequest; + TypedComplexArgument mComplex_Field1; +}; + /* * Command TestDifferentVendorMeiRequest */ @@ -27673,6 +27718,7 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // // // Attributes @@ -27726,6 +27772,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "timed-write-boolean", Attributes::TimedWriteBoolean::Id, credsIssuerConfig), // make_unique(Id, "general-error-boolean", Attributes::GeneralErrorBoolean::Id, credsIssuerConfig), // make_unique(Id, "cluster-error-boolean", Attributes::ClusterErrorBoolean::Id, credsIssuerConfig), // + make_unique(Id, "global-enum", Attributes::GlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "global-struct", Attributes::GlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "unsupported", Attributes::Unsupported::Id, credsIssuerConfig), // make_unique(Id, "nullable-boolean", Attributes::NullableBoolean::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap8", Attributes::NullableBitmap8::Id, credsIssuerConfig), // @@ -27765,6 +27813,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "nullable-range-restricted-int16s", Attributes::NullableRangeRestrictedInt16s::Id, credsIssuerConfig), // make_unique(Id, "write-only-int8u", Attributes::WriteOnlyInt8u::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-enum", Attributes::NullableGlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-struct", Attributes::NullableGlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // @@ -27873,6 +27923,10 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "cluster-error-boolean", 0, 1, Attributes::ClusterErrorBoolean::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>( + Id, "global-enum", 0, UINT8_MAX, Attributes::GlobalEnum::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>( + Id, "global-struct", Attributes::GlobalStruct::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "unsupported", 0, 1, Attributes::Unsupported::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( @@ -27966,6 +28020,12 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "write-only-int8u", 0, UINT8_MAX, Attributes::WriteOnlyInt8u::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>>( + Id, "nullable-global-enum", 0, UINT8_MAX, Attributes::NullableGlobalEnum::Id, WriteCommandType::kWrite, + credsIssuerConfig), // + make_unique< + WriteAttributeAsComplex>>( + Id, "nullable-global-struct", Attributes::NullableGlobalStruct::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -28031,6 +28091,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "timed-write-boolean", Attributes::TimedWriteBoolean::Id, credsIssuerConfig), // make_unique(Id, "general-error-boolean", Attributes::GeneralErrorBoolean::Id, credsIssuerConfig), // make_unique(Id, "cluster-error-boolean", Attributes::ClusterErrorBoolean::Id, credsIssuerConfig), // + make_unique(Id, "global-enum", Attributes::GlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "global-struct", Attributes::GlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "unsupported", Attributes::Unsupported::Id, credsIssuerConfig), // make_unique(Id, "nullable-boolean", Attributes::NullableBoolean::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap8", Attributes::NullableBitmap8::Id, credsIssuerConfig), // @@ -28070,6 +28132,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "nullable-range-restricted-int16s", Attributes::NullableRangeRestrictedInt16s::Id, credsIssuerConfig), // make_unique(Id, "write-only-int8u", Attributes::WriteOnlyInt8u::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-enum", Attributes::NullableGlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-struct", Attributes::NullableGlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 3b958cf45af7ff..8a9766461d448c 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -19,6 +19,44 @@ #include +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TestGlobalStruct.name", "name", value.isMember("name"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("TestGlobalStruct.myBitmap", "myBitmap", value.isMember("myBitmap"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"])); + valueCopy.removeMember("name"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "myBitmap"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.myBitmap, value["myBitmap"])); + valueCopy.removeMember("myBitmap"); + + if (value.isMember("myEnum")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "myEnum"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.myEnum, value["myEnum"])); + } + valueCopy.removeMember("myEnum"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.name); + ComplexArgumentParser::Finalize(request.myBitmap); + ComplexArgumentParser::Finalize(request.myEnum); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::ModeTagStruct::Type & request, Json::Value & value) { @@ -423,44 +461,6 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::Opera ComplexArgumentParser::Finalize(request.operationalStateLabel); } -CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request, - Json::Value & value) -{ - VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); - - // Copy to track which members we already processed. - Json::Value valueCopy(value); - - ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TestGlobalStruct.name", "name", value.isMember("name"))); - ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("TestGlobalStruct.myBitmap", "myBitmap", value.isMember("myBitmap"))); - - char labelWithMember[kMaxLabelLength]; - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"])); - valueCopy.removeMember("name"); - - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "myBitmap"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.myBitmap, value["myBitmap"])); - valueCopy.removeMember("myBitmap"); - - if (value.isMember("myEnum")) - { - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "myEnum"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.myEnum, value["myEnum"])); - } - valueCopy.removeMember("myEnum"); - - return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); -} - -void ComplexArgumentParser::Finalize(chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request) -{ - ComplexArgumentParser::Finalize(request.name); - ComplexArgumentParser::Finalize(request.myBitmap); - ComplexArgumentParser::Finalize(request.myEnum); -} - CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request, Json::Value & value) @@ -5739,6 +5739,13 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters: ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.h, value["h"])); valueCopy.removeMember("h"); + if (value.isMember("i")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "i"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.i, value["i"])); + } + valueCopy.removeMember("i"); + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); } @@ -5752,6 +5759,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs:: ComplexArgumentParser::Finalize(request.f); ComplexArgumentParser::Finalize(request.g); ComplexArgumentParser::Finalize(request.h); + ComplexArgumentParser::Finalize(request.i); } CHIP_ERROR ComplexArgumentParser::Setup(const char * label, @@ -5978,6 +5986,13 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters: ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.c, value["c"])); valueCopy.removeMember("c"); + if (value.isMember("d")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "d"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.d, value["d"])); + } + valueCopy.removeMember("d"); + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); } @@ -5986,6 +6001,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs:: ComplexArgumentParser::Finalize(request.a); ComplexArgumentParser::Finalize(request.b); ComplexArgumentParser::Finalize(request.c); + ComplexArgumentParser::Finalize(request.d); } CHIP_ERROR ComplexArgumentParser::Setup(const char * label, diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index 47683b1ab87888..5bb0718efb81ea 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -22,6 +22,11 @@ #include #include +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::ModeTagStruct::Type & request, Json::Value & value); @@ -71,11 +76,6 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs static void Finalize(chip::app::Clusters::detail::Structs::OperationalStateStruct::Type & request); -static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request, - Json::Value & value); - -static void Finalize(chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request); - static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request, Json::Value & value); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index fb156dee2d45dc..7fe1851ba370ce 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -21,6 +21,39 @@ using namespace chip::app::Clusters; +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Name", indent + 1, value.name); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Name'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("MyBitmap", indent + 1, value.myBitmap); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MyBitmap'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("MyEnum", indent + 1, value.myEnum); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MyEnum'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ModeTagStruct::DecodableType & value) { @@ -368,39 +401,6 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } -CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType & value) -{ - DataModelLogger::LogString(label, indent, "{"); - { - CHIP_ERROR err = LogValue("Name", indent + 1, value.name); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Name'"); - return err; - } - } - { - CHIP_ERROR err = LogValue("MyBitmap", indent + 1, value.myBitmap); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MyBitmap'"); - return err; - } - } - { - CHIP_ERROR err = LogValue("MyEnum", indent + 1, value.myEnum); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MyEnum'"); - return err; - } - } - DataModelLogger::LogString(indent, "}"); - - return CHIP_NO_ERROR; -} - CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value) { @@ -5083,6 +5083,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = LogValue("I", indent + 1, value.i); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'I'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -5296,6 +5304,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = LogValue("D", indent + 1, value.d); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'D'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -8758,6 +8774,15 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const UnitTesting::Commands::GlobalEchoResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("field1", indent + 1, value.field1)); + ReturnErrorOnFailure(DataModelLogger::LogValue("field2", indent + 1, value.field2)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const UnitTesting::Commands::TestDifferentVendorMeiResponse::DecodableType & value) { @@ -19002,6 +19027,16 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("cluster_error_boolean", 1, value); } + case UnitTesting::Attributes::GlobalEnum::Id: { + chip::app::Clusters::Globals::TestGlobalEnum value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("global_enum", 1, value); + } + case UnitTesting::Attributes::GlobalStruct::Id: { + chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("global_struct", 1, value); + } case UnitTesting::Attributes::Unsupported::Id: { bool value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19177,6 +19212,16 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("write_only_int8u", 1, value); } + case UnitTesting::Attributes::NullableGlobalEnum::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("nullable_global_enum", 1, value); + } + case UnitTesting::Attributes::NullableGlobalStruct::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("nullable_global_struct", 1, value); + } case UnitTesting::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19991,6 +20036,11 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("StringEchoResponse", 1, value); } + case UnitTesting::Commands::GlobalEchoResponse::Id: { + UnitTesting::Commands::GlobalEchoResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GlobalEchoResponse", 1, value); + } case UnitTesting::Commands::TestDifferentVendorMeiResponse::Id: { UnitTesting::Commands::TestDifferentVendorMeiResponse::DecodableType value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 165d44db24002f..52dede56ab7ec0 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -20,6 +20,9 @@ #include #include +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ModeTagStruct::DecodableType & value); @@ -50,9 +53,6 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::OperationalStateStruct::DecodableType & value); -static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType & value); - static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value); @@ -868,6 +868,8 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Commands::TestBatchHelperResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Commands::StringEchoResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Commands::TestDifferentVendorMeiResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index d31a6b22803f88..e226d87a19aec8 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -177168,6 +177168,7 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * TestBatchHelperRequest | 0x16 | | * TestSecondBatchHelperRequest | 0x17 | | * StringEchoRequest | 0x18 | +| * GlobalEchoRequest | 0x19 | | * TestDifferentVendorMeiRequest | 0xFFF200AA| |------------------------------------------------------------------------------| | Attributes: | | @@ -177218,6 +177219,8 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * TimedWriteBoolean | 0x0030 | | * GeneralErrorBoolean | 0x0031 | | * ClusterErrorBoolean | 0x0032 | +| * GlobalEnum | 0x0033 | +| * GlobalStruct | 0x0034 | | * Unsupported | 0x00FF | | * NullableBoolean | 0x4000 | | * NullableBitmap8 | 0x4001 | @@ -177253,6 +177256,8 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * NullableRangeRestrictedInt16u | 0x4028 | | * NullableRangeRestrictedInt16s | 0x4029 | | * WriteOnlyInt8u | 0x402A | +| * NullableGlobalEnum | 0x4033 | +| * NullableGlobalStruct | 0x4034 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -177605,6 +177610,11 @@ class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand { newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()]; newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g]; newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h]; + if (entry_0.c.i.HasValue()) { + newElement_0.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.i.Value())]; + } else { + newElement_0.c.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; for (auto & entry_2 : entry_0.d) { @@ -177618,6 +177628,11 @@ class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand { newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()]; newElement_2.g = [NSNumber numberWithFloat:entry_2.g]; newElement_2.h = [NSNumber numberWithDouble:entry_2.h]; + if (entry_2.i.HasValue()) { + newElement_2.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.i.Value())]; + } else { + newElement_2.i = nil; + } [array_2 addObject:newElement_2]; } newElement_0.d = array_2; @@ -177666,6 +177681,11 @@ class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand { newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } params.arg2 = array_0; @@ -177756,6 +177776,11 @@ class UnitTestingTestStructArgumentRequest : public ClusterCommand { params.arg1.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.f.Raw()]; params.arg1.g = [NSNumber numberWithFloat:mRequest.arg1.g]; params.arg1.h = [NSNumber numberWithDouble:mRequest.arg1.h]; + if (mRequest.arg1.i.HasValue()) { + params.arg1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.i.Value())]; + } else { + params.arg1.i = nil; + } uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -177822,6 +177847,31 @@ class UnitTestingTestNestedStructArgumentRequest : public ClusterCommand { params.arg1.c.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.f.Raw()]; params.arg1.c.g = [NSNumber numberWithFloat:mRequest.arg1.c.g]; params.arg1.c.h = [NSNumber numberWithDouble:mRequest.arg1.c.h]; + if (mRequest.arg1.c.i.HasValue()) { + params.arg1.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c.i.Value())]; + } else { + params.arg1.c.i = nil; + } + if (mRequest.arg1.d.HasValue()) { + params.arg1.d = [MTRDataTypeTestGlobalStruct new]; + params.arg1.d.name = [[NSString alloc] initWithBytes:mRequest.arg1.d.Value().name.data() length:mRequest.arg1.d.Value().name.size() encoding:NSUTF8StringEncoding]; + if (mRequest.arg1.d.Value().myBitmap.IsNull()) { + params.arg1.d.myBitmap = nil; + } else { + params.arg1.d.myBitmap = [NSNumber numberWithUnsignedInt:mRequest.arg1.d.Value().myBitmap.Value().Raw()]; + } + if (mRequest.arg1.d.Value().myEnum.HasValue()) { + if (mRequest.arg1.d.Value().myEnum.Value().IsNull()) { + params.arg1.d.myEnum = nil; + } else { + params.arg1.d.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.d.Value().myEnum.Value().Value())]; + } + } else { + params.arg1.d.myEnum = nil; + } + } else { + params.arg1.d = nil; + } uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -177889,6 +177939,11 @@ class UnitTestingTestListStructArgumentRequest : public ClusterCommand { newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } params.arg1 = array_0; @@ -178022,6 +178077,11 @@ class UnitTestingTestNestedStructListArgumentRequest : public ClusterCommand { params.arg1.c.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.f.Raw()]; params.arg1.c.g = [NSNumber numberWithFloat:mRequest.arg1.c.g]; params.arg1.c.h = [NSNumber numberWithDouble:mRequest.arg1.c.h]; + if (mRequest.arg1.c.i.HasValue()) { + params.arg1.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c.i.Value())]; + } else { + params.arg1.c.i = nil; + } { // Scope for our temporary variables auto * array_1 = [NSMutableArray new]; for (auto & entry_1 : mRequest.arg1.d) { @@ -178035,6 +178095,11 @@ class UnitTestingTestNestedStructListArgumentRequest : public ClusterCommand { newElement_1.f = [NSNumber numberWithUnsignedChar:entry_1.f.Raw()]; newElement_1.g = [NSNumber numberWithFloat:entry_1.g]; newElement_1.h = [NSNumber numberWithDouble:entry_1.h]; + if (entry_1.i.HasValue()) { + newElement_1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.i.Value())]; + } else { + newElement_1.i = nil; + } [array_1 addObject:newElement_1]; } params.arg1.d = array_1; @@ -178136,6 +178201,11 @@ class UnitTestingTestListNestedStructListArgumentRequest : public ClusterCommand newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()]; newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g]; newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h]; + if (entry_0.c.i.HasValue()) { + newElement_0.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.i.Value())]; + } else { + newElement_0.c.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; for (auto & entry_2 : entry_0.d) { @@ -178149,6 +178219,11 @@ class UnitTestingTestListNestedStructListArgumentRequest : public ClusterCommand newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()]; newElement_2.g = [NSNumber numberWithFloat:entry_2.g]; newElement_2.h = [NSNumber numberWithDouble:entry_2.h]; + if (entry_2.i.HasValue()) { + newElement_2.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.i.Value())]; + } else { + newElement_2.i = nil; + } [array_2 addObject:newElement_2]; } newElement_0.d = array_2; @@ -178483,6 +178558,11 @@ class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand { params.nullableStruct.f = [NSNumber numberWithUnsignedChar:mRequest.nullableStruct.Value().f.Raw()]; params.nullableStruct.g = [NSNumber numberWithFloat:mRequest.nullableStruct.Value().g]; params.nullableStruct.h = [NSNumber numberWithDouble:mRequest.nullableStruct.Value().h]; + if (mRequest.nullableStruct.Value().i.HasValue()) { + params.nullableStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.nullableStruct.Value().i.Value())]; + } else { + params.nullableStruct.i = nil; + } } if (mRequest.optionalStruct.HasValue()) { params.optionalStruct = [MTRUnitTestingClusterSimpleStruct new]; @@ -178494,6 +178574,11 @@ class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand { params.optionalStruct.f = [NSNumber numberWithUnsignedChar:mRequest.optionalStruct.Value().f.Raw()]; params.optionalStruct.g = [NSNumber numberWithFloat:mRequest.optionalStruct.Value().g]; params.optionalStruct.h = [NSNumber numberWithDouble:mRequest.optionalStruct.Value().h]; + if (mRequest.optionalStruct.Value().i.HasValue()) { + params.optionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.optionalStruct.Value().i.Value())]; + } else { + params.optionalStruct.i = nil; + } } else { params.optionalStruct = nil; } @@ -178510,6 +178595,11 @@ class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand { params.nullableOptionalStruct.f = [NSNumber numberWithUnsignedChar:mRequest.nullableOptionalStruct.Value().Value().f.Raw()]; params.nullableOptionalStruct.g = [NSNumber numberWithFloat:mRequest.nullableOptionalStruct.Value().Value().g]; params.nullableOptionalStruct.h = [NSNumber numberWithDouble:mRequest.nullableOptionalStruct.Value().Value().h]; + if (mRequest.nullableOptionalStruct.Value().Value().i.HasValue()) { + params.nullableOptionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.nullableOptionalStruct.Value().Value().i.Value())]; + } else { + params.nullableOptionalStruct.i = nil; + } } } else { params.nullableOptionalStruct = nil; @@ -178625,6 +178715,11 @@ class UnitTestingSimpleStructEchoRequest : public ClusterCommand { params.arg1.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.f.Raw()]; params.arg1.g = [NSNumber numberWithFloat:mRequest.arg1.g]; params.arg1.h = [NSNumber numberWithDouble:mRequest.arg1.h]; + if (mRequest.arg1.i.HasValue()) { + params.arg1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.i.Value())]; + } else { + params.arg1.i = nil; + } uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -179060,6 +179155,88 @@ class UnitTestingStringEchoRequest : public ClusterCommand { chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::Type mRequest; }; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command GlobalEchoRequest + */ +class UnitTestingGlobalEchoRequest : public ClusterCommand { +public: + UnitTestingGlobalEchoRequest() + : ClusterCommand("global-echo-request") + , mComplex_Field1(&mRequest.field1) + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("Field1", &mComplex_Field1); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Field2", 0, UINT8_MAX, &mRequest.field2); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRUnitTestingClusterGlobalEchoRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.field1 = [MTRDataTypeTestGlobalStruct new]; + params.field1.name = [[NSString alloc] initWithBytes:mRequest.field1.name.data() length:mRequest.field1.name.size() encoding:NSUTF8StringEncoding]; + if (mRequest.field1.myBitmap.IsNull()) { + params.field1.myBitmap = nil; + } else { + params.field1.myBitmap = [NSNumber numberWithUnsignedInt:mRequest.field1.myBitmap.Value().Raw()]; + } + if (mRequest.field1.myEnum.HasValue()) { + if (mRequest.field1.myEnum.Value().IsNull()) { + params.field1.myEnum = nil; + } else { + params.field1.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.field1.myEnum.Value().Value())]; + } + } else { + params.field1.myEnum = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.field2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.field2)]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster globalEchoRequestWithParams:params completion: + ^(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Type mRequest; + TypedComplexArgument mComplex_Field1; +}; + #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL /* @@ -183580,6 +183757,11 @@ class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute { newElement_0.nullableStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableStruct.Value().f.Raw()]; newElement_0.nullableStruct.g = [NSNumber numberWithFloat:entry_0.nullableStruct.Value().g]; newElement_0.nullableStruct.h = [NSNumber numberWithDouble:entry_0.nullableStruct.Value().h]; + if (entry_0.nullableStruct.Value().i.HasValue()) { + newElement_0.nullableStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableStruct.Value().i.Value())]; + } else { + newElement_0.nullableStruct.i = nil; + } } if (entry_0.optionalStruct.HasValue()) { newElement_0.optionalStruct = [MTRUnitTestingClusterSimpleStruct new]; @@ -183591,6 +183773,11 @@ class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute { newElement_0.optionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.optionalStruct.Value().f.Raw()]; newElement_0.optionalStruct.g = [NSNumber numberWithFloat:entry_0.optionalStruct.Value().g]; newElement_0.optionalStruct.h = [NSNumber numberWithDouble:entry_0.optionalStruct.Value().h]; + if (entry_0.optionalStruct.Value().i.HasValue()) { + newElement_0.optionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.optionalStruct.Value().i.Value())]; + } else { + newElement_0.optionalStruct.i = nil; + } } else { newElement_0.optionalStruct = nil; } @@ -183607,6 +183794,11 @@ class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute { newElement_0.nullableOptionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalStruct.Value().Value().f.Raw()]; newElement_0.nullableOptionalStruct.g = [NSNumber numberWithFloat:entry_0.nullableOptionalStruct.Value().Value().g]; newElement_0.nullableOptionalStruct.h = [NSNumber numberWithDouble:entry_0.nullableOptionalStruct.Value().Value().h]; + if (entry_0.nullableOptionalStruct.Value().Value().i.HasValue()) { + newElement_0.nullableOptionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableOptionalStruct.Value().Value().i.Value())]; + } else { + newElement_0.nullableOptionalStruct.i = nil; + } } } else { newElement_0.nullableOptionalStruct = nil; @@ -183915,6 +184107,11 @@ class WriteUnitTestingStructAttr : public WriteAttribute { value.f = [NSNumber numberWithUnsignedChar:mValue.f.Raw()]; value.g = [NSNumber numberWithFloat:mValue.g]; value.h = [NSNumber numberWithDouble:mValue.h]; + if (mValue.i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.i.Value())]; + } else { + value.i = nil; + } [cluster writeAttributeStructAttrWithValue:value params:params completion:^(NSError * _Nullable error) { if (error != nil) { @@ -184705,6 +184902,11 @@ class WriteUnitTestingListFabricScoped : public WriteAttribute { newElement_0.fabricSensitiveStruct.f = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveStruct.f.Raw()]; newElement_0.fabricSensitiveStruct.g = [NSNumber numberWithFloat:entry_0.fabricSensitiveStruct.g]; newElement_0.fabricSensitiveStruct.h = [NSNumber numberWithDouble:entry_0.fabricSensitiveStruct.h]; + if (entry_0.fabricSensitiveStruct.i.HasValue()) { + newElement_0.fabricSensitiveStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.fabricSensitiveStruct.i.Value())]; + } else { + newElement_0.fabricSensitiveStruct.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; for (auto & entry_2 : entry_0.fabricSensitiveInt8uList) { @@ -185065,22 +185267,274 @@ class ReadUnitTestingClusterErrorBoolean : public ReadAttribute { class WriteUnitTestingClusterErrorBoolean : public WriteAttribute { public: - WriteUnitTestingClusterErrorBoolean() - : WriteAttribute("cluster-error-boolean") + WriteUnitTestingClusterErrorBoolean() + : WriteAttribute("cluster-error-boolean") + { + AddArgument("attr-name", "cluster-error-boolean"); + AddArgument("attr-value", 0, 1, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingClusterErrorBoolean() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::ClusterErrorBoolean::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue]; + + [cluster writeAttributeClusterErrorBooleanWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting ClusterErrorBoolean write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + bool mValue; +}; + +class SubscribeAttributeUnitTestingClusterErrorBoolean : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingClusterErrorBoolean() + : SubscribeAttribute("cluster-error-boolean") + { + } + + ~SubscribeAttributeUnitTestingClusterErrorBoolean() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::ClusterErrorBoolean::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterErrorBooleanWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.ClusterErrorBoolean response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GlobalEnum + */ +class ReadUnitTestingGlobalEnum : public ReadAttribute { +public: + ReadUnitTestingGlobalEnum() + : ReadAttribute("global-enum") + { + } + + ~ReadUnitTestingGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGlobalEnumWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalEnum response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting GlobalEnum read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingGlobalEnum : public WriteAttribute { +public: + WriteUnitTestingGlobalEnum() + : WriteAttribute("global-enum") + { + AddArgument("attr-name", "global-enum"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue]; + + [cluster writeAttributeGlobalEnumWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting GlobalEnum write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + uint8_t mValue; +}; + +class SubscribeAttributeUnitTestingGlobalEnum : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingGlobalEnum() + : SubscribeAttribute("global-enum") + { + } + + ~SubscribeAttributeUnitTestingGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGlobalEnumWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalEnum response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GlobalStruct + */ +class ReadUnitTestingGlobalStruct : public ReadAttribute { +public: + ReadUnitTestingGlobalStruct() + : ReadAttribute("global-struct") + { + } + + ~ReadUnitTestingGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalStruct::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGlobalStructWithCompletion:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalStruct response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting GlobalStruct read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingGlobalStruct : public WriteAttribute { +public: + WriteUnitTestingGlobalStruct() + : WriteAttribute("global-struct") + , mComplex(&mValue) { - AddArgument("attr-name", "cluster-error-boolean"); - AddArgument("attr-value", 0, 1, &mValue); + AddArgument("attr-name", "global-struct"); + AddArgument("attr-value", &mComplex); WriteAttribute::AddArguments(); } - ~WriteUnitTestingClusterErrorBoolean() + ~WriteUnitTestingGlobalStruct() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::ClusterErrorBoolean::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalStruct::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); @@ -185088,11 +185542,27 @@ class WriteUnitTestingClusterErrorBoolean : public WriteAttribute { __auto_type * params = [[MTRWriteParams alloc] init]; params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue]; + MTRDataTypeTestGlobalStruct * _Nonnull value; + value = [MTRDataTypeTestGlobalStruct new]; + value.name = [[NSString alloc] initWithBytes:mValue.name.data() length:mValue.name.size() encoding:NSUTF8StringEncoding]; + if (mValue.myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:mValue.myBitmap.Value().Raw()]; + } + if (mValue.myEnum.HasValue()) { + if (mValue.myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } - [cluster writeAttributeClusterErrorBooleanWithValue:value params:params completion:^(NSError * _Nullable error) { + [cluster writeAttributeGlobalStructWithValue:value params:params completion:^(NSError * _Nullable error) { if (error != nil) { - LogNSError("UnitTesting ClusterErrorBoolean write Error", error); + LogNSError("UnitTesting GlobalStruct write Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -185101,24 +185571,25 @@ class WriteUnitTestingClusterErrorBoolean : public WriteAttribute { } private: - bool mValue; + chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type mValue; + TypedComplexArgument mComplex; }; -class SubscribeAttributeUnitTestingClusterErrorBoolean : public SubscribeAttribute { +class SubscribeAttributeUnitTestingGlobalStruct : public SubscribeAttribute { public: - SubscribeAttributeUnitTestingClusterErrorBoolean() - : SubscribeAttribute("cluster-error-boolean") + SubscribeAttributeUnitTestingGlobalStruct() + : SubscribeAttribute("global-struct") { } - ~SubscribeAttributeUnitTestingClusterErrorBoolean() + ~SubscribeAttributeUnitTestingGlobalStruct() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::ClusterErrorBoolean::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalStruct::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); @@ -185133,10 +185604,10 @@ class SubscribeAttributeUnitTestingClusterErrorBoolean : public SubscribeAttribu if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeClusterErrorBooleanWithParams:params + [cluster subscribeAttributeGlobalStructWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"UnitTesting.ClusterErrorBoolean response %@", [value description]); + reportHandler:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalStruct response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -185149,6 +185620,8 @@ class SubscribeAttributeUnitTestingClusterErrorBoolean : public SubscribeAttribu } }; +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute Unsupported */ @@ -188876,6 +189349,11 @@ class WriteUnitTestingNullableStruct : public WriteAttribute { value.f = [NSNumber numberWithUnsignedChar:mValue.Value().f.Raw()]; value.g = [NSNumber numberWithFloat:mValue.Value().g]; value.h = [NSNumber numberWithDouble:mValue.Value().h]; + if (mValue.Value().i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.Value().i.Value())]; + } else { + value.i = nil; + } } [cluster writeAttributeNullableStructWithValue:value params:params completion:^(NSError * _Nullable error) { @@ -189565,6 +190043,284 @@ class SubscribeAttributeUnitTestingWriteOnlyInt8u : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute NullableGlobalEnum + */ +class ReadUnitTestingNullableGlobalEnum : public ReadAttribute { +public: + ReadUnitTestingNullableGlobalEnum() + : ReadAttribute("nullable-global-enum") + { + } + + ~ReadUnitTestingNullableGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeNullableGlobalEnumWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalEnum response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting NullableGlobalEnum read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingNullableGlobalEnum : public WriteAttribute { +public: + WriteUnitTestingNullableGlobalEnum() + : WriteAttribute("nullable-global-enum") + { + AddArgument("attr-name", "nullable-global-enum"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingNullableGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedChar:mValue.Value()]; + } + + [cluster writeAttributeNullableGlobalEnumWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting NullableGlobalEnum write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeUnitTestingNullableGlobalEnum : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingNullableGlobalEnum() + : SubscribeAttribute("nullable-global-enum") + { + } + + ~SubscribeAttributeUnitTestingNullableGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeNullableGlobalEnumWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalEnum response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute NullableGlobalStruct + */ +class ReadUnitTestingNullableGlobalStruct : public ReadAttribute { +public: + ReadUnitTestingNullableGlobalStruct() + : ReadAttribute("nullable-global-struct") + { + } + + ~ReadUnitTestingNullableGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalStruct::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeNullableGlobalStructWithCompletion:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalStruct response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting NullableGlobalStruct read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingNullableGlobalStruct : public WriteAttribute { +public: + WriteUnitTestingNullableGlobalStruct() + : WriteAttribute("nullable-global-struct") + , mComplex(&mValue) + { + AddArgument("attr-name", "nullable-global-struct"); + AddArgument("attr-value", &mComplex); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingNullableGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalStruct::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + MTRDataTypeTestGlobalStruct * _Nullable value; + if (mValue.IsNull()) { + value = nil; + } else { + value = [MTRDataTypeTestGlobalStruct new]; + value.name = [[NSString alloc] initWithBytes:mValue.Value().name.data() length:mValue.Value().name.size() encoding:NSUTF8StringEncoding]; + if (mValue.Value().myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:mValue.Value().myBitmap.Value().Raw()]; + } + if (mValue.Value().myEnum.HasValue()) { + if (mValue.Value().myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.Value().myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + } + + [cluster writeAttributeNullableGlobalStructWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting NullableGlobalStruct write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; + TypedComplexArgument> mComplex; +}; + +class SubscribeAttributeUnitTestingNullableGlobalStruct : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingNullableGlobalStruct() + : SubscribeAttribute("nullable-global-struct") + { + } + + ~SubscribeAttributeUnitTestingNullableGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalStruct::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeNullableGlobalStructWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalStruct response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute GeneratedCommandList */ @@ -198236,6 +198992,9 @@ void registerClusterUnitTesting(Commands & commands) #if MTR_ENABLE_PROVISIONAL make_unique(), // #endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // #endif // MTR_ENABLE_PROVISIONAL @@ -198383,6 +199142,16 @@ void registerClusterUnitTesting(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -198488,6 +199257,16 @@ void registerClusterUnitTesting(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // From 5d280dedd0bcea407f575aef11e67c8bb7f0a7a1 Mon Sep 17 00:00:00 2001 From: Michael Rupp <95718139+mykrupp@users.noreply.github.com> Date: Wed, 31 Jul 2024 22:31:44 -0400 Subject: [PATCH 17/21] [Silabs] Port platform specific Multi-Chip OTA work (#34440) * Pull request #1836: Cherry multi ota Merge in WMN_TOOLS/matter from cherry-multi-ota to silabs_slc_1.3 Squashed commit of the following: commit 4320bb46571658bc44fb82345348265def394991 Author: Michael Rupp Date: Fri May 10 14:26:07 2024 -0400 remove some unwanted diffs in provision files commit be160931dc600de7e7ead378b70d6a43c3945e46 Author: Michael Rupp Date: Fri May 10 14:24:25 2024 -0400 revert changes to generator.project.mak commit 14b6605887166e6d5284a61feb2bf407d850bdcf Author: Michael Rupp Date: Fri May 10 13:06:12 2024 -0400 revert NVM key changes and script changes ... and 8 more commits * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Restyled by autopep8 * remove unused libs caught by linter * update doctree with new readmes * rerun CI, cirque failing for unknown reasons * fix include guards in provision examples * Restyled by clang-format --------- Co-authored-by: Restyled.io --- docs/tools/index.md | 2 + .../provision/ProvisionStorageDefault.cpp | 5 +- .../provision/ProvisionStorageFlash.cpp | 5 +- .../silabs/factory_data_generator/README.md | 56 ++++++ .../silabs/factory_data_generator/custom.py | 106 +++++++++++ .../silabs/factory_data_generator/default.py | 131 ++++++++++++++ scripts/tools/silabs/ota/README.md | 15 +- .../binaries/ext_flash_ota_entry_example.bin | Bin 0 -> 7056 bytes .../examples/ota_custom_entries_example.json | 67 +++++++ .../examples/ota_custom_entries_example2.json | 88 +++++++++ .../tools/silabs/ota/ota_multi_image_tool.py | 10 +- scripts/tools/silabs/ota/requirements.txt | 1 + src/platform/silabs/efr32/BUILD.gn | 21 ++- .../silabs/efr32/efr32-psa-crypto-config.h | 5 + .../silabs/multi-ota/OTACustomProcessor.cpp | 94 ++++++++++ .../silabs/multi-ota/OTACustomProcessor.h | 56 ++++++ .../multi-ota/OTAFactoryDataProcessor.cpp | 170 ++++++++++++++++++ .../multi-ota/OTAFactoryDataProcessor.h | 81 +++++++++ .../{efr32 => }/OTAFirmwareProcessor.cpp | 37 +++- .../{efr32 => }/OTAFirmwareProcessor.h | 0 .../silabs/multi-ota/{efr32 => }/OTAHooks.cpp | 27 ++- .../multi-ota/OTAMultiImageProcessorImpl.cpp | 3 - .../silabs/multi-ota/OTATlvProcessor.cpp | 70 +------- .../silabs/multi-ota/OTATlvProcessor.h | 10 ++ .../silabs/multi-ota/OtaTlvEncryptionKey.cpp | 130 ++++++++++++++ .../silabs/multi-ota/OtaTlvEncryptionKey.h | 34 ++++ third_party/silabs/efr32_sdk.gni | 10 ++ 27 files changed, 1145 insertions(+), 89 deletions(-) create mode 100644 scripts/tools/silabs/factory_data_generator/README.md create mode 100644 scripts/tools/silabs/factory_data_generator/custom.py create mode 100644 scripts/tools/silabs/factory_data_generator/default.py create mode 100755 scripts/tools/silabs/ota/examples/binaries/ext_flash_ota_entry_example.bin create mode 100644 scripts/tools/silabs/ota/examples/ota_custom_entries_example.json create mode 100644 scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json create mode 100644 scripts/tools/silabs/ota/requirements.txt create mode 100644 src/platform/silabs/multi-ota/OTACustomProcessor.cpp create mode 100644 src/platform/silabs/multi-ota/OTACustomProcessor.h create mode 100644 src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp create mode 100644 src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h rename src/platform/silabs/multi-ota/{efr32 => }/OTAFirmwareProcessor.cpp (84%) rename src/platform/silabs/multi-ota/{efr32 => }/OTAFirmwareProcessor.h (100%) rename src/platform/silabs/multi-ota/{efr32 => }/OTAHooks.cpp (52%) create mode 100644 src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp create mode 100644 src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h diff --git a/docs/tools/index.md b/docs/tools/index.md index 003573ed5ebb14..a2ff8fd1587f89 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -49,6 +49,8 @@ Source files for these tools are located at `scripts/tools`. :maxdepth: 1 ../scripts/tools/silabs/README +../scripts/tools/silabs/ota/README +../scripts/tools/silabs/factory_data_generator/README ``` diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp index 09f103592d2470..1162323cda3d51 100644 --- a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -28,6 +28,9 @@ #include #include #include +#ifdef OTA_ENCRYPTION_ENABLE +#include +#endif // OTA_ENCRYPTION_ENABLE #ifdef SLI_SI91X_MCU_INTERFACE #include #else @@ -659,7 +662,7 @@ CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) ReturnErrorOnFailure(key.Import(value.data(), value.size())); return SilabsConfig::WriteConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, key.GetId()); } -#endif +#endif // OTA_ENCRYPTION_ENABLE /** * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp index 5bd11108bd9cc6..35a32d6af8f5ec 100644 --- a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -25,6 +25,9 @@ #include #include #include +#ifdef OTA_ENCRYPTION_ENABLE +#include +#endif // OTA_ENCRYPTION_ENABLE using namespace chip::Credentials; @@ -708,7 +711,7 @@ CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) { return CHIP_ERROR_NOT_IMPLEMENTED; } -#endif +#endif // OTA_ENCRYPTION_ENABLE CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) { diff --git a/scripts/tools/silabs/factory_data_generator/README.md b/scripts/tools/silabs/factory_data_generator/README.md new file mode 100644 index 00000000000000..c75c52f91d0333 --- /dev/null +++ b/scripts/tools/silabs/factory_data_generator/README.md @@ -0,0 +1,56 @@ +# Silabs Factory Data Generator + +## Tool implementation + +The tool comprises of two files: `default.py`, `custom.py` + +### `default.py` + +Defines the base `InputArgument` class and its derived classes that will be +referenced as **default classes**. + +`InputArgument` offers an abstract interface in the form of three methods: +`key()`, `length()`, `encode()`, that will be used to generate the `(K, L, V)` +tuple through the public `output()` method. Each custom class should implement +the abstract interface, if its direct parent does not offer a relevant +implementation. + +### `custom.py` + +Defines classes for each argument that should generate data in the output binary +(will be referenced as **custom classes**). Please note that each new class +should derive from a default class, not from `InputArgument` directly. + +### How to add a new argument + +Example of defining a new argument class in `custom.py`: + +``` +class FooArgument(BarArgument): + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return + + def length(self): + return + + def encode(self): + return + + def custom_function(self): + pass +``` + +where `BarArgument` is one of the **default classes**. Please note that a user +can define additional methods if needed (e.g. `custom_function`; also see +`generate_private_key` from `DacPKey` class). + +Then use this class in `generate.py` to create a `FooArgument` object from an +option: + +``` +parser.add_argument("--foo", required=True, type=FooArgument, + help="[int | hex] Foo argument.") +``` diff --git a/scripts/tools/silabs/factory_data_generator/custom.py b/scripts/tools/silabs/factory_data_generator/custom.py new file mode 100644 index 00000000000000..a06d61ca3f8568 --- /dev/null +++ b/scripts/tools/silabs/factory_data_generator/custom.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +'''This file should contain custom classes derived any class from default.py. + +Each class implemented here should describe an input parameter and should +implement the InputArgument abstract interface, if its base class does not +already offer an implementation or if there is a need of a custom behavior. + +Example of defining a new argument class: + + class FooArgument(IntArgument): + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return + + def length(self): + return + + def encode(self): + return + + def custom_function(self): + pass + +Then use this class in generate.py to create a FooArgument object from an +option: + + parser.add_argument("--foo", required=True, type=FooArgument, + help="[int | hex] Foo argument.") +''' + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.serialization import load_der_private_key +from default import FileArgument + + +class DacPKey(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + self.private_key = None + + def key(self): + return 1 + + def length(self): + assert (self.private_key is not None) + return len(self.private_key) + + def encode(self): + assert (self.private_key is not None) + return self.private_key + + def generate_private_key(self, password, use_sss_blob=True): + if use_sss_blob: + self.private_key = self.val + else: + keys = load_der_private_key(self.val, password, backend=default_backend()) + self.private_key = keys.private_numbers().private_value.to_bytes( + 32, byteorder='big' + ) + + +class DacCert(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 2 + + +class PaiCert(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 3 + + +class CertDeclaration(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 4 diff --git a/scripts/tools/silabs/factory_data_generator/default.py b/scripts/tools/silabs/factory_data_generator/default.py new file mode 100644 index 00000000000000..13dc0866aaed40 --- /dev/null +++ b/scripts/tools/silabs/factory_data_generator/default.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +'''This file should contain default argument classes. + +Base class is InputArgument. It defines the abstract interface to be +implemented and offers a way to compute a KLV value through output(). +Other classes that derive InputArgument directly will be referenced +as default classes throughout the docstrings. + +The default classes should not be used to instantiate arguments. +If one wants to add another argument, a custom class should be derived +from one of the default classes. +''' + +import base64 +import logging + + +class InputArgument: + '''Base class for any input argument that will be added to KLV. + + The user will define its arguments as instances of InputArgument + by setting the "type" attribute of ArgumentParser add_argument to + an instance of a derived class. This means that all derived classes + must accept an additional "arg" parameter in the constructor. In the + end, the list of arguments will be parsed into objects derived from + InputArgument (or default derived classes), which decouples the object + creation from its processing. + + Abstract methods: + key: Should be overwritten by final classes to return a "magic number". + length: Can be overwritten by default classes to specify a default value + (e.g. int arguments with a default length value of 4); can also + be overwritten by final classes to specify a custom value for a + certain argument. + encode: Should be overwritten to generate the correct bytes array from + its internal value. + + Main usage is to iterate over an iterable entity of InputArguments and call + the output() method to generate the (K, L, V) tuple. Note that the output() + method should not be implemented, since its a common functionality across + all InputArgument classes. + ''' + + def __init__(self): + self.val = None + + def key(self): + logging.error("key() should be implemented in derived classes.") + + def length(self): + logging.error("length() should be implemented in derived classes.") + + def encode(self): + logging.error("encode() should be implemented in derived classes.") + + def output(self): + out = (self.key(), self.length(), self.encode()) + logging.info("'{}' length: {}".format(type(self).__name__, self.length())) + return out + + +class IntArgument(InputArgument): + + def __init__(self, arg): + super().__init__() + self.val = int(arg, 0) + + def length(self): + return 4 + + def encode(self): + return self.val.to_bytes(self.length(), "little") + + +class Base64Argument(InputArgument): + + def __init__(self, arg): + super().__init__() + self.val = base64.b64decode(arg) + + def length(self): + return len(self.encode()) + + def encode(self): + return base64.b64encode(self.val) + + +class StrArgument(InputArgument): + + def __init__(self, arg): + super().__init__() + self.val = str(arg) + + def length(self): + return len(self.encode()) + + def encode(self): + return str.encode(self.val) + + def max_length(self): + return 32 + + +class FileArgument(InputArgument): + + def __init__(self, arg): + super().__init__() + with open(arg, "rb") as _file: + self.val = _file.read() + + def length(self): + return len(self.val) + + def encode(self): + return self.val diff --git a/scripts/tools/silabs/ota/README.md b/scripts/tools/silabs/ota/README.md index d0c1bd39e068cd..0629d8650c1e8a 100644 --- a/scripts/tools/silabs/ota/README.md +++ b/scripts/tools/silabs/ota/README.md @@ -25,8 +25,7 @@ python3 ./scripts/tools/silabs/ota/ota_multi_image_tool.py create -v 0xDEAD -p 0 ``` followed by \*_custom options_- and a positional argument (should be last) that -specifies the output file. Please see the `create_ota_images.sh` for some -reference commands. +specifies the output file. The list of **custom options**: @@ -38,12 +37,6 @@ The list of **custom options**: --app-version-str --> Application version string. Same as above. --app-build-date --> Application build date. Same as above. -# SSBL options ---bl-input-file --> Path to the SSBL binary. ---bl-version --> SSBL version. ---bl-version-str --> SSBL version string. ---bl-build-date --> SSBL build date. - # Factory data options --factory-data --> If set, enables the generation of factory data. --cert_declaration --> Certification Declaration. @@ -51,6 +44,10 @@ The list of **custom options**: --dac_key --> DAC private key. --pai_cert --> PAI certificate. +# Encryption options +--enc_enable --> Enable ota encryption +--input_ota_key --> 16 Byte AES key + # Custom TLV options --json --> Path to a JSON file following ota_payload.schema ``` @@ -67,5 +64,5 @@ processing. When defining a custom processor, a user is able to also specify the custom format of the TLV by creating a JSON file based on the `ota_payload.schema`. The tool offers support for describing multiple TLV in the same JSON file. Please -see the `examples/ota_max_entries_example.json` for a multi-app + SSBL example. +see the `examples/ota_custom_entries_example.json` for a multi-binary example. Option `--json` must be used to specify the path to the JSON file. diff --git a/scripts/tools/silabs/ota/examples/binaries/ext_flash_ota_entry_example.bin b/scripts/tools/silabs/ota/examples/binaries/ext_flash_ota_entry_example.bin new file mode 100755 index 0000000000000000000000000000000000000000..5800a9860f70aae4d8f235a4371b31c6b77a498f GIT binary patch literal 7056 zcmcIod011|w%;e`Bsn1Tih2}w8sqK!ibrz$w~LA6(|UaMZKL{W=X zD;ft(E)Lb+GKdU{6}gB?ty66if)%wY)@zR#TTd9wVUWCau-<#$_r1T~_q_wZ>~Za3 z?KSMRTjpWJdJLgTKsbTW2}tVz)qtbsz8=A9T|r6^LWQL>k9`Amuf7_{*8(a9Km(`- zd;_Qf)B@@N^?>t$2EawYCBPNHHNbVij{rNs0k{FU3AhEg1Go#g4|o802zUfw0IdKg z;5WcCfD6zL=mfX{U4S0I3xEfJ;RxY?SDz5_Vt@o71^57b0e%2~Kpq_SyM7ujVms4rr0op z|A{cekfjc;B3)r1*c_rjuZ|3~hZ^G4gv!q@Q2N?$aO61uN=5(NMz%!}lGebHqYxX^ zRo;$FeN2!+O%>=7E9)9$7?iqIBXJB$MbuV}%z;=@*Zfl$d!W0IakQf3f=ur?B+u78 zz4iAQ$EOgnUCeZjoIRZ*CL#H5&7)gIP}j}$vyQ^lg#!>yAUG)aI%$Mcu*Y$L6ac^H zipT7{M>L7ZdW_=t_V3;Q|L4Y5qc9rrGaHKf%{GA!rK9O{dPF^Dl(bEcln-sfPPD?wEEH)d3CVi1ozLV zU;{GaooG2`c2r@iAp1ZsEMkyNP$F>V;=t`mgi9?#;k&udVqU0x>`j~r^SBEqz*xY1r^zKXbMK4#~?`eB#5B?Op_Xc zjh8a4g_pPWSzdXD=cNlQ8f5EZ1TpI~s8B2&&gV?F9wblG2vUc$Vw_M(n(sfx+2J@j zd^l?4HpcoH9Ng(>zclEjb#SIQN2a2qWkCoL;;m)t7ic@MI7hm%W0=Ch*%EGx#W#eh zX-gW~Xi8%h1q({5VGVR1H4zG-%yKhN<)@K+}kuDbte}Yy^|Y7g%FK|pyS*? zyrV_ouieQ-QQ9Yh1v|MnsA)n$M>>omNXyM|WZe<>-hdUWNj0zE0cm^sK|j`{3Fq>*LO^);_@&oL_YX-%=&jVyh(t*3l9w)h4aJ0=aX3QtkTH zsY0wH9g}LO^W1>3WhvvTWs?rMNTJ7l-SaTZBI>=N`l~=CvEeE&8>aHASFBx-b*Ji% z`1hu9bw@t8R&_D*wV`VjYeNW_4R+vSl(0U2ERe6H``kiPuu({pE*T1-2Y`%y=~2@n zm+8H;=@duJ^SCXZa2Cf8ixoOKP1?*F^42tt2w9!c#k@?-n(pRE9Xa`LAjuwgxd%>S zdTBbyXwnSEpTkrUD_jh!=Xt`?EbUwjg$!3A2hyX3{d=8Yw@tOI;Al5rs}lwv_hMp zc(e{FELCaAVh5t66~Lh#a+)9S4&w)>Ap~G?zcXlfC5`r;pbNPv(U_{t7HCDPa$9hw zxPP5E^?;e1{Pfm!4w-V8&estBaR9>o1|qx|Ag(sD$Qx6DB}*Wz9=G0uSA4(`J>qK2 zEKndbU-#x8b!_#!Z^y6NRDmMZ?3X59OTFaRTQOZ3=dEtws89!&?;osffZs`}4csA( zu>-xUZu^>owrS)-b=x;o%EG*bmlu+YQWiCE>S=ucP!`8{3O=9oANf$$l*HE?J4_is zKM*SdiqKFRv7dO1&ppe_I3n6tQO1d)p$C-6=rYbLI?Ave)*_SN&bXar2R)5U8=M|7 znJ+uDZbNxwipL$)=ghK#rVXF8G>ZUD@wk2a!VDwW9Q{E}fK6^Vs2OQ9vYvR4JE||l zFbq7fX__V7v|zyCx|ezYFuo?Bg8f=BA|Y8hH3>0 zyT_Dn=m9&bS`i60e1EdqpBB(Tz>lYWh$8D`)f>e56&Ov})bdQIebARh zOVg%j@|MiYAWb8OP2mWmmLm*iO_yC{7!os;BYdGO<;$`PSsmyd3-%762IMZ`HCw#I zUzfYk5v*1T!JY)r<8-TWU(E_kndpKP*QUw~k>;2>d<%81& zicQdR$)zSWbPTMhpifDw6Flw`PXbtj5j1!@GBK*iDMsGShb2qdM1i0O1G^-0uJ=%=N|^IfjP6vX1bZFY})NiXT5NK^9D#-#?OJiZwEMi=PcvYyixXnwIT zHpCYd=mq&m`Lms;;^&Bi@d+o1QB)Dw2Ae(JG9ShjsII}d&G~0QQ!)FbiTrFEnz#4eRt;eo&KdPXx;NeoAA9S2n+<&9J6K zgGI9e+SZj!rTIM|Wn#ygaJ6$>=$faXCkXiGm$PREjRUW0vHCK4>b{01&e zE@pkD>Nd=O1nVm4+*n#q5LeG1Y@+ncT-Iz{Y{i{H_nQ5l70K z_966D<|TDY^DLSuriwi7Z~Bn(mc5B7glk9N=Gy-%lp{PY zL3kl|k-{Q`cBC4U29g*$Fw`$yb_`R2h6-R67)1xv2ZU4Mh@JK#+A=mGshKLKK-yAY zL|bDEO!8meIR{!@+|#mvf;GL<7X~^6zW#vT(BRsN`=J)j1=tT?16@9^txj5j}uwl&+}K@NTGc|nt7|92o}VI%bI+=>@SiQncW{dKTg0*k=9t4l;#SEGoDw?}}4l9d=xC@kSX zt6GIr6Kr8ni!>U?$4+xQF%)Fc6km>1UYPqANE93WY_L zErnU}eQ%|oXA~9*zA?uTxkB>;0@=+qwt4(3oztU?Po|Gp%HrfX zw%kGCrCg)`pS*&>ir&dv*QMXx4bB2oce~_|ZFp~R* zO=|OeYGg|W7};9Tc0$rqLqw?ALnd-RX*tzDqDGE6_Gko+wN<1UDa7Wxtzv~)qx@NF zRa8zghzbhyzSf|0p*0uyGrMXhbD}fFxV!#p5a#q2oZ}uF^XiXurf4^CsHLDDDb~YX zW9pD|U_EVIOVl)R&ka76v!viWGukj5xbD->_02tE>l^`2X9MSj)>nLwH247DMb=Si zLBYO?3*6&Gfx?llmBWT=lb%=gbMYuo*CL%Tn&Wfv|uddxo^G!7&K zQ>xpnCZEn-8Q34C-KLY=gjn7;>@`_IM};&}s@W~31&cA2x^0tbAJpwLDB%{nxBq5Z zpkG)llb;0p`F?j(>uI><%~dqDo`EzS(zB4xS8O-T*>k;h)@Y2{3e-G&I!~@a3gPY% zw2{R~!n~9<&H9GhnDM;wCTE%|bkf6>5LI}_!`+=j%4N2F5KH!{l5Htqua-lN+P229 zKl#mO4Ly+-M`-RMMK17(Fq1BfJnfSBie04mCp%$XaAKnzg$9D<+}6FDdn0>|SnYbc zzKK)j*MJ8>?62!`CcCd97ju5tPL&TB^Dz<(r!Ti{R82=;P3 zu16$jl0>W7f$L}Y-+hr1v6>BijFsNYoZztWZX%{!R2KT=4goDMR2DI<_ORo zq-1T?8u5O-xiVSQT&-!fV{eI^Nuk>{|7^q*g^bXZtvvw|kG=6d-6=?~Hzv^&Xz|D$ zKR0rDF;(0)40mPIe2b*9P=hz`Pkz`8sU3H!6@{9+4lIU@W#B$DryD8v+(zN`EyXUG zmrOpDmH-DN-QJcc@Zr1dQme>Z#|2GM4YMSF;V5=_V-a*}h>t7YYYg=3>`J03`4sS2 zZCzpDTSn4jz_*w{4stqHm3vukb12%P$>~^DKBiQq3onAGEpj_|lk(>T3EP2Bqf2K7 z&zfDvHBnmzBld@`LTDRP+=%#7xWt#Ddun)2X1Bn7@Q*lp&)W#+?eBla4!pn3g7_f= zVhPV(395_&Uu=9Q$!|Ww-x7~#Is!NGFw+?Gd-Rx6%h=f&f7+|~F(?&LsBMb?AVN)@j<2p8#tmWScq!^DeR~Z?HEye*@%vI*d_T0+< zd5Xv36hnF?(TN?(<4Eyst5@7yhA_`zAQn9>w1AzS4sS)FD3re)V%-?@`%8ITX4~qr zU0B>$`*KDzB(Xz!e1O4M-oQPM@-f(25m-L{g_5u|aJxsrE9D1Y(b0PD(aXC8A4~Bu z7B8c`tnzlc8s6qMtqz2jH#h?MTF#>f9pVEimMHAM6;C-l`kH?79h#hj;L(a}M~u_nO*l=>b`9>C*Q#8Ez}-m1lJ)TVH6g4X-UY4!$FFhC*?OGzhp1$M_jvjrun~3;o><|-g!~Wui(uJ&ioq}Z5wR~z#NwCj1ocNc z?T`L7kpAndm0`873i*Q}M}fb5`9R)Z&D)Y!?f+Z)>iK-)%-zqbLt`qxn*8JVo$sa} zJCGT>@zTt~5T(zjJ30gK_?lZ6apKP{-dn~urk1;Yd-BHTj_uF5Z2qx8t# z2RnRMo{1bwjW@mdVvXhF`+{W?w3kH^N8W28y?3ogsw~E!Re#>{;o5UMl0FE!_x;+B zYE>KArp9^UUj@#QMxQ!9>-{vzhZdh4b8X?E0SR}<-FSXs@GsW+E@H(_QAH)IZ8R*C zFE{^Pb~dia%*@S_J92mZ^zq*Jrgg_nyBhV=*`H6gth>2zZLC21{t?T}woR*kN&ar! z#ggYOy+iXhluUd-E9iir<>950^0_{_5?1z)yW;}i^=_L`KI++%@4t%h8vbz19eVNS zo43q3n*YUb?zmZ5x5KN7*Ss!WeK_p=>&q|v`ZT3=$~ZFN*UL+OOfk=VsCGyG>DeLG zI^D`;B?*OJu6md$`7711?bDBYw8y1Aa|fJqF2>*d!g0DHa!1UMzwe!$z3$l$`G1w< zjh}}ksgf4Qjs>$0ylSA4X_ zy>9B(N8djx`tU&Y+-+~icV^emdHda84&)?!d~i+9lZ>3ByWaoxPJHd)cEiV0@6frY aOX=pJ+=kw7SL#0dc~SP73%^%zf&UFmw4W~k literal 0 HcmV?d00001 diff --git a/scripts/tools/silabs/ota/examples/ota_custom_entries_example.json b/scripts/tools/silabs/ota/examples/ota_custom_entries_example.json new file mode 100644 index 00000000000000..8f679a266da9bd --- /dev/null +++ b/scripts/tools/silabs/ota/examples/ota_custom_entries_example.json @@ -0,0 +1,67 @@ +{ + "inputs": [ + { + "tag": 8, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1003 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 9, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1004 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion2" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 10, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1005 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion3" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + } + ] +} diff --git a/scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json b/scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json new file mode 100644 index 00000000000000..3b910f2d163156 --- /dev/null +++ b/scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json @@ -0,0 +1,88 @@ +{ + "inputs": [ + { + "tag": 8, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1003 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 9, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1004 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion2" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 10, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1005 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion3" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 11, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1006 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion4" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + } + ] +} diff --git a/scripts/tools/silabs/ota/ota_multi_image_tool.py b/scripts/tools/silabs/ota/ota_multi_image_tool.py index 64715d784aeecd..280c80ea516a5d 100755 --- a/scripts/tools/silabs/ota/ota_multi_image_tool.py +++ b/scripts/tools/silabs/ota/ota_multi_image_tool.py @@ -50,7 +50,6 @@ from chip.tlv import TLVWriter # noqa: E402 isort:skip from custom import CertDeclaration, DacCert, DacPKey, PaiCert # noqa: E402 isort:skip from default import InputArgument # noqa: E402 isort:skip -from generate import set_logger # noqa: E402 isort:skip OTA_APP_TLV_TEMP = os.path.join(os.path.dirname(__file__), "ota_temp_app_tlv.bin") OTA_BOOTLOADER_TLV_TEMP = os.path.join(os.path.dirname(__file__), "ota_temp_ssbl_tlv.bin") @@ -65,6 +64,15 @@ class TAG: FACTORY_DATA = 3 +def set_logger(): + stdout_handler = logging.StreamHandler(stream=sys.stdout) + logging.basicConfig( + level=logging.DEBUG, + format='[%(levelname)s] %(message)s', + handlers=[stdout_handler] + ) + + def write_to_temp(path: str, payload: bytearray): with open(path, "wb") as _handle: _handle.write(payload) diff --git a/scripts/tools/silabs/ota/requirements.txt b/scripts/tools/silabs/ota/requirements.txt new file mode 100644 index 00000000000000..9d440c9c5b780b --- /dev/null +++ b/scripts/tools/silabs/ota/requirements.txt @@ -0,0 +1 @@ +jsonschema>=3.2.0 diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index 5d661886d54f21..a71a0cd8b335e6 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -78,14 +78,29 @@ static_library("efr32") { } if (chip_enable_multi_ota_requestor) { + if (chip_enable_multi_ota_encryption) { + sources += [ + "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKey.cpp", + "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKey.h", + ] + } + + if (chip_enable_ota_custom_tlv_testing) { + sources += [ + "${silabs_platform_dir}/multi-ota/OTACustomProcessor.cpp", + "${silabs_platform_dir}/multi-ota/OTACustomProcessor.h", + ] + } sources += [ + "${silabs_platform_dir}/multi-ota/OTAFactoryDataProcessor.cpp", + "${silabs_platform_dir}/multi-ota/OTAFactoryDataProcessor.h", + "${silabs_platform_dir}/multi-ota/OTAFirmwareProcessor.cpp", + "${silabs_platform_dir}/multi-ota/OTAFirmwareProcessor.h", + "${silabs_platform_dir}/multi-ota/OTAHooks.cpp", "${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.cpp", "${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.h", "${silabs_platform_dir}/multi-ota/OTATlvProcessor.cpp", "${silabs_platform_dir}/multi-ota/OTATlvProcessor.h", - "${silabs_platform_dir}/multi-ota/efr32/OTAFirmwareProcessor.cpp", - "${silabs_platform_dir}/multi-ota/efr32/OTAFirmwareProcessor.h", - "${silabs_platform_dir}/multi-ota/efr32/OTAHooks.cpp", ] } else if (chip_enable_ota_requestor) { sources += [ diff --git a/src/platform/silabs/efr32/efr32-psa-crypto-config.h b/src/platform/silabs/efr32/efr32-psa-crypto-config.h index b5564f88bd3258..b389431f85ec0b 100644 --- a/src/platform/silabs/efr32/efr32-psa-crypto-config.h +++ b/src/platform/silabs/efr32/efr32-psa-crypto-config.h @@ -30,5 +30,10 @@ #define PSA_WANT_ALG_CBC_NO_PADDING #endif // SL_USE_COAP_CONFIG +// Multi-chip OTA encryption processing +#if OTA_ENCRYPTION_ENABLE +#define PSA_WANT_ALG_CTR +#endif // OTA_ENCRYPTION_ENABLE + // Include Generated fies #include "psa_crypto_config.h" diff --git a/src/platform/silabs/multi-ota/OTACustomProcessor.cpp b/src/platform/silabs/multi-ota/OTACustomProcessor.cpp new file mode 100644 index 00000000000000..85ceb7d44d4eaf --- /dev/null +++ b/src/platform/silabs/multi-ota/OTACustomProcessor.cpp @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +extern "C" { +#include "btl_interface.h" +#include "em_bus.h" // For CORE_CRITICAL_SECTION +#if SL_WIFI +#include "spi_multiplex.h" +#endif // SL_WIFI +} + +/// No error, operation OK +#define SL_BOOTLOADER_OK 0L + +namespace chip { + +// Define static memebers +uint8_t OTACustomProcessor::mSlotId = 0; +uint32_t OTACustomProcessor::mWriteOffset = 0; +uint16_t OTACustomProcessor::writeBufOffset = 0; +uint8_t OTACustomProcessor::writeBuffer[kAlignmentBytes] __attribute__((aligned(4))) = { 0 }; + +CHIP_ERROR OTACustomProcessor::Init() +{ + ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); + mAccumulator.Init(sizeof(Descriptor)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::Clear() +{ + OTATlvProcessor::ClearInternal(); + mAccumulator.Clear(); + mDescriptorProcessed = false; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::ProcessInternal(ByteSpan & block) +{ + if (!mDescriptorProcessed) + { + ReturnErrorOnFailure(ProcessDescriptor(block)); + } + + ChipLogError(SoftwareUpdate, "Reached Custom Processor"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::ProcessDescriptor(ByteSpan & block) +{ + ReturnErrorOnFailure(mAccumulator.Accumulate(block)); + ReturnErrorOnFailure(mCallbackProcessDescriptor(static_cast(mAccumulator.data()))); + + mDescriptorProcessed = true; + mAccumulator.Clear(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::ApplyAction() +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::FinalizeAction() +{ + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OTACustomProcessor.h b/src/platform/silabs/multi-ota/OTACustomProcessor.h new file mode 100644 index 00000000000000..64610f4b41fa37 --- /dev/null +++ b/src/platform/silabs/multi-ota/OTACustomProcessor.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { + +class OTACustomProcessor : public OTATlvProcessor +{ +public: + struct Descriptor + { + uint32_t version; + char versionString[kVersionStringSize]; + char buildDate[kBuildDateSize]; + }; + + CHIP_ERROR Init() override; + CHIP_ERROR Clear() override; + CHIP_ERROR ApplyAction() override; + CHIP_ERROR FinalizeAction() override; + +private: + CHIP_ERROR ProcessInternal(ByteSpan & block) override; + CHIP_ERROR ProcessDescriptor(ByteSpan & block); + + OTADataAccumulator mAccumulator; + bool mDescriptorProcessed = false; + static constexpr size_t kAlignmentBytes = 64; + static uint32_t mWriteOffset; // End of last written block + static uint8_t mSlotId; // Bootloader storage slot + // Bootloader storage API requires the buffer size to be a multiple of 4. + static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4))); + // Offset indicates how far the write buffer has been filled + static uint16_t writeBufOffset; +}; + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp new file mode 100644 index 00000000000000..8d38207df35542 --- /dev/null +++ b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp @@ -0,0 +1,170 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +namespace chip { + +using FactoryProvider = DeviceLayer::Silabs::Provision::Storage; + +CHIP_ERROR OTAFactoryDataProcessor::Init() +{ + mAccumulator.Init(mLength); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::Clear() +{ + OTATlvProcessor::ClearInternal(); + mAccumulator.Clear(); + mPayload.Clear(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::ProcessInternal(ByteSpan & block) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + ReturnErrorOnFailure(mAccumulator.Accumulate(block)); +#if OTA_ENCRYPTION_ENABLE + MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); + OTATlvProcessor::vOtaProcessInternalEncryption(mBlock); +#endif + error = DecodeTlv(); + + if (error != CHIP_NO_ERROR) + { + // The factory data payload can contain a variable number of fields + // to be updated. CHIP_END_OF_TLV is returned if no more fields are + // found. + if (error == CHIP_END_OF_TLV) + { + return CHIP_NO_ERROR; + } + + Clear(); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::ApplyAction() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + SuccessOrExit(error = Update((uint8_t) FactoryTags::kDacKey, mPayload.mCertDacKey)); + SuccessOrExit(error = Update((uint8_t) FactoryTags::kDacCert, mPayload.mCertDac)); + SuccessOrExit(error = Update((uint8_t) FactoryTags::kPaiCert, mPayload.mCertPai)); + SuccessOrExit(error = Update((uint8_t) FactoryTags::kCdCert, mPayload.mCertDeclaration)); + +exit: + if (error != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Failed to update factory data. Error: %s", ErrorStr(error)); + } + else + { + ChipLogProgress(SoftwareUpdate, "Factory data update finished."); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::FinalizeAction() +{ + ChipLogProgress(SoftwareUpdate, "Finalize Action\n"); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::DecodeTlv() +{ + TLV::TLVReader tlvReader; + tlvReader.Init(mAccumulator.data(), mLength); + ReturnErrorOnFailure(tlvReader.Next(TLV::TLVType::kTLVType_Structure, TLV::AnonymousTag())); + + TLV::TLVType outerType; + ReturnErrorOnFailure(tlvReader.EnterContainer(outerType)); + ReturnErrorOnFailure(tlvReader.Next()); + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kDacKey)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDacKey.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kDacCert)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDac.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kPaiCert)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertPai.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kCdCert)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDeclaration.Emplace())); + } + + ReturnErrorOnFailure(tlvReader.ExitContainer(outerType)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::Update(uint8_t tag, Optional & optional) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (optional.HasValue()) + { + error = UpdateValue(tag, optional.Value()); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::UpdateValue(uint8_t tag, ByteSpan & newValue) +{ + FactoryProvider factoryProvider; + switch (tag) + { + case (int) FactoryTags::kDacKey: + ChipLogProgress(SoftwareUpdate, "Set Device Attestation Key"); + return factoryProvider.FactoryProvider::SetDeviceAttestationKey(newValue); + case (int) FactoryTags::kDacCert: + ChipLogProgress(SoftwareUpdate, "Set Device Attestation Cert"); + return factoryProvider.FactoryProvider::SetDeviceAttestationCert(newValue); + case (int) FactoryTags::kPaiCert: + ChipLogProgress(SoftwareUpdate, "Set Product Attestionation Intermediate Cert"); + return factoryProvider.FactoryProvider::SetProductAttestationIntermediateCert(newValue); + case (int) FactoryTags::kCdCert: + ChipLogProgress(SoftwareUpdate, "Set Certification Declaration"); + return factoryProvider.FactoryProvider::SetCertificationDeclaration(newValue); + } + + ChipLogError(DeviceLayer, "Failed to find tag %d.", tag); + return CHIP_ERROR_NOT_FOUND; +} + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h new file mode 100644 index 00000000000000..f7fd106de17220 --- /dev/null +++ b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include // nogncheck +#include // nogncheck + +namespace chip { + +/** + * OTA custom payload that uses Matter TLVs. + * The custom payload is used when factory data needs updating. + * Factory data will be encoded using Matter TLV format to make + * use of the ChipTlv reader. A payload contains metadata (size of + * TLVs) and the TLVs themselves contained in a structure. + * If no factory data need to be updated, the metadata will be 0 + */ +struct OTAFactoryPayload +{ + Optional mCertDacKey; + Optional mCertDac; + Optional mCertPai; + Optional mCertDeclaration; + + void Clear() + { + mCertDacKey.ClearValue(); + mCertDac.ClearValue(); + mCertPai.ClearValue(); + mCertDeclaration.ClearValue(); + } +}; + +enum class FactoryTags +{ + kDacKey = 1, + kDacCert = 2, + kPaiCert = 3, + kCdCert = 4 +}; + +class OTAFactoryDataProcessor : public OTATlvProcessor +{ +public: + CHIP_ERROR Init() override; + CHIP_ERROR Clear() override; + CHIP_ERROR ApplyAction() override; + CHIP_ERROR FinalizeAction() override; + +private: + CHIP_ERROR ProcessInternal(ByteSpan & block) override; + CHIP_ERROR DecodeTlv(); + CHIP_ERROR Update(uint8_t tag, Optional & optional); + CHIP_ERROR UpdateValue(uint8_t tag, ByteSpan & newValue); + + OTAFactoryPayload mPayload; + OTADataAccumulator mAccumulator; + uint8_t * mFactoryData = nullptr; +}; + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.cpp b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp similarity index 84% rename from src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.cpp rename to src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp index fdf4c3d0321262..3fc66e53913b87 100644 --- a/src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp @@ -17,8 +17,8 @@ */ #include +#include #include -#include #include @@ -32,8 +32,6 @@ extern "C" { /// No error, operation OK #define SL_BOOTLOADER_OK 0L -// TODO: more descriptive error codes -#define SL_OTA_ERROR 1L namespace chip { @@ -72,7 +70,33 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (!mDescriptorProcessed) { ReturnErrorOnFailure(ProcessDescriptor(block)); +#if OTA_ENCRYPTION_ENABLE + /* 16 bytes to used to store undecrypted data because of unalignment */ + mAccumulator.Init(requestedOtaMaxBlockSize + 16); +#endif + } +#if OTA_ENCRYPTION_ENABLE + MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); + memcpy(&mBlock[0], &mBlock[requestedOtaMaxBlockSize], mUnalignmentNum); + memcpy(&mBlock[mUnalignmentNum], block.data(), block.size()); + + if (mUnalignmentNum + block.size() < requestedOtaMaxBlockSize) + { + uint32_t mAlignmentNum = (mUnalignmentNum + block.size()) / 16; + mAlignmentNum = mAlignmentNum * 16; + mUnalignmentNum = (mUnalignmentNum + block.size()) % 16; + memcpy(&mBlock[requestedOtaMaxBlockSize], &mBlock[mAlignmentNum], mUnalignmentNum); + mBlock.reduce_size(mAlignmentNum); } + else + { + mUnalignmentNum = mUnalignmentNum + block.size() - requestedOtaMaxBlockSize; + mBlock.reduce_size(requestedOtaMaxBlockSize); + } + + OTATlvProcessor::vOtaProcessInternalEncryption(mBlock); + block = mBlock; +#endif uint32_t blockReadOffset = 0; while (blockReadOffset < block.size()) @@ -88,7 +112,7 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (err != SL_STATUS_OK) { ChipLogError(SoftwareUpdate, "sl_wfx_host_pre_bootloader_spi_transfer() error: %ld", err); - return; + return CHIP_ERROR_CANCELLED; } #endif // SL_BTLCTRL_MUX CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);) @@ -97,15 +121,12 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (err != SL_STATUS_OK) { ChipLogError(SoftwareUpdate, "sl_wfx_host_post_bootloader_spi_transfer() error: %ld", err); - return; + return CHIP_ERROR_CANCELLED; } #endif // SL_BTLCTRL_MUX if (err) { ChipLogError(SoftwareUpdate, "bootloader_eraseWriteStorage() error: %ld", err); - // TODO: add this somewhere - // imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - // TODO: Replace CHIP_ERROR_CANCELLED with new error statement return CHIP_ERROR_CANCELLED; } mWriteOffset += kAlignmentBytes; diff --git a/src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.h similarity index 100% rename from src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h rename to src/platform/silabs/multi-ota/OTAFirmwareProcessor.h diff --git a/src/platform/silabs/multi-ota/efr32/OTAHooks.cpp b/src/platform/silabs/multi-ota/OTAHooks.cpp similarity index 52% rename from src/platform/silabs/multi-ota/efr32/OTAHooks.cpp rename to src/platform/silabs/multi-ota/OTAHooks.cpp index cddb66980c27f9..6be17441be473f 100644 --- a/src/platform/silabs/multi-ota/efr32/OTAHooks.cpp +++ b/src/platform/silabs/multi-ota/OTAHooks.cpp @@ -21,7 +21,12 @@ #include -#include +#include +#include + +#if OTA_TEST_CUSTOM_TLVS +#include +#endif CHIP_ERROR chip::OTAMultiImageProcessorImpl::ProcessDescriptor(void * descriptor) { @@ -34,11 +39,29 @@ CHIP_ERROR chip::OTAMultiImageProcessorImpl::ProcessDescriptor(void * descriptor CHIP_ERROR chip::OTAMultiImageProcessorImpl::OtaHookInit() { static chip::OTAFirmwareProcessor sApplicationProcessor; + static chip::OTAFactoryDataProcessor sFactoryDataProcessor; sApplicationProcessor.RegisterDescriptorCallback(ProcessDescriptor); + sFactoryDataProcessor.RegisterDescriptorCallback(ProcessDescriptor); auto & imageProcessor = chip::OTAMultiImageProcessorImpl::GetDefaultInstance(); - ReturnErrorOnFailure(imageProcessor.RegisterProcessor(1, &sApplicationProcessor)); + ReturnErrorOnFailure( + imageProcessor.RegisterProcessor(static_cast(OTAProcessorTag::kApplicationProcessor), &sApplicationProcessor)); + ReturnErrorOnFailure( + imageProcessor.RegisterProcessor(static_cast(OTAProcessorTag::kFactoryDataProcessor), &sFactoryDataProcessor)); + +#if OTA_TEST_CUSTOM_TLVS + static chip::OTACustomProcessor customProcessor1; + static chip::OTACustomProcessor customProcessor2; + static chip::OTACustomProcessor customProcessor3; + + customProcessor1.RegisterDescriptorCallback(ProcessDescriptor); + customProcessor2.RegisterDescriptorCallback(ProcessDescriptor); + customProcessor3.RegisterDescriptorCallback(ProcessDescriptor); + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(8, &customProcessor1)); + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(9, &customProcessor2)); + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(10, &customProcessor3)); +#endif return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp b/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp index 147dcdaf8317ee..9dfb42fc879c4b 100644 --- a/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp +++ b/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp @@ -420,9 +420,6 @@ void OTAMultiImageProcessorImpl::HandleApply(intptr_t context) ChipLogProgress(SoftwareUpdate, "HandleApply: Finished"); - // TODO: check where to put this - // ConfigurationManagerImpl().StoreSoftwareUpdateCompleted(); - // This reboots the device CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();) } diff --git a/src/platform/silabs/multi-ota/OTATlvProcessor.cpp b/src/platform/silabs/multi-ota/OTATlvProcessor.cpp index a5da7eaba00c10..91a748c077ec79 100644 --- a/src/platform/silabs/multi-ota/OTATlvProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTATlvProcessor.cpp @@ -23,9 +23,12 @@ #include #include #if OTA_ENCRYPTION_ENABLE -#include "OtaUtils.h" -#include "rom_aes.h" +#include +#include #endif + +using namespace ::chip::DeviceLayer::Internal; + namespace chip { #if OTA_ENCRYPTION_ENABLE @@ -105,65 +108,10 @@ CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block) #if OTA_ENCRYPTION_ENABLE CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block) { - uint8_t iv[16]; - uint8_t key[kOTAEncryptionKeyLength]; - uint8_t dataOut[16] = { 0 }; - uint32_t u32IVCount; - uint32_t Offset = 0; - uint8_t data; - tsReg128 sKey; - aesContext_t Context; - - memcpy(iv, au8Iv, sizeof(au8Iv)); - - u32IVCount = (((uint32_t) iv[12]) << 24) | (((uint32_t) iv[13]) << 16) | (((uint32_t) iv[14]) << 8) | (iv[15]); - u32IVCount += (mIVOffset >> 4); - - iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); - iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); - iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); - iv[15] = (uint8_t) (u32IVCount & 0xff); - - if (Encoding::HexToBytes(OTA_ENCRYPTION_KEY, strlen(OTA_ENCRYPTION_KEY), key, kOTAEncryptionKeyLength) != - kOTAEncryptionKeyLength) - { - // Failed to convert the OTAEncryptionKey string to octstr type value - return CHIP_ERROR_INVALID_STRING_LENGTH; - } - - ByteSpan KEY = ByteSpan(key); - Encoding::LittleEndian::Reader reader_key(KEY.data(), KEY.size()); - ReturnErrorOnFailure(reader_key.Read32(&sKey.u32register0) - .Read32(&sKey.u32register1) - .Read32(&sKey.u32register2) - .Read32(&sKey.u32register3) - .StatusCode()); - - while (Offset + 16 <= block.size()) - { - /*Encrypt the IV*/ - Context.mode = AES_MODE_ECB_ENCRYPT; - Context.pSoftwareKey = (uint32_t *) &sKey; - AES_128_ProcessBlocks(&Context, (uint32_t *) &iv[0], (uint32_t *) &dataOut[0], 1); - - /* Decrypt a block of the buffer */ - for (uint8_t i = 0; i < 16; i++) - { - data = block[Offset + i] ^ dataOut[i]; - memcpy(&block[Offset + i], &data, sizeof(uint8_t)); - } - - /* increment the IV for the next block */ - u32IVCount++; - - iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); - iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); - iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); - iv[15] = (uint8_t) (u32IVCount & 0xff); - - Offset += 16; /* increment the buffer offset */ - mIVOffset += 16; - } + uint32_t keyId; + SilabsConfig::ReadConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, keyId); + chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key(keyId); + key.Decrypt(block, mIVOffset); return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/multi-ota/OTATlvProcessor.h b/src/platform/silabs/multi-ota/OTATlvProcessor.h index 9e8e56a2b35825..fe2070b75e5634 100644 --- a/src/platform/silabs/multi-ota/OTATlvProcessor.h +++ b/src/platform/silabs/multi-ota/OTATlvProcessor.h @@ -43,6 +43,8 @@ namespace chip { #define CHIP_OTA_PROCESSOR_START_IMAGE CHIP_ERROR_TLV_PROCESSOR(0x0E) #define SL_GENERIC_OTA_ERROR CHIP_ERROR_TLV_PROCESSOR(0x0E) +constexpr uint16_t requestedOtaMaxBlockSize = 1024; + // Descriptor constants inline constexpr size_t kVersionStringSize = 64; inline constexpr size_t kBuildDateSize = 64; @@ -60,6 +62,14 @@ struct OTATlvHeader uint32_t length; }; +// TLV tags synced with ota files generate by scripts/tools/silabs/ota/ota_image_tool.py +enum class OTAProcessorTag +{ + kApplicationProcessor = 1, + kBootloaderProcessor = 2, + kFactoryDataProcessor = 3 +}; + /** * This class defines an interface for a Matter TLV processor. * Instances of derived classes can be registered as processors diff --git a/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp new file mode 100644 index 00000000000000..10273e52f5a7a1 --- /dev/null +++ b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp @@ -0,0 +1,130 @@ +#include "OtaTlvEncryptionKey.h" +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace OtaTlvEncryptionKey { + +using SilabsConfig = chip::DeviceLayer::Internal::SilabsConfig; + +int destroyAESKey(uint32_t kid) +{ + psa_key_handle_t key_handle; + + int err = psa_open_key(kid, &key_handle); + if (err) + { + psa_close_key(kid); + } + else + { + err = psa_destroy_key(kid); + } + return err; +} + +CHIP_ERROR OtaTlvEncryptionKey::Import(const uint8_t * key, size_t key_len) +{ + destroyAESKey(mId); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + + psa_key_id_t key_id; + psa_set_key_id(&attributes, mId); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_algorithm(&attributes, PSA_ALG_CTR); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) + { + printf("Failed to import a key error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OtaTlvEncryptionKey::Decrypt(MutableByteSpan & block, uint32_t & mIVOffset) +{ + constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 }; + uint8_t iv[16]; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_status_t status; + uint8_t output[PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)]; + size_t output_len; + size_t total_output; + uint32_t u32IVCount; + uint32_t Offset = 0; + + memcpy(iv, au8Iv, sizeof(au8Iv)); + + u32IVCount = (((uint32_t) iv[12]) << 24) | (((uint32_t) iv[13]) << 16) | (((uint32_t) iv[14]) << 8) | (iv[15]); + u32IVCount += (mIVOffset >> 4); + + iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); + iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); + iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); + iv[15] = (uint8_t) (u32IVCount & 0xff); + + while (Offset + 16 <= block.size()) + { + status = psa_cipher_decrypt_setup(&operation, static_cast(mId), PSA_ALG_CTR); + if (status != PSA_SUCCESS) + { + printf("Failed to begin cipher operation error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + status = psa_cipher_set_iv(&operation, iv, sizeof(iv)); + if (status != PSA_SUCCESS) + { + printf("Failed to set IV error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + status = psa_cipher_update(&operation, static_cast(&block[Offset]), 16, output, sizeof(output), &output_len); + if (status != PSA_SUCCESS) + { + printf("Failed to update cipher operation error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + /* increment the IV for the next block */ + u32IVCount++; + + iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); + iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); + iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); + iv[15] = (uint8_t) (u32IVCount & 0xff); + + memcpy((void *) &block[Offset], &output, output_len); + + Offset += 16; /* increment the buffer offset */ + mIVOffset += 16; + status = psa_cipher_finish(&operation, output + total_output, sizeof(output) - total_output, &total_output); + if (status != PSA_SUCCESS) + { + printf("Failed to finish cipher operation\n"); + return CHIP_ERROR_INTERNAL; + } + } + + printf("Decrypted ciphertext\n"); + + psa_cipher_abort(&operation); + + return CHIP_NO_ERROR; +} + +} // namespace OtaTlvEncryptionKey +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h new file mode 100644 index 00000000000000..919e3b1285ac80 --- /dev/null +++ b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace OtaTlvEncryptionKey { + +static constexpr uint32_t kAES_KeyId_Default = (PSA_KEY_ID_USER_MIN + 2); + +class OtaTlvEncryptionKey +{ +public: + OtaTlvEncryptionKey(uint32_t id = 0) { mId = (id > 0) ? id : kAES_KeyId_Default; } + ~OtaTlvEncryptionKey() = default; + + uint32_t GetId() { return mId; } + CHIP_ERROR Import(const uint8_t * key, size_t key_len); + CHIP_ERROR Decrypt(MutableByteSpan & block, uint32_t & mIVOffset); + +protected: + uint32_t mId = 0; +}; + +} // namespace OtaTlvEncryptionKey +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 08695af1fc3800..ccbae7f1ec23ff 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -80,6 +80,8 @@ declare_args() { # Multi-chip OTA chip_enable_multi_ota_requestor = false + chip_enable_multi_ota_encryption = false + chip_enable_ota_custom_tlv_testing = false } examples_plat_dir = "${chip_root}/examples/platform/silabs/efr32" @@ -496,6 +498,14 @@ template("efr32_sdk") { ] } + if (chip_enable_multi_ota_encryption && chip_enable_multi_ota_requestor) { + defines += [ "OTA_ENCRYPTION_ENABLE=1" ] + } + + if (chip_enable_ota_custom_tlv_testing && chip_enable_multi_ota_requestor) { + defines += [ "OTA_TEST_CUSTOM_TLVS=1" ] + } + if (defined(invoker.chip_enable_wifi) && invoker.chip_enable_wifi) { if (enable_dic) { assert(chip_enable_wifi_ipv4, "enable chip_enable_wifi_ipv4") From c7f5f65cb21e11af81626012e2be2dcb4c77ccf2 Mon Sep 17 00:00:00 2001 From: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Date: Thu, 1 Aug 2024 00:41:18 -0700 Subject: [PATCH 18/21] Add python tests for Thermostat presets feature (#34693) * Add python tests for Thermostat presets feature * Restyled by autopep8 * Restyled by isort * Update the PICS code for presets attribute --------- Co-authored-by: Restyled.io --- src/python_testing/TC_TSTAT_4_2.py | 348 +++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 src/python_testing/TC_TSTAT_4_2.py diff --git a/src/python_testing/TC_TSTAT_4_2.py b/src/python_testing/TC_TSTAT_4_2.py new file mode 100644 index 00000000000000..5f53debfa024a0 --- /dev/null +++ b/src/python_testing/TC_TSTAT_4_2.py @@ -0,0 +1,348 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ALL_CLUSTERS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import copy +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + +cluster = Clusters.Thermostat + + +initial_presets = [] +initial_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x01', presetScenario=cluster.Enums.PresetScenarioEnum.kOccupied, + name=None, coolingSetpoint=2500, heatingSetpoint=2100, builtIn=True)) +initial_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x02', presetScenario=cluster.Enums.PresetScenarioEnum.kUnoccupied, + name=None, coolingSetpoint=2600, heatingSetpoint=2000, builtIn=True)) + +new_presets = initial_presets.copy() +new_presets.append(cluster.Structs.PresetStruct(presetHandle=NullValue, presetScenario=cluster.Enums.PresetScenarioEnum.kSleep, + name="Sleep", coolingSetpoint=2700, heatingSetpoint=1900, builtIn=False)) + +new_presets_with_handle = initial_presets.copy() +new_presets_with_handle.append(cluster.Structs.PresetStruct( + presetHandle=b'\x03', presetScenario=cluster.Enums.PresetScenarioEnum.kSleep, name="Sleep", coolingSetpoint=2700, heatingSetpoint=1900, builtIn=False)) + + +class TC_TSTAT_4_2(MatterBaseTest): + + async def write_presets(self, endpoint, presets) -> Status: + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, cluster.Attributes.Presets(presets))]) + return result[0].Status + + async def send_edit_preset_request_command(self, + endpoint: int = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.StartPresetsSchedulesEditRequest(timeoutSeconds=180), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_commit_preset_request_command(self, + endpoint: int = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.CommitPresetsSchedulesRequest(), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_cancel_preset_request_command(self, + endpoint: int = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.CancelPresetsSchedulesEditRequest(), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_set_active_preset_handle_request_command(self, + endpoint: int = None, + value: bytes = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.SetActivePresetRequest(value), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + def desc_TC_TSTAT_4_2(self) -> str: + """Returns a description of this test""" + return "3.2.4 [TC-TSTAT-4-2] Preset write and command attributes test case with server as DUT" + + def pics_TC_TSTAT_4_2(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["TSTAT.S"] + + def steps_TC_TSTAT_4_2(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH writes to the Presets attribute without calling the StartPresetsSchedulesEditRequest command", + "Verify that the Presets attribute was not updated."), + TestStep("3", "TH writes to the Presets attribute after calling the StartPresetsSchedulesEditRequest command but doesn't call CommitPresetsSchedulesRequest to commit", + "Verify that the Presets attribute was not updated."), + TestStep("4", "TH writes to the Presets attribute after calling the StartPresetsSchedulesEditRequest command and calls CommitPresetsSchedulesRequest to commit", + "Verify that the Presets attribute was updated."), + TestStep("5", "TH writes to the Presets attribute with a built-in preset removed", + "Verify that the CommitPresetsSchedulesRequest returned UNSUPPORTED_ACCESS (0x7e)."), + TestStep("6", "TH writes to the Presets attribute with a preset removed whose handle matches the value in the ActivePresetHandle attribute", + "Verify that the CommitPresetsSchedulesRequest returned INVALID_IN_STATE (0xcb)."), + TestStep("7", "TH writes to the Presets attribute with a built-in preset modified to be not built-in", + "Verify that the CommitPresetsSchedulesRequest returned UNSUPPORTED_ACCESS (0x7e)."), + TestStep("8", "TH writes to the Presets attribute with a new preset having builtIn set to true", + "Verify that the CommitPresetsSchedulesRequest returned CONSTRAINT_ERROR (0x87)."), + TestStep("9", "TH writes to the Presets attribute with a new preset having a preset handle that doesn't exist in the Presets attribute", + "Verify that the CommitPresetsSchedulesRequest returned NOT_FOUND (0x8b)."), + TestStep("10", "TH writes to the Presets attribute with a non built-in preset modified to be built-in", + "Verify that the CommitPresetsSchedulesRequest returned UNSUPPORTED_ACCESS (0x7e)."), + TestStep("11", "TH writes to the Presets attribute with a preset that doesn't support names in the PresetTypeFeatures bitmap but has a name", + "Verify that the CommitPresetsSchedulesRequest returned CONSTRAINT_ERROR (0x87)."), + TestStep("12", "TH writes to the Presets attribute but calls the CancelPresetsSchedulesEditRequest command to cancel the edit request", + "Verify that the edit request was cancelled"), + ] + + return steps + + @async_test_body + async def test_TC_TSTAT_4_2(self): + endpoint = self.user_params.get("endpoint", 1) + + self.step("1") + # Commission DUT - already done + + self.step("2") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050")): + presets = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.Presets) + logger.info(f"Rx'd Presets: {presets}") + asserts.assert_equal(presets, initial_presets, "Presets do not match initial value") + + # Write to the presets attribute without calling StartPresetsSchedulesEditRequest command + status = await self.write_presets(endpoint=endpoint, presets=new_presets) + status_ok = (status == Status.InvalidInState) + asserts.assert_true(status_ok, "Presets write did not return InvalidInState as expected") + + self.step("3") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + await self.send_edit_preset_request_command() + + # Write to the presets attribute after calling StartPresetsSchedulesEditRequest command + status = await self.write_presets(endpoint=endpoint, presets=new_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Read the presets attribute and verify it was not updated since CommitPresetsSchedulesRequest was not called after writing presets + presets = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.Presets) + logger.info(f"Rx'd Presets: {presets}") + asserts.assert_equal(presets, initial_presets, "Presets were updated which is not expected") + + self.step("4") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after calling StartPresetsSchedulesEditRequest command + status = await self.write_presets(endpoint=endpoint, presets=new_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command + await self.send_commit_preset_request_command() + + # Read the presets attribute and verify it was updated since CommitPresetsSchedulesRequest was called after writing presets + presets = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.Presets) + logger.info(f"Rx'd Presets: {presets}") + asserts.assert_equal(presets, new_presets_with_handle, "Presets were not updated which is not expected") + + self.step("5") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after removing a built in preset from the list. Remove the first entry. + test_presets = new_presets_with_handle.copy() + test_presets.pop(0) + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect UnsupportedAccess + await self.send_commit_preset_request_command(expected_status=Status.UnsupportedAccess) + + self.step("6") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C06.Rsp") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the SetActivePresetRequest command + await self.send_set_active_preset_handle_request_command(value=b'\x03') + + # Read the active preset handle attribute and verify it was updated to preset handle + activePresetHandle = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ActivePresetHandle) + logger.info(f"Rx'd ActivePresetHandle: {activePresetHandle}") + asserts.assert_equal(activePresetHandle, b'\x03', "Active preset handle was not updated as expected") + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after removing the preset that was set as the active preset handle. Remove the last entry with preset handle (b'\x03') + test_presets = new_presets_with_handle.copy() + del test_presets[-1] + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect InvalidInState + await self.send_commit_preset_request_command(expected_status=Status.InvalidInState) + + self.step("7") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after setting the builtIn flag to False for preset with handle (b'\x01') + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets[0].builtIn = False + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect UnsupportedAccess + await self.send_commit_preset_request_command(expected_status=Status.UnsupportedAccess) + + self.step("8") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after adding a preset with builtIn set to True + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct(presetHandle=NullValue, presetScenario=cluster.Enums.PresetScenarioEnum.kWake, + name="Wake", coolingSetpoint=2800, heatingSetpoint=1800, builtIn=True)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect ConstraintError + await self.send_commit_preset_request_command(expected_status=Status.ConstraintError) + + self.step("9") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after adding a preset with a preset handle that doesn't exist in Presets attribute + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x08', presetScenario=cluster.Enums.PresetScenarioEnum.kWake, + name="Wake", coolingSetpoint=2800, heatingSetpoint=1800, builtIn=True)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect NotFound + await self.send_commit_preset_request_command(expected_status=Status.NotFound) + + self.step("10") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after setting the builtIn flag to True for preset with handle (b'\x03') + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets[2].builtIn = True + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect UnsupportedAccess + await self.send_commit_preset_request_command(expected_status=Status.UnsupportedAccess) + + self.step("11") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after setting a name for preset with handle (b'\x01') that doesn't support names + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets[0].name = "Occupied" + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect ConstraintError + await self.send_commit_preset_request_command(expected_status=Status.ConstraintError) + + self.step("12") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute with a new valid preset added + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x04', presetScenario=cluster.Enums.PresetScenarioEnum.kWake, + name="Wake", coolingSetpoint=2800, heatingSetpoint=1800, builtIn=False)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CancelPresetsSchedulesRequest command + await self.send_cancel_preset_request_command() + + # Send the CommitPresetsSchedulesRequest command and expect InvalidInState as the previous edit request was cancelled + await self.send_commit_preset_request_command(expected_status=Status.InvalidInState) + + # TODO: Add tests for the total number of Presets exceeds the NumberOfPresets supported. Also Add tests for adding presets with preset scenario not present in PresetTypes. + + +if __name__ == "__main__": + default_matter_test_main() From fb1d2d8c398488b7ffb17d796694e6dc40fddec2 Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:00:52 +0200 Subject: [PATCH 19/21] removing unneccessary git fetch (#34698) --- scripts/helpers/restyle-diff.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/helpers/restyle-diff.sh b/scripts/helpers/restyle-diff.sh index 5f37c69762e281..58904e06a38565 100755 --- a/scripts/helpers/restyle-diff.sh +++ b/scripts/helpers/restyle-diff.sh @@ -78,7 +78,7 @@ done if [[ -z "$ref" ]]; then ref="master" - git remote | grep -qxF upstream && ref="upstream/master" && git fetch upstream + git remote | grep -qxF upstream && ref="upstream/master" fi if [[ $pull_image -eq 1 ]]; then From 1bebacd29d8ece107658b8e5b6e758ac7f723303 Mon Sep 17 00:00:00 2001 From: shripad621git <79364691+shripad621git@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:13:58 +0530 Subject: [PATCH 20/21] [ESP32] Update the esp32 ci to use the latest docker version . (#34659) * Update the esp32 ci to use the latest docker version * Added the CI fixes for ESP32 builds --- .github/workflows/chef.yaml | 2 +- .github/workflows/examples-esp32.yaml | 4 ++-- .github/workflows/qemu.yaml | 2 +- .github/workflows/release_artifacts.yaml | 2 +- .../all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults | 6 ++++++ .../esp32/sdkconfig_m5stack_rpc.defaults | 6 ++++++ examples/chef/esp32/partitions.csv | 2 +- examples/light-switch-app/esp32/main/DeviceCallbacks.cpp | 2 +- .../light-switch-app/esp32/main/include/DeviceCallbacks.h | 2 +- 9 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index da12476696bce9..efb408f80bfc26 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -56,7 +56,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:66 + image: ghcr.io/project-chip/chip-build-esp32:67 options: --user root steps: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index cdfdee65148aff..fb0d2bc29b5b8d 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:66 + image: ghcr.io/project-chip/chip-build-esp32:67 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -126,7 +126,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:66 + image: ghcr.io/project-chip/chip-build-esp32:67 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index acced0da5d9849..6dff2dadc3d533 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32-qemu:66 + image: ghcr.io/project-chip/chip-build-esp32-qemu:67 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index 97468ec3b5ce0c..481def01c629c6 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-esp32:66 + image: ghcr.io/project-chip/chip-build-esp32:67 steps: - name: Checkout diff --git a/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults b/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults index 56fed5d65e6797..3f1168ecb907ec 100644 --- a/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults +++ b/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults @@ -82,3 +82,9 @@ CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=1024 CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP=y + +# Memory Optimizations +CONFIG_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BTDM_CTRL_BLE_MAX_CONN=1 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=n +CONFIG_BT_NIMBLE_ROLE_OBSERVER=n diff --git a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults index 56fed5d65e6797..d2eaffb9bfd15b 100644 --- a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults +++ b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults @@ -72,6 +72,12 @@ CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=n # Enable HKDF in mbedtls CONFIG_MBEDTLS_HKDF_C=y +# Memory Optimizations +CONFIG_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BTDM_CTRL_BLE_MAX_CONN=1 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=n +CONFIG_BT_NIMBLE_ROLE_OBSERVER=n + # Build chip tests CONFIG_BUILD_CHIP_TESTS=y diff --git a/examples/chef/esp32/partitions.csv b/examples/chef/esp32/partitions.csv index c0855b66229dc4..c84d53a64b6e59 100644 --- a/examples/chef/esp32/partitions.csv +++ b/examples/chef/esp32/partitions.csv @@ -3,4 +3,4 @@ nvs, data, nvs, , 0xC000, phy_init, data, phy, , 0x1000, # Factory partition size about 1.9MB -factory, app, factory, , 1945K, +factory, app, factory, , 2M, diff --git a/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp b/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp index 795c433436330e..8fb0dabd95dec7 100644 --- a/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp @@ -35,7 +35,7 @@ using namespace chip::System; using namespace chip::app::Clusters; void AppDeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, - uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) + uint8_t type, uint16_t size, uint8_t * value) { ESP_LOGI(TAG, "PostAttributeChangeCallback - Cluster ID: '0x%" PRIx32 "', EndPoint ID: '0x%x', Attribute ID: '0x%" PRIx32 "'", clusterId, endpointId, attributeId); diff --git a/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h b/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h index 93c53cbfd37e97..7d9c0b00b32861 100644 --- a/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h +++ b/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h @@ -33,7 +33,7 @@ class AppDeviceCallbacks : public CommonDeviceCallbacks { public: virtual void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, - uint8_t mask, uint8_t type, uint16_t size, uint8_t * value); + uint8_t type, uint16_t size, uint8_t * value) override; private: void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); From 923619aedf0f3ddce76fc968c2a6b280dc06570e Mon Sep 17 00:00:00 2001 From: sumaky <63414112+sumaky@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:20:46 +0530 Subject: [PATCH 21/21] DRLK Test Plan -Aliro Update (#34638) * Add files via upload * Update Test_TC_DRLK_2_1.yaml Aliro Attributes * Update PICS.yaml for Aliro PICS * Update PICS.yaml * Update PICS.yaml-Formatting * Update PICS.yaml * Update Test_TC_DRLK_2_13.yaml - PICS:PICS_SKIP_SAMPLE_APP * Update Test_TC_DRLK_2_1.yaml-PICS_SKIP_SAMPLE_APP * Update PICS.yaml * Update PICS.yaml * Update ci-pics-values-update DRLKA0080 * Update ci-pics-values-Aliro * Update PICS.yaml * Update ci-pics-values-Aliro Cmds and Feature PICS * Update Test_TC_DRLK_2_13.yaml * formatted using prettier * Update PICS.yaml-prettier * Update Test_TC_DRLK_2_13.yaml * Update Test_TC_DRLK_2_1.yaml * Restyled by prettier-yaml * Update Test_TC_DRLK_2_13.yaml * Update ciTests.json-Added DRLK 2.1 and 2.13 * Update ciTests.json * Update ciTests.json * Restyled by whitespace * Restyled by prettier-json * Update Test_TC_DRLK_2_1.yaml fixed the values in the list as hex in step 41b removed PICS_SKIP_SAMPLE_APP * deleted DRLK_2_13 yaml file. will be covered in python script * Update ci-pics-values * Update PICS.yaml removed readonly type of PICS * Update ci-pics-values-removed readonly pics * Update ciTests.json-restored * updated the Aliro labels without readonly , updated the ids to DRLK.S.A0028.ReadOnly and DRLK.S.A002c.ReadOnly * Removed PICS for step 37 * Restyled by whitespace * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io Co-authored-by: chaitanya jandhyala --- src/app/tests/suites/certification/PICS.yaml | 54 ++++ .../certification/Test_TC_DRLK_2_1.yaml | 286 +++++++++++++++++- .../tests/suites/certification/ci-pics-values | 14 + 3 files changed, 345 insertions(+), 9 deletions(-) diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 836e71e3964e40..8a3e1fce94326f 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -2738,6 +2738,46 @@ PICS: - label: "Does the DUT(server) support the ExpiringUserTimeOut attribute?" id: DRLK.S.A0035 + - label: + "Does the DUT(server) support the AliroReaderVerificationKey attribute" + id: DRLK.S.A0080 + + - label: + "Does the DUT(server) support the AliroReaderGroupIdentifier attribute" + id: DRLK.S.A0081 + + - label: + "Does the DUT(server) support the AliroReaderGroupSubIdentifier + attribute" + id: DRLK.S.A0082 + + - label: + "Does the DUT(server) support the + AliroExpeditedTransactionSupportedProtocolVersions attribute" + id: DRLK.S.A0083 + + - label: "Does the DUT(server) support the AliroGroupResolvingKey attribute" + id: DRLK.S.A0084 + + - label: + "Does the DUT(server) support the AliroSupportedBLEUWBProtocolVersions + attribute" + id: DRLK.S.A0085 + + - label: + "Does the DUT(server) support the AliroBLEAdvertisingVersion attribute" + id: DRLK.S.A0086 + + - label: + "Does the DUT(server) support the + NumberOfAliroCredentialIssuerKeysSupported attribute" + id: DRLK.S.A0087 + + - label: + "Does the DUT(server) support the NumberOfAliroEndpointKeysSupported + attribute" + id: DRLK.S.A0088 + # #Server ReadOnly attribute # @@ -2869,6 +2909,12 @@ PICS: - label: "Does the DUT(server) support the Unbolt Door command?" id: DRLK.S.C27.Rsp + - label: "Does the DUT(server) support the SetAliroReaderConfig command?" + id: DRLK.S.C28.Rsp + + - label: "Does the DUT(server) support the ClearAliroReaderConfig command?" + id: DRLK.S.C29.Rsp + # # server / commandsGenerated # @@ -2970,6 +3016,14 @@ PICS: - label: "Does the DUT(server) support the Lock supports unbolting feature?" id: DRLK.S.F0c + - label: "Does the DUT(server) support AliroProvisioning feature?" + id: DRLK.S.F0d + + - label: + "Does the DUT(server) support Bluetooth LE + UWB Access Control Flow + feature?" + id: DRLK.S.F0e + # # server / manually # diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml index e84b1ebdbc8459..8bce2046d74897 100755 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml @@ -1551,8 +1551,18 @@ tests: response: value: NumberOfCredentialsSupportedPerUserValue - - label: "Cleanup the created user" - PICS: DRLK.S.F00 && DRLK.S.F07 + - label: "Step 36: TH sends ClearCredential Command to DUT" + PICS: DRLK.S.F00 && DRLK.S.F07 && DRLK.S.C26.Rsp + command: "ClearCredential" + timedInteractionTimeoutMs: 1000 + arguments: + values: + - name: "Credential" + value: { CredentialType: 1, CredentialIndex: 1 } + + - label: + "Step 37: TH sends ClearUser Command to DUT with the UserIndex as 1" + PICS: DRLK.S.F07 && DRLK.S.C1d.Rsp command: "ClearUser" timedInteractionTimeoutMs: 1000 arguments: @@ -1560,11 +1570,269 @@ tests: - name: "UserIndex" value: 1 - - label: "Clean the created credential" - PICS: DRLK.S.F00 && DRLK.S.F07 && DRLK.S.C26.Rsp - command: "ClearCredential" - timedInteractionTimeoutMs: 1000 + - label: "Step 38a: TH reads AliroReaderVerificationKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0080 + command: "readAttribute" + attribute: "AliroReaderVerificationKey" + response: + saveAs: verificationkey + constraints: + type: octet_string + minLength: 65 + + - label: + "Step 38b: TH writes AliroReaderVerificationKey attribute as an octstr + value of length 65 which is different from verificationkey" + PICS: DRLK.S.F0d && DRLK.S.A0080 + command: "writeAttribute" + attribute: "AliroReaderVerificationKey" arguments: - values: - - name: "Credential" - value: { CredentialType: 1, CredentialIndex: 1 } + value: "047a4c992d753924cdf3779a3c84fec2debaa6f0b3084450878acc7ddcce7856ae57b1ebbe2561015103dd7474c2a183675378ec55f1e465ac3436bf3dd5ca54d4" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 38c: TH reads AliroReaderVerificationKey attribute from DUT" + + PICS: DRLK.S.F0d && DRLK.S.A0080 + command: "readAttribute" + attribute: "AliroReaderVerificationKey" + response: + value: verificationkey + + - label: "Step 39a: TH reads AliroReaderGroupIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0081 + command: "readAttribute" + attribute: "AliroReaderGroupIdentifier" + response: + saveAs: aliroreadergrpidentifier + constraints: + type: octet_string + minLength: 16 + - label: + "Step 39b: TH writes AliroReaderGroupIdentifier attribute as octstr + value of length 16 which is different from aliroreadergrpidentifier" + PICS: DRLK.S.F0d && DRLK.S.A0081 + command: "writeAttribute" + attribute: "AliroReaderVerificationKey" + arguments: + value: "047a4c992d753924" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 39c: TH reads AliroReaderGroupIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0081 + command: "readAttribute" + attribute: "AliroReaderGroupIdentifier" + response: + value: aliroreadergrpidentifier + - label: + "Step 40a: TH reads AliroReaderGroupSubIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0082 + command: "readAttribute" + attribute: "AliroReaderGroupSubIdentifier" + response: + saveAs: aliroreadergrpsubidentifier + constraints: + type: octet_string + minLength: 16 + + - label: + "Step 40b: TH writes AliroReaderGroupSubIdentifier attribute as octstr + value of length 16 which is different from aliroreadergrpsubidentifier" + PICS: DRLK.S.F0d && DRLK.S.A0082 + command: "writeAttribute" + attribute: "AliroReaderGroupSubIdentifier" + arguments: + value: "047a4c992d75368" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 40c: TH reads AliroReaderGroupIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0082 + command: "readAttribute" + attribute: "AliroReaderGroupSubIdentifier" + response: + value: aliroreadergrpsubidentifier + + - label: + "Step 41a: TH reads AliroExpeditedTransactionSupportedProtocolVersions + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0083 + command: "readAttribute" + attribute: "AliroExpeditedTransactionSupportedProtocolVersions" + response: + saveAs: aliroprotocolversion + constraints: + type: list + maxLength: 16 + - label: + "Step 41b: TH writes + AliroExpeditedTransactionSupportedProtocolVersions attribute as list + which is different from aliroprotocolversion" + PICS: DRLK.S.F0d && DRLK.S.A0083 + command: "writeAttribute" + attribute: "AliroExpeditedTransactionSupportedProtocolVersions" + arguments: + value: ["0x1", "0x2"] + response: + error: UNSUPPORTED_WRITE + - label: + "Step 41c: TH reads AliroExpeditedTransactionSupportedProtocolVersions + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0083 + command: "readAttribute" + attribute: "AliroExpeditedTransactionSupportedProtocolVersions" + response: + value: aliroprotocolversion + + - label: "Step 42a: TH reads AliroGroupResolvingKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0084 + command: "readAttribute" + attribute: "AliroGroupResolvingKey" + response: + saveAs: alirogrpresolvingkey + constraints: + type: octet_string + minLength: 16 + + - label: + "Step 42b: TH writes AliroGroupResolvingKey attribute as octstr value + of length 16 which is different from alirogrpresolvingkey" + PICS: DRLK.S.F0d && DRLK.S.A0084 + command: "writeAttribute" + attribute: "AliroGroupResolvingKey" + arguments: + value: "047a4c992d75368" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 42c: TH reads AliroGroupResolvingKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0084 + command: "readAttribute" + attribute: "AliroGroupResolvingKey" + response: + value: alirogrpresolvingkey + - label: + "Step 43a: TH reads AliroSupportedBLEUWBProtocolVersions attribute + from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0085 + command: "readAttribute" + attribute: "AliroSupportedBLEUWBProtocolVersions" + response: + saveAs: alirobleuwbprotocolversion + constraints: + type: octet_string + minLength: 16 + + - label: + "Step 43b: TH writes AliroSupportedBLEUWBProtocolVersions attribute as + list which is different from alirobleuwbprotocolversion" + PICS: DRLK.S.F0d && DRLK.S.A0085 + command: "writeAttribute" + attribute: "AliroSupportedBLEUWBProtocolVersions" + arguments: + value: "047a4c992d75368" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 43c: TH reads AliroGroupResolvingKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0085 + command: "readAttribute" + attribute: "AliroSupportedBLEUWBProtocolVersions" + response: + value: alirobleuwbprotocolversion + + - label: "Step 44a: TH reads AliroBLEAdvertisingVersion attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0086 + command: "readAttribute" + attribute: "AliroBLEAdvertisingVersion" + response: + saveAs: alirobleadvversion + constraints: + type: int8u + minValue: 0 + maxValue: 255 + + - label: + "Step 44b: TH writes AliroBLEAdvertisingVersion attribute as any value + different from alirobleadvversion" + PICS: DRLK.S.F0d && DRLK.S.A0086 + command: "writeAttribute" + attribute: "AliroBLEAdvertisingVersion" + arguments: + value: 85 + response: + error: UNSUPPORTED_WRITE + + - label: "Step 44c: TH reads AliroBLEAdvertisingVersion attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0086 + command: "readAttribute" + attribute: "AliroBLEAdvertisingVersion" + response: + value: alirobleadvversion + + - label: + "Step 45a: TH reads NumberOfAliroCredentialIssuerKeysSupported + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0087 + command: "readAttribute" + attribute: "NumberOfAliroCredentialIssuerKeysSupported" + response: + saveAs: alirokeysupported + constraints: + type: int16u + minValue: 0 + maxValue: 65534 + + - label: + "Step 45b: TH writes NumberOfAliroCredentialIssuerKeysSupported + attribute as any value different from alirokeysupported" + PICS: DRLK.S.F0d && DRLK.S.A0087 + command: "writeAttribute" + attribute: "NumberOfAliroCredentialIssuerKeysSupported" + arguments: + value: 30 + response: + error: UNSUPPORTED_WRITE + + - label: + "Step 45c: TH reads NumberOfAliroCredentialIssuerKeysSupported + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0087 + command: "readAttribute" + attribute: "NumberOfAliroCredentialIssuerKeysSupported" + response: + value: alirokeysupported + + - label: + "Step 46a: TH reads NumberOfAliroEndpointKeysSupported attribute from + DUT" + PICS: DRLK.S.F0d && DRLK.S.A0088 + command: "readAttribute" + attribute: "NumberOfAliroEndpointKeysSupported" + response: + saveAs: aliroepkeysupported + constraints: + type: int16u + minValue: 0 + maxValue: 65534 + + - label: + "Step 46b: TH writes NumberOfAliroEndpointKeysSupported attribute as + any value different from aliroepkeysupported" + PICS: DRLK.S.F0d && DRLK.S.A0088 + command: "writeAttribute" + attribute: "NumberOfAliroEndpointKeysSupported" + arguments: + value: 1000 + response: + error: UNSUPPORTED_WRITE + + - label: + "Step 46c: TH reads NumberOfAliroEndpointKeysSupported attribute from + DUT" + PICS: DRLK.S.F0d && DRLK.S.A0088 + command: "readAttribute" + attribute: "NumberOfAliroEndpointKeysSupported" + response: + value: aliroepkeysupported diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index fe5ffcdab753b1..5aa8dba1f684a8 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -1519,11 +1519,21 @@ DRLK.S.A0031=1 DRLK.S.A0032=1 DRLK.S.A0033=1 DRLK.S.A0035=0 +DRLK.S.A0080=0 +DRLK.S.A0081=0 +DRLK.S.A0082=0 +DRLK.S.A0083=0 +DRLK.S.A0084=0 +DRLK.S.A0085=0 +DRLK.S.A0086=0 +DRLK.S.A0087=0 +DRLK.S.A0088=0 #ReadOnly attributes DRLK.S.A0028.ReadOnly=1 DRLK.S.A002c.ReadOnly=1 + #write attributes DRLK.S.M.SimulateNotFullyLocked=1 DRLK.S.M.DetectLockJammed=1 @@ -1564,6 +1574,8 @@ DRLK.S.F08=1 DRLK.S.F0a=1 DRLK.S.F0b=1 DRLK.S.F0c=1 +DRLK.S.F0d=0 +DRLK.S.F0e=0 # Server Commands DRLK.S.C00.Rsp=1 @@ -1585,6 +1597,8 @@ DRLK.S.C22.Rsp=1 DRLK.S.C24.Rsp=1 DRLK.S.C26.Rsp=1 DRLK.S.C27.Rsp=1 +DRLK.S.C28.Rsp=0 +DRLK.S.C29.Rsp=0 DRLK.S.C0c.Tx=1 DRLK.S.C0f.Tx=1 DRLK.S.C12.Tx=1