From ab113098f1037835d5333798cd68c6add14d8246 Mon Sep 17 00:00:00 2001 From: fesseha-eve <88329315+fessehaeve@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:43:30 +0100 Subject: [PATCH 01/83] Update valve configuration and control cluster XML according to latest spec (#30955) * update valve configuration and control cluster according to latest spec * DefaultOpenDuration is writable and updated device type name to Water Valve * moved domain to be the first element --- .../zcl/data-model/chip/matter-devices.xml | 4 +- ...alve-configuration-and-control-cluster.xml | 71 ++-- .../data_model/controller-clusters.matter | 41 +- .../chip/devicecontroller/ChipClusters.java | 159 +++----- .../devicecontroller/ChipEventStructs.java | 19 +- .../devicecontroller/ClusterIDMapping.java | 34 +- .../devicecontroller/ClusterInfoMapping.java | 45 +- .../devicecontroller/ClusterReadMapping.java | 36 +- .../devicecontroller/ClusterWriteMapping.java | 54 +-- ...AndControlClusterValveStateChangedEvent.kt | 20 +- .../ValveConfigurationAndControlCluster.kt | 343 ++++++---------- ...AndControlClusterValveStateChangedEvent.kt | 20 +- .../CHIPAttributeTLVValueDecoder.cpp | 60 +-- .../zap-generated/CHIPClustersWrite-JNI.cpp | 68 +-- .../CHIPEventTLVValueDecoder.cpp | 22 +- .../java/zap-generated/CHIPReadCallbacks.cpp | 113 ++--- .../python/chip/clusters/CHIPClusters.py | 24 +- .../python/chip/clusters/Objects.py | 90 ++-- .../MTRAttributeSpecifiedCheck.mm | 8 +- .../MTRAttributeTLVValueDecoder.mm | 38 +- .../CHIP/zap-generated/MTRBaseClusters.h | 54 +-- .../CHIP/zap-generated/MTRBaseClusters.mm | 171 +++----- .../CHIP/zap-generated/MTRClusterConstants.h | 13 +- .../CHIP/zap-generated/MTRClusters.h | 17 +- .../CHIP/zap-generated/MTRClusters.mm | 66 +-- .../zap-generated/MTRCommandPayloadsObjc.h | 34 +- .../zap-generated/MTRCommandPayloadsObjc.mm | 106 +---- .../MTRCommandPayloads_Internal.h | 6 - .../zap-generated/MTRDeviceTypeMetadata.mm | 2 +- .../zap-generated/MTREventTLVValueDecoder.mm | 9 + .../CHIP/zap-generated/MTRStructsObjc.h | 1 + .../CHIP/zap-generated/MTRStructsObjc.mm | 5 +- .../zap-generated/attributes/Accessors.cpp | 120 +++--- .../zap-generated/attributes/Accessors.h | 21 +- .../app-common/zap-generated/callback.h | 6 - .../zap-generated/cluster-enums-check.h | 16 +- .../app-common/zap-generated/cluster-enums.h | 27 +- .../zap-generated/cluster-objects.cpp | 57 +-- .../zap-generated/cluster-objects.h | 91 ++--- .../app-common/zap-generated/ids/Attributes.h | 20 +- .../app-common/zap-generated/ids/Commands.h | 4 - .../zap-generated/cluster/Commands.h | 79 +--- .../cluster/logging/DataModelLogger.cpp | 24 +- .../zap-generated/cluster/Commands.h | 386 +++++++----------- 44 files changed, 1033 insertions(+), 1571 deletions(-) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index 58bba4c850f9a6..f76a7bb4be5fba 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -2115,9 +2115,9 @@ limitations under the License. - MA-valve + MA-water-valve CHIP - Matter Valve + Matter Water Valve 0x0103 0x0042 Simple diff --git a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml index d4207d6f116e2f..557792a6b1331a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml @@ -19,26 +19,35 @@ limitations under the License. - - + + - - - + + + + + + - - + + + + + + + + - Valve Configuration and Control HVAC + Valve Configuration and Control 0x0081 VALVE_CONFIGURATION_AND_CONTROL_CLUSTER true @@ -48,51 +57,37 @@ limitations under the License. - - OpenDuration - - - - AutoCloseTime - RemainingDuration - CurrentState - TargetState - - StartUpState - - - + OpenDuration + + + DefaultOpenDuration + AutoCloseTime + RemainingDuration + CurrentState + TargetState CurrentLevel TargetLevel - - OpenLevel - - - + DefaultOpenLevel ValveFault - This command is used to set the valve to its fully open position. - + This command is used to set the valve to its open position. + + - This command is used to set the valve to its fully closed position. - - - - This command is used to set the valve to a specific level. - - + This command is used to set the valve to its closed position. - This event SHALL be generated when the valve changes state, either opens or closes. + This event SHALL be generated when the valve state changed. + - This event SHALL be generated when the valve registers a fault. + This event SHALL be generated when the valve registers or clears a fault. diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index f2edd0f158926a..e37e3563dfc567 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -4058,9 +4058,14 @@ provisional cluster BooleanStateConfiguration = 128 { provisional cluster ValveConfigurationAndControl = 129 { revision 1; + enum StatusCodeEnum : enum8 { + kFailureDueToFault = 2; + } + enum ValveStateEnum : enum8 { - kOpen = 0; - kClosed = 1; + kClosed = 0; + kOpen = 1; + kTransitioning = 2; } bitmap Feature : bitmap32 { @@ -4072,25 +4077,29 @@ provisional cluster ValveConfigurationAndControl = 129 { kGeneralFault = 0x1; kBlocked = 0x2; kLeaking = 0x4; + kNotConnected = 0x8; + kShortCircuit = 0x10; + kCurrentExceeded = 0x20; } info event ValveStateChanged = 0 { ValveStateEnum valveState = 0; + optional percent valveLevel = 1; } info event ValveFault = 1 { ValveFaultBitmap valveFault = 0; } - attribute access(write: manage) nullable elapsed_s openDuration = 0; - readonly attribute optional nullable epoch_us autoCloseTime = 1; - readonly attribute optional nullable elapsed_s remainingDuration = 2; - readonly attribute nullable ValveStateEnum currentState = 3; - readonly attribute nullable ValveStateEnum targetState = 4; - attribute access(write: manage) optional ValveStateEnum startUpState = 5; + readonly attribute nullable elapsed_s openDuration = 0; + attribute nullable elapsed_s defaultOpenDuration = 1; + readonly attribute optional nullable epoch_us autoCloseTime = 2; + readonly attribute nullable elapsed_s remainingDuration = 3; + readonly attribute nullable ValveStateEnum currentState = 4; + readonly attribute nullable ValveStateEnum targetState = 5; readonly attribute optional nullable percent currentLevel = 6; readonly attribute optional nullable percent targetLevel = 7; - attribute access(write: manage) optional nullable percent openLevel = 8; + attribute optional percent defaultOpenLevel = 8; readonly attribute optional ValveFaultBitmap valveFault = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -4100,20 +4109,14 @@ provisional cluster ValveConfigurationAndControl = 129 { readonly attribute int16u clusterRevision = 65533; request struct OpenRequest { - optional elapsed_s openDuration = 0; - } - - request struct SetLevelRequest { - percent level = 0; - optional elapsed_s openDuration = 1; + optional nullable elapsed_s openDuration = 0; + optional percent targetLevel = 1; } - /** This command is used to set the valve to its fully open position. */ + /** This command is used to set the valve to its open position. */ command Open(OpenRequest): DefaultSuccess = 0; - /** This command is used to set the valve to its fully closed position. */ + /** This command is used to set the valve to its closed position. */ command Close(): DefaultSuccess = 1; - /** This command is used to set the valve to a specific level. */ - command SetLevel(SetLevelRequest): DefaultSuccess = 2; } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 601c14f5da66c2..a7b89fa3b5d7eb 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -27864,14 +27864,14 @@ public static class ValveConfigurationAndControlCluster extends BaseChipCluster public static final long CLUSTER_ID = 129L; private static final long OPEN_DURATION_ATTRIBUTE_ID = 0L; - private static final long AUTO_CLOSE_TIME_ATTRIBUTE_ID = 1L; - private static final long REMAINING_DURATION_ATTRIBUTE_ID = 2L; - private static final long CURRENT_STATE_ATTRIBUTE_ID = 3L; - private static final long TARGET_STATE_ATTRIBUTE_ID = 4L; - private static final long START_UP_STATE_ATTRIBUTE_ID = 5L; + private static final long DEFAULT_OPEN_DURATION_ATTRIBUTE_ID = 1L; + private static final long AUTO_CLOSE_TIME_ATTRIBUTE_ID = 2L; + private static final long REMAINING_DURATION_ATTRIBUTE_ID = 3L; + private static final long CURRENT_STATE_ATTRIBUTE_ID = 4L; + private static final long TARGET_STATE_ATTRIBUTE_ID = 5L; private static final long CURRENT_LEVEL_ATTRIBUTE_ID = 6L; private static final long TARGET_LEVEL_ATTRIBUTE_ID = 7L; - private static final long OPEN_LEVEL_ATTRIBUTE_ID = 8L; + private static final long DEFAULT_OPEN_LEVEL_ATTRIBUTE_ID = 8L; private static final long VALVE_FAULT_ATTRIBUTE_ID = 9L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; @@ -27890,18 +27890,22 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void open(DefaultClusterCallback callback, Optional openDuration) { - open(callback, openDuration, 0); + public void open(DefaultClusterCallback callback, @Nullable Optional openDuration, Optional targetLevel) { + open(callback, openDuration, targetLevel, 0); } - public void open(DefaultClusterCallback callback, Optional openDuration, int timedInvokeTimeoutMs) { + public void open(DefaultClusterCallback callback, @Nullable Optional openDuration, Optional targetLevel, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); final long openDurationFieldID = 0L; - BaseTLVType openDurationtlvValue = openDuration.map((nonOptionalopenDuration) -> new UIntType(nonOptionalopenDuration)).orElse(new EmptyType()); + BaseTLVType openDurationtlvValue = openDuration != null ? openDuration.map((nonOptionalopenDuration) -> new UIntType(nonOptionalopenDuration)).orElse(new EmptyType()) : new NullType(); elements.add(new StructElement(openDurationFieldID, openDurationtlvValue)); + final long targetLevelFieldID = 1L; + BaseTLVType targetLeveltlvValue = targetLevel.map((nonOptionaltargetLevel) -> new UIntType(nonOptionaltargetLevel)).orElse(new EmptyType()); + elements.add(new StructElement(targetLevelFieldID, targetLeveltlvValue)); + StructType value = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @Override @@ -27926,31 +27930,11 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, value, timedInvokeTimeoutMs); } - public void setLevel(DefaultClusterCallback callback, Integer level, Optional openDuration) { - setLevel(callback, level, openDuration, 0); - } - - public void setLevel(DefaultClusterCallback callback, Integer level, Optional openDuration, int timedInvokeTimeoutMs) { - final long commandId = 2L; - - ArrayList elements = new ArrayList<>(); - final long levelFieldID = 0L; - BaseTLVType leveltlvValue = new UIntType(level); - elements.add(new StructElement(levelFieldID, leveltlvValue)); - - final long openDurationFieldID = 1L; - BaseTLVType openDurationtlvValue = openDuration.map((nonOptionalopenDuration) -> new UIntType(nonOptionalopenDuration)).orElse(new EmptyType()); - elements.add(new StructElement(openDurationFieldID, openDurationtlvValue)); - - StructType value = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, value, timedInvokeTimeoutMs); + public interface OpenDurationAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); } - public interface OpenDurationAttributeCallback extends BaseAttributeCallback { + public interface DefaultOpenDurationAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable Long value); } @@ -27978,10 +27962,6 @@ public interface TargetLevelAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable Integer value); } - public interface OpenLevelAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -28011,25 +27991,50 @@ public void onSuccess(byte[] tlv) { }, OPEN_DURATION_ATTRIBUTE_ID, true); } - public void writeOpenDurationAttribute(DefaultClusterCallback callback, Long value) { - writeOpenDurationAttribute(callback, value, 0); + public void subscribeOpenDurationAttribute( + OpenDurationAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, OPEN_DURATION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, OPEN_DURATION_ATTRIBUTE_ID, minInterval, maxInterval); } - public void writeOpenDurationAttribute(DefaultClusterCallback callback, Long value, int timedWriteTimeoutMs) { + public void readDefaultOpenDurationAttribute( + DefaultOpenDurationAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_OPEN_DURATION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEFAULT_OPEN_DURATION_ATTRIBUTE_ID, true); + } + + public void writeDefaultOpenDurationAttribute(DefaultClusterCallback callback, Long value) { + writeDefaultOpenDurationAttribute(callback, value, 0); + } + + public void writeDefaultOpenDurationAttribute(DefaultClusterCallback callback, Long value, int timedWriteTimeoutMs) { BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), OPEN_DURATION_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + writeAttribute(new WriteAttributesCallbackImpl(callback), DEFAULT_OPEN_DURATION_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); } - public void subscribeOpenDurationAttribute( - OpenDurationAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, OPEN_DURATION_ATTRIBUTE_ID); + public void subscribeDefaultOpenDurationAttribute( + DefaultOpenDurationAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_OPEN_DURATION_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); } - }, OPEN_DURATION_ATTRIBUTE_ID, minInterval, maxInterval); + }, DEFAULT_OPEN_DURATION_ATTRIBUTE_ID, minInterval, maxInterval); } public void readAutoCloseTimeAttribute( @@ -28132,40 +28137,6 @@ public void onSuccess(byte[] tlv) { }, TARGET_STATE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readStartUpStateAttribute( - IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_STATE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_STATE_ATTRIBUTE_ID, true); - } - - public void writeStartUpStateAttribute(DefaultClusterCallback callback, Integer value) { - writeStartUpStateAttribute(callback, value, 0); - } - - public void writeStartUpStateAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = new UIntType(value); - writeAttribute(new WriteAttributesCallbackImpl(callback), START_UP_STATE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeStartUpStateAttribute( - IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_STATE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - } - }, START_UP_STATE_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readCurrentLevelAttribute( CurrentLevelAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LEVEL_ATTRIBUTE_ID); @@ -28216,38 +28187,38 @@ public void onSuccess(byte[] tlv) { }, TARGET_LEVEL_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readOpenLevelAttribute( - OpenLevelAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, OPEN_LEVEL_ATTRIBUTE_ID); + public void readDefaultOpenLevelAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_OPEN_LEVEL_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, OPEN_LEVEL_ATTRIBUTE_ID, true); + }, DEFAULT_OPEN_LEVEL_ATTRIBUTE_ID, true); } - public void writeOpenLevelAttribute(DefaultClusterCallback callback, Integer value) { - writeOpenLevelAttribute(callback, value, 0); + public void writeDefaultOpenLevelAttribute(DefaultClusterCallback callback, Integer value) { + writeDefaultOpenLevelAttribute(callback, value, 0); } - public void writeOpenLevelAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), OPEN_LEVEL_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + public void writeDefaultOpenLevelAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), DEFAULT_OPEN_LEVEL_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); } - public void subscribeOpenLevelAttribute( - OpenLevelAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, OPEN_LEVEL_ATTRIBUTE_ID); + public void subscribeDefaultOpenLevelAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEFAULT_OPEN_LEVEL_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); } - }, OPEN_LEVEL_ATTRIBUTE_ID, minInterval, maxInterval); + }, DEFAULT_OPEN_LEVEL_ATTRIBUTE_ID, minInterval, maxInterval); } public void readValveFaultAttribute( diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index 4ad4fd533b207d..b140401dcc6689 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -3016,17 +3016,22 @@ public String toString() { } public static class ValveConfigurationAndControlClusterValveStateChangedEvent { public Integer valveState; + public Optional valveLevel; private static final long VALVE_STATE_ID = 0L; + private static final long VALVE_LEVEL_ID = 1L; public ValveConfigurationAndControlClusterValveStateChangedEvent( - Integer valveState + Integer valveState, + Optional valveLevel ) { this.valveState = valveState; + this.valveLevel = valveLevel; } public StructType encodeTlv() { ArrayList values = new ArrayList<>(); values.add(new StructElement(VALVE_STATE_ID, new UIntType(valveState))); + values.add(new StructElement(VALVE_LEVEL_ID, valveLevel.map((nonOptionalvalveLevel) -> new UIntType(nonOptionalvalveLevel)).orElse(new EmptyType()))); return new StructType(values); } @@ -3036,16 +3041,23 @@ public static ValveConfigurationAndControlClusterValveStateChangedEvent decodeTl return null; } Integer valveState = null; + Optional valveLevel = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == VALVE_STATE_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); valveState = castingValue.value(Integer.class); } + } else if (element.contextTagNum() == VALVE_LEVEL_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + valveLevel = Optional.of(castingValue.value(Integer.class)); + } } } return new ValveConfigurationAndControlClusterValveStateChangedEvent( - valveState + valveState, + valveLevel ); } @@ -3056,6 +3068,9 @@ public String toString() { output.append("\tvalveState: "); output.append(valveState); output.append("\n"); + output.append("\tvalveLevel: "); + output.append(valveLevel); + 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 3b44c508979b8e..28503ea511d188 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -8922,14 +8922,14 @@ public long getID() { public enum Attribute { OpenDuration(0L), - AutoCloseTime(1L), - RemainingDuration(2L), - CurrentState(3L), - TargetState(4L), - StartUpState(5L), + DefaultOpenDuration(1L), + AutoCloseTime(2L), + RemainingDuration(3L), + CurrentState(4L), + TargetState(5L), CurrentLevel(6L), TargetLevel(7L), - OpenLevel(8L), + DefaultOpenLevel(8L), ValveFault(9L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), @@ -8980,8 +8980,7 @@ public static Event value(long id) throws NoSuchFieldError { public enum Command { Open(0L), - Close(1L), - SetLevel(2L),; + Close(1L),; private final long id; Command(long id) { this.id = id; @@ -8999,7 +8998,7 @@ public static Command value(long id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }public enum OpenCommandField {OpenDuration(0),; + }public enum OpenCommandField {OpenDuration(0),TargetLevel(1),; private final int id; OpenCommandField(int id) { this.id = id; @@ -9016,23 +9015,6 @@ public static OpenCommandField value(int id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }public enum SetLevelCommandField {Level(0),OpenDuration(1),; - private final int id; - SetLevelCommandField(int id) { - this.id = id; - } - - public int getID() { - return id; - } - public static SetLevelCommandField value(int id) throws NoSuchFieldError { - for (SetLevelCommandField field : SetLevelCommandField.values()) { - if (field.getID() == id) { - return field; - } - } - throw new NoSuchFieldError(); - } }@Override public String getAttributeName(long id) throws NoSuchFieldError { return Attribute.value(id).toString(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 390cd09f42544c..601c43a38b210f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -9777,7 +9777,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterAutoCloseTimeAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.AutoCloseTimeAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterDefaultOpenDurationAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.DefaultOpenDurationAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -9798,7 +9798,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterRemainingDurationAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.RemainingDurationAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterAutoCloseTimeAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.AutoCloseTimeAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -9819,7 +9819,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterCurrentStateAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.CurrentStateAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterRemainingDurationAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.RemainingDurationAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -9827,9 +9827,9 @@ public void setCallbackDelegate(ClusterCommandCallback callback) { } @Override - public void onSuccess(@Nullable Integer value) { + public void onSuccess(@Nullable Long value) { Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); responseValues.put(commandResponseInfo, value); callback.onSuccess(responseValues); } @@ -9840,7 +9840,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterTargetStateAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.TargetStateAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterCurrentStateAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.CurrentStateAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -9861,7 +9861,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterCurrentLevelAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.CurrentLevelAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterTargetStateAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.TargetStateAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -9882,7 +9882,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterTargetLevelAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.TargetLevelAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterCurrentLevelAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.CurrentLevelAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -9903,7 +9903,7 @@ public void onError(Exception ex) { } } - public static class DelegatedValveConfigurationAndControlClusterOpenLevelAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.OpenLevelAttributeCallback, DelegatedClusterCallback { + public static class DelegatedValveConfigurationAndControlClusterTargetLevelAttributeCallback implements ChipClusters.ValveConfigurationAndControlCluster.TargetLevelAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -22707,12 +22707,17 @@ public Map> getCommandMap() { CommandParameterInfo valveConfigurationAndControlopenopenDurationCommandParameterInfo = new CommandParameterInfo("openDuration", Optional.class, Long.class); valveConfigurationAndControlopenCommandParams.put("openDuration",valveConfigurationAndControlopenopenDurationCommandParameterInfo); + + CommandParameterInfo valveConfigurationAndControlopentargetLevelCommandParameterInfo = new CommandParameterInfo("targetLevel", Optional.class, Integer.class); + valveConfigurationAndControlopenCommandParams.put("targetLevel",valveConfigurationAndControlopentargetLevelCommandParameterInfo); InteractionInfo valveConfigurationAndControlopenInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.ValveConfigurationAndControlCluster) cluster) .open((DefaultClusterCallback) callback , (Optional) commandArguments.get("openDuration") + , (Optional) + commandArguments.get("targetLevel") ); }, () -> new DelegatedDefaultClusterCallback(), @@ -22732,28 +22737,6 @@ public Map> getCommandMap() { ); valveConfigurationAndControlClusterInteractionInfoMap.put("close", valveConfigurationAndControlcloseInteractionInfo); - Map valveConfigurationAndControlsetLevelCommandParams = new LinkedHashMap(); - - CommandParameterInfo valveConfigurationAndControlsetLevellevelCommandParameterInfo = new CommandParameterInfo("level", Integer.class, Integer.class); - valveConfigurationAndControlsetLevelCommandParams.put("level",valveConfigurationAndControlsetLevellevelCommandParameterInfo); - - CommandParameterInfo valveConfigurationAndControlsetLevelopenDurationCommandParameterInfo = new CommandParameterInfo("openDuration", Optional.class, Long.class); - valveConfigurationAndControlsetLevelCommandParams.put("openDuration",valveConfigurationAndControlsetLevelopenDurationCommandParameterInfo); - InteractionInfo valveConfigurationAndControlsetLevelInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ValveConfigurationAndControlCluster) cluster) - .setLevel((DefaultClusterCallback) callback - , (Integer) - commandArguments.get("level") - , (Optional) - commandArguments.get("openDuration") - ); - }, - () -> new DelegatedDefaultClusterCallback(), - valveConfigurationAndControlsetLevelCommandParams - ); - valveConfigurationAndControlClusterInteractionInfoMap.put("setLevel", valveConfigurationAndControlsetLevelInteractionInfo); - commandMap.put("valveConfigurationAndControl", valveConfigurationAndControlClusterInteractionInfoMap); Map electricalEnergyMeasurementClusterInteractionInfoMap = new LinkedHashMap<>(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 5e36aca034a4c2..3ff5881314f8a3 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -8807,6 +8807,17 @@ private static Map readValveConfigurationAndControlInte readValveConfigurationAndControlOpenDurationCommandParams ); result.put("readOpenDurationAttribute", readValveConfigurationAndControlOpenDurationAttributeInteractionInfo); + Map readValveConfigurationAndControlDefaultOpenDurationCommandParams = new LinkedHashMap(); + InteractionInfo readValveConfigurationAndControlDefaultOpenDurationAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ValveConfigurationAndControlCluster) cluster).readDefaultOpenDurationAttribute( + (ChipClusters.ValveConfigurationAndControlCluster.DefaultOpenDurationAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedValveConfigurationAndControlClusterDefaultOpenDurationAttributeCallback(), + readValveConfigurationAndControlDefaultOpenDurationCommandParams + ); + result.put("readDefaultOpenDurationAttribute", readValveConfigurationAndControlDefaultOpenDurationAttributeInteractionInfo); Map readValveConfigurationAndControlAutoCloseTimeCommandParams = new LinkedHashMap(); InteractionInfo readValveConfigurationAndControlAutoCloseTimeAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -8851,17 +8862,6 @@ private static Map readValveConfigurationAndControlInte readValveConfigurationAndControlTargetStateCommandParams ); result.put("readTargetStateAttribute", readValveConfigurationAndControlTargetStateAttributeInteractionInfo); - Map readValveConfigurationAndControlStartUpStateCommandParams = new LinkedHashMap(); - InteractionInfo readValveConfigurationAndControlStartUpStateAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ValveConfigurationAndControlCluster) cluster).readStartUpStateAttribute( - (ChipClusters.IntegerAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), - readValveConfigurationAndControlStartUpStateCommandParams - ); - result.put("readStartUpStateAttribute", readValveConfigurationAndControlStartUpStateAttributeInteractionInfo); Map readValveConfigurationAndControlCurrentLevelCommandParams = new LinkedHashMap(); InteractionInfo readValveConfigurationAndControlCurrentLevelAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -8884,17 +8884,17 @@ private static Map readValveConfigurationAndControlInte readValveConfigurationAndControlTargetLevelCommandParams ); result.put("readTargetLevelAttribute", readValveConfigurationAndControlTargetLevelAttributeInteractionInfo); - Map readValveConfigurationAndControlOpenLevelCommandParams = new LinkedHashMap(); - InteractionInfo readValveConfigurationAndControlOpenLevelAttributeInteractionInfo = new InteractionInfo( + Map readValveConfigurationAndControlDefaultOpenLevelCommandParams = new LinkedHashMap(); + InteractionInfo readValveConfigurationAndControlDefaultOpenLevelAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.ValveConfigurationAndControlCluster) cluster).readOpenLevelAttribute( - (ChipClusters.ValveConfigurationAndControlCluster.OpenLevelAttributeCallback) callback + ((ChipClusters.ValveConfigurationAndControlCluster) cluster).readDefaultOpenLevelAttribute( + (ChipClusters.IntegerAttributeCallback) callback ); }, - () -> new ClusterInfoMapping.DelegatedValveConfigurationAndControlClusterOpenLevelAttributeCallback(), - readValveConfigurationAndControlOpenLevelCommandParams + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readValveConfigurationAndControlDefaultOpenLevelCommandParams ); - result.put("readOpenLevelAttribute", readValveConfigurationAndControlOpenLevelAttributeInteractionInfo); + result.put("readDefaultOpenLevelAttribute", readValveConfigurationAndControlDefaultOpenLevelAttributeInteractionInfo); Map readValveConfigurationAndControlValveFaultCommandParams = new LinkedHashMap(); InteractionInfo readValveConfigurationAndControlValveFaultAttributeInteractionInfo = 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 3db35dfd2b3970..6eb5f233a5d3db 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -1189,72 +1189,50 @@ public Map> getWriteAttributeMap() { writeBooleanStateConfigurationInteractionInfo.put("writeCurrentSensitivityLevelAttribute", writeBooleanStateConfigurationCurrentSensitivityLevelAttributeInteractionInfo); writeAttributeMap.put("booleanStateConfiguration", writeBooleanStateConfigurationInteractionInfo); Map writeValveConfigurationAndControlInteractionInfo = new LinkedHashMap<>(); - Map writeValveConfigurationAndControlOpenDurationCommandParams = new LinkedHashMap(); - CommandParameterInfo valveConfigurationAndControlopenDurationCommandParameterInfo = + Map writeValveConfigurationAndControlDefaultOpenDurationCommandParams = new LinkedHashMap(); + CommandParameterInfo valveConfigurationAndControldefaultOpenDurationCommandParameterInfo = new CommandParameterInfo( "value", Long.class, Long.class ); - writeValveConfigurationAndControlOpenDurationCommandParams.put( + writeValveConfigurationAndControlDefaultOpenDurationCommandParams.put( "value", - valveConfigurationAndControlopenDurationCommandParameterInfo + valveConfigurationAndControldefaultOpenDurationCommandParameterInfo ); - InteractionInfo writeValveConfigurationAndControlOpenDurationAttributeInteractionInfo = new InteractionInfo( + InteractionInfo writeValveConfigurationAndControlDefaultOpenDurationAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.ValveConfigurationAndControlCluster) cluster).writeOpenDurationAttribute( + ((ChipClusters.ValveConfigurationAndControlCluster) cluster).writeDefaultOpenDurationAttribute( (DefaultClusterCallback) callback, (Long) commandArguments.get("value") ); }, () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeValveConfigurationAndControlOpenDurationCommandParams + writeValveConfigurationAndControlDefaultOpenDurationCommandParams ); - writeValveConfigurationAndControlInteractionInfo.put("writeOpenDurationAttribute", writeValveConfigurationAndControlOpenDurationAttributeInteractionInfo); - Map writeValveConfigurationAndControlStartUpStateCommandParams = new LinkedHashMap(); - CommandParameterInfo valveConfigurationAndControlstartUpStateCommandParameterInfo = + writeValveConfigurationAndControlInteractionInfo.put("writeDefaultOpenDurationAttribute", writeValveConfigurationAndControlDefaultOpenDurationAttributeInteractionInfo); + Map writeValveConfigurationAndControlDefaultOpenLevelCommandParams = new LinkedHashMap(); + CommandParameterInfo valveConfigurationAndControldefaultOpenLevelCommandParameterInfo = new CommandParameterInfo( "value", Integer.class, Integer.class ); - writeValveConfigurationAndControlStartUpStateCommandParams.put( + writeValveConfigurationAndControlDefaultOpenLevelCommandParams.put( "value", - valveConfigurationAndControlstartUpStateCommandParameterInfo + valveConfigurationAndControldefaultOpenLevelCommandParameterInfo ); - InteractionInfo writeValveConfigurationAndControlStartUpStateAttributeInteractionInfo = new InteractionInfo( + InteractionInfo writeValveConfigurationAndControlDefaultOpenLevelAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.ValveConfigurationAndControlCluster) cluster).writeStartUpStateAttribute( + ((ChipClusters.ValveConfigurationAndControlCluster) cluster).writeDefaultOpenLevelAttribute( (DefaultClusterCallback) callback, (Integer) commandArguments.get("value") ); }, () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeValveConfigurationAndControlStartUpStateCommandParams + writeValveConfigurationAndControlDefaultOpenLevelCommandParams ); - writeValveConfigurationAndControlInteractionInfo.put("writeStartUpStateAttribute", writeValveConfigurationAndControlStartUpStateAttributeInteractionInfo); - Map writeValveConfigurationAndControlOpenLevelCommandParams = new LinkedHashMap(); - CommandParameterInfo valveConfigurationAndControlopenLevelCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeValveConfigurationAndControlOpenLevelCommandParams.put( - "value", - valveConfigurationAndControlopenLevelCommandParameterInfo - ); - InteractionInfo writeValveConfigurationAndControlOpenLevelAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ValveConfigurationAndControlCluster) cluster).writeOpenLevelAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeValveConfigurationAndControlOpenLevelCommandParams - ); - writeValveConfigurationAndControlInteractionInfo.put("writeOpenLevelAttribute", writeValveConfigurationAndControlOpenLevelAttributeInteractionInfo); + writeValveConfigurationAndControlInteractionInfo.put("writeDefaultOpenLevelAttribute", writeValveConfigurationAndControlDefaultOpenLevelAttributeInteractionInfo); writeAttributeMap.put("valveConfigurationAndControl", writeValveConfigurationAndControlInteractionInfo); Map writeElectricalEnergyMeasurementInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("electricalEnergyMeasurement", writeElectricalEnergyMeasurementInteractionInfo); diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt index d015f73b2e61b5..e34e14aee60c7d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt @@ -17,15 +17,20 @@ package chip.devicecontroller.cluster.eventstructs 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 ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: UInt) { +class ValveConfigurationAndControlClusterValveStateChangedEvent( + val valveState: UInt, + val valveLevel: Optional +) { override fun toString(): String = buildString { append("ValveConfigurationAndControlClusterValveStateChangedEvent {\n") append("\tvalveState : $valveState\n") + append("\tvalveLevel : $valveLevel\n") append("}\n") } @@ -33,12 +38,17 @@ class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: tlvWriter.apply { startStructure(tlvTag) put(ContextSpecificTag(TAG_VALVE_STATE), valveState) + if (valveLevel.isPresent) { + val optvalveLevel = valveLevel.get() + put(ContextSpecificTag(TAG_VALVE_LEVEL), optvalveLevel) + } endStructure() } } companion object { private const val TAG_VALVE_STATE = 0 + private const val TAG_VALVE_LEVEL = 1 fun fromTlv( tlvTag: Tag, @@ -46,10 +56,16 @@ class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: ): ValveConfigurationAndControlClusterValveStateChangedEvent { tlvReader.enterStructure(tlvTag) val valveState = tlvReader.getUInt(ContextSpecificTag(TAG_VALVE_STATE)) + val valveLevel = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_VALVE_LEVEL))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_VALVE_LEVEL))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return ValveConfigurationAndControlClusterValveStateChangedEvent(valveState) + return ValveConfigurationAndControlClusterValveStateChangedEvent(valveState, valveLevel) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt index 1ca214354c7f19..155fa8d43e4232 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt @@ -57,6 +57,16 @@ class ValveConfigurationAndControlCluster( object SubscriptionEstablished : OpenDurationAttributeSubscriptionState() } + class DefaultOpenDurationAttribute(val value: UInt?) + + sealed class DefaultOpenDurationAttributeSubscriptionState { + data class Success(val value: UInt?) : DefaultOpenDurationAttributeSubscriptionState() + + data class Error(val exception: Exception) : DefaultOpenDurationAttributeSubscriptionState() + + object SubscriptionEstablished : DefaultOpenDurationAttributeSubscriptionState() + } + class AutoCloseTimeAttribute(val value: ULong?) sealed class AutoCloseTimeAttributeSubscriptionState { @@ -117,16 +127,6 @@ class ValveConfigurationAndControlCluster( object SubscriptionEstablished : TargetLevelAttributeSubscriptionState() } - class OpenLevelAttribute(val value: UByte?) - - sealed class OpenLevelAttributeSubscriptionState { - data class Success(val value: UByte?) : OpenLevelAttributeSubscriptionState() - - data class Error(val exception: Exception) : OpenLevelAttributeSubscriptionState() - - object SubscriptionEstablished : OpenLevelAttributeSubscriptionState() - } - class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -167,7 +167,7 @@ class ValveConfigurationAndControlCluster( object SubscriptionEstablished : AttributeListAttributeSubscriptionState() } - suspend fun open(openDuration: UInt?, timedInvokeTimeout: Duration? = null) { + suspend fun open(openDuration: UInt?, targetLevel: UByte?, timedInvokeTimeout: Duration? = null) { val commandId: UInt = 0u val tlvWriter = TlvWriter() @@ -175,6 +175,9 @@ class ValveConfigurationAndControlCluster( val TAG_OPEN_DURATION_REQ: Int = 0 openDuration?.let { tlvWriter.put(ContextSpecificTag(TAG_OPEN_DURATION_REQ), openDuration) } + + val TAG_TARGET_LEVEL_REQ: Int = 1 + targetLevel?.let { tlvWriter.put(ContextSpecificTag(TAG_TARGET_LEVEL_REQ), targetLevel) } tlvWriter.endStructure() val request: InvokeRequest = @@ -206,30 +209,6 @@ class ValveConfigurationAndControlCluster( logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun setLevel(level: UByte, openDuration: UInt?, timedInvokeTimeout: Duration? = null) { - val commandId: UInt = 2u - - val tlvWriter = TlvWriter() - tlvWriter.startStructure(AnonymousTag) - - val TAG_LEVEL_REQ: Int = 0 - tlvWriter.put(ContextSpecificTag(TAG_LEVEL_REQ), level) - - val TAG_OPEN_DURATION_REQ: Int = 1 - openDuration?.let { tlvWriter.put(ContextSpecificTag(TAG_OPEN_DURATION_REQ), openDuration) } - 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}") - } - suspend fun readOpenDurationAttribute(): OpenDurationAttribute { val ATTRIBUTE_ID: UInt = 0u @@ -267,46 +246,6 @@ class ValveConfigurationAndControlCluster( return OpenDurationAttribute(decodedValue) } - suspend fun writeOpenDurationAttribute(value: UInt, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 0u - - 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 subscribeOpenDurationAttribute( minInterval: Int, maxInterval: Int @@ -363,7 +302,7 @@ class ValveConfigurationAndControlCluster( } } - suspend fun readAutoCloseTimeAttribute(): AutoCloseTimeAttribute { + suspend fun readDefaultOpenDurationAttribute(): DefaultOpenDurationAttribute { val ATTRIBUTE_ID: UInt = 1u val attributePath = @@ -385,29 +324,65 @@ class ValveConfigurationAndControlCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Autoclosetime attribute not found in response" } + requireNotNull(attributeData) { "Defaultopenduration attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: ULong? = + val decodedValue: UInt? = if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getULong(AnonymousTag) - } else { - null - } + tlvReader.getUInt(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return AutoCloseTimeAttribute(decodedValue) + return DefaultOpenDurationAttribute(decodedValue) } - suspend fun subscribeAutoCloseTimeAttribute( + suspend fun writeDefaultOpenDurationAttribute(value: UInt, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 1u + + 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 subscribeDefaultOpenDurationAttribute( minInterval: Int, maxInterval: Int - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 1u val attributePaths = listOf( @@ -426,7 +401,7 @@ class ValveConfigurationAndControlCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - AutoCloseTimeAttributeSubscriptionState.Error( + DefaultOpenDurationAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -439,32 +414,30 @@ class ValveConfigurationAndControlCluster( .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Autoclosetime attribute not found in Node State update" } + requireNotNull(attributeData) { + "Defaultopenduration 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: UInt? = if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getULong(AnonymousTag) - } else { - null - } + tlvReader.getUInt(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(AutoCloseTimeAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(DefaultOpenDurationAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(AutoCloseTimeAttributeSubscriptionState.SubscriptionEstablished) + emit(DefaultOpenDurationAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readRemainingDurationAttribute(): RemainingDurationAttribute { + suspend fun readAutoCloseTimeAttribute(): AutoCloseTimeAttribute { val ATTRIBUTE_ID: UInt = 2u val attributePath = @@ -486,14 +459,14 @@ class ValveConfigurationAndControlCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Remainingduration attribute not found in response" } + requireNotNull(attributeData) { "Autoclosetime attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UInt? = + val decodedValue: ULong? = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUInt(AnonymousTag) + tlvReader.getULong(AnonymousTag) } else { null } @@ -502,13 +475,13 @@ class ValveConfigurationAndControlCluster( null } - return RemainingDurationAttribute(decodedValue) + return AutoCloseTimeAttribute(decodedValue) } - suspend fun subscribeRemainingDurationAttribute( + suspend fun subscribeAutoCloseTimeAttribute( minInterval: Int, maxInterval: Int - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 2u val attributePaths = listOf( @@ -527,7 +500,7 @@ class ValveConfigurationAndControlCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - RemainingDurationAttributeSubscriptionState.Error( + AutoCloseTimeAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -540,16 +513,14 @@ class ValveConfigurationAndControlCluster( .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Remainingduration attribute not found in Node State update" - } + requireNotNull(attributeData) { "Autoclosetime 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: ULong? = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUInt(AnonymousTag) + tlvReader.getULong(AnonymousTag) } else { null } @@ -558,16 +529,16 @@ class ValveConfigurationAndControlCluster( null } - decodedValue?.let { emit(RemainingDurationAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(AutoCloseTimeAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(RemainingDurationAttributeSubscriptionState.SubscriptionEstablished) + emit(AutoCloseTimeAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readCurrentStateAttribute(): CurrentStateAttribute { + suspend fun readRemainingDurationAttribute(): RemainingDurationAttribute { val ATTRIBUTE_ID: UInt = 3u val attributePath = @@ -589,25 +560,25 @@ class ValveConfigurationAndControlCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Currentstate attribute not found in response" } + requireNotNull(attributeData) { "Remainingduration attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = + val decodedValue: UInt? = if (!tlvReader.isNull()) { - tlvReader.getUByte(AnonymousTag) + tlvReader.getUInt(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return CurrentStateAttribute(decodedValue) + return RemainingDurationAttribute(decodedValue) } - suspend fun subscribeCurrentStateAttribute( + suspend fun subscribeRemainingDurationAttribute( minInterval: Int, maxInterval: Int - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 3u val attributePaths = listOf( @@ -626,7 +597,7 @@ class ValveConfigurationAndControlCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - CurrentStateAttributeSubscriptionState.Error( + RemainingDurationAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -639,28 +610,30 @@ class ValveConfigurationAndControlCluster( .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Currentstate attribute not found in Node State update" } + requireNotNull(attributeData) { + "Remainingduration attribute not found in Node State update" + } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = + val decodedValue: UInt? = if (!tlvReader.isNull()) { - tlvReader.getUByte(AnonymousTag) + tlvReader.getUInt(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(CurrentStateAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(RemainingDurationAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(CurrentStateAttributeSubscriptionState.SubscriptionEstablished) + emit(RemainingDurationAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readTargetStateAttribute(): TargetStateAttribute { + suspend fun readCurrentStateAttribute(): CurrentStateAttribute { val ATTRIBUTE_ID: UInt = 4u val attributePath = @@ -682,7 +655,7 @@ class ValveConfigurationAndControlCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Targetstate attribute not found in response" } + requireNotNull(attributeData) { "Currentstate attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -694,13 +667,13 @@ class ValveConfigurationAndControlCluster( null } - return TargetStateAttribute(decodedValue) + return CurrentStateAttribute(decodedValue) } - suspend fun subscribeTargetStateAttribute( + suspend fun subscribeCurrentStateAttribute( minInterval: Int, maxInterval: Int - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 4u val attributePaths = listOf( @@ -719,7 +692,7 @@ class ValveConfigurationAndControlCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - TargetStateAttributeSubscriptionState.Error( + CurrentStateAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -732,7 +705,7 @@ class ValveConfigurationAndControlCluster( .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Targetstate attribute not found in Node State update" } + requireNotNull(attributeData) { "Currentstate attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -744,16 +717,16 @@ class ValveConfigurationAndControlCluster( null } - decodedValue?.let { emit(TargetStateAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(CurrentStateAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(TargetStateAttributeSubscriptionState.SubscriptionEstablished) + emit(CurrentStateAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readStartUpStateAttribute(): UByte? { + suspend fun readTargetStateAttribute(): TargetStateAttribute { val ATTRIBUTE_ID: UInt = 5u val attributePath = @@ -775,64 +748,25 @@ class ValveConfigurationAndControlCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Startupstate attribute not found in response" } + requireNotNull(attributeData) { "Targetstate attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) val decodedValue: UByte? = - if (tlvReader.isNextTag(AnonymousTag)) { + if (!tlvReader.isNull()) { tlvReader.getUByte(AnonymousTag) } else { + tlvReader.getNull(AnonymousTag) null } - return decodedValue - } - - suspend fun writeStartUpStateAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 5u - - 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") - } - } + return TargetStateAttribute(decodedValue) } - suspend fun subscribeStartUpStateAttribute( + suspend fun subscribeTargetStateAttribute( minInterval: Int, maxInterval: Int - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 5u val attributePaths = listOf( @@ -851,7 +785,7 @@ class ValveConfigurationAndControlCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - UByteSubscriptionState.Error( + TargetStateAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -864,21 +798,22 @@ class ValveConfigurationAndControlCluster( .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Startupstate attribute not found in Node State update" } + requireNotNull(attributeData) { "Targetstate 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.isNextTag(AnonymousTag)) { + if (!tlvReader.isNull()) { tlvReader.getUByte(AnonymousTag) } else { + tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } + decodedValue?.let { emit(TargetStateAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(UByteSubscriptionState.SubscriptionEstablished) + emit(TargetStateAttributeSubscriptionState.SubscriptionEstablished) } } } @@ -1086,7 +1021,7 @@ class ValveConfigurationAndControlCluster( } } - suspend fun readOpenLevelAttribute(): OpenLevelAttribute { + suspend fun readDefaultOpenLevelAttribute(): UByte? { val ATTRIBUTE_ID: UInt = 8u val attributePath = @@ -1108,26 +1043,21 @@ class ValveConfigurationAndControlCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Openlevel attribute not found in response" } + requireNotNull(attributeData) { "Defaultopenlevel attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) } else { - tlvReader.getNull(AnonymousTag) null } - return OpenLevelAttribute(decodedValue) + return decodedValue } - suspend fun writeOpenLevelAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + suspend fun writeDefaultOpenLevelAttribute(value: UByte, timedWriteTimeout: Duration? = null) { val ATTRIBUTE_ID: UInt = 8u val tlvWriter = TlvWriter() @@ -1167,10 +1097,10 @@ class ValveConfigurationAndControlCluster( } } - suspend fun subscribeOpenLevelAttribute( + suspend fun subscribeDefaultOpenLevelAttribute( minInterval: Int, maxInterval: Int - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 8u val attributePaths = listOf( @@ -1189,7 +1119,7 @@ class ValveConfigurationAndControlCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - OpenLevelAttributeSubscriptionState.Error( + UByteSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -1202,26 +1132,23 @@ class ValveConfigurationAndControlCluster( .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Openlevel attribute not found in Node State update" } + requireNotNull(attributeData) { + "Defaultopenlevel 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()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) } else { - tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(OpenLevelAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(OpenLevelAttributeSubscriptionState.SubscriptionEstablished) + emit(UByteSubscriptionState.SubscriptionEstablished) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt index 4ff645d6acaf8c..c12b94b0e375bf 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt @@ -16,16 +16,21 @@ */ package matter.controller.cluster.eventstructs +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 ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: UByte) { +class ValveConfigurationAndControlClusterValveStateChangedEvent( + val valveState: UByte, + val valveLevel: Optional +) { override fun toString(): String = buildString { append("ValveConfigurationAndControlClusterValveStateChangedEvent {\n") append("\tvalveState : $valveState\n") + append("\tvalveLevel : $valveLevel\n") append("}\n") } @@ -33,12 +38,17 @@ class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: tlvWriter.apply { startStructure(tlvTag) put(ContextSpecificTag(TAG_VALVE_STATE), valveState) + if (valveLevel.isPresent) { + val optvalveLevel = valveLevel.get() + put(ContextSpecificTag(TAG_VALVE_LEVEL), optvalveLevel) + } endStructure() } } companion object { private const val TAG_VALVE_STATE = 0 + private const val TAG_VALVE_LEVEL = 1 fun fromTlv( tlvTag: Tag, @@ -46,10 +56,16 @@ class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: ): ValveConfigurationAndControlClusterValveStateChangedEvent { tlvReader.enterStructure(tlvTag) val valveState = tlvReader.getUByte(ContextSpecificTag(TAG_VALVE_STATE)) + val valveLevel = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_VALVE_LEVEL))) { + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_VALVE_LEVEL))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return ValveConfigurationAndControlClusterValveStateChangedEvent(valveState) + return ValveConfigurationAndControlClusterValveStateChangedEvent(valveState, valveLevel) } } } diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 5fba45d25734e3..3732f1a9629a7e 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -19078,6 +19078,29 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } + case Attributes::DefaultOpenDuration::Id: { + using TypeInfo = Attributes::DefaultOpenDuration::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/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } case Attributes::AutoCloseTime::Id: { using TypeInfo = Attributes::AutoCloseTime::TypeInfo; TypeInfo::DecodableType cppValue; @@ -19170,22 +19193,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::StartUpState::Id: { - using TypeInfo = Attributes::StartUpState::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::CurrentLevel::Id: { using TypeInfo = Attributes::CurrentLevel::TypeInfo; TypeInfo::DecodableType cppValue; @@ -19232,8 +19239,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::OpenLevel::Id: { - using TypeInfo = Attributes::OpenLevel::TypeInfo; + case Attributes::DefaultOpenLevel::Id: { + using TypeInfo = Attributes::DefaultOpenLevel::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -19241,18 +19248,11 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR 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); - } + 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::ValveFault::Id: { diff --git a/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp b/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp index d5b8cec9d91b2f..4abaeb56cf5901 100644 --- a/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp @@ -3340,12 +3340,12 @@ JNI_METHOD(void, BooleanStateConfigurationCluster, writeCurrentSensitivityLevelA onFailure.release(); } -JNI_METHOD(void, ValveConfigurationAndControlCluster, writeOpenDurationAttribute) +JNI_METHOD(void, ValveConfigurationAndControlCluster, writeDefaultOpenDurationAttribute) (JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) { chip::DeviceLayer::StackLock lock; ListFreer listFreer; - using TypeInfo = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + using TypeInfo = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenDuration::TypeInfo; TypeInfo::Type cppValue; std::vector> cleanupByteArrays; @@ -3400,12 +3400,12 @@ JNI_METHOD(void, ValveConfigurationAndControlCluster, writeOpenDurationAttribute onFailure.release(); } -JNI_METHOD(void, ValveConfigurationAndControlCluster, writeStartUpStateAttribute) +JNI_METHOD(void, ValveConfigurationAndControlCluster, writeDefaultOpenLevelAttribute) (JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) { chip::DeviceLayer::StackLock lock; ListFreer listFreer; - using TypeInfo = chip::app::Clusters::ValveConfigurationAndControl::Attributes::StartUpState::TypeInfo; + using TypeInfo = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenLevel::TypeInfo; TypeInfo::Type cppValue; std::vector> cleanupByteArrays; @@ -3452,66 +3452,6 @@ JNI_METHOD(void, ValveConfigurationAndControlCluster, writeStartUpStateAttribute onFailure.release(); } -JNI_METHOD(void, ValveConfigurationAndControlCluster, writeOpenLevelAttribute) -(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) -{ - chip::DeviceLayer::StackLock lock; - ListFreer listFreer; - using TypeInfo = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenLevel::TypeInfo; - TypeInfo::Type cppValue; - - std::vector> cleanupByteArrays; - std::vector> cleanupStrings; - - if (value == nullptr) - { - cppValue.SetNull(); - } - else - { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = static_cast>( - chip::JniReferences::GetInstance().IntegerToPrimitive(value)); - } - - std::unique_ptr onSuccess( - Platform::New(callback), Platform::Delete); - VerifyOrReturn(onSuccess.get() != nullptr, - chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( - env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY)); - - std::unique_ptr onFailure( - Platform::New(callback), Platform::Delete); - VerifyOrReturn(onFailure.get() != nullptr, - chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( - env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY)); - - CHIP_ERROR err = CHIP_NO_ERROR; - ValveConfigurationAndControlCluster * cppCluster = reinterpret_cast(clusterPtr); - VerifyOrReturn(cppCluster != nullptr, - chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( - env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE)); - - auto successFn = chip::Callback::Callback::FromCancelable(onSuccess->Cancel()); - auto failureFn = chip::Callback::Callback::FromCancelable(onFailure->Cancel()); - - if (timedWriteTimeoutMs == nullptr) - { - err = cppCluster->WriteAttribute(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall); - } - else - { - err = cppCluster->WriteAttribute(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall, - chip::JniReferences::GetInstance().IntegerToPrimitive(timedWriteTimeoutMs)); - } - VerifyOrReturn( - err == CHIP_NO_ERROR, - chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error writing attribute", err)); - - onSuccess.release(); - onFailure.release(); -} - JNI_METHOD(void, DemandResponseLoadControlCluster, writeDefaultRandomStartAttribute) (JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) { diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 997cccac866bde..ed6b539e8539f3 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -3782,6 +3782,23 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & chip::JniReferences::GetInstance().CreateBoxedObject( value_valveStateClassName.c_str(), value_valveStateCtorSignature.c_str(), jnivalue_valveState, value_valveState); + jobject value_valveLevel; + if (!cppValue.valveLevel.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_valveLevel); + } + else + { + jobject value_valveLevelInsideOptional; + std::string value_valveLevelInsideOptionalClassName = "java/lang/Integer"; + std::string value_valveLevelInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_valveLevelInsideOptional = static_cast(cppValue.valveLevel.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_valveLevelInsideOptionalClassName.c_str(), value_valveLevelInsideOptionalCtorSignature.c_str(), + jnivalue_valveLevelInsideOptional, value_valveLevelInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_valveLevelInsideOptional, value_valveLevel); + } + jclass valveStateChangedStructClass; err = chip::JniReferences::GetInstance().GetClassRef( env, "chip/devicecontroller/ChipEventStructs$ValveConfigurationAndControlClusterValveStateChangedEvent", @@ -3793,7 +3810,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } jmethodID valveStateChangedStructCtor = - env->GetMethodID(valveStateChangedStructClass, "", "(Ljava/lang/Integer;)V"); + env->GetMethodID(valveStateChangedStructClass, "", "(Ljava/lang/Integer;Ljava/util/Optional;)V"); if (valveStateChangedStructCtor == nullptr) { ChipLogError( @@ -3801,7 +3818,8 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } - jobject value = env->NewObject(valveStateChangedStructClass, valveStateChangedStructCtor, value_valveState); + jobject value = + env->NewObject(valveStateChangedStructClass, valveStateChangedStructCtor, value_valveState, value_valveLevel); return value; } diff --git a/src/controller/java/zap-generated/CHIPReadCallbacks.cpp b/src/controller/java/zap-generated/CHIPReadCallbacks.cpp index f2c06db10fea72..430db0fb5988e7 100644 --- a/src/controller/java/zap-generated/CHIPReadCallbacks.cpp +++ b/src/controller/java/zap-generated/CHIPReadCallbacks.cpp @@ -30081,9 +30081,9 @@ void CHIPValveConfigurationAndControlOpenDurationAttributeCallback::CallbackFn( env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback( - jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), +CHIPValveConfigurationAndControlDefaultOpenDurationAttributeCallback:: +CHIPValveConfigurationAndControlDefaultOpenDurationAttributeCallback(jobject javaCallback, bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30100,7 +30100,8 @@ CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CHIPValveConfigu } } -CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::~CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback() +CHIPValveConfigurationAndControlDefaultOpenDurationAttributeCallback::~ +CHIPValveConfigurationAndControlDefaultOpenDurationAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30111,8 +30112,8 @@ CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::~CHIPValveConfig env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CallbackFn( - void * context, const chip::app::DataModel::Nullable & value) +void CHIPValveConfigurationAndControlDefaultOpenDurationAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -30120,8 +30121,8 @@ void CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CallbackFn( jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; @@ -30149,9 +30150,9 @@ void CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CallbackFn( env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlRemainingDurationAttributeCallback:: -CHIPValveConfigurationAndControlRemainingDurationAttributeCallback(jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), +CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback( + jobject javaCallback, bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30168,8 +30169,7 @@ CHIPValveConfigurationAndControlRemainingDurationAttributeCallback(jobject javaC } } -CHIPValveConfigurationAndControlRemainingDurationAttributeCallback::~ -CHIPValveConfigurationAndControlRemainingDurationAttributeCallback() +CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::~CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30180,8 +30180,8 @@ CHIPValveConfigurationAndControlRemainingDurationAttributeCallback() env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlRemainingDurationAttributeCallback::CallbackFn( - void * context, const chip::app::DataModel::Nullable & value) +void CHIPValveConfigurationAndControlAutoCloseTimeAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -30189,8 +30189,8 @@ void CHIPValveConfigurationAndControlRemainingDurationAttributeCallback::Callbac jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; @@ -30218,9 +30218,9 @@ void CHIPValveConfigurationAndControlRemainingDurationAttributeCallback::Callbac env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CHIPValveConfigurationAndControlCurrentStateAttributeCallback( - jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), +CHIPValveConfigurationAndControlRemainingDurationAttributeCallback:: +CHIPValveConfigurationAndControlRemainingDurationAttributeCallback(jobject javaCallback, bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30237,7 +30237,8 @@ CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CHIPValveConfigur } } -CHIPValveConfigurationAndControlCurrentStateAttributeCallback::~CHIPValveConfigurationAndControlCurrentStateAttributeCallback() +CHIPValveConfigurationAndControlRemainingDurationAttributeCallback::~ +CHIPValveConfigurationAndControlRemainingDurationAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30248,8 +30249,8 @@ CHIPValveConfigurationAndControlCurrentStateAttributeCallback::~CHIPValveConfigu env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CallbackFn( - void * context, const chip::app::DataModel::Nullable & value) +void CHIPValveConfigurationAndControlRemainingDurationAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -30257,8 +30258,8 @@ void CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CallbackFn( jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; @@ -30266,7 +30267,7 @@ void CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CallbackFn( ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); jmethodID javaMethod; - err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;)V", &javaMethod); + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Long;)V", &javaMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); jobject javaValue; @@ -30276,19 +30277,19 @@ void CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CallbackFn( } else { - std::string javaValueClassName = "java/lang/Integer"; - std::string javaValueCtorSignature = "(I)V"; - jint jnijavaValue = static_cast(value.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(javaValueClassName.c_str(), javaValueCtorSignature.c_str(), - jnijavaValue, javaValue); + std::string javaValueClassName = "java/lang/Long"; + std::string javaValueCtorSignature = "(J)V"; + jlong jnijavaValue = static_cast(value.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(javaValueClassName.c_str(), javaValueCtorSignature.c_str(), + jnijavaValue, javaValue); } env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlTargetStateAttributeCallback::CHIPValveConfigurationAndControlTargetStateAttributeCallback( +CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CHIPValveConfigurationAndControlCurrentStateAttributeCallback( jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30305,7 +30306,7 @@ CHIPValveConfigurationAndControlTargetStateAttributeCallback::CHIPValveConfigura } } -CHIPValveConfigurationAndControlTargetStateAttributeCallback::~CHIPValveConfigurationAndControlTargetStateAttributeCallback() +CHIPValveConfigurationAndControlCurrentStateAttributeCallback::~CHIPValveConfigurationAndControlCurrentStateAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30316,7 +30317,7 @@ CHIPValveConfigurationAndControlTargetStateAttributeCallback::~CHIPValveConfigur env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlTargetStateAttributeCallback::CallbackFn( +void CHIPValveConfigurationAndControlCurrentStateAttributeCallback::CallbackFn( void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; @@ -30325,8 +30326,8 @@ void CHIPValveConfigurationAndControlTargetStateAttributeCallback::CallbackFn( jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; @@ -30354,9 +30355,9 @@ void CHIPValveConfigurationAndControlTargetStateAttributeCallback::CallbackFn( env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CHIPValveConfigurationAndControlCurrentLevelAttributeCallback( +CHIPValveConfigurationAndControlTargetStateAttributeCallback::CHIPValveConfigurationAndControlTargetStateAttributeCallback( jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30373,7 +30374,7 @@ CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CHIPValveConfigur } } -CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::~CHIPValveConfigurationAndControlCurrentLevelAttributeCallback() +CHIPValveConfigurationAndControlTargetStateAttributeCallback::~CHIPValveConfigurationAndControlTargetStateAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30384,8 +30385,8 @@ CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::~CHIPValveConfigu env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CallbackFn( - void * context, const chip::app::DataModel::Nullable & value) +void CHIPValveConfigurationAndControlTargetStateAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -30393,8 +30394,8 @@ void CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CallbackFn( jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; @@ -30422,9 +30423,9 @@ void CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CallbackFn( env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CHIPValveConfigurationAndControlTargetLevelAttributeCallback( +CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CHIPValveConfigurationAndControlCurrentLevelAttributeCallback( jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30441,7 +30442,7 @@ CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CHIPValveConfigura } } -CHIPValveConfigurationAndControlTargetLevelAttributeCallback::~CHIPValveConfigurationAndControlTargetLevelAttributeCallback() +CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::~CHIPValveConfigurationAndControlCurrentLevelAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30452,7 +30453,7 @@ CHIPValveConfigurationAndControlTargetLevelAttributeCallback::~CHIPValveConfigur env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CallbackFn( +void CHIPValveConfigurationAndControlCurrentLevelAttributeCallback::CallbackFn( void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; @@ -30461,8 +30462,8 @@ void CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CallbackFn( jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; @@ -30490,9 +30491,9 @@ void CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CallbackFn( env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue); } -CHIPValveConfigurationAndControlOpenLevelAttributeCallback::CHIPValveConfigurationAndControlOpenLevelAttributeCallback( +CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CHIPValveConfigurationAndControlTargetLevelAttributeCallback( jobject javaCallback, bool keepAlive) : - chip::Callback::Callback(CallbackFn, this), + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); @@ -30509,7 +30510,7 @@ CHIPValveConfigurationAndControlOpenLevelAttributeCallback::CHIPValveConfigurati } } -CHIPValveConfigurationAndControlOpenLevelAttributeCallback::~CHIPValveConfigurationAndControlOpenLevelAttributeCallback() +CHIPValveConfigurationAndControlTargetLevelAttributeCallback::~CHIPValveConfigurationAndControlTargetLevelAttributeCallback() { JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); if (env == nullptr) @@ -30520,7 +30521,7 @@ CHIPValveConfigurationAndControlOpenLevelAttributeCallback::~CHIPValveConfigurat env->DeleteGlobalRef(javaCallbackRef); } -void CHIPValveConfigurationAndControlOpenLevelAttributeCallback::CallbackFn( +void CHIPValveConfigurationAndControlTargetLevelAttributeCallback::CallbackFn( void * context, const chip::app::DataModel::Nullable & value) { chip::DeviceLayer::StackUnlock unlock; @@ -30529,8 +30530,8 @@ void CHIPValveConfigurationAndControlOpenLevelAttributeCallback::CallbackFn( jobject javaCallbackRef; VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); - std::unique_ptr cppCallback( - reinterpret_cast(context), maybeDestroy); + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. javaCallbackRef = cppCallback.get()->javaCallbackRef; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 08ff2ab1b8d93a..5c720c7d3da4e4 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -6251,6 +6251,7 @@ class ChipClusters: "commandName": "Open", "args": { "openDuration": "int", + "targetLevel": "int", }, }, 0x00000001: { @@ -6259,14 +6260,6 @@ class ChipClusters: "args": { }, }, - 0x00000002: { - "commandId": 0x00000002, - "commandName": "SetLevel", - "args": { - "level": "int", - "openDuration": "int", - }, - }, }, "attributes": { 0x00000000: { @@ -6274,38 +6267,37 @@ class ChipClusters: "attributeId": 0x00000000, "type": "int", "reportable": True, - "writable": True, }, 0x00000001: { - "attributeName": "AutoCloseTime", + "attributeName": "DefaultOpenDuration", "attributeId": 0x00000001, "type": "int", "reportable": True, + "writable": True, }, 0x00000002: { - "attributeName": "RemainingDuration", + "attributeName": "AutoCloseTime", "attributeId": 0x00000002, "type": "int", "reportable": True, }, 0x00000003: { - "attributeName": "CurrentState", + "attributeName": "RemainingDuration", "attributeId": 0x00000003, "type": "int", "reportable": True, }, 0x00000004: { - "attributeName": "TargetState", + "attributeName": "CurrentState", "attributeId": 0x00000004, "type": "int", "reportable": True, }, 0x00000005: { - "attributeName": "StartUpState", + "attributeName": "TargetState", "attributeId": 0x00000005, "type": "int", "reportable": True, - "writable": True, }, 0x00000006: { "attributeName": "CurrentLevel", @@ -6320,7 +6312,7 @@ class ChipClusters: "reportable": True, }, 0x00000008: { - "attributeName": "OpenLevel", + "attributeName": "DefaultOpenLevel", "attributeId": 0x00000008, "type": "int", "reportable": True, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 4e103ede217200..d5de5ecabd7b30 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -21844,14 +21844,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ ClusterObjectFieldDescriptor(Label="openDuration", Tag=0x00000000, Type=typing.Union[Nullable, uint]), - ClusterObjectFieldDescriptor(Label="autoCloseTime", Tag=0x00000001, Type=typing.Union[None, Nullable, uint]), - ClusterObjectFieldDescriptor(Label="remainingDuration", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), - ClusterObjectFieldDescriptor(Label="currentState", Tag=0x00000003, Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]), - ClusterObjectFieldDescriptor(Label="targetState", Tag=0x00000004, Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]), - ClusterObjectFieldDescriptor(Label="startUpState", Tag=0x00000005, Type=typing.Optional[ValveConfigurationAndControl.Enums.ValveStateEnum]), + ClusterObjectFieldDescriptor(Label="defaultOpenDuration", Tag=0x00000001, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="autoCloseTime", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="remainingDuration", Tag=0x00000003, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="currentState", Tag=0x00000004, Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]), + ClusterObjectFieldDescriptor(Label="targetState", Tag=0x00000005, Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]), ClusterObjectFieldDescriptor(Label="currentLevel", Tag=0x00000006, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="targetLevel", Tag=0x00000007, Type=typing.Union[None, Nullable, uint]), - ClusterObjectFieldDescriptor(Label="openLevel", Tag=0x00000008, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="defaultOpenLevel", Tag=0x00000008, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="valveFault", Tag=0x00000009, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), @@ -21862,14 +21862,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ]) openDuration: 'typing.Union[Nullable, uint]' = None + defaultOpenDuration: 'typing.Union[Nullable, uint]' = None autoCloseTime: 'typing.Union[None, Nullable, uint]' = None - remainingDuration: 'typing.Union[None, Nullable, uint]' = None + remainingDuration: 'typing.Union[Nullable, uint]' = None currentState: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = None targetState: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = None - startUpState: 'typing.Optional[ValveConfigurationAndControl.Enums.ValveStateEnum]' = None currentLevel: 'typing.Union[None, Nullable, uint]' = None targetLevel: 'typing.Union[None, Nullable, uint]' = None - openLevel: 'typing.Union[None, Nullable, uint]' = None + defaultOpenLevel: 'typing.Optional[uint]' = None valveFault: 'typing.Optional[uint]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None @@ -21879,14 +21879,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: clusterRevision: 'uint' = None class Enums: + class StatusCodeEnum(MatterIntEnum): + kFailureDueToFault = 0x02 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 0, + class ValveStateEnum(MatterIntEnum): - kOpen = 0x00 - kClosed = 0x01 + kClosed = 0x00 + kOpen = 0x01 + kTransitioning = 0x02 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only # be used by code to process how it handles receiving and unknown # enum value. This specific should never be transmitted. - kUnknownEnumValue = 2, + kUnknownEnumValue = 3, class Bitmaps: class Feature(IntFlag): @@ -21897,6 +21906,9 @@ class ValveFaultBitmap(IntFlag): kGeneralFault = 0x1 kBlocked = 0x2 kLeaking = 0x4 + kNotConnected = 0x8 + kShortCircuit = 0x10 + kCurrentExceeded = 0x20 class Commands: @dataclass @@ -21910,10 +21922,12 @@ class Open(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="openDuration", Tag=0, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="openDuration", Tag=0, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="targetLevel", Tag=1, Type=typing.Optional[uint]), ]) - openDuration: 'typing.Optional[uint]' = None + openDuration: 'typing.Union[None, Nullable, uint]' = None + targetLevel: 'typing.Optional[uint]' = None @dataclass class Close(ClusterCommand): @@ -21928,24 +21942,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ]) - @dataclass - class SetLevel(ClusterCommand): - cluster_id: typing.ClassVar[int] = 0x00000081 - command_id: typing.ClassVar[int] = 0x00000002 - is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None - - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - ClusterObjectFieldDescriptor(Label="level", Tag=0, Type=uint), - ClusterObjectFieldDescriptor(Label="openDuration", Tag=1, Type=typing.Optional[uint]), - ]) - - level: 'uint' = 0 - openDuration: 'typing.Optional[uint]' = None - class Attributes: @dataclass class OpenDuration(ClusterAttributeDescriptor): @@ -21964,7 +21960,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[Nullable, uint]' = NullValue @dataclass - class AutoCloseTime(ClusterAttributeDescriptor): + class DefaultOpenDuration(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000081 @@ -21975,12 +21971,12 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: 'typing.Union[Nullable, uint]' = NullValue @dataclass - class RemainingDuration(ClusterAttributeDescriptor): + class AutoCloseTime(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000081 @@ -21996,7 +21992,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[None, Nullable, uint]' = None @dataclass - class CurrentState(ClusterAttributeDescriptor): + class RemainingDuration(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000081 @@ -22007,12 +22003,12 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]) + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = NullValue + value: 'typing.Union[Nullable, uint]' = NullValue @dataclass - class TargetState(ClusterAttributeDescriptor): + class CurrentState(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000081 @@ -22028,7 +22024,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = NullValue @dataclass - class StartUpState(ClusterAttributeDescriptor): + class TargetState(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000081 @@ -22039,9 +22035,9 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[ValveConfigurationAndControl.Enums.ValveStateEnum]) + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]) - value: 'typing.Optional[ValveConfigurationAndControl.Enums.ValveStateEnum]' = None + value: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = NullValue @dataclass class CurrentLevel(ClusterAttributeDescriptor): @@ -22076,7 +22072,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[None, Nullable, uint]' = None @dataclass - class OpenLevel(ClusterAttributeDescriptor): + class DefaultOpenLevel(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000081 @@ -22087,9 +22083,9 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: 'typing.Optional[uint]' = None @dataclass class ValveFault(ClusterAttributeDescriptor): @@ -22219,9 +22215,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ ClusterObjectFieldDescriptor(Label="valveState", Tag=0, Type=ValveConfigurationAndControl.Enums.ValveStateEnum), + ClusterObjectFieldDescriptor(Label="valveLevel", Tag=1, Type=typing.Optional[uint]), ]) valveState: 'ValveConfigurationAndControl.Enums.ValveStateEnum' = 0 + valveLevel: 'typing.Optional[uint]' = None @dataclass class ValveFault(ClusterEvent): diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index d579533e2eb296..8d1513ffc0f8b6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -2877,6 +2877,9 @@ static BOOL AttributeIsSpecifiedInValveConfigurationAndControlCluster(AttributeI case Attributes::OpenDuration::Id: { return YES; } + case Attributes::DefaultOpenDuration::Id: { + return YES; + } case Attributes::AutoCloseTime::Id: { return YES; } @@ -2889,16 +2892,13 @@ static BOOL AttributeIsSpecifiedInValveConfigurationAndControlCluster(AttributeI case Attributes::TargetState::Id: { return YES; } - case Attributes::StartUpState::Id: { - return YES; - } case Attributes::CurrentLevel::Id: { return YES; } case Attributes::TargetLevel::Id: { return YES; } - case Attributes::OpenLevel::Id: { + case Attributes::DefaultOpenLevel::Id: { return YES; } case Attributes::ValveFault::Id: { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 5910c74a60e412..a2e2ae45788c22 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -7500,6 +7500,21 @@ static id _Nullable DecodeAttributeValueForValveConfigurationAndControlCluster(A } return value; } + case Attributes::DefaultOpenDuration::Id: { + using TypeInfo = Attributes::DefaultOpenDuration::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 numberWithUnsignedInt:cppValue.Value()]; + } + return value; + } case Attributes::AutoCloseTime::Id: { using TypeInfo = Attributes::AutoCloseTime::TypeInfo; TypeInfo::DecodableType cppValue; @@ -7560,17 +7575,6 @@ static id _Nullable DecodeAttributeValueForValveConfigurationAndControlCluster(A } return value; } - case Attributes::StartUpState::Id: { - using TypeInfo = Attributes::StartUpState::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::CurrentLevel::Id: { using TypeInfo = Attributes::CurrentLevel::TypeInfo; TypeInfo::DecodableType cppValue; @@ -7601,19 +7605,15 @@ static id _Nullable DecodeAttributeValueForValveConfigurationAndControlCluster(A } return value; } - case Attributes::OpenLevel::Id: { - using TypeInfo = Attributes::OpenLevel::TypeInfo; + case Attributes::DefaultOpenLevel::Id: { + using TypeInfo = Attributes::DefaultOpenLevel::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:cppValue.Value()]; - } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; return value; } case Attributes::ValveFault::Id: { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 23f78925c5f2e1..49cc9273260b2d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -7119,32 +7119,32 @@ MTR_PROVISIONALLY_AVAILABLE /** * Command Open * - * This command is used to set the valve to its fully open position. + * This command is used to set the valve to its open position. */ - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; /** * Command Close * - * This command is used to set the valve to its fully closed position. + * This command is used to set the valve to its closed position. */ - (void)closeWithParams:(MTRValveConfigurationAndControlClusterCloseParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)closeWithCompletion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -/** - * Command SetLevel - * - * This command is used to set the valve to a specific level. - */ -- (void)setLevelWithParams:(MTRValveConfigurationAndControlClusterSetLevelParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeOpenDurationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenDurationWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenDurationWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeOpenDurationWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeOpenDurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributeDefaultOpenDurationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenDurationWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenDurationWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeDefaultOpenDurationWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeDefaultOpenDurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeAutoCloseTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAutoCloseTimeWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7169,14 +7169,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeTargetStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeStartUpStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpStateWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpStateWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeStartUpStateWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeStartUpStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeCurrentLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeCurrentLevelWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7189,13 +7181,13 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeTargetLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeOpenLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenLevelWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenLevelWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeOpenLevelWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeOpenLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributeDefaultOpenLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenLevelWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenLevelWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeDefaultOpenLevelWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeDefaultOpenLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeValveFaultWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeValveFaultWithParams:(MTRSubscribeParams *)params @@ -16855,9 +16847,14 @@ typedef NS_OPTIONS(uint16_t, MTRBooleanStateConfigurationSensorFaultBitmap) { MTRBooleanStateConfigurationSensorFaultBitmapGeneralFault MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint8_t, MTRValveConfigurationAndControlStatusCode) { + MTRValveConfigurationAndControlStatusCodeFailureDueToFault MTR_PROVISIONALLY_AVAILABLE = 0x02, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRValveConfigurationAndControlValveState) { - MTRValveConfigurationAndControlValveStateOpen MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRValveConfigurationAndControlValveStateClosed MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRValveConfigurationAndControlValveStateClosed MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRValveConfigurationAndControlValveStateOpen MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRValveConfigurationAndControlValveStateTransitioning MTR_PROVISIONALLY_AVAILABLE = 0x02, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRValveConfigurationAndControlFeature) { @@ -16869,6 +16866,9 @@ typedef NS_OPTIONS(uint16_t, MTRValveConfigurationAndControlValveFaultBitmap) { MTRValveConfigurationAndControlValveFaultBitmapGeneralFault MTR_PROVISIONALLY_AVAILABLE = 0x1, MTRValveConfigurationAndControlValveFaultBitmapBlocked MTR_PROVISIONALLY_AVAILABLE = 0x2, MTRValveConfigurationAndControlValveFaultBitmapLeaking MTR_PROVISIONALLY_AVAILABLE = 0x4, + MTRValveConfigurationAndControlValveFaultBitmapNotConnected MTR_PROVISIONALLY_AVAILABLE = 0x8, + MTRValveConfigurationAndControlValveFaultBitmapShortCircuit MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRValveConfigurationAndControlValveFaultBitmapCurrentExceeded MTR_PROVISIONALLY_AVAILABLE = 0x20, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_ENUM(uint16_t, MTRElectricalEnergyMeasurementMeasurementType) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index a302e645ffec6a..4aab1586c4932c 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -49721,34 +49721,46 @@ - (void)closeWithParams:(MTRValveConfigurationAndControlClusterCloseParams * _Nu queue:self.callbackQueue completion:responseHandler]; } -- (void)setLevelWithParams:(MTRValveConfigurationAndControlClusterSetLevelParams *)params completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRValveConfigurationAndControlClusterSetLevelParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = ValveConfigurationAndControl::Commands::SetLevel::Type; - [self.device _invokeKnownCommandWithEndpointID:@(self.endpoint) - clusterID:@(RequestType::GetClusterId()) - commandID:@(RequestType::GetCommandId()) - commandPayload:params - timedInvokeTimeout:timedInvokeTimeoutMs - serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil +- (void)readAttributeOpenDurationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil queue:self.callbackQueue - completion:responseHandler]; + completion:completion]; } -- (void)readAttributeOpenDurationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +- (void)subscribeAttributeOpenDurationWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeOpenDurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeDefaultOpenDurationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenDuration::TypeInfo; [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -49757,11 +49769,11 @@ - (void)readAttributeOpenDurationWithCompletion:(void (^)(NSNumber * _Nullable v completion:completion]; } -- (void)writeAttributeOpenDurationWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +- (void)writeAttributeDefaultOpenDurationWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion { - [self writeAttributeOpenDurationWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; + [self writeAttributeDefaultOpenDurationWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; } -- (void)writeAttributeOpenDurationWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +- (void)writeAttributeDefaultOpenDurationWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion { // Make a copy of params before we go async. params = [params copy]; @@ -49776,7 +49788,7 @@ - (void)writeAttributeOpenDurationWithValue:(NSNumber * _Nullable)value params:( } ListFreer listFreer; - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenDuration::TypeInfo; TypeInfo::Type cppValue; if (value == nil) { cppValue.SetNull(); @@ -49790,11 +49802,11 @@ - (void)writeAttributeOpenDurationWithValue:(NSNumber * _Nullable)value params:( std::move(*bridge).DispatchAction(self.device); } -- (void)subscribeAttributeOpenDurationWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +- (void)subscribeAttributeDefaultOpenDurationWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler { - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenDuration::TypeInfo; [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -49804,9 +49816,9 @@ - (void)subscribeAttributeOpenDurationWithParams:(MTRSubscribeParams * _Nonnull) subscriptionEstablished:subscriptionEstablished]; } -+ (void)readAttributeOpenDurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion ++ (void)readAttributeDefaultOpenDurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenDuration::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenDuration::TypeInfo; [clusterStateCacheContainer _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) clusterID:TypeInfo::GetClusterId() @@ -49959,70 +49971,6 @@ + (void)readAttributeTargetStateWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } -- (void)readAttributeStartUpStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ValveConfigurationAndControl::Attributes::StartUpState::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeStartUpStateWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeStartUpStateWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; -} -- (void)writeAttributeStartUpStateWithValue:(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 = ValveConfigurationAndControl::Attributes::StartUpState::TypeInfo; - TypeInfo::Type cppValue; - cppValue = static_cast>(value.unsignedCharValue); - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpoint); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeStartUpStateWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ValveConfigurationAndControl::Attributes::StartUpState::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeStartUpStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ValveConfigurationAndControl::Attributes::StartUpState::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeCurrentLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ValveConfigurationAndControl::Attributes::CurrentLevel::TypeInfo; @@ -50095,9 +50043,9 @@ + (void)readAttributeTargetLevelWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } -- (void)readAttributeOpenLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +- (void)readAttributeDefaultOpenLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenLevel::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenLevel::TypeInfo; [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -50106,11 +50054,11 @@ - (void)readAttributeOpenLevelWithCompletion:(void (^)(NSNumber * _Nullable valu completion:completion]; } -- (void)writeAttributeOpenLevelWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +- (void)writeAttributeDefaultOpenLevelWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion { - [self writeAttributeOpenLevelWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; + [self writeAttributeDefaultOpenLevelWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; } -- (void)writeAttributeOpenLevelWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +- (void)writeAttributeDefaultOpenLevelWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion { // Make a copy of params before we go async. params = [params copy]; @@ -50125,25 +50073,20 @@ - (void)writeAttributeOpenLevelWithValue:(NSNumber * _Nullable)value params:(MTR } ListFreer listFreer; - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenLevel::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenLevel::TypeInfo; TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } + cppValue = value.unsignedCharValue; chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpoint); return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); std::move(*bridge).DispatchAction(self.device); } -- (void)subscribeAttributeOpenLevelWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +- (void)subscribeAttributeDefaultOpenLevelWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler { - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenLevel::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenLevel::TypeInfo; [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -50153,9 +50096,9 @@ - (void)subscribeAttributeOpenLevelWithParams:(MTRSubscribeParams * _Nonnull)par subscriptionEstablished:subscriptionEstablished]; } -+ (void)readAttributeOpenLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion ++ (void)readAttributeDefaultOpenLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ValveConfigurationAndControl::Attributes::OpenLevel::TypeInfo; + using TypeInfo = ValveConfigurationAndControl::Attributes::DefaultOpenLevel::TypeInfo; [clusterStateCacheContainer _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) clusterID:TypeInfo::GetClusterId() diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 0ed485f03948a7..9de74b6645d33a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -2594,14 +2594,14 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster ValveConfigurationAndControl attributes MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenDurationID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAutoCloseTimeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeRemainingDurationID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeCurrentStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeTargetStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeStartUpStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeDefaultOpenDurationID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAutoCloseTimeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeRemainingDurationID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeCurrentStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeTargetStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeCurrentLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeTargetLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, + MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeDefaultOpenLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeValveFaultID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, @@ -6257,7 +6257,6 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { // Cluster ValveConfigurationAndControl commands MTRCommandIDTypeClusterValveConfigurationAndControlCommandOpenID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterValveConfigurationAndControlCommandCloseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRCommandIDTypeClusterValveConfigurationAndControlCommandSetLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, // Cluster DemandResponseLoadControl commands MTRCommandIDTypeClusterDemandResponseLoadControlCommandRegisterLoadControlProgramRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 287407184597ce..0da195e4c8bab8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -3378,11 +3378,12 @@ MTR_PROVISIONALLY_AVAILABLE - (void)closeWithParams:(MTRValveConfigurationAndControlClusterCloseParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)closeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)setLevelWithParams:(MTRValveConfigurationAndControlClusterSetLevelParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeOpenDurationWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeDefaultOpenDurationWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAutoCloseTimeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3392,17 +3393,13 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeTargetStateWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeStartUpStateWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpStateWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpStateWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeCurrentLevelWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeTargetLevelWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeOpenLevelWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeDefaultOpenLevelWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeDefaultOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeValveFaultWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 1108e9c4678a67..5af8ad258ac25c 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -9147,47 +9147,25 @@ - (void)closeWithParams:(MTRValveConfigurationAndControlClusterCloseParams * _Nu completion:responseHandler]; } -- (void)setLevelWithParams:(MTRValveConfigurationAndControlClusterSetLevelParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +- (NSDictionary * _Nullable)readAttributeOpenDurationWithParams:(MTRReadParams * _Nullable)params { - if (params == nil) { - params = [[MTRValveConfigurationAndControlClusterSetLevelParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = ValveConfigurationAndControl::Commands::SetLevel::Type; - [self.device _invokeKnownCommandWithEndpointID:@(self.endpoint) - clusterID:@(RequestType::GetClusterId()) - commandID:@(RequestType::GetCommandId()) - commandPayload:params - expectedValues:expectedValues - expectedValueInterval:expectedValueIntervalMs - timedInvokeTimeout:timedInvokeTimeoutMs - serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil - queue:self.callbackQueue - completion:responseHandler]; + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenDurationID) params:params]; } -- (NSDictionary * _Nullable)readAttributeOpenDurationWithParams:(MTRReadParams * _Nullable)params +- (NSDictionary * _Nullable)readAttributeDefaultOpenDurationWithParams:(MTRReadParams * _Nullable)params { - return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenDurationID) params:params]; + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeDefaultOpenDurationID) params:params]; } -- (void)writeAttributeOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +- (void)writeAttributeDefaultOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs { - [self writeAttributeOpenDurationWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; + [self writeAttributeDefaultOpenDurationWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; } -- (void)writeAttributeOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +- (void)writeAttributeDefaultOpenDurationWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params { NSNumber * timedWriteTimeout = params.timedWriteTimeout; - [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenDurationID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; + [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeDefaultOpenDurationID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } - (NSDictionary * _Nullable)readAttributeAutoCloseTimeWithParams:(MTRReadParams * _Nullable)params @@ -9210,22 +9188,6 @@ - (void)writeAttributeOpenDurationWithValue:(NSDictionary *)data return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeTargetStateID) params:params]; } -- (NSDictionary * _Nullable)readAttributeStartUpStateWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeStartUpStateID) params:params]; -} - -- (void)writeAttributeStartUpStateWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeStartUpStateWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeStartUpStateWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeStartUpStateID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - - (NSDictionary * _Nullable)readAttributeCurrentLevelWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeCurrentLevelID) params:params]; @@ -9236,20 +9198,20 @@ - (void)writeAttributeStartUpStateWithValue:(NSDictionary *)data return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeTargetLevelID) params:params]; } -- (NSDictionary * _Nullable)readAttributeOpenLevelWithParams:(MTRReadParams * _Nullable)params +- (NSDictionary * _Nullable)readAttributeDefaultOpenLevelWithParams:(MTRReadParams * _Nullable)params { - return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenLevelID) params:params]; + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeDefaultOpenLevelID) params:params]; } -- (void)writeAttributeOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +- (void)writeAttributeDefaultOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs { - [self writeAttributeOpenLevelWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; + [self writeAttributeDefaultOpenLevelWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; } -- (void)writeAttributeOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +- (void)writeAttributeDefaultOpenLevelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params { NSNumber * timedWriteTimeout = params.timedWriteTimeout; - [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeOpenLevelID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; + [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeDefaultOpenLevelID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } - (NSDictionary * _Nullable)readAttributeValveFaultWithParams:(MTRReadParams * _Nullable)params diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index e01bdabcb6a987..a59c89efbeacd1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -5659,34 +5659,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRValveConfigurationAndControlClusterOpenParams : NSObject @property (nonatomic, copy) NSNumber * _Nullable openDuration 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 MTRValveConfigurationAndControlClusterCloseParams : NSObject +@property (nonatomic, copy) NSNumber * _Nullable targetLevel MTR_PROVISIONALLY_AVAILABLE; /** * Controls whether the command is a timed command (using Timed Invoke). * @@ -5714,11 +5688,7 @@ MTR_PROVISIONALLY_AVAILABLE @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRValveConfigurationAndControlClusterSetLevelParams : NSObject - -@property (nonatomic, copy) NSNumber * _Nonnull level MTR_PROVISIONALLY_AVAILABLE; - -@property (nonatomic, copy) NSNumber * _Nullable openDuration MTR_PROVISIONALLY_AVAILABLE; +@interface MTRValveConfigurationAndControlClusterCloseParams : NSObject /** * Controls whether the command is a timed command (using Timed Invoke). * diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 7e7eccfb8043ca..b82bb7872fbb24 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -15546,6 +15546,8 @@ - (instancetype)init if (self = [super init]) { _openDuration = nil; + + _targetLevel = nil; _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -15557,6 +15559,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; auto other = [[MTRValveConfigurationAndControlClusterOpenParams alloc] init]; other.openDuration = self.openDuration; + other.targetLevel = self.targetLevel; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -15565,7 +15568,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: openDuration:%@; >", NSStringFromClass([self class]), _openDuration]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: openDuration:%@; targetLevel:%@; >", NSStringFromClass([self class]), _openDuration, _targetLevel]; return descriptionString; } @@ -15580,7 +15583,18 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { if (self.openDuration != nil) { auto & definedValue_0 = encodableStruct.openDuration.Emplace(); - definedValue_0 = self.openDuration.unsignedIntValue; + if (self.openDuration == nil) { + definedValue_0.SetNull(); + } else { + auto & nonNullValue_1 = definedValue_0.SetNonNull(); + nonNullValue_1 = self.openDuration.unsignedIntValue; + } + } + } + { + if (self.targetLevel != nil) { + auto & definedValue_0 = encodableStruct.targetLevel.Emplace(); + definedValue_0 = self.targetLevel.unsignedCharValue; } } @@ -15695,94 +15709,6 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRValveConfigurationAndControlClusterSetLevelParams -- (instancetype)init -{ - if (self = [super init]) { - - _level = @(0); - - _openDuration = nil; - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone; -{ - auto other = [[MTRValveConfigurationAndControlClusterSetLevelParams alloc] init]; - - other.level = self.level; - other.openDuration = self.openDuration; - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: level:%@; openDuration:%@; >", NSStringFromClass([self class]), _level, _openDuration]; - return descriptionString; -} - -@end - -@implementation MTRValveConfigurationAndControlClusterSetLevelParams (InternalMethods) - -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader -{ - chip::app::Clusters::ValveConfigurationAndControl::Commands::SetLevel::Type encodableStruct; - ListFreer listFreer; - { - encodableStruct.level = self.level.unsignedCharValue; - } - { - if (self.openDuration != nil) { - auto & definedValue_0 = encodableStruct.openDuration.Emplace(); - definedValue_0 = self.openDuration.unsignedIntValue; - } - } - - 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 MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams - (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 f5738ad6af5b1b..24ef38c1031cc6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1018,12 +1018,6 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface MTRValveConfigurationAndControlClusterSetLevelParams (InternalMethods) - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; - -@end - @interface MTRDemandResponseLoadControlClusterRegisterLoadControlProgramRequestParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index 20b8ec3138d5da..43b459dcc3f9de 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -55,7 +55,7 @@ { 0x0000002C, DeviceTypeClass::Simple, "Matter Air Quality Sensor" }, { 0x0000002D, DeviceTypeClass::Simple, "Matter Air Purifier" }, { 0x00000041, DeviceTypeClass::Simple, "Matter Water Freeze Detector" }, - { 0x00000042, DeviceTypeClass::Simple, "Matter Valve" }, + { 0x00000042, DeviceTypeClass::Simple, "Matter Water Valve" }, { 0x00000043, DeviceTypeClass::Simple, "Matter Water Leak Detector" }, { 0x00000044, DeviceTypeClass::Simple, "Matter Rain Sensor" }, { 0x00000070, DeviceTypeClass::Simple, "Matter Refrigerator" }, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index b8d26c67791e00..eadbca55e92339 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -2439,6 +2439,15 @@ static id _Nullable DecodeEventPayloadForValveConfigurationAndControlCluster(Eve memberValue = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.valveState)]; value.valveState = memberValue; } while (0); + do { + NSNumber * _Nullable memberValue; + if (cppValue.valveLevel.HasValue()) { + memberValue = [NSNumber numberWithUnsignedChar:cppValue.valveLevel.Value()]; + } else { + memberValue = nil; + } + value.valveLevel = memberValue; + } while (0); return value; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index f879cf7be69982..1c6fc64a88d0c4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1066,6 +1066,7 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRValveConfigurationAndControlClusterValveStateChangedEvent : NSObject @property (nonatomic, copy) NSNumber * _Nonnull valveState MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable valveLevel MTR_PROVISIONALLY_AVAILABLE; @end MTR_PROVISIONALLY_AVAILABLE diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 12aa87d41c1c4e..81d7f3b773b4b0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -4266,6 +4266,8 @@ - (instancetype)init if (self = [super init]) { _valveState = @(0); + + _valveLevel = nil; } return self; } @@ -4275,13 +4277,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone auto other = [[MTRValveConfigurationAndControlClusterValveStateChangedEvent alloc] init]; other.valveState = self.valveState; + other.valveLevel = self.valveLevel; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: valveState:%@; >", NSStringFromClass([self class]), _valveState]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: valveState:%@; valveLevel:%@; >", NSStringFromClass([self class]), _valveState, _valveLevel]; 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 d2f762fd845a6c..1a16b52c0e3e90 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 @@ -9655,6 +9655,59 @@ EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullabl } // namespace OpenDuration +namespace DefaultOpenDuration { + +EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} +EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE); +} + +EmberAfStatus SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE); +} + +EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace DefaultOpenDuration + namespace AutoCloseTime { EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) @@ -9871,37 +9924,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, } // namespace TargetState -namespace StartUpState { - -EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - *value = Traits::StorageToWorking(temp); - return status; -} -EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); -} - -} // namespace StartUpState - namespace CurrentLevel { EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) @@ -10008,29 +10030,26 @@ EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullabl } // namespace TargetLevel -namespace OpenLevel { +namespace DefaultOpenLevel { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value) +EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value) { using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { - value.SetNonNull() = Traits::StorageToWorking(temp); + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; } + *value = Traits::StorageToWorking(temp); return status; } EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent value) { using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; } @@ -10040,26 +10059,7 @@ EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent value) return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE); } -EmberAfStatus SetNull(chip::EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::ValveConfigurationAndControl::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE); -} - -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OpenLevel +} // namespace DefaultOpenLevel namespace ValveFault { 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 af68f1c28926d1..9364fc14be08a5 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 @@ -1891,6 +1891,13 @@ EmberAfStatus SetNull(chip::EndpointId endpoint); EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); } // namespace OpenDuration +namespace DefaultOpenDuration { +EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // elapsed_s +EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); +EmberAfStatus SetNull(chip::EndpointId endpoint); +EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +} // namespace DefaultOpenDuration + namespace AutoCloseTime { EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // epoch_us EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value); @@ -1923,12 +1930,6 @@ EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); } // namespace TargetState -namespace StartUpState { -EmberAfStatus Get(chip::EndpointId endpoint, - chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum * value); // ValveStateEnum -EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum value); -} // namespace StartUpState - namespace CurrentLevel { EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // percent EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent value); @@ -1943,12 +1944,10 @@ EmberAfStatus SetNull(chip::EndpointId endpoint); EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); } // namespace TargetLevel -namespace OpenLevel { -EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable & value); // percent +namespace DefaultOpenLevel { +EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value); // percent EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent value); -EmberAfStatus SetNull(chip::EndpointId endpoint); -EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); -} // namespace OpenLevel +} // namespace DefaultOpenLevel namespace ValveFault { EmberAfStatus Get(chip::EndpointId endpoint, 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 1f8b6ffcd0eedd..480683245290c9 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -10120,12 +10120,6 @@ bool emberAfValveConfigurationAndControlClusterOpenCallback( bool emberAfValveConfigurationAndControlClusterCloseCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ValveConfigurationAndControl::Commands::Close::DecodableType & commandData); -/** - * @brief Valve Configuration and Control Cluster SetLevel Command callback (from client) - */ -bool emberAfValveConfigurationAndControlClusterSetLevelCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ValveConfigurationAndControl::Commands::SetLevel::DecodableType & commandData); /** * @brief Demand Response Load Control Cluster RegisterLoadControlProgramRequest Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index 801a7594706266..72f6654c5a3b8b 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -1508,16 +1508,28 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ActivatedCarbonFilterMo } } +static auto __attribute__((unused)) EnsureKnownEnumValue(ValveConfigurationAndControl::StatusCodeEnum val) +{ + using EnumType = ValveConfigurationAndControl::StatusCodeEnum; + switch (val) + { + case EnumType::kFailureDueToFault: + return val; + default: + return static_cast(0); + } +} static auto __attribute__((unused)) EnsureKnownEnumValue(ValveConfigurationAndControl::ValveStateEnum val) { using EnumType = ValveConfigurationAndControl::ValveStateEnum; switch (val) { - case EnumType::kOpen: case EnumType::kClosed: + case EnumType::kOpen: + case EnumType::kTransitioning: return val; default: - return static_cast(2); + return static_cast(3); } } diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 4ad316f2ba3a60..274bea95b7a097 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -2152,16 +2152,28 @@ enum class SensorFaultBitmap : uint16_t namespace ValveConfigurationAndControl { +// Enum for StatusCodeEnum +enum class StatusCodeEnum : uint8_t +{ + kFailureDueToFault = 0x02, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 0, +}; + // Enum for ValveStateEnum enum class ValveStateEnum : uint8_t { - kOpen = 0x00, - kClosed = 0x01, + kClosed = 0x00, + kOpen = 0x01, + kTransitioning = 0x02, // All received enum values that are not listed above will be mapped // to kUnknownEnumValue. This is a helper enum value that should only // be used by code to process how it handles receiving and unknown // enum value. This specific should never be transmitted. - kUnknownEnumValue = 2, + kUnknownEnumValue = 3, }; // Bitmap for Feature @@ -2174,9 +2186,12 @@ enum class Feature : uint32_t // Bitmap for ValveFaultBitmap enum class ValveFaultBitmap : uint16_t { - kGeneralFault = 0x1, - kBlocked = 0x2, - kLeaking = 0x4, + kGeneralFault = 0x1, + kBlocked = 0x2, + kLeaking = 0x4, + kNotConnected = 0x8, + kShortCircuit = 0x10, + kCurrentExceeded = 0x20, }; } // namespace ValveConfigurationAndControl 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 dffd9990ba062f..4ec4eb107d019c 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 @@ -13848,6 +13848,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; encoder.Encode(to_underlying(Fields::kOpenDuration), openDuration); + encoder.Encode(to_underlying(Fields::kTargetLevel), targetLevel); return encoder.Finalize(); } @@ -13869,6 +13870,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, openDuration); } + else if (__context_tag == to_underlying(Fields::kTargetLevel)) + { + err = DataModel::Decode(reader, targetLevel); + } else { } @@ -13897,45 +13902,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace Close. -namespace SetLevel { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kLevel), level); - encoder.Encode(to_underlying(Fields::kOpenDuration), openDuration); - 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::kLevel)) - { - err = DataModel::Decode(reader, level); - } - else if (__context_tag == to_underlying(Fields::kOpenDuration)) - { - err = DataModel::Decode(reader, openDuration); - } - else - { - } - - ReturnErrorOnFailure(err); - } -} -} // namespace SetLevel. } // namespace Commands namespace Attributes { @@ -13945,6 +13911,8 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre { case Attributes::OpenDuration::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, openDuration); + case Attributes::DefaultOpenDuration::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, defaultOpenDuration); case Attributes::AutoCloseTime::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, autoCloseTime); case Attributes::RemainingDuration::TypeInfo::GetAttributeId(): @@ -13953,14 +13921,12 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, currentState); case Attributes::TargetState::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, targetState); - case Attributes::StartUpState::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, startUpState); case Attributes::CurrentLevel::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, currentLevel); case Attributes::TargetLevel::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, targetLevel); - case Attributes::OpenLevel::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, openLevel); + case Attributes::DefaultOpenLevel::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, defaultOpenLevel); case Attributes::ValveFault::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, valveFault); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): @@ -13988,6 +13954,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const TLV::TLVType outer; ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kValveState), valveState)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kValveLevel), valveLevel)); return aWriter.EndContainer(outer); } @@ -14009,6 +13976,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, valveState); } + else if (__context_tag == to_underlying(Fields::kValveLevel)) + { + err = DataModel::Decode(reader, valveLevel); + } else { } 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 7f4d3f97dee070..7c1839591691f8 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 @@ -19843,11 +19843,6 @@ struct Type; struct DecodableType; } // namespace Close -namespace SetLevel { -struct Type; -struct DecodableType; -} // namespace SetLevel - } // namespace Commands namespace Commands { @@ -19855,6 +19850,7 @@ namespace Open { enum class Fields : uint8_t { kOpenDuration = 0, + kTargetLevel = 1, }; struct Type @@ -19864,7 +19860,8 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::Open::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } - Optional openDuration; + Optional> openDuration; + Optional targetLevel; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -19879,7 +19876,8 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::Open::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } - Optional openDuration; + Optional> openDuration; + Optional targetLevel; CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace Open @@ -19911,41 +19909,6 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace Close -namespace SetLevel { -enum class Fields : uint8_t -{ - kLevel = 0, - kOpenDuration = 1, -}; - -struct Type -{ -public: - // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SetLevel::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } - - chip::Percent level = static_cast(0); - Optional openDuration; - - 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::SetLevel::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } - - chip::Percent level = static_cast(0); - Optional openDuration; - CHIP_ERROR Decode(TLV::TLVReader & reader); -}; -}; // namespace SetLevel } // namespace Commands namespace Attributes { @@ -19962,6 +19925,18 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace OpenDuration +namespace DefaultOpenDuration { +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::ValveConfigurationAndControl::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::DefaultOpenDuration::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace DefaultOpenDuration namespace AutoCloseTime { struct TypeInfo { @@ -20012,18 +19987,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace TargetState -namespace StartUpState { -struct TypeInfo -{ - using Type = chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum; - using DecodableType = chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum; - using DecodableArgType = chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum; - - static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::StartUpState::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace StartUpState namespace CurrentLevel { struct TypeInfo { @@ -20048,18 +20011,18 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace TargetLevel -namespace OpenLevel { +namespace DefaultOpenLevel { struct TypeInfo { - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; + using Type = chip::Percent; + using DecodableType = chip::Percent; + using DecodableArgType = chip::Percent; static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::OpenLevel::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::DefaultOpenLevel::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace OpenLevel +} // namespace DefaultOpenLevel namespace ValveFault { struct TypeInfo { @@ -20118,15 +20081,14 @@ struct TypeInfo CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); Attributes::OpenDuration::TypeInfo::DecodableType openDuration; + Attributes::DefaultOpenDuration::TypeInfo::DecodableType defaultOpenDuration; Attributes::AutoCloseTime::TypeInfo::DecodableType autoCloseTime; Attributes::RemainingDuration::TypeInfo::DecodableType remainingDuration; Attributes::CurrentState::TypeInfo::DecodableType currentState; Attributes::TargetState::TypeInfo::DecodableType targetState; - Attributes::StartUpState::TypeInfo::DecodableType startUpState = - static_cast(0); Attributes::CurrentLevel::TypeInfo::DecodableType currentLevel; Attributes::TargetLevel::TypeInfo::DecodableType targetLevel; - Attributes::OpenLevel::TypeInfo::DecodableType openLevel; + Attributes::DefaultOpenLevel::TypeInfo::DecodableType defaultOpenLevel = static_cast(0); Attributes::ValveFault::TypeInfo::DecodableType valveFault = static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; @@ -20145,6 +20107,7 @@ static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; enum class Fields : uint8_t { kValveState = 0, + kValveLevel = 1, }; struct Type @@ -20156,6 +20119,7 @@ struct Type static constexpr bool kIsFabricScoped = false; ValveStateEnum valveState = static_cast(0); + Optional valveLevel; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; }; @@ -20168,6 +20132,7 @@ struct DecodableType static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } ValveStateEnum valveState = static_cast(0); + Optional valveLevel; CHIP_ERROR Decode(TLV::TLVReader & reader); }; 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 dbd1e568b6e348..ae707a1554f607 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 @@ -3582,25 +3582,25 @@ namespace OpenDuration { static constexpr AttributeId Id = 0x00000000; } // namespace OpenDuration -namespace AutoCloseTime { +namespace DefaultOpenDuration { static constexpr AttributeId Id = 0x00000001; +} // namespace DefaultOpenDuration + +namespace AutoCloseTime { +static constexpr AttributeId Id = 0x00000002; } // namespace AutoCloseTime namespace RemainingDuration { -static constexpr AttributeId Id = 0x00000002; +static constexpr AttributeId Id = 0x00000003; } // namespace RemainingDuration namespace CurrentState { -static constexpr AttributeId Id = 0x00000003; +static constexpr AttributeId Id = 0x00000004; } // namespace CurrentState namespace TargetState { -static constexpr AttributeId Id = 0x00000004; -} // namespace TargetState - -namespace StartUpState { static constexpr AttributeId Id = 0x00000005; -} // namespace StartUpState +} // namespace TargetState namespace CurrentLevel { static constexpr AttributeId Id = 0x00000006; @@ -3610,9 +3610,9 @@ namespace TargetLevel { static constexpr AttributeId Id = 0x00000007; } // namespace TargetLevel -namespace OpenLevel { +namespace DefaultOpenLevel { static constexpr AttributeId Id = 0x00000008; -} // namespace OpenLevel +} // namespace DefaultOpenLevel namespace ValveFault { static constexpr AttributeId Id = 0x00000009; 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 95c4ca8d039278..d903540c90f79f 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 @@ -938,10 +938,6 @@ namespace Close { static constexpr CommandId Id = 0x00000001; } // namespace Close -namespace SetLevel { -static constexpr CommandId Id = 0x00000002; -} // namespace SetLevel - } // namespace Commands } // namespace ValveConfigurationAndControl diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 1096ae9394d247..e45f9a82f0de23 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -6480,18 +6480,17 @@ class BooleanStateConfigurationEnableDisableAlarm : public ClusterCommand | Commands: | | | * Open | 0x00 | | * Close | 0x01 | -| * SetLevel | 0x02 | |------------------------------------------------------------------------------| | Attributes: | | | * OpenDuration | 0x0000 | -| * AutoCloseTime | 0x0001 | -| * RemainingDuration | 0x0002 | -| * CurrentState | 0x0003 | -| * TargetState | 0x0004 | -| * StartUpState | 0x0005 | +| * DefaultOpenDuration | 0x0001 | +| * AutoCloseTime | 0x0002 | +| * RemainingDuration | 0x0003 | +| * CurrentState | 0x0004 | +| * TargetState | 0x0005 | | * CurrentLevel | 0x0006 | | * TargetLevel | 0x0007 | -| * OpenLevel | 0x0008 | +| * DefaultOpenLevel | 0x0008 | | * ValveFault | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | @@ -6514,6 +6513,7 @@ class ValveConfigurationAndControlOpen : public ClusterCommand ValveConfigurationAndControlOpen(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("open", credsIssuerConfig) { AddArgument("OpenDuration", 0, UINT32_MAX, &mRequest.openDuration); + AddArgument("TargetLevel", 0, UINT8_MAX, &mRequest.targetLevel); ClusterCommand::AddArguments(); } @@ -6578,45 +6578,6 @@ class ValveConfigurationAndControlClose : public ClusterCommand chip::app::Clusters::ValveConfigurationAndControl::Commands::Close::Type mRequest; }; -/* - * Command SetLevel - */ -class ValveConfigurationAndControlSetLevel : public ClusterCommand -{ -public: - ValveConfigurationAndControlSetLevel(CredentialIssuerCommands * credsIssuerConfig) : - ClusterCommand("set-level", credsIssuerConfig) - { - AddArgument("Level", 0, UINT8_MAX, &mRequest.level); - AddArgument("OpenDuration", 0, UINT32_MAX, &mRequest.openDuration); - ClusterCommand::AddArguments(); - } - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ValveConfigurationAndControl::Commands::SetLevel::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::ValveConfigurationAndControl::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ValveConfigurationAndControl::Commands::SetLevel::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::ValveConfigurationAndControl::Commands::SetLevel::Type mRequest; -}; - /*----------------------------------------------------------------------------*\ | Cluster ElectricalEnergyMeasurement | 0x0091 | |------------------------------------------------------------------------------| @@ -19322,23 +19283,22 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential // // Commands // - make_unique(Id, credsIssuerConfig), // - make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // make_unique(Id, credsIssuerConfig), // make_unique(Id, "open-duration", Attributes::OpenDuration::Id, credsIssuerConfig), // + make_unique(Id, "default-open-duration", Attributes::DefaultOpenDuration::Id, credsIssuerConfig), // make_unique(Id, "auto-close-time", Attributes::AutoCloseTime::Id, credsIssuerConfig), // make_unique(Id, "remaining-duration", Attributes::RemainingDuration::Id, credsIssuerConfig), // make_unique(Id, "current-state", Attributes::CurrentState::Id, credsIssuerConfig), // make_unique(Id, "target-state", Attributes::TargetState::Id, credsIssuerConfig), // - make_unique(Id, "start-up-state", Attributes::StartUpState::Id, credsIssuerConfig), // make_unique(Id, "current-level", Attributes::CurrentLevel::Id, credsIssuerConfig), // make_unique(Id, "target-level", Attributes::TargetLevel::Id, credsIssuerConfig), // - make_unique(Id, "open-level", Attributes::OpenLevel::Id, credsIssuerConfig), // + make_unique(Id, "default-open-level", Attributes::DefaultOpenLevel::Id, credsIssuerConfig), // make_unique(Id, "valve-fault", Attributes::ValveFault::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // @@ -19348,7 +19308,10 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // make_unique>(Id, credsIssuerConfig), // make_unique>>( - Id, "open-duration", 0, UINT32_MAX, Attributes::OpenDuration::Id, WriteCommandType::kWrite, credsIssuerConfig), // + Id, "open-duration", 0, UINT32_MAX, Attributes::OpenDuration::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>(Id, "default-open-duration", 0, UINT32_MAX, + Attributes::DefaultOpenDuration::Id, + WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>(Id, "auto-close-time", 0, UINT64_MAX, Attributes::AutoCloseTime::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -19361,14 +19324,12 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential make_unique< WriteAttribute>>( Id, "target-state", 0, UINT8_MAX, Attributes::TargetState::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>( - Id, "start-up-state", 0, UINT8_MAX, Attributes::StartUpState::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "current-level", 0, UINT8_MAX, Attributes::CurrentLevel::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "target-level", 0, UINT8_MAX, Attributes::TargetLevel::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "open-level", 0, UINT8_MAX, Attributes::OpenLevel::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>(Id, "default-open-level", 0, UINT8_MAX, Attributes::DefaultOpenLevel::Id, + WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "valve-fault", 0, UINT16_MAX, Attributes::ValveFault::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( @@ -19386,14 +19347,14 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique(Id, credsIssuerConfig), // make_unique(Id, "open-duration", Attributes::OpenDuration::Id, credsIssuerConfig), // + make_unique(Id, "default-open-duration", Attributes::DefaultOpenDuration::Id, credsIssuerConfig), // make_unique(Id, "auto-close-time", Attributes::AutoCloseTime::Id, credsIssuerConfig), // make_unique(Id, "remaining-duration", Attributes::RemainingDuration::Id, credsIssuerConfig), // make_unique(Id, "current-state", Attributes::CurrentState::Id, credsIssuerConfig), // make_unique(Id, "target-state", Attributes::TargetState::Id, credsIssuerConfig), // - make_unique(Id, "start-up-state", Attributes::StartUpState::Id, credsIssuerConfig), // make_unique(Id, "current-level", Attributes::CurrentLevel::Id, credsIssuerConfig), // make_unique(Id, "target-level", Attributes::TargetLevel::Id, credsIssuerConfig), // - make_unique(Id, "open-level", Attributes::OpenLevel::Id, credsIssuerConfig), // + make_unique(Id, "default-open-level", Attributes::DefaultOpenLevel::Id, credsIssuerConfig), // make_unique(Id, "valve-fault", Attributes::ValveFault::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::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 86c899d49d69a2..bea41c7e1d7fee 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -5532,6 +5532,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = DataModelLogger::LogValue("ValveLevel", indent + 1, value.valveLevel); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'ValveLevel'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -11642,6 +11650,11 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("OpenDuration", 1, value); } + case ValveConfigurationAndControl::Attributes::DefaultOpenDuration::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("DefaultOpenDuration", 1, value); + } case ValveConfigurationAndControl::Attributes::AutoCloseTime::Id: { chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11662,11 +11675,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("TargetState", 1, value); } - case ValveConfigurationAndControl::Attributes::StartUpState::Id: { - chip::app::Clusters::ValveConfigurationAndControl::ValveStateEnum value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("StartUpState", 1, value); - } case ValveConfigurationAndControl::Attributes::CurrentLevel::Id: { chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11677,10 +11685,10 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("TargetLevel", 1, value); } - case ValveConfigurationAndControl::Attributes::OpenLevel::Id: { - chip::app::DataModel::Nullable value; + case ValveConfigurationAndControl::Attributes::DefaultOpenLevel::Id: { + chip::Percent value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("OpenLevel", 1, value); + return DataModelLogger::LogValue("DefaultOpenLevel", 1, value); } case ValveConfigurationAndControl::Attributes::ValveFault::Id: { chip::BitMask 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 15336c55a565c9..c5aec0730e7d59 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -74642,18 +74642,17 @@ class SubscribeAttributeBooleanStateConfigurationClusterRevision : public Subscr | Commands: | | | * Open | 0x00 | | * Close | 0x01 | -| * SetLevel | 0x02 | |------------------------------------------------------------------------------| | Attributes: | | | * OpenDuration | 0x0000 | -| * AutoCloseTime | 0x0001 | -| * RemainingDuration | 0x0002 | -| * CurrentState | 0x0003 | -| * TargetState | 0x0004 | -| * StartUpState | 0x0005 | +| * DefaultOpenDuration | 0x0001 | +| * AutoCloseTime | 0x0002 | +| * RemainingDuration | 0x0003 | +| * CurrentState | 0x0004 | +| * TargetState | 0x0005 | | * CurrentLevel | 0x0006 | | * TargetLevel | 0x0007 | -| * OpenLevel | 0x0008 | +| * DefaultOpenLevel | 0x0008 | | * ValveFault | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | @@ -74678,6 +74677,9 @@ class ValveConfigurationAndControlOpen : public ClusterCommand { { #if MTR_ENABLE_PROVISIONAL AddArgument("OpenDuration", 0, UINT32_MAX, &mRequest.openDuration); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("TargetLevel", 0, UINT8_MAX, &mRequest.targetLevel); #endif // MTR_ENABLE_PROVISIONAL ClusterCommand::AddArguments(); } @@ -74695,10 +74697,21 @@ class ValveConfigurationAndControlOpen : public ClusterCommand { params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; #if MTR_ENABLE_PROVISIONAL if (mRequest.openDuration.HasValue()) { - params.openDuration = [NSNumber numberWithUnsignedInt:mRequest.openDuration.Value()]; + if (mRequest.openDuration.Value().IsNull()) { + params.openDuration = nil; + } else { + params.openDuration = [NSNumber numberWithUnsignedInt:mRequest.openDuration.Value().Value()]; + } } else { params.openDuration = nil; } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.targetLevel.HasValue()) { + params.targetLevel = [NSNumber numberWithUnsignedChar:mRequest.targetLevel.Value()]; + } else { + params.targetLevel = nil; + } #endif // MTR_ENABLE_PROVISIONAL uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; @@ -74770,101 +74783,123 @@ class ValveConfigurationAndControlClose : public ClusterCommand { }; #endif // MTR_ENABLE_PROVISIONAL + #if MTR_ENABLE_PROVISIONAL + /* - * Command SetLevel + * Attribute OpenDuration */ -class ValveConfigurationAndControlSetLevel : public ClusterCommand { +class ReadValveConfigurationAndControlOpenDuration : public ReadAttribute { public: - ValveConfigurationAndControlSetLevel() - : ClusterCommand("set-level") + ReadValveConfigurationAndControlOpenDuration() + : ReadAttribute("open-duration") + { + } + + ~ReadValveConfigurationAndControlOpenDuration() { -#if MTR_ENABLE_PROVISIONAL - AddArgument("Level", 0, UINT8_MAX, &mRequest.level); -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - AddArgument("OpenDuration", 0, UINT32_MAX, &mRequest.openDuration); -#endif // MTR_ENABLE_PROVISIONAL - ClusterCommand::AddArguments(); } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ValveConfigurationAndControl::Commands::SetLevel::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenDuration::Id; - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + 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 = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRValveConfigurationAndControlClusterSetLevelParams alloc] init]; - params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; -#if MTR_ENABLE_PROVISIONAL - params.level = [NSNumber numberWithUnsignedChar:mRequest.level]; -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - if (mRequest.openDuration.HasValue()) { - params.openDuration = [NSNumber numberWithUnsignedInt:mRequest.openDuration.Value()]; - } else { - params.openDuration = nil; + [cluster readAttributeOpenDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ValveConfigurationAndControl.OpenDuration response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ValveConfigurationAndControl OpenDuration read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeValveConfigurationAndControlOpenDuration : public SubscribeAttribute { +public: + SubscribeAttributeValveConfigurationAndControlOpenDuration() + : SubscribeAttribute("open-duration") + { + } + + ~SubscribeAttributeValveConfigurationAndControlOpenDuration() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenDuration::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 = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); } -#endif // MTR_ENABLE_PROVISIONAL - uint16_t repeatCount = mRepeatCount.ValueOr(1); - uint16_t __block responsesNeeded = repeatCount; - while (repeatCount--) { - [cluster setLevelWithParams:params completion: - ^(NSError * _Nullable error) { - responsesNeeded--; - if (error != nil) { - mError = error; - LogNSError("Error", error); - RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); - } - if (responsesNeeded == 0) { - SetCommandExitStatus(mError); - } - }]; + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeOpenDurationWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ValveConfigurationAndControl.OpenDuration 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; } - -private: - chip::app::Clusters::ValveConfigurationAndControl::Commands::SetLevel::Type mRequest; }; #endif // MTR_ENABLE_PROVISIONAL - #if MTR_ENABLE_PROVISIONAL /* - * Attribute OpenDuration + * Attribute DefaultOpenDuration */ -class ReadValveConfigurationAndControlOpenDuration : public ReadAttribute { +class ReadValveConfigurationAndControlDefaultOpenDuration : public ReadAttribute { public: - ReadValveConfigurationAndControlOpenDuration() - : ReadAttribute("open-duration") + ReadValveConfigurationAndControlDefaultOpenDuration() + : ReadAttribute("default-open-duration") { } - ~ReadValveConfigurationAndControlOpenDuration() + ~ReadValveConfigurationAndControlDefaultOpenDuration() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenDuration::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenDuration::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 = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeOpenDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.OpenDuration response %@", [value description]); + [cluster readAttributeDefaultOpenDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ValveConfigurationAndControl.DefaultOpenDuration response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { - LogNSError("ValveConfigurationAndControl OpenDuration read Error", error); + LogNSError("ValveConfigurationAndControl DefaultOpenDuration read Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -74873,24 +74908,24 @@ class ReadValveConfigurationAndControlOpenDuration : public ReadAttribute { } }; -class WriteValveConfigurationAndControlOpenDuration : public WriteAttribute { +class WriteValveConfigurationAndControlDefaultOpenDuration : public WriteAttribute { public: - WriteValveConfigurationAndControlOpenDuration() - : WriteAttribute("open-duration") + WriteValveConfigurationAndControlDefaultOpenDuration() + : WriteAttribute("default-open-duration") { - AddArgument("attr-name", "open-duration"); + AddArgument("attr-name", "default-open-duration"); AddArgument("attr-value", 0, UINT32_MAX, &mValue); WriteAttribute::AddArguments(); } - ~WriteValveConfigurationAndControlOpenDuration() + ~WriteValveConfigurationAndControlDefaultOpenDuration() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenDuration::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenDuration::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); @@ -74903,9 +74938,9 @@ class WriteValveConfigurationAndControlOpenDuration : public WriteAttribute { value = [NSNumber numberWithUnsignedInt:mValue.Value()]; } - [cluster writeAttributeOpenDurationWithValue:value params:params completion:^(NSError * _Nullable error) { + [cluster writeAttributeDefaultOpenDurationWithValue:value params:params completion:^(NSError * _Nullable error) { if (error != nil) { - LogNSError("ValveConfigurationAndControl OpenDuration write Error", error); + LogNSError("ValveConfigurationAndControl DefaultOpenDuration write Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -74917,21 +74952,21 @@ class WriteValveConfigurationAndControlOpenDuration : public WriteAttribute { chip::app::DataModel::Nullable mValue; }; -class SubscribeAttributeValveConfigurationAndControlOpenDuration : public SubscribeAttribute { +class SubscribeAttributeValveConfigurationAndControlDefaultOpenDuration : public SubscribeAttribute { public: - SubscribeAttributeValveConfigurationAndControlOpenDuration() - : SubscribeAttribute("open-duration") + SubscribeAttributeValveConfigurationAndControlDefaultOpenDuration() + : SubscribeAttribute("default-open-duration") { } - ~SubscribeAttributeValveConfigurationAndControlOpenDuration() + ~SubscribeAttributeValveConfigurationAndControlDefaultOpenDuration() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenDuration::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenDuration::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); @@ -74946,10 +74981,10 @@ class SubscribeAttributeValveConfigurationAndControlOpenDuration : public Subscr if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeOpenDurationWithParams:params + [cluster subscribeAttributeDefaultOpenDurationWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.OpenDuration response %@", [value description]); + NSLog(@"ValveConfigurationAndControl.DefaultOpenDuration response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -75305,132 +75340,6 @@ class SubscribeAttributeValveConfigurationAndControlTargetState : public Subscri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute StartUpState - */ -class ReadValveConfigurationAndControlStartUpState : public ReadAttribute { -public: - ReadValveConfigurationAndControlStartUpState() - : ReadAttribute("start-up-state") - { - } - - ~ReadValveConfigurationAndControlStartUpState() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::StartUpState::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 = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeStartUpStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.StartUpState response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ValveConfigurationAndControl StartUpState read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteValveConfigurationAndControlStartUpState : public WriteAttribute { -public: - WriteValveConfigurationAndControlStartUpState() - : WriteAttribute("start-up-state") - { - AddArgument("attr-name", "start-up-state"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteValveConfigurationAndControlStartUpState() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::StartUpState::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 = [[MTRBaseClusterValveConfigurationAndControl 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 writeAttributeStartUpStateWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("ValveConfigurationAndControl StartUpState write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - uint8_t mValue; -}; - -class SubscribeAttributeValveConfigurationAndControlStartUpState : public SubscribeAttribute { -public: - SubscribeAttributeValveConfigurationAndControlStartUpState() - : SubscribeAttribute("start-up-state") - { - } - - ~SubscribeAttributeValveConfigurationAndControlStartUpState() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::StartUpState::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 = [[MTRBaseClusterValveConfigurationAndControl 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 subscribeAttributeStartUpStateWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.StartUpState 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 CurrentLevel */ @@ -75602,34 +75511,34 @@ class SubscribeAttributeValveConfigurationAndControlTargetLevel : public Subscri #if MTR_ENABLE_PROVISIONAL /* - * Attribute OpenLevel + * Attribute DefaultOpenLevel */ -class ReadValveConfigurationAndControlOpenLevel : public ReadAttribute { +class ReadValveConfigurationAndControlDefaultOpenLevel : public ReadAttribute { public: - ReadValveConfigurationAndControlOpenLevel() - : ReadAttribute("open-level") + ReadValveConfigurationAndControlDefaultOpenLevel() + : ReadAttribute("default-open-level") { } - ~ReadValveConfigurationAndControlOpenLevel() + ~ReadValveConfigurationAndControlDefaultOpenLevel() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenLevel::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenLevel::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 = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeOpenLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.OpenLevel response %@", [value description]); + [cluster readAttributeDefaultOpenLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ValveConfigurationAndControl.DefaultOpenLevel response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { - LogNSError("ValveConfigurationAndControl OpenLevel read Error", error); + LogNSError("ValveConfigurationAndControl DefaultOpenLevel read Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -75638,24 +75547,24 @@ class ReadValveConfigurationAndControlOpenLevel : public ReadAttribute { } }; -class WriteValveConfigurationAndControlOpenLevel : public WriteAttribute { +class WriteValveConfigurationAndControlDefaultOpenLevel : public WriteAttribute { public: - WriteValveConfigurationAndControlOpenLevel() - : WriteAttribute("open-level") + WriteValveConfigurationAndControlDefaultOpenLevel() + : WriteAttribute("default-open-level") { - AddArgument("attr-name", "open-level"); + AddArgument("attr-name", "default-open-level"); AddArgument("attr-value", 0, UINT8_MAX, &mValue); WriteAttribute::AddArguments(); } - ~WriteValveConfigurationAndControlOpenLevel() + ~WriteValveConfigurationAndControlDefaultOpenLevel() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenLevel::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenLevel::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); @@ -75663,14 +75572,11 @@ class WriteValveConfigurationAndControlOpenLevel : 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 * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } + NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue]; - [cluster writeAttributeOpenLevelWithValue:value params:params completion:^(NSError * _Nullable error) { + [cluster writeAttributeDefaultOpenLevelWithValue:value params:params completion:^(NSError * _Nullable error) { if (error != nil) { - LogNSError("ValveConfigurationAndControl OpenLevel write Error", error); + LogNSError("ValveConfigurationAndControl DefaultOpenLevel write Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -75679,24 +75585,24 @@ class WriteValveConfigurationAndControlOpenLevel : public WriteAttribute { } private: - chip::app::DataModel::Nullable mValue; + chip::Percent mValue; }; -class SubscribeAttributeValveConfigurationAndControlOpenLevel : public SubscribeAttribute { +class SubscribeAttributeValveConfigurationAndControlDefaultOpenLevel : public SubscribeAttribute { public: - SubscribeAttributeValveConfigurationAndControlOpenLevel() - : SubscribeAttribute("open-level") + SubscribeAttributeValveConfigurationAndControlDefaultOpenLevel() + : SubscribeAttribute("default-open-level") { } - ~SubscribeAttributeValveConfigurationAndControlOpenLevel() + ~SubscribeAttributeValveConfigurationAndControlDefaultOpenLevel() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::OpenLevel::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::DefaultOpenLevel::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); @@ -75711,10 +75617,10 @@ class SubscribeAttributeValveConfigurationAndControlOpenLevel : public Subscribe if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeOpenLevelWithParams:params + [cluster subscribeAttributeDefaultOpenLevelWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.OpenLevel response %@", [value description]); + NSLog(@"ValveConfigurationAndControl.DefaultOpenLevel response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -176654,18 +176560,19 @@ void registerClusterValveConfigurationAndControl(Commands & commands) #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // #endif // MTR_ENABLE_PROVISIONAL make_unique(Id), // make_unique(Id), // make_unique(Id), // #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 #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -176682,11 +176589,6 @@ void registerClusterValveConfigurationAndControl(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -176696,9 +176598,9 @@ void registerClusterValveConfigurationAndControl(Commands & commands) make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // + make_unique(), // + make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // From cc752a9861ae0e4017fe40056d398d6ddfc99f28 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 19 Dec 2023 11:31:42 -0500 Subject: [PATCH 02/83] Tool to generate a minimal representation of a device. (#30641) * DeviceConformance: Factor out conformance checks This will let us use conformance as a pre-requisite in other tools. * Generates a minimal representation of a device This representation gives all the top level optional elements that are implemented on the device. Anything that DOES NOT appear in this representation is either mandatory or disallowed based on the elements represented here. * Fix linter * Restyled by isort * address review comments --------- Co-authored-by: Restyled.io --- src/python_testing/MinimalRepresentation.py | 139 ++++++++++++++++++++ src/python_testing/TC_DeviceConformance.py | 131 ++++++++++-------- src/python_testing/spec_parsing_support.py | 4 +- 3 files changed, 218 insertions(+), 56 deletions(-) create mode 100644 src/python_testing/MinimalRepresentation.py diff --git a/src/python_testing/MinimalRepresentation.py b/src/python_testing/MinimalRepresentation.py new file mode 100644 index 00000000000000..c4a19b76cbbf9f --- /dev/null +++ b/src/python_testing/MinimalRepresentation.py @@ -0,0 +1,139 @@ +# +# 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. +# + +from dataclasses import dataclass, field + +from chip.tlv import uint +from conformance_support import ConformanceDecision +from global_attribute_ids import GlobalAttributeIds +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from TC_DeviceConformance import DeviceConformanceTests + + +@dataclass +class ClusterMinimalElements: + feature_masks: list[uint] = field(default_factory=list) + attribute_ids: list[uint] = field(default_factory=list) + # Only received commands are necessary - generated events are ALWAYS determined from accepted + command_ids: list[uint] = field(default_factory=list) + # TODO: need event support + + +class MinimalRepresentationChecker(DeviceConformanceTests): + def GenerateMinimals(self, ignore_in_progress: bool, is_ci: bool) -> dict[uint, dict[uint, ClusterMinimalElements]]: + if not self.xml_clusters: + self.setup_class_helper() + + success, _ = self.check_conformance(ignore_in_progress, is_ci) + if not success: + self.fail_current_test("Problems with conformance") + + # Now what we know the conformance is OK, we want to expose all the data model elements on the device + # that are OPTIONAL given the other elements that are present. We can do this by assessing the conformance + # again only on the elements we have. Because we've already run the full conformance checkers, we can rely + # on the optional response really meaning optional. + # TODO: do we also want to record the optional stuff that's NOT implemented? + # endpoint -> list of clusters by id + representation: dict[uint, dict[uint, ClusterMinimalElements]] = {} + for endpoint_id, endpoint in self.endpoints_tlv.items(): + representation[endpoint_id] = {} + for cluster_id, cluster in endpoint.items(): + minimal = ClusterMinimalElements() + if cluster_id not in self.xml_clusters.keys(): + continue + + feature_map = cluster[GlobalAttributeIds.FEATURE_MAP_ID] + attribute_list = cluster[GlobalAttributeIds.ATTRIBUTE_LIST_ID] + all_command_list = cluster[GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID] + \ + cluster[GlobalAttributeIds.GENERATED_COMMAND_LIST_ID] + accepted_command_list = cluster[GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID] + + # All optional features + feature_masks = [1 << i for i in range(32) if feature_map & (1 << i)] + for f in feature_masks: + xml_feature = self.xml_clusters[cluster_id].features[f] + conformance_decision = xml_feature.conformance(feature_map, attribute_list, all_command_list) + if conformance_decision == ConformanceDecision.OPTIONAL: + minimal.feature_masks.append(f) + + # All optional attributes + for attribute_id, attribute in cluster.items(): + if attribute_id not in self.xml_clusters[cluster_id].attributes.keys(): + if attribute_id > 0xFFFF: + # MEI + minimal.attribute_ids.append(attribute_id) + continue + xml_attribute = self.xml_clusters[cluster_id].attributes[attribute_id] + conformance_decision = xml_attribute.conformance(feature_map, attribute_list, all_command_list) + if conformance_decision == ConformanceDecision.OPTIONAL: + minimal.attribute_ids.append(attribute_id) + + # All optional commands + for command_id in accepted_command_list: + if command_id not in self.xml_clusters[cluster_id].accepted_commands: + if command_id > 0xFFFF: + # MEI + minimal.attribute_ids.append(command_id) + continue + xml_command = self.xml_clusters[cluster_id].accepted_commands[command_id] + conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) + if conformance_decision == ConformanceDecision.OPTIONAL: + minimal.command_ids.append(command_id) + + representation[endpoint_id][cluster_id] = minimal + + return representation + + def PrettyPrintRepresentation(self, representation: dict[uint, dict[uint, ClusterMinimalElements]]) -> None: + for endpoint_id, cluster_list in representation.items(): + print(f'Endpoint: {endpoint_id}') + for cluster_id, minimals in cluster_list.items(): + name = self.xml_clusters[cluster_id].name + print(f' Cluster {cluster_id:04x} - {name}') + print(' Features:') + for feature in minimals.feature_masks: + code = self.xml_clusters[cluster_id].features[feature].code + print(f' {feature:02x}: {code}') + print(' Attributes:') + for attribute in minimals.attribute_ids: + name = self.xml_clusters[cluster_id].attributes[attribute].name + print(f' {attribute:02x}: {name}') + print(' Commands:') + for command in minimals.command_ids: + name = self.xml_clusters[cluster_id].accepted_commands[command].name + print(f' {command:02x}: {name}') + + +# Helper for running this against a test device through the python test framework +class MinimalRunner(MatterBaseTest, MinimalRepresentationChecker): + @async_test_body + async def setup_class(self): + super().setup_class() + await self.setup_class_helper() + + def test_MinimalRepresentation(self): + # Before we can generate a minimal representation, we need to make sure that the device is conformant. + # Otherwise, the values we extract aren't fully informative. + ignore_in_progress = self.user_params.get("ignore_in_progress", False) + is_ci = self.check_pics('PICS_SDK_CI_ONLY') + representation = self.GenerateMinimals(ignore_in_progress, is_ci) + print(type(representation[0])) + self.PrettyPrintRepresentation(representation) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index ddccc041cba567..18ad273a6241d6 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -22,19 +22,20 @@ from chip.tlv import uint from conformance_support import ConformanceDecision, conformance_allowed from global_attribute_ids import GlobalAttributeIds -from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, MatterBaseTest, - async_test_body, default_matter_test_main) +from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, MatterBaseTest, ProblemNotice, + ProblemSeverity, async_test_body, default_matter_test_main) from spec_parsing_support import CommandType, build_xml_clusters -class TC_DeviceConformance(MatterBaseTest, BasicCompositionTests): - @async_test_body - async def setup_class(self): - super().setup_class() - await self.setup_class_helper() +class DeviceConformanceTests(BasicCompositionTests): + async def setup_class_helper(self): + await super().setup_class_helper() self.xml_clusters, self.problems = build_xml_clusters() - def test_TC_IDM_10_2(self): + def check_conformance(self, ignore_in_progress: bool, is_ci: bool): + problems = [] + success = True + def conformance_str(conformance: Callable, feature_map: uint, feature_dict: dict[str, uint]) -> str: codes = [] for mask, details in feature_dict.items(): @@ -43,8 +44,16 @@ def conformance_str(conformance: Callable, feature_map: uint, feature_dict: dict return f'Conformance: {str(conformance)}, implemented features: {",".join(codes)}' - ignore_in_progress = self.user_params.get("ignore_in_progress", False) - is_ci = self.check_pics('PICS_SDK_CI_ONLY') + def record_problem(location, problem, severity): + problems.append(ProblemNotice("IDM-10.2", location, severity, problem, "")) + + def record_error(location, problem): + nonlocal success + record_problem(location, problem, ProblemSeverity.ERROR) + success = False + + def record_warning(location, problem): + record_problem(location, problem, ProblemSeverity.WARNING) ignore_attributes: dict[int, list[int]] = {} ignore_features: dict[int, list[int]] = {} @@ -75,8 +84,7 @@ def conformance_str(conformance: Callable, feature_map: uint, feature_dict: dict continue location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id) # TODO: update this from a warning once we have all the data - self.record_warning(self.get_test_name(), location=location, - problem='Standard cluster found on device, but is not present in spec data') + record_warning(location=location, problem='Standard cluster found on device, but is not present in spec data') continue feature_map = cluster[GlobalAttributeIds.FEATURE_MAP_ID] @@ -90,25 +98,21 @@ def conformance_str(conformance: Callable, feature_map: uint, feature_dict: dict location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=GlobalAttributeIds.FEATURE_MAP_ID) if f not in self.xml_clusters[cluster_id].features.keys(): - self.record_error(self.get_test_name(), location=location, problem=f'Unknown feature with mask 0x{f:02x}') - success = False + record_error(location=location, problem=f'Unknown feature with mask 0x{f:02x}') continue if cluster_id in ignore_features and f in ignore_features[cluster_id]: continue xml_feature = self.xml_clusters[cluster_id].features[f] conformance_decision = xml_feature.conformance(feature_map, attribute_list, all_command_list) if not conformance_allowed(conformance_decision, allow_provisional): - self.record_error(self.get_test_name(), location=location, - problem=f'Disallowed feature with mask 0x{f:02x}') - success = False + record_error(location=location, problem=f'Disallowed feature with mask 0x{f:02x}') for feature_mask, xml_feature in self.xml_clusters[cluster_id].features.items(): if cluster_id in ignore_features and feature_mask in ignore_features[cluster_id]: continue conformance_decision = xml_feature.conformance(feature_map, attribute_list, all_command_list) if conformance_decision == ConformanceDecision.MANDATORY and feature_mask not in feature_masks: - self.record_error(self.get_test_name(), location=location, - problem=f'Required feature with mask 0x{f:02x} is not present in feature map. {conformance_str(xml_feature.conformance, feature_map, self.xml_clusters[cluster_id].features)}') - success = False + record_error( + location=location, problem=f'Required feature with mask 0x{f:02x} is not present in feature map. {conformance_str(xml_feature.conformance, feature_map, self.xml_clusters[cluster_id].features)}') # Attribute conformance checking for attribute_id, attribute in cluster.items(): @@ -119,29 +123,24 @@ def conformance_str(conformance: Callable, feature_map: uint, feature_dict: dict # TODO: Consolidate the range checks with IDM-10.1 once that lands if attribute_id <= 0x4FFF: # manufacturer attribute - self.record_error(self.get_test_name(), location=location, - problem='Standard attribute found on device, but not in spec') - success = False + record_error(location=location, problem='Standard attribute found on device, but not in spec') continue xml_attribute = self.xml_clusters[cluster_id].attributes[attribute_id] conformance_decision = xml_attribute.conformance(feature_map, attribute_list, all_command_list) if not conformance_allowed(conformance_decision, allow_provisional): location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=attribute_id) - self.record_error(self.get_test_name(), location=location, - problem=f'Attribute 0x{attribute_id:02x} is included, but is disallowed by conformance. {conformance_str(xml_attribute.conformance, feature_map, self.xml_clusters[cluster_id].features)}') - success = False + record_error( + location=location, problem=f'Attribute 0x{attribute_id:02x} is included, but is disallowed by conformance. {conformance_str(xml_attribute.conformance, feature_map, self.xml_clusters[cluster_id].features)}') for attribute_id, xml_attribute in self.xml_clusters[cluster_id].attributes.items(): if cluster_id in ignore_attributes and attribute_id in ignore_attributes[cluster_id]: continue conformance_decision = xml_attribute.conformance(feature_map, attribute_list, all_command_list) if conformance_decision == ConformanceDecision.MANDATORY and attribute_id not in cluster.keys(): location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=attribute_id) - self.record_error(self.get_test_name(), location=location, - problem=f'Attribute 0x{attribute_id:02x} is required, but is not present on the DUT. {conformance_str(xml_attribute.conformance, feature_map, self.xml_clusters[cluster_id].features)}') - success = False + record_error( + location=location, problem=f'Attribute 0x{attribute_id:02x} is required, but is not present on the DUT. {conformance_str(xml_attribute.conformance, feature_map, self.xml_clusters[cluster_id].features)}') - def check_spec_conformance_for_commands(command_type: CommandType) -> bool: - success = True + def check_spec_conformance_for_commands(command_type: CommandType): global_attribute_id = GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID if command_type == CommandType.ACCEPTED else GlobalAttributeIds.GENERATED_COMMAND_LIST_ID xml_commands_dict = self.xml_clusters[cluster_id].accepted_commands if command_type == CommandType.ACCEPTED else self.xml_clusters[cluster_id].generated_commands command_list = cluster[global_attribute_id] @@ -152,40 +151,42 @@ def check_spec_conformance_for_commands(command_type: CommandType) -> bool: if command_id <= 0xFF: # manufacturer command continue - self.record_error(self.get_test_name(), location=location, - problem='Standard command found on device, but not in spec') - success = False + record_error(location=location, problem='Standard command found on device, but not in spec') continue xml_command = xml_commands_dict[command_id] conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) if not conformance_allowed(conformance_decision, allow_provisional): - self.record_error(self.get_test_name(), location=location, - problem=f'Command 0x{command_id:02x} is included, but disallowed by conformance. {conformance_str(xml_command.conformance, feature_map, self.xml_clusters[cluster_id].features)}') - success = False + record_error( + location=location, problem=f'Command 0x{command_id:02x} is included, but disallowed by conformance. {conformance_str(xml_command.conformance, feature_map, self.xml_clusters[cluster_id].features)}') for command_id, xml_command in xml_commands_dict.items(): conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) if conformance_decision == ConformanceDecision.MANDATORY and command_id not in command_list: location = CommandPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, command_id=command_id) - self.record_error(self.get_test_name(), location=location, - problem=f'Command 0x{command_id:02x} is required, but is not present on the DUT. {conformance_str(xml_command.conformance, feature_map, self.xml_clusters[cluster_id].features)}') - success = False - return success + record_error( + location=location, problem=f'Command 0x{command_id:02x} is required, but is not present on the DUT. {conformance_str(xml_command.conformance, feature_map, self.xml_clusters[cluster_id].features)}') # Command conformance checking - cmd_success = check_spec_conformance_for_commands(CommandType.ACCEPTED) - success = False if not cmd_success else success - cmd_success = check_spec_conformance_for_commands(CommandType.GENERATED) - success = False if not cmd_success else success + check_spec_conformance_for_commands(CommandType.ACCEPTED) + check_spec_conformance_for_commands(CommandType.GENERATED) # TODO: Add choice checkers + print(f'success = {success}') + return success, problems - if not success: - self.fail_current_test("Problems with conformance") - - def test_IDM_10_3(self): + def check_revisions(self, ignore_in_progress: bool): + problems = [] success = True - ignore_in_progress = self.user_params.get("ignore_in_progress", False) + def record_problem(location, problem, severity): + problems.append(ProblemNotice("IDM-10.3", location, severity, problem, "")) + + def record_error(location, problem): + nonlocal success + record_problem(location, problem, ProblemSeverity.ERROR) + success = False + + def record_warning(location, problem): + record_problem(location, problem, ProblemSeverity.WARNING) ignore_revisions: list[int] = [] if ignore_in_progress: @@ -201,17 +202,37 @@ def test_IDM_10_3(self): continue location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id) # TODO: update this from a warning once we have all the data - self.record_warning(self.get_test_name(), location=location, - problem='Standard cluster found on device, but is not present in spec data') + record_warning(location=location, problem='Standard cluster found on device, but is not present in spec data') continue if cluster_id in ignore_revisions: continue if int(self.xml_clusters[cluster_id].revision) != cluster[GlobalAttributeIds.CLUSTER_REVISION_ID]: location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=GlobalAttributeIds.CLUSTER_REVISION_ID) - self.record_error(self.get_test_name( - ), location=location, problem=f'Revision found on cluster ({cluster[GlobalAttributeIds.CLUSTER_REVISION_ID]}) does not match revision listed in the spec ({self.xml_clusters[cluster_id].revision})') - success = False + record_error( + location=location, problem=f'Revision found on cluster ({cluster[GlobalAttributeIds.CLUSTER_REVISION_ID]}) does not match revision listed in the spec ({self.xml_clusters[cluster_id].revision})') + + return success, problems + + +class TC_DeviceConformance(MatterBaseTest, DeviceConformanceTests): + @async_test_body + async def setup_class(self): + super().setup_class() + await self.setup_class_helper() + + def test_TC_IDM_10_2(self): + ignore_in_progress = self.user_params.get("ignore_in_progress", False) + is_ci = self.check_pics('PICS_SDK_CI_ONLY') + success, problems = self.check_conformance(ignore_in_progress, is_ci) + self.problems.extend(problems) + if not success: + self.fail_current_test("Problems with conformance") + + def test_TC_IDM_10_3(self): + ignore_in_progress = self.user_params.get("ignore_in_progress", False) + success, problems = self.check_revisions(ignore_in_progress) + self.problems.extend(problems) if not success: self.fail_current_test("Problems with cluster revision on at least one cluster") diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index fa08f34d776a5d..13c2f91e203029 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -68,7 +68,9 @@ class XmlCluster: feature_map: dict[str, uint] attribute_map: dict[str, uint] command_map: dict[str, uint] - features: dict[str, XmlFeature] + # mask to XmlFeature + features: dict[uint, XmlFeature] + # IDs to class attributes: dict[uint, XmlAttribute] accepted_commands: dict[uint, XmlCommand] generated_commands: dict[uint, XmlCommand] From 7f2b39130b5f55bbd103ad7e6c62ab9f3ca6a676 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 19 Dec 2023 11:40:13 -0500 Subject: [PATCH 03/83] TC-ACL-2.2: Implement in python (#31049) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * TC-ACL-2.2: Implement in python Lets us do the all endpoint check in a sane way. * flake8 * Apply suggestions from code review Co-authored-by: René Josefsen <69624991+ReneJosefsen@users.noreply.github.com> --------- Co-authored-by: René Josefsen <69624991+ReneJosefsen@users.noreply.github.com> --- src/python_testing/TC_ACL_2_2.py | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/python_testing/TC_ACL_2_2.py diff --git a/src/python_testing/TC_ACL_2_2.py b/src/python_testing/TC_ACL_2_2.py new file mode 100644 index 00000000000000..5c21f177f332fc --- /dev/null +++ b/src/python_testing/TC_ACL_2_2.py @@ -0,0 +1,51 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_ACL_2_2(MatterBaseTest): + + def desc_TC_ACL_2_2(self) -> str: + return "[TC-ACL-2.2] Cluster endpoint" + + def steps_TC_ACE_2_2(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH1 reads DUT Descriptor cluster ServerList attribute from Endpoint 0"), + TestStep(3, "TH1 reads DUT Descriptor cluster ServerList attribute from every Endpoint except 0"), + ] + return steps + + @async_test_body + async def test_TC_ACE_2_2(self): + self.step(1) + self.step(2) + data = await self.default_controller.ReadAttribute(nodeid=self.dut_node_id, attributes=[(Clusters.Descriptor.Attributes.ServerList)]) + asserts.assert_true(Clusters.AccessControl.id in data[0][Clusters.Descriptor] + [Clusters.Descriptor.Attributes.ServerList], "ACL cluster not on EP0") + self.step(3) + for endpoint, ep_data in data.items(): + if endpoint == 0: + continue + asserts.assert_false(Clusters.AccessControl.id in ep_data[Clusters.Descriptor][Clusters.Descriptor.Attributes.ServerList], + f"ACL cluster incorrectly present on endpoint {endpoint}") + + +if __name__ == "__main__": + default_matter_test_main() From 9643ea470619cd3c8286da2f626cebe52135f707 Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:54:34 -0500 Subject: [PATCH 04/83] [ICD] Add Nonce validation to Check-In protocol and parsing unit tests (#31080) * Add Nonce validation and parsing unit tests * Add missing comments * Remove unused test signature * fix comment * remove include * fix comment --- .../secure_channel/CheckinMessage.cpp | 19 +- src/protocols/secure_channel/CheckinMessage.h | 9 +- .../tests/CheckIn_Message_test_vectors.h | 42 +++ .../secure_channel/tests/TestCheckinMsg.cpp | 357 ++++++++++++------ 4 files changed, 311 insertions(+), 116 deletions(-) diff --git a/src/protocols/secure_channel/CheckinMessage.cpp b/src/protocols/secure_channel/CheckinMessage.cpp index 82f87cb478cb05..24fd07fba6be4f 100644 --- a/src/protocols/secure_channel/CheckinMessage.cpp +++ b/src/protocols/secure_channel/CheckinMessage.cpp @@ -105,10 +105,25 @@ CHIP_ERROR CheckinMessage::ParseCheckinMessagePayload(const Crypto::Aes128KeyHan } // Read decrypted counter and application data - counter = Encoding::LittleEndian::Get32(appData.data()); + static_assert(sizeof(CounterType) == sizeof(uint32_t), "Expect counter to be 32 bits for correct decoding"); + CounterType tempCounter = Encoding::LittleEndian::Get32(appData.data()); - // TODO : Validate received nonce by calculating it with the hmacKeyHandle and received Counter value + // Validate that the received nonce is correct + { + uint8_t calculatedNonceBuffer[CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES] = { 0 }; + Encoding::LittleEndian::BufferWriter writer(calculatedNonceBuffer, sizeof(calculatedNonceBuffer)); + + ReturnErrorOnFailure(GenerateCheckInMessageNonce(hmacKeyHandle, tempCounter, writer)); + + // Validate received nonce is the same as the calculated + ByteSpan nonce = payload.SubSpan(0, CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES); + VerifyOrReturnError(memcmp(nonce.data(), calculatedNonceBuffer, sizeof(calculatedNonceBuffer)) == 0, CHIP_ERROR_INTERNAL); + } + + // We have successfully decrypted and validated Check-In message + // Set output values + counter = tempCounter; // Shift to remove the counter from the appData memmove(appData.data(), sizeof(CounterType) + appData.data(), appDataSize); appData.reduce_size(appDataSize); diff --git a/src/protocols/secure_channel/CheckinMessage.h b/src/protocols/secure_channel/CheckinMessage.h index 530c601a2432fe..a0123f3749ce2b 100644 --- a/src/protocols/secure_channel/CheckinMessage.h +++ b/src/protocols/secure_channel/CheckinMessage.h @@ -74,13 +74,16 @@ class DLL_EXPORT CheckinMessage * @param[in] hmac128KeyHandle Key handle with which to verify the received nonce in the check-in payload (using HMAC). * @param[in] payload The received payload to decrypt and parse * @param[out] counter The counter value retrieved from the payload + * If an error occurs, no value will be set. * @param[in,out] appData The optional application data decrypted. The input size of appData must be at least the - * size of GetAppDataSize(payload) + sizeof(CounterType), because appData is used as a work buffer for the decryption process. - * The output size on success will be GetAppDataSize(payload). + * size of GetAppDataSize(payload) + sizeof(CounterType), because appData is used as a work + * buffer for the decryption process. The output size on success will be + * GetAppDataSize(payload). If an error occurs, appData might countain data, + * but the data CANNOT be used since we were not able to validate it. * * @return CHIP_ERROR_INVALID_MESSAGE_LENGTH if the payload is shorter than the minimum payload size * CHIP_ERROR_BUFFER_TOO_SMALL if appData buffer is too small - * CHIP_ERROR_INVALID_ARGUMENT if the provided arguments cannot be used to parse the Check-In message + * CHIP_ERROR_INTERNAL if we were not able to decrypt or validate the Check-In message */ static CHIP_ERROR ParseCheckinMessagePayload(const Crypto::Aes128KeyHandle & aes128KeyHandle, const Crypto::Hmac128KeyHandle & hmacKeyHandle, ByteSpan & payload, diff --git a/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h b/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h index c49bf4e4766a85..5563150ebfee12 100644 --- a/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h +++ b/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h @@ -207,3 +207,45 @@ const CheckIn_Message_test_vector vector5 = { .key = kKey5, .payload_len = sizeof(kPayload5) }; const CheckIn_Message_test_vector checkIn_message_test_vectors[]{ vector1, vector2, vector3, vector4, vector5 }; + +/** + * Invalid Counter / Nonce Match vector + */ + +const uint8_t kInvalidNonceKey[] = { + 0xca, 0x67, 0xd4, 0x1f, 0xf7, 0x11, 0x29, 0x10, 0xfd, 0xd1, 0x8a, 0x1b, 0xf9, 0x9e, 0xa9, 0x74 +}; + +const uint8_t kInvalidNonceApplicationData[] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6c, + 0x6f, 0x6e, 0x67, 0x75, 0x65, 0x72, 0x20, 0x6c, 0x6f, 0x6e, 0x67, + 0x75, 0x65, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67 }; + +const uint8_t kInvalidNonceNonce[] = { 0x06, 0x34, 0x67, 0x6e, 0xa6, 0xe0, 0x70, 0x7b, 0x7a, 0xd7, 0x81, 0x4f, 0xf8 }; + +const uint8_t kInvalidNonceCiphertext[] = { 0x29, 0x5b, 0x18, 0xd1, 0x9a, 0x23, 0xb2, 0xe4, 0xfa, 0xdf, 0x82, 0x92, + 0x53, 0x51, 0x7f, 0xf3, 0xc9, 0x1d, 0x9d, 0x50, 0xd6, 0x62, 0x42, 0x03, + 0x35, 0x01, 0xaa, 0x23, 0xad, 0x19, 0xcb, 0x6f, 0x5b, 0xee, 0x56, 0xb3 }; + +const uint8_t kInvalidNonceMic[] = { + 0xd5, 0x8a, 0x92, 0x2b, 0x66, 0x44, 0x89, 0x3e, 0x66, 0x31, 0x8b, 0xb5, 0x53, 0x79, 0x24, 0x8b +}; + +const uint8_t kInvalidNoncePayload[] = { 0x06, 0x34, 0x67, 0x6e, 0xa6, 0xe0, 0x70, 0x7b, 0x7a, 0xd7, 0x81, 0x4f, 0xf8, + 0x29, 0x5b, 0x18, 0xd1, 0x9a, 0x23, 0xb2, 0xe4, 0xfa, 0xdf, 0x82, 0x92, 0x53, + 0x51, 0x7f, 0xf3, 0xc9, 0x1d, 0x9d, 0x50, 0xd6, 0x62, 0x42, 0x03, 0x35, 0x01, + 0xaa, 0x23, 0xad, 0x19, 0xcb, 0x6f, 0x5b, 0xee, 0x56, 0xb3, 0xd5, 0x8a, 0x92, + 0x2b, 0x66, 0x44, 0x89, 0x3e, 0x66, 0x31, 0x8b, 0xb5, 0x53, 0x79, 0x24, 0x8b }; + +const CheckIn_Message_test_vector invalidNonceVector = { .key = kInvalidNonceKey, + .key_len = sizeof(kInvalidNonceKey), + .application_data = kInvalidNonceApplicationData, + .application_data_len = sizeof(kInvalidNonceApplicationData), + .counter = 12, + .nonce = kInvalidNonceNonce, + .nonce_len = sizeof(kInvalidNonceNonce), + .ciphertext = kInvalidNonceCiphertext, + .ciphertext_len = sizeof(kInvalidNonceCiphertext), + .mic = kInvalidNonceMic, + .mic_len = sizeof(kInvalidNonceMic), + .payload = kInvalidNoncePayload, + .payload_len = sizeof(kInvalidNoncePayload) }; diff --git a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp index 8fe3a4eaeac768..f756b627defef9 100644 --- a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp +++ b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp @@ -20,19 +20,15 @@ #include #include #include +#include #include +#include #include #include #include #include #include #include -// AES_CCM_128_test_vectors is being replaced by the CheckIn_Message_test_vectors -// New tests need to use the CheckIn_Message_test_vectors -#include -#include -#include -#include using namespace chip; using namespace chip::Protocols; @@ -48,18 +44,25 @@ class TestCheckInMsg public: static void TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload(nlTestSuite * inSuite, void * inContext); static void TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput(nlTestSuite * inSuite, void * inContext); - static void TestCheckInMessagePayloadSize(nlTestSuite * inSuite, void * inContext); - static void TestCheckInMessagePayloadSizeNullBuffer(nlTestSuite * inSuite, void * inContext); static void TestCheckinMessageGenerate_ValidInputsTooSmallOutput(nlTestSuite * inSuite, void * inContext); static void TestCheckInMessageGenerate_EmptyAesKeyHandle(nlTestSuite * inSuite, void * inContext); static void TestCheckInMessageGenerate_EmptyHmacKeyHandle(nlTestSuite * inSuite, void * inContext); - - static void TestCheckinParse(nlTestSuite * inSuite, void * inContext); - static void TestCheckinGenerateParse(nlTestSuite * inSuite, void * inContext); + static void TestCheckinMessageParse_ValidInputsSameSizeMinAppData(nlTestSuite * inSuite, void * inContext); + static void TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData(nlTestSuite * inSuite, void * inContext); + static void TestCheckinMessageParse_ValidInputsTooSmallAppData(nlTestSuite * inSuite, void * inContext); + static void TestCheckInMessageParse_EmptyAesKeyHandle(nlTestSuite * inSuite, void * inContext); + static void TestCheckInMessageParse_EmptyHmacKeyHandle(nlTestSuite * inSuite, void * inContext); + static void TestCheckInMessagePayloadSize(nlTestSuite * inSuite, void * inContext); + static void TestCheckInMessagePayloadSizeNullBuffer(nlTestSuite * inSuite, void * inContext); + static void TestCheckinMessageParse_CorruptedNonce(nlTestSuite * inSuite, void * inContext); + static void TestCheckinMessageParse_InvalidNonce(nlTestSuite * inSuite, void * inContext); private: static CHIP_ERROR GenerateAndVerifyPayload(nlTestSuite * inSuite, MutableByteSpan & output, const CheckIn_Message_test_vector & vector); + + static CHIP_ERROR ParseAndVerifyPayload(nlTestSuite * inSuite, MutableByteSpan & applicationData, + const CheckIn_Message_test_vector & vector, bool injectInvalidNonce); }; /** @@ -92,8 +95,15 @@ CHIP_ERROR TestCheckInMsg::GenerateAndVerifyPayload(nlTestSuite * inSuite, Mutab ByteSpan applicationData(vector.application_data, vector.application_data_len); // Verify that the generation succeeded - ReturnErrorOnFailure( - CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output)); + CHIP_ERROR err = + CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output); + if (err != CHIP_NO_ERROR) + { + keystore.DestroyKey(aes128KeyHandle); + keystore.DestroyKey(hmac128KeyHandle); + + return err; + } // Validate Full payload NL_TEST_ASSERT_EQUALS(inSuite, output.size(), vector.payload_len); @@ -120,7 +130,73 @@ CHIP_ERROR TestCheckInMsg::GenerateAndVerifyPayload(nlTestSuite * inSuite, Mutab keystore.DestroyKey(aes128KeyHandle); keystore.DestroyKey(hmac128KeyHandle); - return CHIP_NO_ERROR; + return err; +} + +/** + * @brief Helper function that parses the Check-In message based on the test vector + * and verifies parsed Check-In message + * Helper is to avoid having the same code in multiple tests + * + * @return CHIP_NO_ERROR if the parsing was successful + * error code if the generation failed - see ParseCheckinMessagePayload + */ +CHIP_ERROR TestCheckInMsg::ParseAndVerifyPayload(nlTestSuite * inSuite, MutableByteSpan & applicationData, + const CheckIn_Message_test_vector & vector, bool injectInvalidNonce) +{ + TestSessionKeystoreImpl keystore; + + // Copy payload to be able to modify it for invalid nonce tests + uint8_t payloadBuffer[300] = { 0 }; + memcpy(payloadBuffer, vector.payload, vector.payload_len); + + if (injectInvalidNonce) + { + // Modify nonce to validate that the parsing can detect that the message was manipulated + payloadBuffer[0] ^= 0xFF; + } + + // Create payload byte span + ByteSpan payload(payloadBuffer, vector.payload_len); + + CounterType decryptedCounter = 0; + + // Two distinct key material buffers to ensure crypto-hardware-assist with single-usage keys create two different handles. + Symmetric128BitsKeyByteArray aesKeyMaterial; + memcpy(aesKeyMaterial, vector.key, vector.key_len); + + Symmetric128BitsKeyByteArray hmacKeyMaterial; + memcpy(hmacKeyMaterial, vector.key, vector.key_len); + + Aes128KeyHandle aes128KeyHandle; + NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle)); + + Hmac128KeyHandle hmac128KeyHandle; + NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle)); + + // Verify that the Parsing succeeded + CHIP_ERROR err = + CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData); + if (err != CHIP_NO_ERROR) + { + keystore.DestroyKey(aes128KeyHandle); + keystore.DestroyKey(hmac128KeyHandle); + + return err; + } + + // Verify decrypted counter value + NL_TEST_ASSERT_EQUALS(inSuite, vector.counter, decryptedCounter); + + // Verify application data + NL_TEST_ASSERT_EQUALS(inSuite, vector.application_data_len, applicationData.size()); + NL_TEST_ASSERT(inSuite, memcmp(vector.application_data, applicationData.data(), applicationData.size()) == 0); + + // Cleanup + keystore.DestroyKey(aes128KeyHandle); + keystore.DestroyKey(hmac128KeyHandle); + + return err; } /** @@ -203,16 +279,16 @@ void TestCheckInMsg::TestCheckInMessageGenerate_EmptyAesKeyHandle(nlTestSuite * ByteSpan applicationData(vector.application_data, vector.application_data_len); /* - Passing an empty key handle while using PSA crypto will result in a failure. - When using OpenSSL this same test result in a success. - Issue #28986 - - Verify that the generation fails with an empty key handle + TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure. + When using OpenSSL this same test result in a success. + */ +#if 0 + // Verify that the generation fails with an empty key handle NL_TEST_ASSERT_(inSuite, CHIP_NO_ERROR != CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output)); - */ +#endif // Clean up keystore.DestroyKey(hmac128KeyHandle); @@ -245,133 +321,188 @@ void TestCheckInMsg::TestCheckInMessageGenerate_EmptyHmacKeyHandle(nlTestSuite * ByteSpan applicationData(vector.application_data, vector.application_data_len); /* - Passing an empty key handle while using PSA crypto will result in a failure. - When using OpenSSL this same test result in a success. - Issue #28986 - - Verify that the generation fails with an empty key handle + TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure. + When using OpenSSL this same test result in a success. + */ +#if 0 + // Verify that the generation fails with an empty key handle NL_TEST_ASSERT_(inSuite, CHIP_NO_ERROR != CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output)); - */ +#endif // Clean up keystore.DestroyKey(aes128KeyHandle); } -void TestCheckInMsg::TestCheckinParse(nlTestSuite * inSuite, void * inContext) +/** + * @brief Test verifies that the Check-In message parsing succeeds with the Application buffer set to the minimum required size + */ +void TestCheckInMsg::TestCheckinMessageParse_ValidInputsSameSizeMinAppData(nlTestSuite * inSuite, void * inContext) { - uint8_t a[300] = { 0 }; - uint8_t b[300] = { 0 }; - MutableByteSpan outputBuffer{ a }; - MutableByteSpan buffer{ b }; - uint32_t counter = 0, decryptedCounter; - ByteSpan userData; + int numOfTestCases = ArraySize(checkIn_message_test_vectors); + for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++) + { + CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted]; - CHIP_ERROR err = CHIP_NO_ERROR; + uint8_t applicationDataBuffer[128] = { 0 }; + MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer)); + applicationData.reduce_size(vector.application_data_len + sizeof(CounterType)); - TestSessionKeystoreImpl keystore; + NL_TEST_ASSERT_SUCCESS(inSuite, ParseAndVerifyPayload(inSuite, applicationData, vector, false)); + } +} + +/** + * @brief Test verifies that the Check-In message parsing succeeds with the Application buffer set to a larger than necessary size + */ +void TestCheckInMsg::TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData(nlTestSuite * inSuite, void * inContext) +{ + int numOfTestCases = ArraySize(checkIn_message_test_vectors); + for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++) + { + CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted]; - // Verify User Data Encryption Decryption - uint8_t data[] = { "This is some user Data. It should be encrypted" }; - userData = chip::ByteSpan(data); - const ccm_128_test_vector & test = *ccm_128_test_vectors[0]; + uint8_t applicationDataBuffer[128] = { 0 }; + MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer)); - // Two distinct key material buffers to ensure crypto-hardware-assist with single-usage keys create two different handles. - Symmetric128BitsKeyByteArray aesKeyMaterial; - memcpy(aesKeyMaterial, test.key, test.key_len); + NL_TEST_ASSERT_SUCCESS(inSuite, ParseAndVerifyPayload(inSuite, applicationData, vector, false)); + } +} - Symmetric128BitsKeyByteArray hmacKeyMaterial; - memcpy(hmacKeyMaterial, test.key, test.key_len); +/** + * @brief Test verifies that the Check-In message throws an error if the application data buffer is too small + */ +void TestCheckInMsg::TestCheckinMessageParse_ValidInputsTooSmallAppData(nlTestSuite * inSuite, void * inContext) +{ + CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0]; - Aes128KeyHandle aes128KeyHandle; - NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle)); + // Create applicationData buffer with 0 size + MutableByteSpan applicationData; - Hmac128KeyHandle hmac128KeyHandle; - NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle)); + NL_TEST_ASSERT(inSuite, CHIP_ERROR_BUFFER_TOO_SMALL == ParseAndVerifyPayload(inSuite, applicationData, vector, false)); +} - //=================Encrypt======================= +/** + * @brief Test verifies that the Check-In Message parsing returns an error if the AesKeyHandle is empty + */ +void TestCheckInMsg::TestCheckInMessageParse_EmptyAesKeyHandle(nlTestSuite * inSuite, void * inContexT) +{ + TestSessionKeystoreImpl keystore; + CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0]; - err = CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, counter, userData, outputBuffer); - ByteSpan payload = chip::ByteSpan(outputBuffer.data(), outputBuffer.size()); - NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR == err)); + // Create application data ByteSpan + uint8_t applicationDataBuffer[128] = { 0 }; + MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer)); + applicationData.reduce_size(vector.application_data_len + sizeof(CounterType)); - //=================Decrypt======================= + // Create payload byte span + ByteSpan payload(vector.payload, vector.payload_len); - MutableByteSpan empty; - err = CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, empty); - NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR != err)); + CounterType decryptedCounter = 0; + // + (void) decryptedCounter; - ByteSpan emptyPayload; - err = CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, emptyPayload, decryptedCounter, buffer); - NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR != err)); + // Empty AES Key handle + Aes128KeyHandle aes128KeyHandle; - // Cleanup - keystore.DestroyKey(aes128KeyHandle); + Symmetric128BitsKeyByteArray hmacKeyMaterial; + memcpy(hmacKeyMaterial, vector.key, vector.key_len); + + Hmac128KeyHandle hmac128KeyHandle; + NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle)); + + /* + TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure. + When using OpenSSL this same test result in a success. + */ +#if 0 + // Verify that the generation fails with an empty key handle + NL_TEST_ASSERT_(inSuite, + CHIP_ERROR err != + CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData)); +#endif + + // Clean up keystore.DestroyKey(hmac128KeyHandle); } -void TestCheckInMsg::TestCheckinGenerateParse(nlTestSuite * inSuite, void * inContext) +/** + * @brief Test verifies that the Check-In Message parsing returns an error if the HmacKeyHandle is empty + */ +void TestCheckInMsg::TestCheckInMessageParse_EmptyHmacKeyHandle(nlTestSuite * inSuite, void * inContexT) { - uint8_t a[300] = { 0 }; - uint8_t b[300] = { 0 }; - MutableByteSpan outputBuffer{ a }; - MutableByteSpan buffer{ b }; - uint32_t counter = 0xDEADBEEF; - ByteSpan userData; - - CHIP_ERROR err = CHIP_NO_ERROR; - TestSessionKeystoreImpl keystore; + CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0]; - // Verify User Data Encryption Decryption - uint8_t data[] = { "This is some user Data. It should be encrypted" }; - userData = chip::ByteSpan(data); - for (const ccm_128_test_vector * testPtr : ccm_128_test_vectors) - { - const ccm_128_test_vector & test = *testPtr; + // Create application data ByteSpan + uint8_t applicationDataBuffer[128] = { 0 }; + MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer)); + applicationData.reduce_size(vector.application_data_len + sizeof(CounterType)); - // Two disctint key material to force the PSA unit tests to create two different Key IDs - Symmetric128BitsKeyByteArray aesKeyMaterial; - memcpy(aesKeyMaterial, test.key, test.key_len); + // Create payload byte span + ByteSpan payload(vector.payload, vector.payload_len); - Symmetric128BitsKeyByteArray hmacKeyMaterial; - memcpy(hmacKeyMaterial, test.key, test.key_len); + CounterType decryptedCounter = 0; + // + (void) decryptedCounter; - Aes128KeyHandle aes128KeyHandle; - NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle)); + // Empty Hmac Key handle + Hmac128KeyHandle hmac128KeyHandle; - Hmac128KeyHandle hmac128KeyHandle; - NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle)); + Symmetric128BitsKeyByteArray aesKeyMaterial; + memcpy(aesKeyMaterial, vector.key, vector.key_len); - //=================Encrypt======================= + Aes128KeyHandle aes128KeyHandle; + NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle)); - err = CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, counter, userData, outputBuffer); - NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR == err)); + /* + TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure. + When using OpenSSL this same test result in a success. + */ +#if 0 + // Verify that the generation fails with an empty key handle + NL_TEST_ASSERT_(inSuite, + CHIP_ERROR err != + CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData)); +#endif - //=================Decrypt======================= - uint32_t decryptedCounter = 0; - ByteSpan payload = chip::ByteSpan(outputBuffer.data(), outputBuffer.size()); + // Clean up + keystore.DestroyKey(aes128KeyHandle); +} + +/** + * @brief Test verifies that the Check-In message processing throws an error if the nonce is corrupted + */ +void TestCheckInMsg::TestCheckinMessageParse_CorruptedNonce(nlTestSuite * inSuite, void * inContext) +{ + int numOfTestCases = ArraySize(checkIn_message_test_vectors); + for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++) + { + CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted]; - err = CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, buffer); - NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR == err)); + uint8_t applicationDataBuffer[128] = { 0 }; + MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer)); + applicationData.reduce_size(vector.application_data_len + sizeof(CounterType)); - NL_TEST_ASSERT(inSuite, (memcmp(data, buffer.data(), sizeof(data)) == 0)); - NL_TEST_ASSERT(inSuite, (counter == decryptedCounter)); + NL_TEST_ASSERT(inSuite, CHIP_ERROR_INTERNAL == ParseAndVerifyPayload(inSuite, applicationData, vector, true)); + } +} - // reset buffers - memset(a, 0, sizeof(a)); - memset(b, 0, sizeof(b)); - outputBuffer = MutableByteSpan(a); - buffer = MutableByteSpan(b); +/** + * @brief Test verifies that the Check-In message processing throws an error if the nonce was not calculated with the counter in the + * payload + */ +void TestCheckInMsg::TestCheckinMessageParse_InvalidNonce(nlTestSuite * inSuite, void * inContext) +{ + CheckIn_Message_test_vector vector = invalidNonceVector; - counter += chip::Crypto::GetRandU32() + 1; + uint8_t applicationDataBuffer[128] = { 0 }; + MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer)); + applicationData.reduce_size(vector.application_data_len + sizeof(CounterType)); - // Cleanup - keystore.DestroyKey(aes128KeyHandle); - keystore.DestroyKey(hmac128KeyHandle); - } + NL_TEST_ASSERT(inSuite, CHIP_ERROR_INTERNAL == ParseAndVerifyPayload(inSuite, applicationData, vector, false)); } /** @@ -419,13 +550,17 @@ static const nlTest sTests[] = NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload", TestCheckInMsg::TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload), NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput", TestCheckInMsg::TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput), NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsTooSmallOutput", TestCheckInMsg::TestCheckinMessageGenerate_ValidInputsTooSmallOutput), - NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsTooSmallOutput", TestCheckInMsg::TestCheckInMessageGenerate_EmptyAesKeyHandle), - NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsTooSmallOutput", TestCheckInMsg::TestCheckInMessageGenerate_EmptyHmacKeyHandle), - NL_TEST_DEF("TestCheckinParse", TestCheckInMsg::TestCheckinParse), - NL_TEST_DEF("TestCheckinGenerateParse", TestCheckInMsg::TestCheckinGenerateParse), + NL_TEST_DEF("TestCheckInMessageGenerate_EmptyAesKeyHandle", TestCheckInMsg::TestCheckInMessageGenerate_EmptyAesKeyHandle), + NL_TEST_DEF("TestCheckInMessageGenerate_EmptyHmacKeyHandle", TestCheckInMsg::TestCheckInMessageGenerate_EmptyHmacKeyHandle), + NL_TEST_DEF("TestCheckinMessageParse_ValidInputsSameSizeMinAppData", TestCheckInMsg::TestCheckinMessageParse_ValidInputsSameSizeMinAppData), + NL_TEST_DEF("TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData", TestCheckInMsg::TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData), + NL_TEST_DEF("TestCheckinMessageParse_ValidInputsTooSmallAppData", TestCheckInMsg::TestCheckinMessageParse_ValidInputsTooSmallAppData), + NL_TEST_DEF("TestCheckInMessageParse_EmptyAesKeyHandle", TestCheckInMsg::TestCheckInMessageParse_EmptyAesKeyHandle), + NL_TEST_DEF("TestCheckInMessageParse_EmptyHmacKeyHandle", TestCheckInMsg::TestCheckInMessageParse_EmptyHmacKeyHandle), + NL_TEST_DEF("TestCheckinMessageParse_CorruptedNonce", TestCheckInMsg::TestCheckinMessageParse_CorruptedNonce), + NL_TEST_DEF("TestCheckinMessageParse_InvalidNonce", TestCheckInMsg::TestCheckinMessageParse_InvalidNonce), NL_TEST_DEF("TestCheckInMessagePayloadSize", TestCheckInMsg::TestCheckInMessagePayloadSize), NL_TEST_DEF("TestCheckInMessagePayloadSizeNullBuffer", TestCheckInMsg::TestCheckInMessagePayloadSizeNullBuffer), - NL_TEST_SENTINEL() }; // clang-format on From b38d1406c71b0c4f74632067c5149061f6d93c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Ba=C5=82ys?= Date: Tue, 19 Dec 2023 19:22:50 +0100 Subject: [PATCH 05/83] [nrfconnect] Add kconfig for enabling Read Client (#31073) To save some FLASH and RAM memory space we can disable Read Client functionality in nrfconnect samples. This commit adds kconfig to enable or disable Read Client in the Interaction Model. --- config/nrfconnect/chip-module/CMakeLists.txt | 1 + config/nrfconnect/chip-module/Kconfig | 7 +++++++ examples/all-clusters-app/nrfconnect/prj.conf | 3 +++ examples/all-clusters-app/nrfconnect/prj_dfu.conf | 3 +++ examples/all-clusters-app/nrfconnect/prj_release.conf | 3 +++ examples/light-switch-app/nrfconnect/prj.conf | 3 +++ examples/light-switch-app/nrfconnect/prj_no_dfu.conf | 3 +++ examples/light-switch-app/nrfconnect/prj_release.conf | 3 +++ src/test_driver/nrfconnect/prj.conf | 3 +++ 9 files changed, 29 insertions(+) diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 81f7769ac21094..672bf5834da196 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -137,6 +137,7 @@ matter_add_gn_arg_bool ("chip_enable_wifi" CONFIG_WIFI_NR matter_add_gn_arg_bool ("chip_system_config_provide_statistics" CONFIG_CHIP_STATISTICS) matter_add_gn_arg_bool ("chip_enable_icd_server" CONFIG_CHIP_ENABLE_ICD_SUPPORT) matter_add_gn_arg_bool ("chip_enable_factory_data" CONFIG_CHIP_FACTORY_DATA) +matter_add_gn_arg_bool ("chip_enable_read_client" CONFIG_CHIP_ENABLE_READ_CLIENT) if (CONFIG_CHIP_FACTORY_DATA OR CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) matter_add_gn_arg_bool("chip_use_transitional_commissionable_data_provider" FALSE) diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index 33528638670917..3414bdd26c9687 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -273,4 +273,11 @@ config CHIP_OPENTHREAD_JOINER_ENABLED If disabled, it allows to optimize memory usage even if Thread Joiner support is enabled. +config CHIP_ENABLE_READ_CLIENT + bool "Enable Read Client in the Interaction Model" + help + Enable support for Read Client in the Interaction Model. + This config can be disabled for device types that do not require Read Client functionality. + Disabling this config can save flash and RAM space. + endif # CHIP diff --git a/examples/all-clusters-app/nrfconnect/prj.conf b/examples/all-clusters-app/nrfconnect/prj.conf index 527fae10089448..dfb604a06349c1 100644 --- a/examples/all-clusters-app/nrfconnect/prj.conf +++ b/examples/all-clusters-app/nrfconnect/prj.conf @@ -44,3 +44,6 @@ CONFIG_CHIP_OTA_REQUESTOR=n # Disable QSPI NOR CONFIG_CHIP_QSPI_NOR=n + +# Enable the Read Client for binding purposes +CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/examples/all-clusters-app/nrfconnect/prj_dfu.conf b/examples/all-clusters-app/nrfconnect/prj_dfu.conf index ca8f536fafce18..3b5937b4073d9a 100644 --- a/examples/all-clusters-app/nrfconnect/prj_dfu.conf +++ b/examples/all-clusters-app/nrfconnect/prj_dfu.conf @@ -45,3 +45,6 @@ CONFIG_ASSERT_NO_MSG_INFO=y # Enable Factory Data feature CONFIG_CHIP_FACTORY_DATA=y CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable the Read Client for binding purposes +CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/examples/all-clusters-app/nrfconnect/prj_release.conf b/examples/all-clusters-app/nrfconnect/prj_release.conf index ebe3a71f8765eb..714fa9dd4ab740 100644 --- a/examples/all-clusters-app/nrfconnect/prj_release.conf +++ b/examples/all-clusters-app/nrfconnect/prj_release.conf @@ -52,3 +52,6 @@ CONFIG_BOOT_BANNER=n # Enable Factory Data feature CONFIG_CHIP_FACTORY_DATA=y CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable the Read Client for binding purposes +CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/examples/light-switch-app/nrfconnect/prj.conf b/examples/light-switch-app/nrfconnect/prj.conf index 2327bafd36bff9..dd75cdf99c4fd1 100644 --- a/examples/light-switch-app/nrfconnect/prj.conf +++ b/examples/light-switch-app/nrfconnect/prj.conf @@ -45,3 +45,6 @@ CONFIG_USE_SEGGER_RTT=n # Enable Factory Data feature CONFIG_CHIP_FACTORY_DATA=y CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable the Read Client for binding purposes +CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/examples/light-switch-app/nrfconnect/prj_no_dfu.conf b/examples/light-switch-app/nrfconnect/prj_no_dfu.conf index df884ba56d4300..def17d5345e22c 100644 --- a/examples/light-switch-app/nrfconnect/prj_no_dfu.conf +++ b/examples/light-switch-app/nrfconnect/prj_no_dfu.conf @@ -47,3 +47,6 @@ CONFIG_CHIP_OTA_REQUESTOR=n # Disable QSPI NOR CONFIG_CHIP_QSPI_NOR=n + +# Enable the Read Client for binding purposes +CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/examples/light-switch-app/nrfconnect/prj_release.conf b/examples/light-switch-app/nrfconnect/prj_release.conf index 5366a4f3dc3b6c..c57d5eb42bf168 100644 --- a/examples/light-switch-app/nrfconnect/prj_release.conf +++ b/examples/light-switch-app/nrfconnect/prj_release.conf @@ -59,3 +59,6 @@ CONFIG_BOOT_BANNER=n # Enable Factory Data feature CONFIG_CHIP_FACTORY_DATA=y CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable the Read Client for binding purposes +CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/src/test_driver/nrfconnect/prj.conf b/src/test_driver/nrfconnect/prj.conf index a4af4f769a4c67..4a49d837a1d56a 100644 --- a/src/test_driver/nrfconnect/prj.conf +++ b/src/test_driver/nrfconnect/prj.conf @@ -93,3 +93,6 @@ CONFIG_CHIP_ENABLE_DNSSD_SRP=n CONFIG_CHIP_DEVICE_VENDOR_ID=65521 CONFIG_CHIP_DEVICE_PRODUCT_ID=32768 CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" + +# Enable the Read Client +CONFIG_CHIP_ENABLE_READ_CLIENT=y From 5cd1c52cfe6812052fc8ed4751e66a41c32bd92f Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 19 Dec 2023 15:50:25 -0500 Subject: [PATCH 06/83] Make sure the MTRDevice lock is held when we touch _weakDelegate. (#31109) --- src/darwin/Framework/CHIP/MTRDevice.mm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 116f70f5bec235..021d00c64f2e62 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -327,7 +327,11 @@ - (void)nodeMayBeAdvertisingOperational // Return YES if there's a valid delegate AND subscription is expected to report value - (BOOL)_subscriptionAbleToReport { - return (_weakDelegate.strongObject) && (_state == MTRDeviceStateReachable); + os_unfair_lock_lock(&self->_lock); + id delegate = _weakDelegate.strongObject; + auto state = _state; + os_unfair_lock_unlock(&self->_lock); + return (delegate != nil) && (state == MTRDeviceStateReachable); } // assume lock is held @@ -634,6 +638,8 @@ - (void)_handleEventReport:(NSArray *> *)eventRepor // assume lock is held - (void)_setupSubscription { + os_unfair_lock_assert_owner(&self->_lock); + #ifdef DEBUG id delegate = _weakDelegate.strongObject; Optional maxIntervalOverride; @@ -645,8 +651,6 @@ - (void)_setupSubscription } #endif - os_unfair_lock_assert_owner(&self->_lock); - // for now just subscribe once if (_subscriptionActive) { return; @@ -1088,7 +1092,9 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID BOOL useValueAsExpectedValue = YES; #ifdef DEBUG + os_unfair_lock_lock(&self->_lock); id delegate = _weakDelegate.strongObject; + os_unfair_lock_unlock(&self->_lock); if ([delegate respondsToSelector:@selector(unitTestShouldSkipExpectedValuesForWrite:)]) { useValueAsExpectedValue = ![delegate unitTestShouldSkipExpectedValuesForWrite:self]; } From 13fd61daedf23c8b4bde79adbdc5e137942c3180 Mon Sep 17 00:00:00 2001 From: David Rempel <63119829+drempelg@users.noreply.github.com> Date: Tue, 19 Dec 2023 13:46:20 -0800 Subject: [PATCH 07/83] Added just the energy preferences xml. (#30934) * Added just the xml and regenerated. No implementations yet as requested. * regen * Apply suggestions from code review Added suggestions for ARRAY vs array Co-authored-by: Boris Zbarsky * regenerate --------- Co-authored-by: Boris Zbarsky --- docs/clusters.md | 1 + src/app/zap-templates/zcl/data-model/all.xml | 1 + .../chip/energy-preference-cluster.xml | 71 + .../zcl/zcl-with-test-extensions.json | 1 + src/app/zap-templates/zcl/zcl.json | 1 + src/app/zap_cluster_list.json | 2 + .../data_model/controller-clusters.matter | 34 + .../chip/devicecontroller/ChipClusters.java | 347 +++++ .../chip/devicecontroller/ChipStructs.java | 61 + .../devicecontroller/ClusterIDMapping.java | 108 ++ .../devicecontroller/ClusterInfoMapping.java | 156 ++ .../devicecontroller/ClusterReadMapping.java | 126 ++ .../devicecontroller/ClusterWriteMapping.java | 46 + .../chip/devicecontroller/cluster/files.gni | 1 + .../EnergyPreferenceClusterBalanceStruct.kt | 65 + .../clusters/EnergyPreferenceCluster.kt | 1262 +++++++++++++++++ .../java/matter/controller/cluster/files.gni | 2 + .../EnergyPreferenceClusterBalanceStruct.kt | 65 + .../CHIPAttributeTLVValueDecoder.cpp | 315 ++++ .../java/zap-generated/CHIPClientCallbacks.h | 16 + .../zap-generated/CHIPClustersWrite-JNI.cpp | 104 ++ .../CHIPEventTLVValueDecoder.cpp | 10 + .../java/zap-generated/CHIPReadCallbacks.cpp | 565 ++++++++ .../python/chip/clusters/CHIPClusters.py | 78 + .../python/chip/clusters/Objects.py | 242 ++++ .../MTRAttributeSpecifiedCheck.mm | 45 + .../MTRAttributeTLVValueDecoder.mm | 137 ++ .../CHIP/zap-generated/MTRBaseClusters.h | 107 ++ .../CHIP/zap-generated/MTRBaseClusters.mm | 456 ++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 14 + .../CHIP/zap-generated/MTRClusters.h | 50 + .../CHIP/zap-generated/MTRClusters.mm | 81 ++ .../zap-generated/MTRCommandTimedCheck.mm | 12 + .../zap-generated/MTREventTLVValueDecoder.mm | 15 + .../CHIP/zap-generated/MTRStructsObjc.h | 6 + .../CHIP/zap-generated/MTRStructsObjc.mm | 30 + .../zap-generated/attributes/Accessors.cpp | 130 ++ .../zap-generated/attributes/Accessors.h | 26 + .../app-common/zap-generated/callback.h | 86 ++ .../zap-generated/cluster-enums-check.h | 15 + .../app-common/zap-generated/cluster-enums.h | 24 + .../zap-generated/cluster-objects.cpp | 83 ++ .../zap-generated/cluster-objects.h | 154 ++ .../app-common/zap-generated/ids/Attributes.h | 50 + .../app-common/zap-generated/ids/Clusters.h | 3 + .../app-common/zap-generated/print-cluster.h | 7 + .../zap-generated/cluster/Commands.h | 103 ++ .../cluster/ComplexArgumentParser.cpp | 32 + .../cluster/ComplexArgumentParser.h | 5 + .../cluster/logging/DataModelLogger.cpp | 86 ++ .../cluster/logging/DataModelLogger.h | 3 + .../zap-generated/cluster/Commands.h | 1105 +++++++++++++++ 52 files changed, 6545 insertions(+) create mode 100644 src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyPreferenceCluster.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt diff --git a/docs/clusters.md b/docs/clusters.md index 2043c6fe45ffb9..1d0453033db586 100644 --- a/docs/clusters.md +++ b/docs/clusters.md @@ -81,6 +81,7 @@ Generally regenerate using one of: | 150 | 0x96 | DemandResponseLoadControl | | 152 | 0x98 | DeviceEnergyManagement | | 153 | 0x99 | EnergyEvse | +| 155 | 0x9B | EnergyPreference | | 257 | 0x101 | DoorLock | | 258 | 0x102 | WindowCovering | | 259 | 0x103 | BarrierControl | diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 4eedb32f3578d9..f2ed0cc9919c03 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -30,6 +30,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml new file mode 100644 index 00000000000000..f7a45dfd016b05 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml @@ -0,0 +1,71 @@ + + + + + + Energy Preference + Energy Management + 0x009B + ENERGY_PREFERENCE_CLUSTER + true + true + This cluster provides an interface to specify preferences for how devices should consume energy. + + + + EnergyBalances + + + + + + CurrentEnergyBalance + + + + EnergyPriorities + + + LowPowerModeSensitivities + + + + + + CurrentLowPowerModeSensitivity + + + + + + + + + + + + + + + + + + + + + + + + + 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 31a334577fb4eb..634f66606f6a60 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -45,6 +45,7 @@ "microwave-oven-mode-cluster.xml", "microwave-oven-control-cluster.xml", "door-lock-cluster.xml", + "energy-preference-cluster.xml", "electrical-energy-measurement-cluster.xml", "electrical-measurement-cluster.xml", "energy-evse-cluster.xml", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 565d500aeb2293..a0556e6da7ebb2 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -46,6 +46,7 @@ "drlc-cluster.xml", "electrical-measurement-cluster.xml", "energy-evse-cluster.xml", + "energy-preference-cluster.xml", "ethernet-network-diagnostics-cluster.xml", "fan-control-cluster.xml", "fault-injection-cluster.xml", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 77b466541f1a54..15df401e161d4f 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -39,6 +39,7 @@ "ELECTRICAL_MEASUREMENT_CLUSTER": [], "ENERGY_EVSE_CLUSTER": [], "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER": [], + "ENERGY_PREFERENCE_CLUSTER": [], "FAN_CONTROL_CLUSTER": [], "FAULT_INJECTION_CLUSTER": [], "FIXED_LABEL_CLUSTER": [], @@ -179,6 +180,7 @@ "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER": [ "ethernet-network-diagnostics-server" ], + "ENERGY_PREFERENCE_CLUSTER": [""], "FAN_CONTROL_CLUSTER": ["fan-control-server"], "FAULT_INJECTION_CLUSTER": ["fault-injection-server"], "FIXED_LABEL_CLUSTER": ["fixed-label-server"], diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index e37e3563dfc567..1d0fcc7ec86b61 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -4754,6 +4754,40 @@ provisional cluster EnergyEvse = 153 { timed command ClearTargets(): DefaultSuccess = 7; } +/** This cluster provides an interface to specify preferences for how devices should consume energy. */ +cluster EnergyPreference = 155 { + revision 1; // NOTE: Default/not specifically set + + enum EnergyPriorityEnum : enum8 { + kComfort = 0; + kSpeed = 1; + kEfficiency = 2; + kWaterConsumption = 3; + } + + bitmap Feature : bitmap32 { + kEnergyBalance = 0x1; + kLowPowerModeSensitivity = 0x2; + } + + struct BalanceStruct { + percent step = 0; + optional char_string<64> label = 1; + } + + readonly attribute optional BalanceStruct energyBalances[] = 0; + attribute optional int8u currentEnergyBalance = 1; + readonly attribute optional EnergyPriorityEnum energyPriorities[] = 2; + readonly attribute optional BalanceStruct lowPowerModeSensitivities[] = 3; + attribute optional int8u currentLowPowerModeSensitivity = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + /** An interface to a generic way to secure a door */ cluster DoorLock = 257 { revision 7; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index a7b89fa3b5d7eb..201229af2f710c 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -30844,6 +30844,353 @@ public void onSuccess(byte[] tlv) { } } + public static class EnergyPreferenceCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 155L; + + private static final long ENERGY_BALANCES_ATTRIBUTE_ID = 0L; + private static final long CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID = 1L; + private static final long ENERGY_PRIORITIES_ATTRIBUTE_ID = 2L; + private static final long LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID = 3L; + private static final long CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID = 4L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public EnergyPreferenceCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public interface EnergyBalancesAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EnergyPrioritiesAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface LowPowerModeSensitivitiesAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readEnergyBalancesAttribute( + EnergyBalancesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_BALANCES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ENERGY_BALANCES_ATTRIBUTE_ID, true); + } + + public void subscribeEnergyBalancesAttribute( + EnergyBalancesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_BALANCES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, ENERGY_BALANCES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readCurrentEnergyBalanceAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, true); + } + + public void writeCurrentEnergyBalanceAttribute(DefaultClusterCallback callback, Integer value) { + writeCurrentEnergyBalanceAttribute(callback, value, 0); + } + + public void writeCurrentEnergyBalanceAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeCurrentEnergyBalanceAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, CURRENT_ENERGY_BALANCE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEnergyPrioritiesAttribute( + EnergyPrioritiesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_PRIORITIES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ENERGY_PRIORITIES_ATTRIBUTE_ID, true); + } + + public void subscribeEnergyPrioritiesAttribute( + EnergyPrioritiesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ENERGY_PRIORITIES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, ENERGY_PRIORITIES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readLowPowerModeSensitivitiesAttribute( + LowPowerModeSensitivitiesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID, true); + } + + public void subscribeLowPowerModeSensitivitiesAttribute( + LowPowerModeSensitivitiesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, LOW_POWER_MODE_SENSITIVITIES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readCurrentLowPowerModeSensitivityAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, true); + } + + public void writeCurrentLowPowerModeSensitivityAttribute(DefaultClusterCallback callback, Integer value) { + writeCurrentLowPowerModeSensitivityAttribute(callback, value, 0); + } + + public void writeCurrentLowPowerModeSensitivityAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeCurrentLowPowerModeSensitivityAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, CURRENT_LOW_POWER_MODE_SENSITIVITY_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class DoorLockCluster extends BaseChipCluster { public static final long CLUSTER_ID = 257L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index e7e40657b7915f..98bc3ca71303f5 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -7351,6 +7351,67 @@ public String toString() { return output.toString(); } } +public static class EnergyPreferenceClusterBalanceStruct { + public Integer step; + public Optional label; + private static final long STEP_ID = 0L; + private static final long LABEL_ID = 1L; + + public EnergyPreferenceClusterBalanceStruct( + Integer step, + Optional label + ) { + this.step = step; + this.label = label; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(STEP_ID, new UIntType(step))); + values.add(new StructElement(LABEL_ID, label.map((nonOptionallabel) -> new StringType(nonOptionallabel)).orElse(new EmptyType()))); + + return new StructType(values); + } + + public static EnergyPreferenceClusterBalanceStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer step = null; + Optional label = Optional.empty(); + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == STEP_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + step = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == LABEL_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + label = Optional.of(castingValue.value(String.class)); + } + } + } + return new EnergyPreferenceClusterBalanceStruct( + step, + label + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("EnergyPreferenceClusterBalanceStruct {\n"); + output.append("\tstep: "); + output.append(step); + output.append("\n"); + output.append("\tlabel: "); + output.append(label); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class DoorLockClusterCredentialStruct { public Integer credentialType; public Integer credentialIndex; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 28503ea511d188..e432edea9dc9c3 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -235,6 +235,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == EnergyEvse.ID) { return new EnergyEvse(); } + if (clusterId == EnergyPreference.ID) { + return new EnergyPreference(); + } if (clusterId == DoorLock.ID) { return new DoorLock(); } @@ -9743,6 +9746,111 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class EnergyPreference implements BaseCluster { + public static final long ID = 155L; + public long getID() { + return ID; + } + + public enum Attribute { + EnergyBalances(0L), + CurrentEnergyBalance(1L), + EnergyPriorities(2L), + LowPowerModeSensitivities(3L), + CurrentLowPowerModeSensitivity(4L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command {; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class DoorLock implements BaseCluster { public static final long ID = 257L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 601c43a38b210f..6860b30cff08ad 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -10894,6 +10894,153 @@ public void onError(Exception ex) { } } + public static class DelegatedEnergyPreferenceClusterEnergyBalancesAttributeCallback implements ChipClusters.EnergyPreferenceCluster.EnergyBalancesAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEnergyPreferenceClusterEnergyPrioritiesAttributeCallback implements ChipClusters.EnergyPreferenceCluster.EnergyPrioritiesAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEnergyPreferenceClusterLowPowerModeSensitivitiesAttributeCallback implements ChipClusters.EnergyPreferenceCluster.LowPowerModeSensitivitiesAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEnergyPreferenceClusterGeneratedCommandListAttributeCallback implements ChipClusters.EnergyPreferenceCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEnergyPreferenceClusterAcceptedCommandListAttributeCallback implements ChipClusters.EnergyPreferenceCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEnergyPreferenceClusterEventListAttributeCallback implements ChipClusters.EnergyPreferenceCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEnergyPreferenceClusterAttributeListAttributeCallback implements ChipClusters.EnergyPreferenceCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedDoorLockClusterGetWeekDayScheduleResponseCallback implements ChipClusters.DoorLockCluster.GetWeekDayScheduleResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @@ -19570,6 +19717,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.EnergyEvseCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("energyEvse", energyEvseClusterInfo); + ClusterInfo energyPreferenceClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.EnergyPreferenceCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("energyPreference", energyPreferenceClusterInfo); + ClusterInfo doorLockClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.DoorLockCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("doorLock", doorLockClusterInfo); @@ -19815,6 +19966,7 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("energyEvse", energyEvseClusterInteractionInfoMap); + Map energyPreferenceClusterInteractionInfoMap = new LinkedHashMap<>(); + + commandMap.put("energyPreference", energyPreferenceClusterInteractionInfoMap); + Map doorLockClusterInteractionInfoMap = new LinkedHashMap<>(); Map doorLocklockDoorCommandParams = new LinkedHashMap(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 3ff5881314f8a3..b00f3c842b6656 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -9684,6 +9684,131 @@ private static Map readEnergyEvseInteractionInfo() { return result; } + private static Map readEnergyPreferenceInteractionInfo() { + Map result = new LinkedHashMap<>();Map readEnergyPreferenceEnergyBalancesCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceEnergyBalancesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readEnergyBalancesAttribute( + (ChipClusters.EnergyPreferenceCluster.EnergyBalancesAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterEnergyBalancesAttributeCallback(), + readEnergyPreferenceEnergyBalancesCommandParams + ); + result.put("readEnergyBalancesAttribute", readEnergyPreferenceEnergyBalancesAttributeInteractionInfo); + Map readEnergyPreferenceCurrentEnergyBalanceCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceCurrentEnergyBalanceAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readCurrentEnergyBalanceAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readEnergyPreferenceCurrentEnergyBalanceCommandParams + ); + result.put("readCurrentEnergyBalanceAttribute", readEnergyPreferenceCurrentEnergyBalanceAttributeInteractionInfo); + Map readEnergyPreferenceEnergyPrioritiesCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceEnergyPrioritiesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readEnergyPrioritiesAttribute( + (ChipClusters.EnergyPreferenceCluster.EnergyPrioritiesAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterEnergyPrioritiesAttributeCallback(), + readEnergyPreferenceEnergyPrioritiesCommandParams + ); + result.put("readEnergyPrioritiesAttribute", readEnergyPreferenceEnergyPrioritiesAttributeInteractionInfo); + Map readEnergyPreferenceLowPowerModeSensitivitiesCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceLowPowerModeSensitivitiesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readLowPowerModeSensitivitiesAttribute( + (ChipClusters.EnergyPreferenceCluster.LowPowerModeSensitivitiesAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterLowPowerModeSensitivitiesAttributeCallback(), + readEnergyPreferenceLowPowerModeSensitivitiesCommandParams + ); + result.put("readLowPowerModeSensitivitiesAttribute", readEnergyPreferenceLowPowerModeSensitivitiesAttributeInteractionInfo); + Map readEnergyPreferenceCurrentLowPowerModeSensitivityCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceCurrentLowPowerModeSensitivityAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readCurrentLowPowerModeSensitivityAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readEnergyPreferenceCurrentLowPowerModeSensitivityCommandParams + ); + result.put("readCurrentLowPowerModeSensitivityAttribute", readEnergyPreferenceCurrentLowPowerModeSensitivityAttributeInteractionInfo); + Map readEnergyPreferenceGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.EnergyPreferenceCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterGeneratedCommandListAttributeCallback(), + readEnergyPreferenceGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readEnergyPreferenceGeneratedCommandListAttributeInteractionInfo); + Map readEnergyPreferenceAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.EnergyPreferenceCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterAcceptedCommandListAttributeCallback(), + readEnergyPreferenceAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readEnergyPreferenceAcceptedCommandListAttributeInteractionInfo); + Map readEnergyPreferenceEventListCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readEventListAttribute( + (ChipClusters.EnergyPreferenceCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterEventListAttributeCallback(), + readEnergyPreferenceEventListCommandParams + ); + result.put("readEventListAttribute", readEnergyPreferenceEventListAttributeInteractionInfo); + Map readEnergyPreferenceAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readAttributeListAttribute( + (ChipClusters.EnergyPreferenceCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEnergyPreferenceClusterAttributeListAttributeCallback(), + readEnergyPreferenceAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readEnergyPreferenceAttributeListAttributeInteractionInfo); + Map readEnergyPreferenceFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readEnergyPreferenceFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readEnergyPreferenceFeatureMapAttributeInteractionInfo); + Map readEnergyPreferenceClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readEnergyPreferenceClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readEnergyPreferenceClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readEnergyPreferenceClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readDoorLockInteractionInfo() { Map result = new LinkedHashMap<>();Map readDoorLockLockStateCommandParams = new LinkedHashMap(); InteractionInfo readDoorLockLockStateAttributeInteractionInfo = new InteractionInfo( @@ -19510,6 +19635,7 @@ public Map> getReadAttributeMap() { put("demandResponseLoadControl", readDemandResponseLoadControlInteractionInfo()); put("deviceEnergyManagement", readDeviceEnergyManagementInteractionInfo()); put("energyEvse", readEnergyEvseInteractionInfo()); + put("energyPreference", readEnergyPreferenceInteractionInfo()); put("doorLock", readDoorLockInteractionInfo()); put("windowCovering", readWindowCoveringInteractionInfo()); put("barrierControl", readBarrierControlInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 6eb5f233a5d3db..6373b57b8bef14 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -1352,6 +1352,52 @@ public Map> getWriteAttributeMap() { ); writeEnergyEvseInteractionInfo.put("writeApproximateEVEfficiencyAttribute", writeEnergyEvseApproximateEVEfficiencyAttributeInteractionInfo); writeAttributeMap.put("energyEvse", writeEnergyEvseInteractionInfo); + Map writeEnergyPreferenceInteractionInfo = new LinkedHashMap<>(); + Map writeEnergyPreferenceCurrentEnergyBalanceCommandParams = new LinkedHashMap(); + CommandParameterInfo energyPreferencecurrentEnergyBalanceCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeEnergyPreferenceCurrentEnergyBalanceCommandParams.put( + "value", + energyPreferencecurrentEnergyBalanceCommandParameterInfo + ); + InteractionInfo writeEnergyPreferenceCurrentEnergyBalanceAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).writeCurrentEnergyBalanceAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeEnergyPreferenceCurrentEnergyBalanceCommandParams + ); + writeEnergyPreferenceInteractionInfo.put("writeCurrentEnergyBalanceAttribute", writeEnergyPreferenceCurrentEnergyBalanceAttributeInteractionInfo); + Map writeEnergyPreferenceCurrentLowPowerModeSensitivityCommandParams = new LinkedHashMap(); + CommandParameterInfo energyPreferencecurrentLowPowerModeSensitivityCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeEnergyPreferenceCurrentLowPowerModeSensitivityCommandParams.put( + "value", + energyPreferencecurrentLowPowerModeSensitivityCommandParameterInfo + ); + InteractionInfo writeEnergyPreferenceCurrentLowPowerModeSensitivityAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EnergyPreferenceCluster) cluster).writeCurrentLowPowerModeSensitivityAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeEnergyPreferenceCurrentLowPowerModeSensitivityCommandParams + ); + writeEnergyPreferenceInteractionInfo.put("writeCurrentLowPowerModeSensitivityAttribute", writeEnergyPreferenceCurrentLowPowerModeSensitivityAttributeInteractionInfo); + writeAttributeMap.put("energyPreference", writeEnergyPreferenceInteractionInfo); Map writeDoorLockInteractionInfo = new LinkedHashMap<>(); Map writeDoorLockDoorOpenEventsCommandParams = new LinkedHashMap(); CommandParameterInfo doorLockdoorOpenEventsCommandParameterInfo = 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 363e418f960f6d..41532a359802fa 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -57,6 +57,7 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ElectricalEnergyMeasurementClusterMeasurementAccuracyRangeStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ElectricalEnergyMeasurementClusterMeasurementAccuracyStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EnergyEvseClusterChargingTargetStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/FixedLabelClusterLabelStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/GeneralCommissioningClusterBasicCommissioningInfo.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/GeneralDiagnosticsClusterNetworkInterface.kt", diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt new file mode 100644 index 00000000000000..75f77558f0e982 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt @@ -0,0 +1,65 @@ +/* + * + * 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 EnergyPreferenceClusterBalanceStruct(val step: UInt, val label: Optional) { + override fun toString(): String = buildString { + append("EnergyPreferenceClusterBalanceStruct {\n") + append("\tstep : $step\n") + append("\tlabel : $label\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_STEP), step) + if (label.isPresent) { + val optlabel = label.get() + put(ContextSpecificTag(TAG_LABEL), optlabel) + } + endStructure() + } + } + + companion object { + private const val TAG_STEP = 0 + private const val TAG_LABEL = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyPreferenceClusterBalanceStruct { + tlvReader.enterStructure(tlvTag) + val step = tlvReader.getUInt(ContextSpecificTag(TAG_STEP)) + val label = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_LABEL))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_LABEL))) + } else { + Optional.empty() + } + + tlvReader.exitContainer() + + return EnergyPreferenceClusterBalanceStruct(step, label) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyPreferenceCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyPreferenceCluster.kt new file mode 100644 index 00000000000000..8030bbd3cf96d0 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyPreferenceCluster.kt @@ -0,0 +1,1262 @@ +/* + * + * 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.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UByteSubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.WriteRequest +import matter.controller.WriteRequests +import matter.controller.WriteResponse +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class EnergyPreferenceCluster( + private val controller: MatterController, + private val endpointId: UShort +) { + class EnergyBalancesAttribute(val value: List?) + + sealed class EnergyBalancesAttributeSubscriptionState { + data class Success(val value: List?) : + EnergyBalancesAttributeSubscriptionState() + + data class Error(val exception: Exception) : EnergyBalancesAttributeSubscriptionState() + + object SubscriptionEstablished : EnergyBalancesAttributeSubscriptionState() + } + + class EnergyPrioritiesAttribute(val value: List?) + + sealed class EnergyPrioritiesAttributeSubscriptionState { + data class Success(val value: List?) : EnergyPrioritiesAttributeSubscriptionState() + + data class Error(val exception: Exception) : EnergyPrioritiesAttributeSubscriptionState() + + object SubscriptionEstablished : EnergyPrioritiesAttributeSubscriptionState() + } + + class LowPowerModeSensitivitiesAttribute(val value: List?) + + sealed class LowPowerModeSensitivitiesAttributeSubscriptionState { + data class Success(val value: List?) : + LowPowerModeSensitivitiesAttributeSubscriptionState() + + data class Error(val exception: Exception) : + LowPowerModeSensitivitiesAttributeSubscriptionState() + + object SubscriptionEstablished : LowPowerModeSensitivitiesAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun readEnergyBalancesAttribute(): EnergyBalancesAttribute { + val ATTRIBUTE_ID: UInt = 0u + + 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) { "Energybalances attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(EnergyPreferenceClusterBalanceStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return EnergyBalancesAttribute(decodedValue) + } + + suspend fun subscribeEnergyBalancesAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + 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( + EnergyBalancesAttributeSubscriptionState.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) { + "Energybalances attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(EnergyPreferenceClusterBalanceStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + decodedValue?.let { emit(EnergyBalancesAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(EnergyBalancesAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readCurrentEnergyBalanceAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + 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) { "Currentenergybalance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeCurrentEnergyBalanceAttribute( + value: UByte, + timedWriteTimeout: Duration? = null + ) { + val ATTRIBUTE_ID: UInt = 1u + + 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 subscribeCurrentEnergyBalanceAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + 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( + UByteSubscriptionState.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) { + "Currentenergybalance 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.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEnergyPrioritiesAttribute(): EnergyPrioritiesAttribute { + val ATTRIBUTE_ID: UInt = 2u + + 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) { "Energypriorities attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return EnergyPrioritiesAttribute(decodedValue) + } + + suspend fun subscribeEnergyPrioritiesAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + 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( + EnergyPrioritiesAttributeSubscriptionState.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) { + "Energypriorities attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + decodedValue?.let { emit(EnergyPrioritiesAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(EnergyPrioritiesAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readLowPowerModeSensitivitiesAttribute(): LowPowerModeSensitivitiesAttribute { + val ATTRIBUTE_ID: UInt = 3u + + 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) { "Lowpowermodesensitivities attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(EnergyPreferenceClusterBalanceStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return LowPowerModeSensitivitiesAttribute(decodedValue) + } + + suspend fun subscribeLowPowerModeSensitivitiesAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 3u + 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( + LowPowerModeSensitivitiesAttributeSubscriptionState.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) { + "Lowpowermodesensitivities attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(EnergyPreferenceClusterBalanceStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + decodedValue?.let { + emit(LowPowerModeSensitivitiesAttributeSubscriptionState.Success(it)) + } + } + SubscriptionState.SubscriptionEstablished -> { + emit(LowPowerModeSensitivitiesAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readCurrentLowPowerModeSensitivityAttribute(): UByte? { + 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) { + "Currentlowpowermodesensitivity attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeCurrentLowPowerModeSensitivityAttribute( + value: UByte, + timedWriteTimeout: Duration? = null + ) { + val ATTRIBUTE_ID: UInt = 4u + + 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 subscribeCurrentLowPowerModeSensitivityAttribute( + 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( + UByteSubscriptionState.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) { + "Currentlowpowermodesensitivity 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.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + 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) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + 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( + GeneratedCommandListAttributeSubscriptionState.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) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + 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) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + 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( + AcceptedCommandListAttributeSubscriptionState.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) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + 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) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + 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( + EventListAttributeSubscriptionState.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) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + 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) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + 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( + AttributeListAttributeSubscriptionState.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) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + 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) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + 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( + UIntSubscriptionState.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) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + 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) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + 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) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(EnergyPreferenceCluster::class.java.name) + const val CLUSTER_ID: UInt = 155u + } +} 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 ff107deb40dcbb..2ebed3b24f6c2c 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -57,6 +57,7 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ElectricalEnergyMeasurementClusterMeasurementAccuracyRangeStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ElectricalEnergyMeasurementClusterMeasurementAccuracyStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/EnergyEvseClusterChargingTargetStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/FixedLabelClusterLabelStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/GeneralCommissioningClusterBasicCommissioningInfo.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/GeneralDiagnosticsClusterNetworkInterface.kt", @@ -233,6 +234,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ElectricalEnergyMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ElectricalMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyEvseCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyPreferenceCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/EthernetNetworkDiagnosticsCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/FanControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/FaultInjectionCluster.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt new file mode 100644 index 00000000000000..29980664d4cbec --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/EnergyPreferenceClusterBalanceStruct.kt @@ -0,0 +1,65 @@ +/* + * + * 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 EnergyPreferenceClusterBalanceStruct(val step: UByte, val label: Optional) { + override fun toString(): String = buildString { + append("EnergyPreferenceClusterBalanceStruct {\n") + append("\tstep : $step\n") + append("\tlabel : $label\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_STEP), step) + if (label.isPresent) { + val optlabel = label.get() + put(ContextSpecificTag(TAG_LABEL), optlabel) + } + endStructure() + } + } + + companion object { + private const val TAG_STEP = 0 + private const val TAG_LABEL = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyPreferenceClusterBalanceStruct { + tlvReader.enterStructure(tlvTag) + val step = tlvReader.getUByte(ContextSpecificTag(TAG_STEP)) + val label = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_LABEL))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_LABEL))) + } else { + Optional.empty() + } + + tlvReader.exitContainer() + + return EnergyPreferenceClusterBalanceStruct(step, label) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 3732f1a9629a7e..c5377559a05d7a 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -22985,6 +22985,321 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::EnergyPreference::Id: { + using namespace app::Clusters::EnergyPreference; + switch (aPath.mAttributeId) + { + case Attributes::EnergyBalances::Id: { + using TypeInfo = Attributes::EnergyBalances::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + jobject newElement_0_step; + std::string newElement_0_stepClassName = "java/lang/Integer"; + std::string newElement_0_stepCtorSignature = "(I)V"; + jint jninewElement_0_step = static_cast(entry_0.step); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_stepClassName.c_str(), + newElement_0_stepCtorSignature.c_str(), + jninewElement_0_step, newElement_0_step); + jobject newElement_0_label; + if (!entry_0.label.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_label); + } + else + { + jobject newElement_0_labelInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label.Value(), + newElement_0_labelInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_labelInsideOptional, newElement_0_label); + } + + jclass balanceStructStructClass_1; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$EnergyPreferenceClusterBalanceStruct", balanceStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EnergyPreferenceClusterBalanceStruct"); + return nullptr; + } + jmethodID balanceStructStructCtor_1 = + env->GetMethodID(balanceStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/util/Optional;)V"); + if (balanceStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EnergyPreferenceClusterBalanceStruct constructor"); + return nullptr; + } + + newElement_0 = + env->NewObject(balanceStructStructClass_1, balanceStructStructCtor_1, newElement_0_step, newElement_0_label); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::CurrentEnergyBalance::Id: { + using TypeInfo = Attributes::CurrentEnergyBalance::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::EnergyPriorities::Id: { + using TypeInfo = Attributes::EnergyPriorities::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Integer"; + std::string newElement_0CtorSignature = "(I)V"; + jint jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::LowPowerModeSensitivities::Id: { + using TypeInfo = Attributes::LowPowerModeSensitivities::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + jobject newElement_0_step; + std::string newElement_0_stepClassName = "java/lang/Integer"; + std::string newElement_0_stepCtorSignature = "(I)V"; + jint jninewElement_0_step = static_cast(entry_0.step); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_stepClassName.c_str(), + newElement_0_stepCtorSignature.c_str(), + jninewElement_0_step, newElement_0_step); + jobject newElement_0_label; + if (!entry_0.label.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_label); + } + else + { + jobject newElement_0_labelInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label.Value(), + newElement_0_labelInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_labelInsideOptional, newElement_0_label); + } + + jclass balanceStructStructClass_1; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$EnergyPreferenceClusterBalanceStruct", balanceStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EnergyPreferenceClusterBalanceStruct"); + return nullptr; + } + jmethodID balanceStructStructCtor_1 = + env->GetMethodID(balanceStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/util/Optional;)V"); + if (balanceStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EnergyPreferenceClusterBalanceStruct constructor"); + return nullptr; + } + + newElement_0 = + env->NewObject(balanceStructStructClass_1, balanceStructStructCtor_1, newElement_0_step, newElement_0_label); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::CurrentLowPowerModeSensitivity::Id: { + using TypeInfo = Attributes::CurrentLowPowerModeSensitivity::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::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::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; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::DoorLock::Id: { using namespace app::Clusters::DoorLock; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPClientCallbacks.h b/src/controller/java/zap-generated/CHIPClientCallbacks.h index 4ba2a2d93b7451..de2ce285d6513e 100644 --- a/src/controller/java/zap-generated/CHIPClientCallbacks.h +++ b/src/controller/java/zap-generated/CHIPClientCallbacks.h @@ -777,6 +777,22 @@ typedef void (*EnergyEvseEventListListAttributeCallback)(void * context, const chip::app::DataModel::DecodableList & data); typedef void (*EnergyEvseAttributeListListAttributeCallback)(void * context, const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceEnergyBalancesListAttributeCallback)( + void * context, + const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceEnergyPrioritiesListAttributeCallback)( + void * context, const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceLowPowerModeSensitivitiesListAttributeCallback)( + void * context, + const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceGeneratedCommandListListAttributeCallback)( + void * context, const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceAcceptedCommandListListAttributeCallback)( + void * context, const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceEventListListAttributeCallback)(void * context, + const chip::app::DataModel::DecodableList & data); +typedef void (*EnergyPreferenceAttributeListListAttributeCallback)( + void * context, const chip::app::DataModel::DecodableList & data); typedef void (*DoorLockGeneratedCommandListListAttributeCallback)( void * context, const chip::app::DataModel::DecodableList & data); typedef void (*DoorLockAcceptedCommandListListAttributeCallback)(void * context, diff --git a/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp b/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp index 4abaeb56cf5901..bbb1d9df9158c1 100644 --- a/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClustersWrite-JNI.cpp @@ -3718,6 +3718,110 @@ JNI_METHOD(void, EnergyEvseCluster, writeApproximateEVEfficiencyAttribute) onFailure.release(); } +JNI_METHOD(void, EnergyPreferenceCluster, writeCurrentEnergyBalanceAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) +{ + chip::DeviceLayer::StackLock lock; + ListFreer listFreer; + using TypeInfo = chip::app::Clusters::EnergyPreference::Attributes::CurrentEnergyBalance::TypeInfo; + TypeInfo::Type cppValue; + + std::vector> cleanupByteArrays; + std::vector> cleanupStrings; + + cppValue = + static_cast>(chip::JniReferences::GetInstance().IntegerToPrimitive(value)); + + std::unique_ptr onSuccess( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onSuccess.get() != nullptr, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY)); + + std::unique_ptr onFailure( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onFailure.get() != nullptr, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY)); + + CHIP_ERROR err = CHIP_NO_ERROR; + EnergyPreferenceCluster * cppCluster = reinterpret_cast(clusterPtr); + VerifyOrReturn(cppCluster != nullptr, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE)); + + auto successFn = chip::Callback::Callback::FromCancelable(onSuccess->Cancel()); + auto failureFn = chip::Callback::Callback::FromCancelable(onFailure->Cancel()); + + if (timedWriteTimeoutMs == nullptr) + { + err = cppCluster->WriteAttribute(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall); + } + else + { + err = cppCluster->WriteAttribute(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall, + chip::JniReferences::GetInstance().IntegerToPrimitive(timedWriteTimeoutMs)); + } + VerifyOrReturn( + err == CHIP_NO_ERROR, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error writing attribute", err)); + + onSuccess.release(); + onFailure.release(); +} + +JNI_METHOD(void, EnergyPreferenceCluster, writeCurrentLowPowerModeSensitivityAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) +{ + chip::DeviceLayer::StackLock lock; + ListFreer listFreer; + using TypeInfo = chip::app::Clusters::EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::TypeInfo; + TypeInfo::Type cppValue; + + std::vector> cleanupByteArrays; + std::vector> cleanupStrings; + + cppValue = + static_cast>(chip::JniReferences::GetInstance().IntegerToPrimitive(value)); + + std::unique_ptr onSuccess( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onSuccess.get() != nullptr, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY)); + + std::unique_ptr onFailure( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onFailure.get() != nullptr, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY)); + + CHIP_ERROR err = CHIP_NO_ERROR; + EnergyPreferenceCluster * cppCluster = reinterpret_cast(clusterPtr); + VerifyOrReturn(cppCluster != nullptr, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE)); + + auto successFn = chip::Callback::Callback::FromCancelable(onSuccess->Cancel()); + auto failureFn = chip::Callback::Callback::FromCancelable(onFailure->Cancel()); + + if (timedWriteTimeoutMs == nullptr) + { + err = cppCluster->WriteAttribute(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall); + } + else + { + err = cppCluster->WriteAttribute(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall, + chip::JniReferences::GetInstance().IntegerToPrimitive(timedWriteTimeoutMs)); + } + VerifyOrReturn( + err == CHIP_NO_ERROR, + chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error writing attribute", err)); + + onSuccess.release(); + onFailure.release(); +} + JNI_METHOD(void, DoorLockCluster, writeDoorOpenEventsAttribute) (JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject value, jobject timedWriteTimeoutMs) { diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index ed6b539e8539f3..c4ae9e316db9ec 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -5369,6 +5369,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::EnergyPreference::Id: { + using namespace app::Clusters::EnergyPreference; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::DoorLock::Id: { using namespace app::Clusters::DoorLock; switch (aPath.mEventId) diff --git a/src/controller/java/zap-generated/CHIPReadCallbacks.cpp b/src/controller/java/zap-generated/CHIPReadCallbacks.cpp index 430db0fb5988e7..bf307bba811fe4 100644 --- a/src/controller/java/zap-generated/CHIPReadCallbacks.cpp +++ b/src/controller/java/zap-generated/CHIPReadCallbacks.cpp @@ -34359,6 +34359,571 @@ void CHIPEnergyEvseAttributeListAttributeCallback::CallbackFn(void * context, env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); } +CHIPEnergyPreferenceEnergyBalancesAttributeCallback::CHIPEnergyPreferenceEnergyBalancesAttributeCallback(jobject javaCallback, + bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceEnergyBalancesAttributeCallback::~CHIPEnergyPreferenceEnergyBalancesAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceEnergyBalancesAttributeCallback::CallbackFn( + void * context, + const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + jobject newElement_0_step; + std::string newElement_0_stepClassName = "java/lang/Integer"; + std::string newElement_0_stepCtorSignature = "(I)V"; + jint jninewElement_0_step = static_cast(entry_0.step); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_stepClassName.c_str(), newElement_0_stepCtorSignature.c_str(), jninewElement_0_step, newElement_0_step); + jobject newElement_0_label; + if (!entry_0.label.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_label); + } + else + { + jobject newElement_0_labelInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label.Value(), newElement_0_labelInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_labelInsideOptional, newElement_0_label); + } + + jclass balanceStructStructClass_1; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$EnergyPreferenceClusterBalanceStruct", balanceStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EnergyPreferenceClusterBalanceStruct"); + return; + } + jmethodID balanceStructStructCtor_1 = + env->GetMethodID(balanceStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/util/Optional;)V"); + if (balanceStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EnergyPreferenceClusterBalanceStruct constructor"); + return; + } + + newElement_0 = env->NewObject(balanceStructStructClass_1, balanceStructStructCtor_1, newElement_0_step, newElement_0_label); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + +CHIPEnergyPreferenceEnergyPrioritiesAttributeCallback::CHIPEnergyPreferenceEnergyPrioritiesAttributeCallback(jobject javaCallback, + bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), + keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceEnergyPrioritiesAttributeCallback::~CHIPEnergyPreferenceEnergyPrioritiesAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceEnergyPrioritiesAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Integer"; + std::string newElement_0CtorSignature = "(I)V"; + jint jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), + jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + +CHIPEnergyPreferenceLowPowerModeSensitivitiesAttributeCallback::CHIPEnergyPreferenceLowPowerModeSensitivitiesAttributeCallback( + jobject javaCallback, bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), + keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceLowPowerModeSensitivitiesAttributeCallback::~CHIPEnergyPreferenceLowPowerModeSensitivitiesAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceLowPowerModeSensitivitiesAttributeCallback::CallbackFn( + void * context, + const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + jobject newElement_0_step; + std::string newElement_0_stepClassName = "java/lang/Integer"; + std::string newElement_0_stepCtorSignature = "(I)V"; + jint jninewElement_0_step = static_cast(entry_0.step); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_stepClassName.c_str(), newElement_0_stepCtorSignature.c_str(), jninewElement_0_step, newElement_0_step); + jobject newElement_0_label; + if (!entry_0.label.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_label); + } + else + { + jobject newElement_0_labelInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label.Value(), newElement_0_labelInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_labelInsideOptional, newElement_0_label); + } + + jclass balanceStructStructClass_1; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$EnergyPreferenceClusterBalanceStruct", balanceStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EnergyPreferenceClusterBalanceStruct"); + return; + } + jmethodID balanceStructStructCtor_1 = + env->GetMethodID(balanceStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/util/Optional;)V"); + if (balanceStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EnergyPreferenceClusterBalanceStruct constructor"); + return; + } + + newElement_0 = env->NewObject(balanceStructStructClass_1, balanceStructStructCtor_1, newElement_0_step, newElement_0_label); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + +CHIPEnergyPreferenceGeneratedCommandListAttributeCallback::CHIPEnergyPreferenceGeneratedCommandListAttributeCallback( + jobject javaCallback, bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), + keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceGeneratedCommandListAttributeCallback::~CHIPEnergyPreferenceGeneratedCommandListAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceGeneratedCommandListAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + +CHIPEnergyPreferenceAcceptedCommandListAttributeCallback::CHIPEnergyPreferenceAcceptedCommandListAttributeCallback( + jobject javaCallback, bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), + keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceAcceptedCommandListAttributeCallback::~CHIPEnergyPreferenceAcceptedCommandListAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceAcceptedCommandListAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + +CHIPEnergyPreferenceEventListAttributeCallback::CHIPEnergyPreferenceEventListAttributeCallback(jobject javaCallback, + bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceEventListAttributeCallback::~CHIPEnergyPreferenceEventListAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceEventListAttributeCallback::CallbackFn(void * context, + const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + +CHIPEnergyPreferenceAttributeListAttributeCallback::CHIPEnergyPreferenceAttributeListAttributeCallback(jobject javaCallback, + bool keepAlive) : + chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } +} + +CHIPEnergyPreferenceAttributeListAttributeCallback::~CHIPEnergyPreferenceAttributeListAttributeCallback() +{ + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not delete global reference for Java callback"); + return; + } + env->DeleteGlobalRef(javaCallbackRef); +} + +void CHIPEnergyPreferenceAttributeListAttributeCallback::CallbackFn( + void * context, const chip::app::DataModel::DecodableList & list) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context), maybeDestroy); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jmethodID javaMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + jobject arrayListObj; + chip::JniReferences::GetInstance().CreateArrayList(arrayListObj); + + auto iter_arrayListObj_0 = list.begin(); + while (iter_arrayListObj_0.Next()) + { + auto & entry_0 = iter_arrayListObj_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(arrayListObj, newElement_0); + } + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); +} + CHIPDoorLockLockStateAttributeCallback::CHIPDoorLockLockStateAttributeCallback(jobject javaCallback, bool keepAlive) : chip::Callback::Callback(CallbackFn, this), keepAlive(keepAlive) { diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 5c720c7d3da4e4..57d6c97e833340 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -6947,6 +6947,82 @@ class ChipClusters: }, }, } + _ENERGY_PREFERENCE_CLUSTER_INFO = { + "clusterName": "EnergyPreference", + "clusterId": 0x0000009B, + "commands": { + }, + "attributes": { + 0x00000000: { + "attributeName": "EnergyBalances", + "attributeId": 0x00000000, + "type": "", + "reportable": True, + }, + 0x00000001: { + "attributeName": "CurrentEnergyBalance", + "attributeId": 0x00000001, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00000002: { + "attributeName": "EnergyPriorities", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + }, + 0x00000003: { + "attributeName": "LowPowerModeSensitivities", + "attributeId": 0x00000003, + "type": "", + "reportable": True, + }, + 0x00000004: { + "attributeName": "CurrentLowPowerModeSensitivity", + "attributeId": 0x00000004, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _DOOR_LOCK_CLUSTER_INFO = { "clusterName": "DoorLock", "clusterId": 0x00000101, @@ -13864,6 +13940,7 @@ class ChipClusters: 0x00000096: _DEMAND_RESPONSE_LOAD_CONTROL_CLUSTER_INFO, 0x00000098: _DEVICE_ENERGY_MANAGEMENT_CLUSTER_INFO, 0x00000099: _ENERGY_EVSE_CLUSTER_INFO, + 0x0000009B: _ENERGY_PREFERENCE_CLUSTER_INFO, 0x00000101: _DOOR_LOCK_CLUSTER_INFO, 0x00000102: _WINDOW_COVERING_CLUSTER_INFO, 0x00000103: _BARRIER_CONTROL_CLUSTER_INFO, @@ -13979,6 +14056,7 @@ class ChipClusters: "DemandResponseLoadControl": _DEMAND_RESPONSE_LOAD_CONTROL_CLUSTER_INFO, "DeviceEnergyManagement": _DEVICE_ENERGY_MANAGEMENT_CLUSTER_INFO, "EnergyEvse": _ENERGY_EVSE_CLUSTER_INFO, + "EnergyPreference": _ENERGY_PREFERENCE_CLUSTER_INFO, "DoorLock": _DOOR_LOCK_CLUSTER_INFO, "WindowCovering": _WINDOW_COVERING_CLUSTER_INFO, "BarrierControl": _BARRIER_CONTROL_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index d5de5ecabd7b30..c5ca57c4ac6653 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -24793,6 +24793,248 @@ def descriptor(cls) -> ClusterObjectDescriptor: uid: 'bytes' = b"" +@dataclass +class EnergyPreference(Cluster): + id: typing.ClassVar[int] = 0x0000009B + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="energyBalances", Tag=0x00000000, Type=typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]), + ClusterObjectFieldDescriptor(Label="currentEnergyBalance", Tag=0x00000001, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="energyPriorities", Tag=0x00000002, Type=typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]), + ClusterObjectFieldDescriptor(Label="lowPowerModeSensitivities", Tag=0x00000003, Type=typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]), + ClusterObjectFieldDescriptor(Label="currentLowPowerModeSensitivity", Tag=0x00000004, Type=typing.Optional[uint]), + 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]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + energyBalances: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None + currentEnergyBalance: 'typing.Optional[uint]' = None + energyPriorities: 'typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]' = None + lowPowerModeSensitivities: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None + currentLowPowerModeSensitivity: 'typing.Optional[uint]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Enums: + class EnergyPriorityEnum(MatterIntEnum): + kComfort = 0x00 + kSpeed = 0x01 + kEfficiency = 0x02 + kWaterConsumption = 0x03 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 4, + + class Bitmaps: + class Feature(IntFlag): + kEnergyBalance = 0x1 + kLowPowerModeSensitivity = 0x2 + + class Structs: + @dataclass + class BalanceStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="step", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="label", Tag=1, Type=typing.Optional[str]), + ]) + + step: 'uint' = 0 + label: 'typing.Optional[str]' = None + + class Attributes: + @dataclass + class EnergyBalances(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]) + + value: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None + + @dataclass + class CurrentEnergyBalance(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class EnergyPriorities(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]) + + value: 'typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]' = None + + @dataclass + class LowPowerModeSensitivities(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000003 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]) + + value: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None + + @dataclass + class CurrentLowPowerModeSensitivity(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @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 GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009B + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class DoorLock(Cluster): id: typing.ClassVar[int] = 0x00000101 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 8d1513ffc0f8b6..9563685182a1be 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -3170,6 +3170,48 @@ static BOOL AttributeIsSpecifiedInEnergyEVSECluster(AttributeId aAttributeId) } } } +static BOOL AttributeIsSpecifiedInEnergyPreferenceCluster(AttributeId aAttributeId) +{ + using namespace Clusters::EnergyPreference; + switch (aAttributeId) { + case Attributes::EnergyBalances::Id: { + return YES; + } + case Attributes::CurrentEnergyBalance::Id: { + return YES; + } + case Attributes::EnergyPriorities::Id: { + return YES; + } + case Attributes::LowPowerModeSensitivities::Id: { + return YES; + } + case Attributes::CurrentLowPowerModeSensitivity::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInDoorLockCluster(AttributeId aAttributeId) { using namespace Clusters::DoorLock; @@ -6372,6 +6414,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::EnergyEvse::Id: { return AttributeIsSpecifiedInEnergyEVSECluster(aAttributeId); } + case Clusters::EnergyPreference::Id: { + return AttributeIsSpecifiedInEnergyPreferenceCluster(aAttributeId); + } case Clusters::DoorLock::Id: { return AttributeIsSpecifiedInDoorLockCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index a2e2ae45788c22..b31bee80bbf65a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -8813,6 +8813,140 @@ static id _Nullable DecodeAttributeValueForEnergyEVSECluster(AttributeId aAttrib *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForEnergyPreferenceCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::EnergyPreference; + switch (aAttributeId) { + case Attributes::EnergyBalances::Id: { + using TypeInfo = Attributes::EnergyBalances::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTREnergyPreferenceClusterBalanceStruct * newElement_0; + newElement_0 = [MTREnergyPreferenceClusterBalanceStruct new]; + newElement_0.step = [NSNumber numberWithUnsignedChar:entry_0.step]; + if (entry_0.label.HasValue()) { + newElement_0.label = AsString(entry_0.label.Value()); + if (newElement_0.label == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + } else { + newElement_0.label = nil; + } + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::CurrentEnergyBalance::Id: { + using TypeInfo = Attributes::CurrentEnergyBalance::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; + return value; + } + case Attributes::EnergyPriorities::Id: { + using TypeInfo = Attributes::EnergyPriorities::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + NSNumber * newElement_0; + newElement_0 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0)]; + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::LowPowerModeSensitivities::Id: { + using TypeInfo = Attributes::LowPowerModeSensitivities::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTREnergyPreferenceClusterBalanceStruct * newElement_0; + newElement_0 = [MTREnergyPreferenceClusterBalanceStruct new]; + newElement_0.step = [NSNumber numberWithUnsignedChar:entry_0.step]; + if (entry_0.label.HasValue()) { + newElement_0.label = AsString(entry_0.label.Value()); + if (newElement_0.label == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + } else { + newElement_0.label = nil; + } + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::CurrentLowPowerModeSensitivity::Id: { + using TypeInfo = Attributes::CurrentLowPowerModeSensitivity::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForDoorLockCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DoorLock; @@ -17966,6 +18100,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::EnergyEvse::Id: { return DecodeAttributeValueForEnergyEVSECluster(aPath.mAttributeId, aReader, aError); } + case Clusters::EnergyPreference::Id: { + return DecodeAttributeValueForEnergyPreferenceCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::DoorLock::Id: { return DecodeAttributeValueForDoorLockCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 49cc9273260b2d..9526a2cd3230c4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -7901,6 +7901,101 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Energy Preference + * + * This cluster provides an interface to specify preferences for how devices should consume energy. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterEnergyPreference : MTRGenericBaseCluster + +- (void)readAttributeEnergyBalancesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEnergyBalancesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEnergyBalancesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeCurrentEnergyBalanceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentEnergyBalanceWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentEnergyBalanceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEnergyPrioritiesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEnergyPrioritiesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEnergyPrioritiesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeLowPowerModeSensitivitiesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeLowPowerModeSensitivitiesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeLowPowerModeSensitivitiesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeCurrentLowPowerModeSensitivityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentLowPowerModeSensitivityWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentLowPowerModeSensitivityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterEnergyPreference (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Door Lock * @@ -17089,6 +17184,18 @@ typedef NS_OPTIONS(uint8_t, MTREnergyEVSETargetDayOfWeekBitmap) { MTREnergyEVSETargetDayOfWeekBitmapSaturday MTR_PROVISIONALLY_AVAILABLE = 0x40, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint8_t, MTREnergyPreferenceEnergyPriority) { + MTREnergyPreferenceEnergyPriorityComfort MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTREnergyPreferenceEnergyPrioritySpeed MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTREnergyPreferenceEnergyPriorityEfficiency MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTREnergyPreferenceEnergyPriorityWaterConsumption MTR_PROVISIONALLY_AVAILABLE = 0x03, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint32_t, MTREnergyPreferenceFeature) { + MTREnergyPreferenceFeatureEnergyBalance MTR_PROVISIONALLY_AVAILABLE = 0x1, + MTREnergyPreferenceFeatureLowPowerModeSensitivity MTR_PROVISIONALLY_AVAILABLE = 0x2, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRDoorLockAlarmCode) { MTRDoorLockAlarmCodeLockJammed MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00, MTRDoorLockAlarmCodeLockFactoryReset MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 4aab1586c4932c..ff63771e70e0f4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -53510,6 +53510,462 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterEnergyPreference + +- (void)readAttributeEnergyBalancesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::EnergyBalances::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEnergyBalancesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::EnergyBalances::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEnergyBalancesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::EnergyBalances::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeCurrentEnergyBalanceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::CurrentEnergyBalance::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeCurrentEnergyBalanceWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeCurrentEnergyBalanceWithValue:(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 = EnergyPreference::Attributes::CurrentEnergyBalance::TypeInfo; + TypeInfo::Type cppValue; + cppValue = value.unsignedCharValue; + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpoint); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeCurrentEnergyBalanceWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::CurrentEnergyBalance::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCurrentEnergyBalanceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::CurrentEnergyBalance::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEnergyPrioritiesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::EnergyPriorities::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEnergyPrioritiesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::EnergyPriorities::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEnergyPrioritiesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::EnergyPriorities::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeLowPowerModeSensitivitiesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::LowPowerModeSensitivities::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeLowPowerModeSensitivitiesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::LowPowerModeSensitivities::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeLowPowerModeSensitivitiesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::LowPowerModeSensitivities::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeCurrentLowPowerModeSensitivityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(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 = EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::TypeInfo; + TypeInfo::Type cppValue; + cppValue = value.unsignedCharValue; + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpoint); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeCurrentLowPowerModeSensitivityWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCurrentLowPowerModeSensitivityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::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 = EnergyPreference::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EnergyPreference::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:@(self.endpoint) + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EnergyPreference::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterDoorLock - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 9de74b6645d33a..e2e41259e4f052 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -154,6 +154,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeDemandResponseLoadControlID MTR_PROVISIONALLY_AVAILABLE = 0x00000096, MTRClusterIDTypeDeviceEnergyManagementID MTR_PROVISIONALLY_AVAILABLE = 0x00000098, MTRClusterIDTypeEnergyEVSEID MTR_PROVISIONALLY_AVAILABLE = 0x00000099, + MTRClusterIDTypeEnergyPreferenceID MTR_PROVISIONALLY_AVAILABLE = 0x0000009B, MTRClusterIDTypeDoorLockID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000101, MTRClusterIDTypeWindowCoveringID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000102, MTRClusterIDTypeBarrierControlID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000103, @@ -2687,6 +2688,19 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEnergyEVSEAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEnergyEVSEAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster EnergyPreference attributes + MTRAttributeIDTypeClusterEnergyPreferenceAttributeEnergyBalancesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentEnergyBalanceID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeEnergyPrioritiesID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeLowPowerModeSensitivitiesID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentLowPowerModeSensitivityID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterEnergyPreferenceAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster DoorLock deprecated attribute names MTRClusterDoorLockAttributeLockStateID MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterDoorLockAttributeLockStateID", 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/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 0da195e4c8bab8..912cb7f36a1bc4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -3710,6 +3710,56 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Energy Preference + * This cluster provides an interface to specify preferences for how devices should consume energy. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterEnergyPreference : MTRGenericCluster + +- (NSDictionary * _Nullable)readAttributeEnergyBalancesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeCurrentEnergyBalanceWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEnergyPrioritiesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeLowPowerModeSensitivitiesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeCurrentLowPowerModeSensitivityWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterEnergyPreference (Availability) + +/** + * The queue is currently unused, but may be used in the future for calling completions + * for command invocations if commands are added to this cluster. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Door Lock * An interface to a generic way to secure a door diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 5af8ad258ac25c..d319e14799a619 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -10225,6 +10225,87 @@ - (void)writeAttributeApproximateEVEfficiencyWithValue:(NSDictionary * _Nullable)readAttributeEnergyBalancesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeEnergyBalancesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeCurrentEnergyBalanceWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentEnergyBalanceID) params:params]; +} + +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeCurrentEnergyBalanceWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeCurrentEnergyBalanceWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentEnergyBalanceID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeEnergyPrioritiesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeEnergyPrioritiesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeLowPowerModeSensitivitiesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeLowPowerModeSensitivitiesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeCurrentLowPowerModeSensitivityWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentLowPowerModeSensitivityID) params:params]; +} + +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeCurrentLowPowerModeSensitivityWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentLowPowerModeSensitivityID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterDoorLock - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 8d20da304754e6..3c5c7439d15e2c 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -647,6 +647,15 @@ static BOOL CommandNeedsTimedInvokeInEnergyEVSECluster(AttributeId aAttributeId) } } } +static BOOL CommandNeedsTimedInvokeInEnergyPreferenceCluster(AttributeId aAttributeId) +{ + using namespace Clusters::EnergyPreference; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInDoorLockCluster(AttributeId aAttributeId) { using namespace Clusters::DoorLock; @@ -1266,6 +1275,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::EnergyEvse::Id: { return CommandNeedsTimedInvokeInEnergyEVSECluster(commandID); } + case Clusters::EnergyPreference::Id: { + return CommandNeedsTimedInvokeInEnergyPreferenceCluster(commandID); + } case Clusters::DoorLock::Id: { return CommandNeedsTimedInvokeInDoorLockCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index eadbca55e92339..09fea691852259 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -3044,6 +3044,18 @@ static id _Nullable DecodeEventPayloadForEnergyEVSECluster(EventId aEventId, TLV *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForEnergyPreferenceCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::EnergyPreference; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForDoorLockCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DoorLock; @@ -4482,6 +4494,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::EnergyEvse::Id: { return DecodeEventPayloadForEnergyEVSECluster(aPath.mEventId, aReader, aError); } + case Clusters::EnergyPreference::Id: { + return DecodeEventPayloadForEnergyPreferenceCluster(aPath.mEventId, aReader, aError); + } case Clusters::DoorLock::Id: { return DecodeEventPayloadForDoorLockCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 1c6fc64a88d0c4..6af977728ee470 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1324,6 +1324,12 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSData * _Nonnull uid MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTREnergyPreferenceClusterBalanceStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull step MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable label MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRDoorLockClusterCredentialStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull credentialType MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 81d7f3b773b4b0..9ddf0fa17f9128 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -5436,6 +5436,36 @@ - (NSString *)description @end +@implementation MTREnergyPreferenceClusterBalanceStruct +- (instancetype)init +{ + if (self = [super init]) { + + _step = @(0); + + _label = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTREnergyPreferenceClusterBalanceStruct alloc] init]; + + other.step = self.step; + other.label = self.label; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: step:%@; label:%@; >", NSStringFromClass([self class]), _step, _label]; + return descriptionString; +} + +@end + @implementation MTRDoorLockClusterCredentialStruct - (instancetype)init { 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 1a16b52c0e3e90..12d34873854914 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 @@ -11843,6 +11843,136 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) } // namespace Attributes } // namespace EnergyEvse +namespace EnergyPreference { +namespace Attributes { + +namespace CurrentEnergyBalance { + +EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::EnergyPreference::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + *value = Traits::StorageToWorking(temp); + return status; +} +EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +} // namespace CurrentEnergyBalance + +namespace CurrentLowPowerModeSensitivity { + +EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::EnergyPreference::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + *value = Traits::StorageToWorking(temp); + return status; +} +EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +} // namespace CurrentLowPowerModeSensitivity + +namespace FeatureMap { + +EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::EnergyPreference::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + *value = Traits::StorageToWorking(temp); + return status; +} +EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::EnergyPreference::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + *value = Traits::StorageToWorking(temp); + return status; +} +EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return EMBER_ZCL_STATUS_CONSTRAINT_ERROR; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::EnergyPreference::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace EnergyPreference + namespace DoorLock { namespace Attributes { 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 9364fc14be08a5..9540569158a171 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 @@ -2239,6 +2239,32 @@ EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); } // namespace Attributes } // namespace EnergyEvse +namespace EnergyPreference { +namespace Attributes { + +namespace CurrentEnergyBalance { +EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u +EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); +} // namespace CurrentEnergyBalance + +namespace CurrentLowPowerModeSensitivity { +EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value); // int8u +EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value); +} // namespace CurrentLowPowerModeSensitivity + +namespace FeatureMap { +EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value); +} // namespace FeatureMap + +namespace ClusterRevision { +EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value); // int16u +EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace EnergyPreference + namespace DoorLock { namespace Attributes { 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 480683245290c9..c37f234ce8a751 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -585,6 +585,14 @@ void emberAfDeviceEnergyManagementClusterInitCallback(chip::EndpointId endpoint) */ void emberAfEnergyEvseClusterInitCallback(chip::EndpointId endpoint); +/** @brief Energy Preference Cluster Init + * + * Cluster Init + * + * @param endpoint Endpoint that is being initialized + */ +void emberAfEnergyPreferenceClusterInitCallback(chip::EndpointId endpoint); + /** @brief Door Lock Cluster Init * * Cluster Init @@ -6251,6 +6259,84 @@ void emberAfEnergyEvseClusterServerTickCallback(chip::EndpointId endpoint); */ void emberAfEnergyEvseClusterClientTickCallback(chip::EndpointId endpoint); +// +// Energy Preference Cluster +// + +/** @brief Energy Preference Cluster Server Init + * + * Server Init + * + * @param endpoint Endpoint that is being initialized + */ +void emberAfEnergyPreferenceClusterServerInitCallback(chip::EndpointId endpoint); + +/** @brief Energy Preference Cluster Server Shutdown + * + * Server Shutdown + * + * @param endpoint Endpoint that is being shutdown + */ +void MatterEnergyPreferenceClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** @brief Energy Preference Cluster Client Init + * + * Client Init + * + * @param endpoint Endpoint that is being initialized + */ +void emberAfEnergyPreferenceClusterClientInitCallback(chip::EndpointId endpoint); + +/** @brief Energy Preference Cluster Server Attribute Changed + * + * Server Attribute Changed + * + * @param attributePath Concrete attribute path that changed + */ +void MatterEnergyPreferenceClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** @brief Energy Preference Cluster Server Pre Attribute Changed + * + * Server Pre Attribute Changed + * + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status +MatterEnergyPreferenceClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** @brief Energy Preference Cluster Client Pre Attribute Changed + * + * Client Pre Attribute Changed + * + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status +MatterEnergyPreferenceClusterClientPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** @brief Energy Preference Cluster Server Tick + * + * Server Tick + * + * @param endpoint Endpoint that is being served + */ +void emberAfEnergyPreferenceClusterServerTickCallback(chip::EndpointId endpoint); + +/** @brief Energy Preference Cluster Client Tick + * + * Client Tick + * + * @param endpoint Endpoint that is being served + */ +void emberAfEnergyPreferenceClusterClientTickCallback(chip::EndpointId endpoint); + // // Door Lock Cluster // diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index 72f6654c5a3b8b..0b450692c1486f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -1771,6 +1771,21 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(EnergyEvse::SupplyState } } +static auto __attribute__((unused)) EnsureKnownEnumValue(EnergyPreference::EnergyPriorityEnum val) +{ + using EnumType = EnergyPreference::EnergyPriorityEnum; + switch (val) + { + case EnumType::kComfort: + case EnumType::kSpeed: + case EnumType::kEfficiency: + case EnumType::kWaterConsumption: + return val; + default: + return static_cast(4); + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(DoorLock::AlarmCodeEnum val) { using EnumType = DoorLock::AlarmCodeEnum; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 274bea95b7a097..1bcc2a286d63c3 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -2534,6 +2534,30 @@ enum class TargetDayOfWeekBitmap : uint8_t }; } // namespace EnergyEvse +namespace EnergyPreference { + +// Enum for EnergyPriorityEnum +enum class EnergyPriorityEnum : uint8_t +{ + kComfort = 0x00, + kSpeed = 0x01, + kEfficiency = 0x02, + kWaterConsumption = 0x03, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 4, +}; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kEnergyBalance = 0x1, + kLowPowerModeSensitivity = 0x2, +}; +} // namespace EnergyPreference + namespace DoorLock { // Enum for AlarmCodeEnum 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 4ec4eb107d019c..770ec90ad04adb 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 @@ -16438,6 +16438,89 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace Events } // namespace EnergyEvse +namespace EnergyPreference { +namespace Structs { + +namespace BalanceStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStep), step); + encoder.Encode(to_underlying(Fields::kLabel), label); + 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::kStep)) + { + err = DataModel::Decode(reader, step); + } + else if (__context_tag == to_underlying(Fields::kLabel)) + { + err = DataModel::Decode(reader, label); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace BalanceStruct +} // namespace Structs + +namespace Commands {} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::EnergyBalances::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, energyBalances); + case Attributes::CurrentEnergyBalance::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentEnergyBalance); + case Attributes::EnergyPriorities::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, energyPriorities); + case Attributes::LowPowerModeSensitivities::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, lowPowerModeSensitivities); + case Attributes::CurrentLowPowerModeSensitivity::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentLowPowerModeSensitivity); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace EnergyPreference namespace DoorLock { namespace Structs { 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 7c1839591691f8..703f14128611ae 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 @@ -22877,6 +22877,160 @@ struct DecodableType } // namespace Rfid } // namespace Events } // namespace EnergyEvse +namespace EnergyPreference { +namespace Structs { +namespace BalanceStruct { +enum class Fields : uint8_t +{ + kStep = 0, + kLabel = 1, +}; + +struct Type +{ +public: + chip::Percent step = static_cast(0); + Optional label; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace BalanceStruct +} // namespace Structs + +namespace Attributes { + +namespace EnergyBalances { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = + chip::app::DataModel::DecodableList; + using DecodableArgType = + const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::EnergyBalances::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace EnergyBalances +namespace CurrentEnergyBalance { +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentEnergyBalance::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentEnergyBalance +namespace EnergyPriorities { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList; + using DecodableArgType = const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::EnergyPriorities::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace EnergyPriorities +namespace LowPowerModeSensitivities { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = + chip::app::DataModel::DecodableList; + using DecodableArgType = + const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::LowPowerModeSensitivities::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace LowPowerModeSensitivities +namespace CurrentLowPowerModeSensitivity { +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentLowPowerModeSensitivity::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentLowPowerModeSensitivity +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::EnergyBalances::TypeInfo::DecodableType energyBalances; + Attributes::CurrentEnergyBalance::TypeInfo::DecodableType currentEnergyBalance = static_cast(0); + Attributes::EnergyPriorities::TypeInfo::DecodableType energyPriorities; + Attributes::LowPowerModeSensitivities::TypeInfo::DecodableType lowPowerModeSensitivities; + Attributes::CurrentLowPowerModeSensitivity::TypeInfo::DecodableType currentLowPowerModeSensitivity = + static_cast(0); + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace EnergyPreference namespace DoorLock { namespace Structs { namespace CredentialStruct { 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 ae707a1554f607..3e23f66beb1d2c 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 @@ -3945,6 +3945,56 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace EnergyEvse +namespace EnergyPreference { +namespace Attributes { + +namespace EnergyBalances { +static constexpr AttributeId Id = 0x00000000; +} // namespace EnergyBalances + +namespace CurrentEnergyBalance { +static constexpr AttributeId Id = 0x00000001; +} // namespace CurrentEnergyBalance + +namespace EnergyPriorities { +static constexpr AttributeId Id = 0x00000002; +} // namespace EnergyPriorities + +namespace LowPowerModeSensitivities { +static constexpr AttributeId Id = 0x00000003; +} // namespace LowPowerModeSensitivities + +namespace CurrentLowPowerModeSensitivity { +static constexpr AttributeId Id = 0x00000004; +} // namespace CurrentLowPowerModeSensitivity + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace EnergyPreference + namespace DoorLock { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index 3bcd1734de0353..32a8b316847eee 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -232,6 +232,9 @@ static constexpr ClusterId Id = 0x00000098; namespace EnergyEvse { static constexpr ClusterId Id = 0x00000099; } // namespace EnergyEvse +namespace EnergyPreference { +static constexpr ClusterId Id = 0x0000009B; +} // namespace EnergyPreference namespace DoorLock { static constexpr ClusterId Id = 0x00000101; } // namespace DoorLock diff --git a/zzz_generated/app-common/app-common/zap-generated/print-cluster.h b/zzz_generated/app-common/app-common/zap-generated/print-cluster.h index a2f0dd80afba47..fa4778a1438519 100644 --- a/zzz_generated/app-common/app-common/zap-generated/print-cluster.h +++ b/zzz_generated/app-common/app-common/zap-generated/print-cluster.h @@ -471,6 +471,12 @@ #define CHIP_PRINTCLUSTER_ENERGY_EVSE_CLUSTER #endif +#if defined(ZCL_USING_ENERGY_PREFERENCE_CLUSTER_SERVER) || defined(ZCL_USING_ENERGY_PREFERENCE_CLUSTER_CLIENT) +#define CHIP_PRINTCLUSTER_ENERGY_PREFERENCE_CLUSTER { chip::app::Clusters::EnergyPreference::Id, "Energy Preference" }, +#else +#define CHIP_PRINTCLUSTER_ENERGY_PREFERENCE_CLUSTER +#endif + #if defined(ZCL_USING_DOOR_LOCK_CLUSTER_SERVER) || defined(ZCL_USING_DOOR_LOCK_CLUSTER_CLIENT) #define CHIP_PRINTCLUSTER_DOOR_LOCK_CLUSTER { chip::app::Clusters::DoorLock::Id, "Door Lock" }, #else @@ -829,6 +835,7 @@ CHIP_PRINTCLUSTER_DEMAND_RESPONSE_LOAD_CONTROL_CLUSTER \ CHIP_PRINTCLUSTER_DEVICE_ENERGY_MANAGEMENT_CLUSTER \ CHIP_PRINTCLUSTER_ENERGY_EVSE_CLUSTER \ + CHIP_PRINTCLUSTER_ENERGY_PREFERENCE_CLUSTER \ CHIP_PRINTCLUSTER_DOOR_LOCK_CLUSTER \ CHIP_PRINTCLUSTER_WINDOW_COVERING_CLUSTER \ CHIP_PRINTCLUSTER_BARRIER_CONTROL_CLUSTER \ diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index e45f9a82f0de23..61c0f0250b465c 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -103,6 +103,7 @@ | DemandResponseLoadControl | 0x0096 | | DeviceEnergyManagement | 0x0098 | | EnergyEvse | 0x0099 | +| EnergyPreference | 0x009B | | DoorLock | 0x0101 | | WindowCovering | 0x0102 | | BarrierControl | 0x0103 | @@ -7462,6 +7463,27 @@ class EnergyEvseClearTargets : public ClusterCommand chip::app::Clusters::EnergyEvse::Commands::ClearTargets::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster EnergyPreference | 0x009B | +|------------------------------------------------------------------------------| +| Commands: | | +|------------------------------------------------------------------------------| +| Attributes: | | +| * EnergyBalances | 0x0000 | +| * CurrentEnergyBalance | 0x0001 | +| * EnergyPriorities | 0x0002 | +| * LowPowerModeSensitivities | 0x0003 | +| * CurrentLowPowerModeSensitivity | 0x0004 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------*\ | Cluster DoorLock | 0x0101 | |------------------------------------------------------------------------------| @@ -19863,6 +19885,86 @@ void registerClusterEnergyEvse(Commands & commands, CredentialIssuerCommands * c commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterEnergyPreference(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::EnergyPreference; + + const char * clusterName = "EnergyPreference"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "energy-balances", Attributes::EnergyBalances::Id, credsIssuerConfig), // + make_unique(Id, "current-energy-balance", Attributes::CurrentEnergyBalance::Id, credsIssuerConfig), // + make_unique(Id, "energy-priorities", Attributes::EnergyPriorities::Id, credsIssuerConfig), // + make_unique(Id, "low-power-mode-sensitivities", Attributes::LowPowerModeSensitivities::Id, + credsIssuerConfig), // + make_unique(Id, "current-low-power-mode-sensitivity", Attributes::CurrentLowPowerModeSensitivity::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), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "energy-balances", Attributes::EnergyBalances::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "current-energy-balance", 0, UINT8_MAX, Attributes::CurrentEnergyBalance::Id, + WriteCommandType::kWrite, credsIssuerConfig), // + make_unique< + WriteAttributeAsComplex>>( + Id, "energy-priorities", Attributes::EnergyPriorities::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "low-power-mode-sensitivities", Attributes::LowPowerModeSensitivities::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>(Id, "current-low-power-mode-sensitivity", 0, UINT8_MAX, + Attributes::CurrentLowPowerModeSensitivity::Id, WriteCommandType::kWrite, + credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "energy-balances", Attributes::EnergyBalances::Id, credsIssuerConfig), // + make_unique(Id, "current-energy-balance", Attributes::CurrentEnergyBalance::Id, credsIssuerConfig), // + make_unique(Id, "energy-priorities", Attributes::EnergyPriorities::Id, credsIssuerConfig), // + make_unique(Id, "low-power-mode-sensitivities", Attributes::LowPowerModeSensitivities::Id, + credsIssuerConfig), // + make_unique(Id, "current-low-power-mode-sensitivity", Attributes::CurrentLowPowerModeSensitivity::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), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterDoorLock(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::DoorLock; @@ -25414,6 +25516,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterDemandResponseLoadControl(commands, credsIssuerConfig); registerClusterDeviceEnergyManagement(commands, credsIssuerConfig); registerClusterEnergyEvse(commands, credsIssuerConfig); + registerClusterEnergyPreference(commands, credsIssuerConfig); registerClusterDoorLock(commands, credsIssuerConfig); registerClusterWindowCovering(commands, credsIssuerConfig); registerClusterBarrierControl(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 155f91f1db84c9..acbd349dc09dfc 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -3249,6 +3249,38 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::EnergyEvse::Structs::C ComplexArgumentParser::Finalize(request.addedEnergy); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::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("BalanceStruct.step", "step", value.isMember("step"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "step"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.step, value["step"])); + valueCopy.removeMember("step"); + + if (value.isMember("label")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "label"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.label, value["label"])); + } + valueCopy.removeMember("label"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.step); + ComplexArgumentParser::Finalize(request.label); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type & request, Json::Value & value) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index c7affea5f68209..445524c97f85e4 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -378,6 +378,11 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::EnergyEvse::Str static void Finalize(chip::app::Clusters::EnergyEvse::Structs::ChargingTargetStruct::Type & request); +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::DoorLock::Structs::CredentialStruct::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 bea41c7e1d7fee..e0e24074789701 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -2890,6 +2890,31 @@ 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::EnergyPreference::Structs::BalanceStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Step", indent + 1, value.step); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Step'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Label", indent + 1, value.label); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Label'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Structs::CredentialStruct::DecodableType & value) { @@ -12114,6 +12139,67 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case EnergyPreference::Id: { + switch (path.mAttributeId) + { + case EnergyPreference::Attributes::EnergyBalances::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EnergyBalances", 1, value); + } + case EnergyPreference::Attributes::CurrentEnergyBalance::Id: { + uint8_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CurrentEnergyBalance", 1, value); + } + case EnergyPreference::Attributes::EnergyPriorities::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EnergyPriorities", 1, value); + } + case EnergyPreference::Attributes::LowPowerModeSensitivities::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("LowPowerModeSensitivities", 1, value); + } + case EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::Id: { + uint8_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CurrentLowPowerModeSensitivity", 1, value); + } + case EnergyPreference::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case EnergyPreference::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case EnergyPreference::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case EnergyPreference::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case EnergyPreference::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case EnergyPreference::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case DoorLock::Id: { switch (path.mAttributeId) { 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 d768721f46c0fc..8828a11491c5d3 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -238,6 +238,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::EnergyEvse::Structs::ChargingTargetStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Structs::CredentialStruct::DecodableType & 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 c5aec0730e7d59..049ecbb65d29d5 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -106,6 +106,7 @@ | DemandResponseLoadControl | 0x0096 | | DeviceEnergyManagement | 0x0098 | | EnergyEvse | 0x0099 | +| EnergyPreference | 0x009B | | DoorLock | 0x0101 | | WindowCovering | 0x0102 | | BarrierControl | 0x0103 | @@ -83651,6 +83652,1046 @@ class SubscribeAttributeEnergyEvseClusterRevision : public SubscribeAttribute { } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster EnergyPreference | 0x009B | +|------------------------------------------------------------------------------| +| Commands: | | +|------------------------------------------------------------------------------| +| Attributes: | | +| * EnergyBalances | 0x0000 | +| * CurrentEnergyBalance | 0x0001 | +| * EnergyPriorities | 0x0002 | +| * LowPowerModeSensitivities | 0x0003 | +| * CurrentLowPowerModeSensitivity | 0x0004 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EnergyBalances + */ +class ReadEnergyPreferenceEnergyBalances : public ReadAttribute { +public: + ReadEnergyPreferenceEnergyBalances() + : ReadAttribute("energy-balances") + { + } + + ~ReadEnergyPreferenceEnergyBalances() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EnergyBalances::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEnergyBalancesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.EnergyBalances response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference EnergyBalances read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceEnergyBalances : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceEnergyBalances() + : SubscribeAttribute("energy-balances") + { + } + + ~SubscribeAttributeEnergyPreferenceEnergyBalances() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EnergyBalances::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeEnergyBalancesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.EnergyBalances 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 CurrentEnergyBalance + */ +class ReadEnergyPreferenceCurrentEnergyBalance : public ReadAttribute { +public: + ReadEnergyPreferenceCurrentEnergyBalance() + : ReadAttribute("current-energy-balance") + { + } + + ~ReadEnergyPreferenceCurrentEnergyBalance() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::CurrentEnergyBalance::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCurrentEnergyBalanceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.CurrentEnergyBalance response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference CurrentEnergyBalance read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteEnergyPreferenceCurrentEnergyBalance : public WriteAttribute { +public: + WriteEnergyPreferenceCurrentEnergyBalance() + : WriteAttribute("current-energy-balance") + { + AddArgument("attr-name", "current-energy-balance"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteEnergyPreferenceCurrentEnergyBalance() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::CurrentEnergyBalance::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 = [[MTRBaseClusterEnergyPreference 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 writeAttributeCurrentEnergyBalanceWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("EnergyPreference CurrentEnergyBalance write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + uint8_t mValue; +}; + +class SubscribeAttributeEnergyPreferenceCurrentEnergyBalance : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceCurrentEnergyBalance() + : SubscribeAttribute("current-energy-balance") + { + } + + ~SubscribeAttributeEnergyPreferenceCurrentEnergyBalance() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::CurrentEnergyBalance::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeCurrentEnergyBalanceWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.CurrentEnergyBalance 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 EnergyPriorities + */ +class ReadEnergyPreferenceEnergyPriorities : public ReadAttribute { +public: + ReadEnergyPreferenceEnergyPriorities() + : ReadAttribute("energy-priorities") + { + } + + ~ReadEnergyPreferenceEnergyPriorities() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EnergyPriorities::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEnergyPrioritiesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.EnergyPriorities response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference EnergyPriorities read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceEnergyPriorities : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceEnergyPriorities() + : SubscribeAttribute("energy-priorities") + { + } + + ~SubscribeAttributeEnergyPreferenceEnergyPriorities() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EnergyPriorities::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeEnergyPrioritiesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.EnergyPriorities 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 LowPowerModeSensitivities + */ +class ReadEnergyPreferenceLowPowerModeSensitivities : public ReadAttribute { +public: + ReadEnergyPreferenceLowPowerModeSensitivities() + : ReadAttribute("low-power-mode-sensitivities") + { + } + + ~ReadEnergyPreferenceLowPowerModeSensitivities() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::LowPowerModeSensitivities::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeLowPowerModeSensitivitiesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.LowPowerModeSensitivities response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference LowPowerModeSensitivities read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceLowPowerModeSensitivities : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceLowPowerModeSensitivities() + : SubscribeAttribute("low-power-mode-sensitivities") + { + } + + ~SubscribeAttributeEnergyPreferenceLowPowerModeSensitivities() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::LowPowerModeSensitivities::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeLowPowerModeSensitivitiesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.LowPowerModeSensitivities 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 CurrentLowPowerModeSensitivity + */ +class ReadEnergyPreferenceCurrentLowPowerModeSensitivity : public ReadAttribute { +public: + ReadEnergyPreferenceCurrentLowPowerModeSensitivity() + : ReadAttribute("current-low-power-mode-sensitivity") + { + } + + ~ReadEnergyPreferenceCurrentLowPowerModeSensitivity() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCurrentLowPowerModeSensitivityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.CurrentLowPowerModeSensitivity response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference CurrentLowPowerModeSensitivity read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteEnergyPreferenceCurrentLowPowerModeSensitivity : public WriteAttribute { +public: + WriteEnergyPreferenceCurrentLowPowerModeSensitivity() + : WriteAttribute("current-low-power-mode-sensitivity") + { + AddArgument("attr-name", "current-low-power-mode-sensitivity"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteEnergyPreferenceCurrentLowPowerModeSensitivity() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::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 = [[MTRBaseClusterEnergyPreference 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 writeAttributeCurrentLowPowerModeSensitivityWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("EnergyPreference CurrentLowPowerModeSensitivity write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + uint8_t mValue; +}; + +class SubscribeAttributeEnergyPreferenceCurrentLowPowerModeSensitivity : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceCurrentLowPowerModeSensitivity() + : SubscribeAttribute("current-low-power-mode-sensitivity") + { + } + + ~SubscribeAttributeEnergyPreferenceCurrentLowPowerModeSensitivity() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::CurrentLowPowerModeSensitivity::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeCurrentLowPowerModeSensitivityWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.CurrentLowPowerModeSensitivity 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 GeneratedCommandList + */ +class ReadEnergyPreferenceGeneratedCommandList : public ReadAttribute { +public: + ReadEnergyPreferenceGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadEnergyPreferenceGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::GeneratedCommandList::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeEnergyPreferenceGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::GeneratedCommandList::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.GeneratedCommandList 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 AcceptedCommandList + */ +class ReadEnergyPreferenceAcceptedCommandList : public ReadAttribute { +public: + ReadEnergyPreferenceAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadEnergyPreferenceAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::AcceptedCommandList::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeEnergyPreferenceAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::AcceptedCommandList::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.AcceptedCommandList 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 EventList + */ +class ReadEnergyPreferenceEventList : public ReadAttribute { +public: + ReadEnergyPreferenceEventList() + : ReadAttribute("event-list") + { + } + + ~ReadEnergyPreferenceEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EventList::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceEventList : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeEnergyPreferenceEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EventList::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.EventList 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 AttributeList + */ +class ReadEnergyPreferenceAttributeList : public ReadAttribute { +public: + ReadEnergyPreferenceAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadEnergyPreferenceAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::AttributeList::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeEnergyPreferenceAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::AttributeList::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.AttributeList 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 FeatureMap + */ +class ReadEnergyPreferenceFeatureMap : public ReadAttribute { +public: + ReadEnergyPreferenceFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadEnergyPreferenceFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::FeatureMap::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeEnergyPreferenceFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::FeatureMap::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.FeatureMap 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 ClusterRevision + */ +class ReadEnergyPreferenceClusterRevision : public ReadAttribute { +public: + ReadEnergyPreferenceClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadEnergyPreferenceClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::ClusterRevision::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 = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EnergyPreference ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEnergyPreferenceClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeEnergyPreferenceClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeEnergyPreferenceClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::ClusterRevision::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 = [[MTRBaseClusterEnergyPreference 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 subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EnergyPreference.ClusterRevision 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 #endif // MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ @@ -177051,6 +178092,69 @@ void registerClusterEnergyEvse(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterEnergyPreference(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::EnergyPreference; + + const char * clusterName = "EnergyPreference"; + + commands_list clusterCommands = { + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterDoorLock(Commands & commands) { using namespace chip::app::Clusters::DoorLock; @@ -180378,6 +181482,7 @@ void registerClusters(Commands & commands) registerClusterDemandResponseLoadControl(commands); registerClusterDeviceEnergyManagement(commands); registerClusterEnergyEvse(commands); + registerClusterEnergyPreference(commands); registerClusterDoorLock(commands); registerClusterWindowCovering(commands); registerClusterBarrierControl(commands); From ce32d114547172f6aed35a08ff61f7376694030c Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Wed, 20 Dec 2023 02:17:27 +0000 Subject: [PATCH 08/83] EVSE Delegate callbacks to user application (#30999) * Fix #30665 (EVSE) - Changed to use amperage_mA, energy_mWh - removed max on epoch_s - removed access for operate - removed side for events * Fix #30665 updates to try to get further with ZAP and autogen, but still fails with some parts of regen_all * Added ember-compatibility-functions.cpp which was missing. * Made all types all lowercase to resolve regen_all issues. * Fixed lint issue (trailing whitespace). * Fixes #30727 - Added initial EVSE cluster and Example Energy Managament app. * Tidied up old comments. * Restyled by whitespace * Restyled by gn * Restyled by prettier-markdown * Added copy of files to all-clusters-app linux BUILD.gn and did basic test with chip-tool * Fixed lint error (Remove PRId64) * Fix for Documentation Build and publish checker. * Updated all-clusters-app.zap after merge and regen_all * Added Cluster to ESP32 CMakeLists.txt * Fixed ESP32 compile error caused by %d * Added missing source files to each build variant * Restyled by gn * Fixed incorrect uint64_t in EnableCharging/EnableDischarging command * Fixed more issues seen on different platforms * Removed unused mEndpointId * Add source files to shell standalone BUILD.gn, More %d fixes for different platforms * Restyled by gn * Removed unused mMinimumChargingCurrentLimitFromCommand * Removed yet more unused variables * Fixed missing semi-colon. How did the other compilers not pick this up? * Capitalise function names * PR comment - Moved PluginServerInitCallback to sdk. Capitalised more function names in energy-management-app. * Restyled by whitespace * Fixes #30805 Updated energy-evse-cluster.xml * Fixes #30805 zap_regen_all commit. * Made Fault Event allow a nullable SessionID * Updates based on review (use kMaximumChargeCurrent instead of duplicate #define). Add HwSetVehicleID implementation * Added RFID Event support. Removed more unnecessary chip:: * Added Feature flags, optional commands and optional attributes. * Made command handling conditional based on features * Added Feature support to all-clusters-app * Restyled by clang-format * Fix to Darwin compile error - not checking strcmp return * Attempt to fix Darwin errors (return after else) * Updated based on latest upstream master * Removed unnecessary mInstance and used 'this' instead. * Regen_all after merge to master. * Fix review comment. * Ensure Init() returns a failure if there is one. Aligned to mode-base-server.cpp * Backed out Read attr check based on features. * Fixed EnumerateAcceptedCommands to handle Loop::Break condition. * Had missed StartDiagnostic as an optional command in InvokeCommand * Removed extra chip:: in attr types. * Updated HwSetVehicleID to copy the value from callee * Fixed potential buffer overrun in HwSetVehicleID. * Fixed simple to address comments raised by Andrei in PR 30857 * Fixed simple to address comments raised by Andrei in PR 30857 * Check Delegate is initialized before calling functions. * Check Delegate is initialized before calling functions. * Added callbacks into Application code * Restyled by whitespace * Ensured that mVehicleID free's any malloc'd CharSpan in destructor * Sync EnergyEvseDelegateImpl.cpp from Example Energy Management * Ensured that mVehicleID free's any malloc'd CharSpan in destructor * Sync EnergyEvseDelegateImpl.cpp from Example Energy Management * Sync'd changes from example energy management app, and commits from #30857 & #30727 * Added namespace to avoid global namespace error in header file. * Re-write of ApplicationInit to handle potential errors * Re-write of ApplicationInit to handle potential errors * Removed unnecessary void in function decl. * Open and saved in ZAP, then regen_all * Updated Energy-management-app.zap / .matter after change to general-diagnostics.xml change to MS. * Updated Energy-management-app.zap / .matter after change to general-diagnostics.xml change to MS. * Restyled by whitespace * Fixed types to be signed=true * Fixed 31032 - revert removal of side="server". Also turned on Events. * PR comment fix - remove Localization Config and Time Format Localization cluster * Removed EVSE commands from ZAP to avoid emberAf linker errors since these are handled in the IM Commands handler * Regen_all to update energy-management.matter file to remove commands that cause linker errors. * Minor changes to align all-clusters and energy-management common. * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Addressed comment and replicated into example energy management copies. * Added documentation to EVSE Callbacks as to which struct in the union is used. * Added Energy EVSE and Device Energy Management to config-data.yml under CommandHandlerInterfaceOnlyClusters. Then turned on EVSE commands in ZAP. --------- Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky --- .../all-clusters-app.matter | 9 ++ .../all-clusters-common/all-clusters-app.zap | 66 +++++++++++++ .../include/EVSECallbacks.h | 84 ++++++++++++++++ .../include/EnergyEvseDelegateImpl.h | 12 ++- .../src/EnergyEvseDelegateImpl.cpp | 96 ++++++++++++++---- .../include/EVSECallbacks.h | 84 ++++++++++++++++ .../include/EVSEManufacturerImpl.h | 5 + .../include/EnergyEvseDelegateImpl.h | 12 ++- .../src/EVSEManufacturerImpl.cpp | 26 ++++- .../src/EnergyEvseDelegateImpl.cpp | 98 ++++++++++++++----- src/app/common/templates/config-data.yaml | 2 + .../app-common/zap-generated/callback.h | 84 ---------------- 12 files changed, 448 insertions(+), 130 deletions(-) create mode 100644 examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h create mode 100644 examples/energy-management-app/energy-management-common/include/EVSECallbacks.h 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 45be7ed614d227..59090b662d6486 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 @@ -7354,6 +7354,15 @@ endpoint 1 { callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; + + handle command GetTargetsResponse; + handle command Disable; + handle command EnableCharging; + handle command EnableDischarging; + handle command StartDiagnostics; + handle command SetTargets; + handle command GetTargets; + handle command ClearTargets; } server cluster WindowCovering { 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 0bba4b8871e6c2..6f35331ee14640 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 @@ -11737,6 +11737,72 @@ "side": "server", "enabled": 1, "apiMaturity": "provisional", + "commands": [ + { + "name": "GetTargetsResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "Disable", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "EnableCharging", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "EnableDischarging", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartDiagnostics", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetTargets", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetTargets", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ClearTargets", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], "attributes": [ { "name": "State", diff --git a/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h b/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h new file mode 100644 index 00000000000000..5bdac2f8e853d6 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h @@ -0,0 +1,84 @@ +/* + * + * 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 + +namespace chip { +namespace app { +namespace Clusters { + +using namespace chip::app::Clusters::EnergyEvse; + +/* This callbacks mechanism is intended to allow different delegates to + * dispatch notifications that something has changed. + * + * This is not specific to the EnergyEVSE cluster, but includes DeviceEnergyManagement + * and potential future clusters. + */ +enum EVSECallbackType +{ + /* + * The State has changed (e.g. from Disabled to Charging, or vice-versa) + */ + StateChanged, + /* + * ChargeCurrent has changed + */ + ChargeCurrentChanged, + /* + * Charging Preferences have changed + */ + ChargingPreferencesChanged, + /* + * DeviceEnergyManagement has changed + */ + DeviceEnergyManagementChanged, +}; + +struct EVSECbInfo +{ + EVSECallbackType type; + + union + { + /* for type = StateChanged */ + struct + { + StateEnum state; + SupplyStateEnum supplyState; + } StateChange; + + /* for type = ChargeCurrentChanged */ + struct + { + int64_t maximumChargeCurrent; + } ChargingCurrent; + }; +}; + +typedef void (*EVSECallbackFunc)(const EVSECbInfo * cb, intptr_t arg); + +struct EVSECallbackWrapper +{ + EVSECallbackFunc handler; + intptr_t arg; +}; + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h b/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h index 0a967e2472be8b..f3c003d081fc6e 100644 --- a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h +++ b/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h @@ -19,6 +19,7 @@ #pragma once #include "app/clusters/energy-evse-server/energy-evse-server.h" +#include #include #include @@ -68,9 +69,13 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate */ Status StartDiagnostics() override; + /** + * @brief Called by EVSE Hardware to register a single callback handler + */ + Status HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg); + // ----------------------------------------------------------------- // Internal API to allow an EVSE to change its internal state etc - // TODO Status HwRegisterEvseHardwareCallback(Callback); Status HwSetMaxHardwareCurrentLimit(int64_t currentmA); Status HwSetCircuitCapacity(int64_t currentmA); Status HwSetCableAssemblyLimit(int64_t currentmA); @@ -150,6 +155,11 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate int64_t mActualChargingCurrentLimit = 0; StateEnum mHwState = StateEnum::kNotPluggedIn; /* Hardware state */ + /* Callback related */ + EVSECallbackWrapper mCallbacks = { .handler = nullptr, .arg = 0 }; /* Wrapper to allow callbacks to be registered */ + Status NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent); + Status NotifyApplicationStateChange(); + /** * @brief Helper function to work out the charge limit based on conditions and settings */ diff --git a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp b/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp index 64d8b98bafc644..4cc83eaaf8a835 100644 --- a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp @@ -83,6 +83,7 @@ Status EnergyEvseDelegate::Disable() /* update MaximumDischargeCurrent to 0 */ SetMaximumDischargeCurrent(0); + NotifyApplicationStateChange(); // TODO: Generate events return Status::Success; @@ -102,31 +103,31 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & if (maximumChargeCurrent < kMinimumChargeCurrent || maximumChargeCurrent > kMaximumChargeCurrent) { - ChipLogError(NotSpecified, "Maximum Current outside limits"); + ChipLogError(AppServer, "Maximum Current outside limits"); return Status::ConstraintError; } if (minimumChargeCurrent < kMinimumChargeCurrent || minimumChargeCurrent > kMaximumChargeCurrent) { - ChipLogError(NotSpecified, "Maximum Current outside limits"); + ChipLogError(AppServer, "Maximum Current outside limits"); return Status::ConstraintError; } if (minimumChargeCurrent > maximumChargeCurrent) { - ChipLogError(NotSpecified, "Minium Current > Maximum Current!"); + ChipLogError(AppServer, "Minium Current > Maximum Current!"); return Status::ConstraintError; } if (chargingEnabledUntil.IsNull()) { /* Charging enabled indefinitely */ - ChipLogError(NotSpecified, "Charging enabled indefinitely"); + ChipLogError(AppServer, "Charging enabled indefinitely"); } else { /* check chargingEnabledUntil is in the future */ - ChipLogError(NotSpecified, "Charging enabled until: %lu", static_cast(chargingEnabledUntil.Value())); + ChipLogError(AppServer, "Charging enabled until: %lu", static_cast(chargingEnabledUntil.Value())); // TODO // if (checkChargingEnabled) } @@ -169,6 +170,8 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & // TODO: Generate events + NotifyApplicationStateChange(); + return this->ComputeMaxChargeCurrentLimit(); } @@ -188,6 +191,8 @@ Status EnergyEvseDelegate::EnableDischarging(const DataModel::Nullable // TODO: Generate events + NotifyApplicationStateChange(); + return Status::Success; } @@ -199,25 +204,42 @@ Status EnergyEvseDelegate::StartDiagnostics() /* For EVSE manufacturers to customize */ ChipLogProgress(AppServer, "EnergyEvseDelegate::StartDiagnostics()"); - /* update SupplyState */ + /* update SupplyState to indicate we are now in Diagnostics mode */ SetSupplyState(SupplyStateEnum::kDisabledDiagnostics); // TODO: Generate events + // TODO: Notify Application to implement Diagnostics + + NotifyApplicationStateChange(); + return Status::Success; } /* --------------------------------------------------------------------------- - * FUNCTIONS BELOW: - * - EVSE Hardware interface + * EVSE Hardware interface below + */ + +/** + * @brief Called by EVSE Hardware to register a callback handler mechanism * - * SetMaxHardwareCurrentLimit( currentmA ) - * SetCircuitCapacity( currentmA ) - * SetCableAssemblyLimit( currentmA ) - * SetState( EVSEStateEnum ) - * SetFault + * This is normally called at start-up. * + * @param EVSECallbackFunct - function pointer to call + * @param intptr_t - optional context to provide back to callback handler */ +Status EnergyEvseDelegate::HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg) +{ + if (mCallbacks.handler != nullptr) + { + ChipLogError(AppServer, "Callback handler already initialized"); + return Status::Failure; + } + mCallbacks.handler = handler; + mCallbacks.arg = arg; + + return Status::Success; +} /** * @brief Called by EVSE Hardware to notify the delegate of the maximum @@ -420,17 +442,18 @@ Status EnergyEvseDelegate::HwSetVehicleID(const CharSpan & newValue) /** * @brief Called to compute the safe charging current limit + * + * mActualChargingCurrentLimit is the minimum of: + * - MaxHardwareCurrentLimit (of the hardware) + * - CircuitCapacity (set by the electrician - less than the hardware) + * - CableAssemblyLimit (detected when the cable is inserted) + * - MaximumChargeCurrent (from charging command) + * - UserMaximumChargeCurrent (could dynamically change) + * */ Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit() { int64_t oldValue; - /* mActualChargingCurrentLimit is the minimum of: - * - MaxHardwareCurrentLimit (of the hardware) - * - CircuitCapacity (set by the electrician - less than the hardware) - * - CableAssemblyLimit (detected when the cable is inserted) - * - MaximumChargeCurrent (from charging command) - * - UserMaximumChargeCurrent (could dynamically change) - */ oldValue = mActualChargingCurrentLimit; mActualChargingCurrentLimit = mMaxHardwareCurrentLimit; @@ -448,11 +471,42 @@ Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit() MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); /* Call the EV Charger hardware current limit callback */ - // TODO + NotifyApplicationCurrentLimitChange(mMaximumChargeCurrent); } return Status::Success; } +Status EnergyEvseDelegate::NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent) +{ + EVSECbInfo cbInfo; + + cbInfo.type = EVSECallbackType::ChargeCurrentChanged; + cbInfo.ChargingCurrent.maximumChargeCurrent = maximumChargeCurrent; + + if (mCallbacks.handler != nullptr) + { + mCallbacks.handler(&cbInfo, mCallbacks.arg); + } + + return Status::Success; +} + +Status EnergyEvseDelegate::NotifyApplicationStateChange() +{ + EVSECbInfo cbInfo; + + cbInfo.type = EVSECallbackType::StateChanged; + cbInfo.StateChange.state = mState; + cbInfo.StateChange.supplyState = mSupplyState; + + if (mCallbacks.handler != nullptr) + { + mCallbacks.handler(&cbInfo, mCallbacks.arg); + } + + return Status::Success; +} + /** * Attribute methods */ diff --git a/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h b/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h new file mode 100644 index 00000000000000..5bdac2f8e853d6 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h @@ -0,0 +1,84 @@ +/* + * + * 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 + +namespace chip { +namespace app { +namespace Clusters { + +using namespace chip::app::Clusters::EnergyEvse; + +/* This callbacks mechanism is intended to allow different delegates to + * dispatch notifications that something has changed. + * + * This is not specific to the EnergyEVSE cluster, but includes DeviceEnergyManagement + * and potential future clusters. + */ +enum EVSECallbackType +{ + /* + * The State has changed (e.g. from Disabled to Charging, or vice-versa) + */ + StateChanged, + /* + * ChargeCurrent has changed + */ + ChargeCurrentChanged, + /* + * Charging Preferences have changed + */ + ChargingPreferencesChanged, + /* + * DeviceEnergyManagement has changed + */ + DeviceEnergyManagementChanged, +}; + +struct EVSECbInfo +{ + EVSECallbackType type; + + union + { + /* for type = StateChanged */ + struct + { + StateEnum state; + SupplyStateEnum supplyState; + } StateChange; + + /* for type = ChargeCurrentChanged */ + struct + { + int64_t maximumChargeCurrent; + } ChargingCurrent; + }; +}; + +typedef void (*EVSECallbackFunc)(const EVSECbInfo * cb, intptr_t arg); + +struct EVSECallbackWrapper +{ + EVSECallbackFunc handler; + intptr_t arg; +}; + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h index 34e9027e626ad5..4ff45e925674aa 100644 --- a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h +++ b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h @@ -43,6 +43,11 @@ class EVSEManufacturer */ CHIP_ERROR Shutdown(EnergyEvseManager * aInstance); + /** + * @brief Main Callback handler from delegate to user code + */ + static void ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_t arg); + private: }; diff --git a/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h b/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h index 0a967e2472be8b..f3c003d081fc6e 100644 --- a/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h +++ b/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h @@ -19,6 +19,7 @@ #pragma once #include "app/clusters/energy-evse-server/energy-evse-server.h" +#include #include #include @@ -68,9 +69,13 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate */ Status StartDiagnostics() override; + /** + * @brief Called by EVSE Hardware to register a single callback handler + */ + Status HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg); + // ----------------------------------------------------------------- // Internal API to allow an EVSE to change its internal state etc - // TODO Status HwRegisterEvseHardwareCallback(Callback); Status HwSetMaxHardwareCurrentLimit(int64_t currentmA); Status HwSetCircuitCapacity(int64_t currentmA); Status HwSetCableAssemblyLimit(int64_t currentmA); @@ -150,6 +155,11 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate int64_t mActualChargingCurrentLimit = 0; StateEnum mHwState = StateEnum::kNotPluggedIn; /* Hardware state */ + /* Callback related */ + EVSECallbackWrapper mCallbacks = { .handler = nullptr, .arg = 0 }; /* Wrapper to allow callbacks to be registered */ + Status NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent); + Status NotifyApplicationStateChange(); + /** * @brief Helper function to work out the charge limit based on conditions and settings */ diff --git a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp index e5ad19306ea239..8daf1781103831 100644 --- a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp @@ -35,7 +35,7 @@ CHIP_ERROR EVSEManufacturer::Init(EnergyEvseManager * aInstance) return CHIP_ERROR_UNINITIALIZED; } - // TODO EnergyEvseManager::GetInstance()->GetDelegate()->RegisterCallbacks(); + dg->HwRegisterEvseCallbackHandler(ApplicationCallbackHandler, reinterpret_cast(nullptr)); /* Set the EVSE Hardware Maximum current limit */ // For Manufacturer to specify the hardware capability in mA @@ -67,3 +67,27 @@ CHIP_ERROR EVSEManufacturer::Shutdown(EnergyEvseManager * aInstance) return CHIP_NO_ERROR; } + +/** + * @brief Main Callback handler - to be implemented by Manufacturer + * + * @param EVSECbInfo describes the type of call back, and a union of structs + * which contain relevant info for the specific callback type + * + * @param arg - optional pointer to some context information (see register function) + */ +void EVSEManufacturer::ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_t arg) +{ + switch (cb->type) + { + case EVSECallbackType::StateChanged: + ChipLogProgress(AppServer, "EVSE callback - state changed"); + break; + case EVSECallbackType::ChargeCurrentChanged: + ChipLogProgress(AppServer, "EVSE callback - maxChargeCurrent changed to %ld", + static_cast(cb->ChargingCurrent.maximumChargeCurrent)); + break; + default: + ChipLogError(AppServer, "Unhandler EVSE Callback type %d", static_cast(cb->type)); + } +} diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp index 7ad16c3737dacb..4cc83eaaf8a835 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp @@ -48,7 +48,7 @@ Status EnergyEvseDelegate::Disable() { ChipLogProgress(AppServer, "EnergyEvseDelegate::Disable()"); - /* update State */ + /* Update State */ switch (mHwState) { case StateEnum::kNotPluggedIn: @@ -83,6 +83,7 @@ Status EnergyEvseDelegate::Disable() /* update MaximumDischargeCurrent to 0 */ SetMaximumDischargeCurrent(0); + NotifyApplicationStateChange(); // TODO: Generate events return Status::Success; @@ -102,31 +103,31 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & if (maximumChargeCurrent < kMinimumChargeCurrent || maximumChargeCurrent > kMaximumChargeCurrent) { - ChipLogError(NotSpecified, "Maximum Current outside limits"); + ChipLogError(AppServer, "Maximum Current outside limits"); return Status::ConstraintError; } if (minimumChargeCurrent < kMinimumChargeCurrent || minimumChargeCurrent > kMaximumChargeCurrent) { - ChipLogError(NotSpecified, "Maximum Current outside limits"); + ChipLogError(AppServer, "Maximum Current outside limits"); return Status::ConstraintError; } if (minimumChargeCurrent > maximumChargeCurrent) { - ChipLogError(NotSpecified, "Minium Current > Maximum Current!"); + ChipLogError(AppServer, "Minium Current > Maximum Current!"); return Status::ConstraintError; } if (chargingEnabledUntil.IsNull()) { /* Charging enabled indefinitely */ - ChipLogError(NotSpecified, "Charging enabled indefinitely"); + ChipLogError(AppServer, "Charging enabled indefinitely"); } else { /* check chargingEnabledUntil is in the future */ - ChipLogError(NotSpecified, "Charging enabled until: %lu", static_cast(chargingEnabledUntil.Value())); + ChipLogError(AppServer, "Charging enabled until: %lu", static_cast(chargingEnabledUntil.Value())); // TODO // if (checkChargingEnabled) } @@ -169,6 +170,8 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & // TODO: Generate events + NotifyApplicationStateChange(); + return this->ComputeMaxChargeCurrentLimit(); } @@ -188,6 +191,8 @@ Status EnergyEvseDelegate::EnableDischarging(const DataModel::Nullable // TODO: Generate events + NotifyApplicationStateChange(); + return Status::Success; } @@ -199,25 +204,42 @@ Status EnergyEvseDelegate::StartDiagnostics() /* For EVSE manufacturers to customize */ ChipLogProgress(AppServer, "EnergyEvseDelegate::StartDiagnostics()"); - /* update SupplyState */ + /* update SupplyState to indicate we are now in Diagnostics mode */ SetSupplyState(SupplyStateEnum::kDisabledDiagnostics); // TODO: Generate events + // TODO: Notify Application to implement Diagnostics + + NotifyApplicationStateChange(); + return Status::Success; } /* --------------------------------------------------------------------------- - * FUNCTIONS BELOW: - * - EVSE Hardware interface + * EVSE Hardware interface below + */ + +/** + * @brief Called by EVSE Hardware to register a callback handler mechanism * - * SetMaxHardwareCurrentLimit( currentmA ) - * SetCircuitCapacity( currentmA ) - * SetCableAssemblyLimit( currentmA ) - * SetState( EVSEStateEnum ) - * SetFault + * This is normally called at start-up. * + * @param EVSECallbackFunct - function pointer to call + * @param intptr_t - optional context to provide back to callback handler */ +Status EnergyEvseDelegate::HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg) +{ + if (mCallbacks.handler != nullptr) + { + ChipLogError(AppServer, "Callback handler already initialized"); + return Status::Failure; + } + mCallbacks.handler = handler; + mCallbacks.arg = arg; + + return Status::Success; +} /** * @brief Called by EVSE Hardware to notify the delegate of the maximum @@ -420,17 +442,18 @@ Status EnergyEvseDelegate::HwSetVehicleID(const CharSpan & newValue) /** * @brief Called to compute the safe charging current limit + * + * mActualChargingCurrentLimit is the minimum of: + * - MaxHardwareCurrentLimit (of the hardware) + * - CircuitCapacity (set by the electrician - less than the hardware) + * - CableAssemblyLimit (detected when the cable is inserted) + * - MaximumChargeCurrent (from charging command) + * - UserMaximumChargeCurrent (could dynamically change) + * */ Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit() { int64_t oldValue; - /* mActualChargingCurrentLimit is the minimum of: - * - MaxHardwareCurrentLimit (of the hardware) - * - CircuitCapacity (set by the electrician - less than the hardware) - * - CableAssemblyLimit (detected when the cable is inserted) - * - MaximumChargeCurrent (from charging command) - * - UserMaximumChargeCurrent (could dynamically change) - */ oldValue = mActualChargingCurrentLimit; mActualChargingCurrentLimit = mMaxHardwareCurrentLimit; @@ -448,11 +471,42 @@ Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit() MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); /* Call the EV Charger hardware current limit callback */ - // TODO + NotifyApplicationCurrentLimitChange(mMaximumChargeCurrent); } return Status::Success; } +Status EnergyEvseDelegate::NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent) +{ + EVSECbInfo cbInfo; + + cbInfo.type = EVSECallbackType::ChargeCurrentChanged; + cbInfo.ChargingCurrent.maximumChargeCurrent = maximumChargeCurrent; + + if (mCallbacks.handler != nullptr) + { + mCallbacks.handler(&cbInfo, mCallbacks.arg); + } + + return Status::Success; +} + +Status EnergyEvseDelegate::NotifyApplicationStateChange() +{ + EVSECbInfo cbInfo; + + cbInfo.type = EVSECallbackType::StateChanged; + cbInfo.StateChange.state = mState; + cbInfo.StateChange.supplyState = mSupplyState; + + if (mCallbacks.handler != nullptr) + { + mCallbacks.handler(&cbInfo, mCallbacks.arg); + } + + return Status::Success; +} + /** * Attribute methods */ diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 9d3e094ffb046c..577e04ab04a856 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -37,6 +37,8 @@ CommandHandlerInterfaceOnlyClusters: - RVC Operational State - Sample MEI - Microwave Oven Control + - Energy EVSE + - Device Energy Management # We need a more configurable way of deciding which clusters have which init functions.... # See https://github.com/project-chip/connectedhomeip/issues/4369 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 c37f234ce8a751..439ed6b63ab082 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -10237,90 +10237,6 @@ bool emberAfDemandResponseLoadControlClusterRemoveLoadControlEventRequestCallbac bool emberAfDemandResponseLoadControlClusterClearLoadControlEventsRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::DemandResponseLoadControl::Commands::ClearLoadControlEventsRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster PowerAdjustRequest Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterPowerAdjustRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::PowerAdjustRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster CancelPowerAdjustRequest Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterCancelPowerAdjustRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::CancelPowerAdjustRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster StartTimeAdjustRequest Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterStartTimeAdjustRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::StartTimeAdjustRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster PauseRequest Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterPauseRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::PauseRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster ResumeRequest Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterResumeRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::ResumeRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster ModifyForecastRequest Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterModifyForecastRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::ModifyForecastRequest::DecodableType & commandData); -/** - * @brief Device Energy Management Cluster RequestConstraintBasedForecast Command callback (from client) - */ -bool emberAfDeviceEnergyManagementClusterRequestConstraintBasedForecastCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::DeviceEnergyManagement::Commands::RequestConstraintBasedForecast::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster Disable Command callback (from client) - */ -bool emberAfEnergyEvseClusterDisableCallback(chip::app::CommandHandler * commandObj, - const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::Disable::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster EnableCharging Command callback (from client) - */ -bool emberAfEnergyEvseClusterEnableChargingCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::EnableCharging::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster EnableDischarging Command callback (from client) - */ -bool emberAfEnergyEvseClusterEnableDischargingCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::EnableDischarging::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster StartDiagnostics Command callback (from client) - */ -bool emberAfEnergyEvseClusterStartDiagnosticsCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::StartDiagnostics::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster SetTargets Command callback (from client) - */ -bool emberAfEnergyEvseClusterSetTargetsCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::SetTargets::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster GetTargets Command callback (from client) - */ -bool emberAfEnergyEvseClusterGetTargetsCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::GetTargets::DecodableType & commandData); -/** - * @brief Energy EVSE Cluster ClearTargets Command callback (from client) - */ -bool emberAfEnergyEvseClusterClearTargetsCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::EnergyEvse::Commands::ClearTargets::DecodableType & commandData); /** * @brief Door Lock Cluster LockDoor Command callback (from client) */ From 19e202e62f3051f62e720412f439c4777405485d Mon Sep 17 00:00:00 2001 From: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> Date: Wed, 20 Dec 2023 06:15:10 -0800 Subject: [PATCH 09/83] Media Clusters: Fix for cert test failures (#31047) * Fix for cert test failures * Fix for channel test cases --- .../clusters/channel/ChannelManager.cpp | 63 ++++++++++++++++++- .../clusters/channel/ChannelManager.h | 3 + .../ContentAppObserver.cpp | 23 +++++-- .../content-app-observer/ContentAppObserver.h | 4 +- .../content-control/ContentController.cpp | 40 ++++++------ .../content-control/ContentController.h | 4 +- .../media-playback/MediaPlaybackManager.h | 30 ++++----- examples/tv-app/tv-common/include/AppTv.h | 4 +- .../tv-app/tv-common/src/ZCLCallbacks.cpp | 26 ++++++-- 9 files changed, 144 insertions(+), 53 deletions(-) diff --git a/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp b/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp index 59b00e828aff26..a278de45489112 100644 --- a/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp +++ b/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp @@ -62,6 +62,36 @@ ChannelManager::ChannelManager() mCurrentChannelIndex = 0; mCurrentChannel = mChannels[mCurrentChannelIndex]; + + ProgramType program1; + program1.identifier = chip::CharSpan::fromCharString("progid-abc1"); + program1.channel = abc; + program1.title = chip::CharSpan::fromCharString("ABC Title1"); + program1.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle1")); + program1.startTime = 0; + program1.endTime = 30 * 60 * 60; + + mPrograms.push_back(program1); + + ProgramType program_abc1; + program_abc1.identifier = chip::CharSpan::fromCharString("progid-pbs1"); + program_abc1.channel = pbs; + program_abc1.title = chip::CharSpan::fromCharString("PBS Title1"); + program_abc1.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle1")); + program_abc1.startTime = 0; + program_abc1.endTime = 30 * 60 * 60; + + mPrograms.push_back(program_abc1); + + ProgramType program2; + program2.identifier = chip::CharSpan::fromCharString("progid-abc2"); + program2.channel = abc; + program2.title = chip::CharSpan::fromCharString("My Program Title2"); + program2.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle2")); + program2.startTime = 30 * 60 * 60; + program2.endTime = 30 * 60 * 60; + + mPrograms.push_back(program2); } CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder) @@ -203,9 +233,19 @@ void ChannelManager::HandleGetProgramGuide( // 1. Decode received parameters // 2. Perform search // 3. Return results + + // PageTokenType paging; + // paging.limit = MakeOptional(static_cast(10)); + // paging.after = MakeOptional(chip::CharSpan::fromCharString("after-token")); + // paging.before = MakeOptional(chip::CharSpan::fromCharString("before-token")); + + // ChannelPagingStructType channelPaging; + // channelPaging.nextToken = MakeOptional>(paging); + ProgramGuideResponseType response; - // response.channelPagingStruct; - // response.programList; + // response.channelPagingStruct = channelPaging; + response.programList = DataModel::List(mPrograms.data(), mPrograms.size()); + helper.Success(response); } @@ -214,6 +254,16 @@ bool ChannelManager::HandleRecordProgram(const chip::CharSpan & programIdentifie const chip::ByteSpan & data) { // Start recording + std::string idString(programIdentifier.data(), programIdentifier.size()); + for (auto & program : mPrograms) + { + std::string nextIdString(program.identifier.data(), program.identifier.size()); + if (strcmp(idString.c_str(), nextIdString.c_str()) == 0) + { + program.recordingFlag = MakeOptional(static_cast(shouldRecordSeries ? 2 : 1)); + } + } + return true; } @@ -222,6 +272,15 @@ bool ChannelManager::HandleCancelRecordProgram(const chip::CharSpan & programIde const chip::ByteSpan & data) { // Cancel recording + std::string idString(programIdentifier.data(), programIdentifier.size()); + for (auto & program : mPrograms) + { + std::string nextIdString(program.identifier.data(), program.identifier.size()); + if (strcmp(idString.c_str(), nextIdString.c_str()) == 0) + { + program.recordingFlag = MakeOptional(static_cast(0)); + } + } return true; } diff --git a/examples/tv-app/tv-common/clusters/channel/ChannelManager.h b/examples/tv-app/tv-common/clusters/channel/ChannelManager.h index 68c473e74dc70d..c0c28bb9d00c08 100644 --- a/examples/tv-app/tv-common/clusters/channel/ChannelManager.h +++ b/examples/tv-app/tv-common/clusters/channel/ChannelManager.h @@ -31,6 +31,8 @@ using ChannelInfoType = chip::app::Clusters::Channel::Structs::Channel using AdditionalInfoType = chip::app::Clusters::Channel::Structs::AdditionalInfoStruct::Type; using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type; using PageTokenType = chip::app::Clusters::Channel::Structs::PageTokenStruct::Type; +using ProgramType = chip::app::Clusters::Channel::Structs::ProgramStruct::Type; +using ChannelPagingType = chip::app::Clusters::Channel::Structs::ChannelPagingStruct::Type; class ChannelManager : public ChannelDelegate { @@ -66,6 +68,7 @@ class ChannelManager : public ChannelDelegate uint16_t mCurrentChannelIndex; ChannelInfoType mCurrentChannel; std::vector mChannels; + std::vector mPrograms; private: // TODO: set this based upon meta data from app diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp index 7145ba24305f21..0b5c949216ed55 100644 --- a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp @@ -24,13 +24,28 @@ using namespace std; using namespace chip; using namespace chip::app::Clusters::ContentAppObserver; -ContentAppObserver::ContentAppObserver() +ContentAppObserverManager::ContentAppObserverManager() { // Create Test Data } -void ContentAppObserver::HandleContentAppMessage(chip::app::CommandResponseHelper & helper, - const chip::Optional & data, const chip::CharSpan & encodingHint) +void ContentAppObserverManager::HandleContentAppMessage(chip::app::CommandResponseHelper & helper, + const chip::Optional & data, + const chip::CharSpan & encodingHint) { - ChipLogProgress(Zcl, "ContentAppObserver::HandleContentAppMessage"); + ChipLogProgress(Zcl, "ContentAppObserverManager::HandleContentAppMessage"); + + string dataString(data.HasValue() ? data.Value().data() : "", data.HasValue() ? data.Value().size() : 0); + string encodingHintString(encodingHint.data(), encodingHint.size()); + + ChipLogProgress(Zcl, "ContentAppObserverManager::HandleContentAppMessage TEST CASE hint=%s data=%s ", + encodingHintString.c_str(), dataString.c_str()); + + ContentAppMessageResponse response; + // TODO: Insert code here + // TODO: optional and mandatory are swapped + response.data = CharSpan::fromCharString("exampleData"); + response.encodingHint = CharSpan::fromCharString(encodingHintString.c_str()); + response.status = chip::MakeOptional(StatusEnum::kSuccess); + helper.Success(response); } diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h index 07ba89b2de3a1a..0c0f6fb6efbaec 100644 --- a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h @@ -25,10 +25,10 @@ using ContentAppObserverDelegate = chip::app::Clusters::ContentAppObserver::Delegate; using ContentAppMessageResponse = chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::Type; -class ContentAppObserver : public ContentAppObserverDelegate +class ContentAppObserverManager : public ContentAppObserverDelegate { public: - ContentAppObserver(); + ContentAppObserverManager(); void HandleContentAppMessage(chip::app::CommandResponseHelper & helper, const chip::Optional & data, const chip::CharSpan & encodingHint) override; diff --git a/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp b/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp index c4eee0355f4552..7ebb2ee4a45954 100644 --- a/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp +++ b/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp @@ -25,74 +25,74 @@ using namespace chip::app::Clusters; using namespace chip::app::DataModel; using namespace chip::app::Clusters::ContentControl; -ContentController::ContentController() +ContentControlManager::ContentControlManager() { // Create Test Data } // Attribute Delegates -bool ContentController::HandleGetEnabled() +bool ContentControlManager::HandleGetEnabled() { return false; } -CHIP_ERROR ContentController::HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ContentControlManager::HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) { return aEncoder.Encode(chip::CharSpan()); } -chip::CharSpan ContentController::HandleGetOnDemandRatingThreshold() +chip::CharSpan ContentControlManager::HandleGetOnDemandRatingThreshold() { return chip::CharSpan(); } -CHIP_ERROR ContentController::HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ContentControlManager::HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) { return aEncoder.Encode(chip::CharSpan()); } -chip::CharSpan ContentController::HandleGetScheduledContentRatingThreshold() +chip::CharSpan ContentControlManager::HandleGetScheduledContentRatingThreshold() { return chip::CharSpan(); } -uint32_t ContentController::HandleGetScreenDailyTime() +uint32_t ContentControlManager::HandleGetScreenDailyTime() { return (uint32_t) 0xFFFFFFFF; } -uint32_t ContentController::HandleGetRemainingScreenTime() +uint32_t ContentControlManager::HandleGetRemainingScreenTime() { return (uint32_t) 0xFFFFFFFF; } -bool ContentController::HandleGetBlockUnrated() +bool ContentControlManager::HandleGetBlockUnrated() { return false; } // Command Delegates -void ContentController::HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) {} +void ContentControlManager::HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) {} -void ContentController::HandleResetPIN(chip::app::CommandResponseHelper & helper) {} +void ContentControlManager::HandleResetPIN(chip::app::CommandResponseHelper & helper) {} -void ContentController::HandleEnable() {} +void ContentControlManager::HandleEnable() {} -void ContentController::HandleDisable() {} +void ContentControlManager::HandleDisable() {} -void ContentController::HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) {} +void ContentControlManager::HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) {} -void ContentController::HandleSetScreenDailyTime(uint32_t screenDailyTime) {} +void ContentControlManager::HandleSetScreenDailyTime(uint32_t screenDailyTime) {} -void ContentController::HandleBlockUnratedContent() {} +void ContentControlManager::HandleBlockUnratedContent() {} -void ContentController::HandleUnblockUnratedContent() {} +void ContentControlManager::HandleUnblockUnratedContent() {} -void ContentController::HandleSetOnDemandRatingThreshold(chip::CharSpan rating) {} +void ContentControlManager::HandleSetOnDemandRatingThreshold(chip::CharSpan rating) {} -void ContentController::HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) {} +void ContentControlManager::HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) {} -uint32_t ContentController::GetFeatureMap(chip::EndpointId endpoint) +uint32_t ContentControlManager::GetFeatureMap(chip::EndpointId endpoint) { if (endpoint >= EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT) { diff --git a/examples/tv-app/tv-common/clusters/content-control/ContentController.h b/examples/tv-app/tv-common/clusters/content-control/ContentController.h index 01636f37fcb772..719d42bcbf79b4 100644 --- a/examples/tv-app/tv-common/clusters/content-control/ContentController.h +++ b/examples/tv-app/tv-common/clusters/content-control/ContentController.h @@ -25,10 +25,10 @@ using ContentControlDelegate = chip::app::Clusters::ContentControl::Delegate; using ResetPINResponseType = chip::app::Clusters::ContentControl::Commands::ResetPINResponse::Type; -class ContentController : public ContentControlDelegate +class ContentControlManager : public ContentControlDelegate { public: - ContentController(); + ContentControlManager(); // Attribute Delegates bool HandleGetEnabled() override; diff --git a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h index 54fc9de5b67e87..18ed5ca1a12bd9 100644 --- a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h +++ b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h @@ -73,37 +73,37 @@ class MediaPlaybackManager : public MediaPlaybackDelegate PlaybackPositionType mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; TrackType mActiveAudioTrack = { chip::CharSpan("activeAudioTrackId_0", 20), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }; + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }; std::vector mAvailableAudioTracks = { { chip::CharSpan("activeAudioTrackId_0", 20), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }, + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }, { chip::CharSpan("activeAudioTrackId_1", 20), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode2", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) } + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) } }; - TrackType mActiveTextTrack = { chip::CharSpan("activeTextTrackId_0", 20), + TrackType mActiveTextTrack = { chip::CharSpan("activeTextTrackId_0", 19), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }; + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }; std::vector mAvailableTextTracks = { - { chip::CharSpan("activeTextTrackId_0", 20), + { chip::CharSpan("activeTextTrackId_0", 19), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }, - { chip::CharSpan("activeTextTrackId_1", 20), + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }, + { chip::CharSpan("activeTextTrackId_1", 19), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode2", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) } + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) } }; float mPlaybackSpeed = 0; uint64_t mStartTime = 0; diff --git a/examples/tv-app/tv-common/include/AppTv.h b/examples/tv-app/tv-common/include/AppTv.h index 8bfdf558dd1465..0a56ebe1da8624 100644 --- a/examples/tv-app/tv-common/include/AppTv.h +++ b/examples/tv-app/tv-common/include/AppTv.h @@ -101,8 +101,8 @@ class DLL_EXPORT ContentAppImpl : public ContentApp ApplicationLauncherManager mApplicationLauncherDelegate; ChannelManager mChannelDelegate; ContentLauncherManager mContentLauncherDelegate; - ContentAppObserver mContentAppObserverDelegate; - ContentController mContentControlDelegate; + ContentAppObserverManager mContentAppObserverDelegate; + ContentControlManager mContentControlDelegate; KeypadInputManager mKeypadInputDelegate; MediaPlaybackManager mMediaPlaybackDelegate; TargetNavigatorManager mTargetNavigatorDelegate; diff --git a/examples/tv-app/tv-common/src/ZCLCallbacks.cpp b/examples/tv-app/tv-common/src/ZCLCallbacks.cpp index 8a5416ff3569b4..1358ab0bba9bb1 100644 --- a/examples/tv-app/tv-common/src/ZCLCallbacks.cpp +++ b/examples/tv-app/tv-common/src/ZCLCallbacks.cpp @@ -51,6 +51,8 @@ static ApplicationLauncherManager applicationLauncherManager(false); #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED static AudioOutputManager audioOutputManager; static ChannelManager channelManager; +static ContentAppObserverManager contentAppObserverManager; +static ContentControlManager contentControlManager; static ContentLauncherManager contentLauncherManager; static KeypadInputManager keypadInputManager; static LowPowerManager lowPowerManager; @@ -104,12 +106,6 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint) // TODO: implement any additional Cluster Server init actions } -void emberAfContentLauncherClusterInitCallback(EndpointId endpoint) -{ - ChipLogProgress(Zcl, "TV Linux App: ContentLauncher::SetDefaultDelegate"); - ContentLauncher::SetDefaultDelegate(endpoint, &contentLauncherManager); -} - void emberAfAccountLoginClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: AccountLogin::SetDefaultDelegate"); @@ -134,6 +130,24 @@ void emberAfAudioOutputClusterInitCallback(EndpointId endpoint) AudioOutput::SetDefaultDelegate(endpoint, &audioOutputManager); } +void emberAfContentAppObserverClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: ContentAppObserverManager::SetDefaultDelegate"); + ContentAppObserver::SetDefaultDelegate(endpoint, &contentAppObserverManager); +} + +void emberAfContentControlClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: ContentControlManager::SetDefaultDelegate"); + ContentControl::SetDefaultDelegate(endpoint, &contentControlManager); +} + +void emberAfContentLauncherClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: ContentLauncher::SetDefaultDelegate"); + ContentLauncher::SetDefaultDelegate(endpoint, &contentLauncherManager); +} + void emberAfChannelClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: Channel::SetDefaultDelegate"); From aaa94059648ef299d21840ffa134e801274135eb Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Thu, 21 Dec 2023 07:08:45 +1300 Subject: [PATCH 10/83] Simplify CertificationDeclaration EncodeSignerInfo (#31087) ... by using ConvertECDSASignatureRawToDER which directly integrates with the ASN.1 writer rather than EcdsaRawSignatureToAsn1 from CHIPCryptoPAL. Also make the same change in the chip-cert gen-cd command. --- src/credentials/CertificationDeclaration.cpp | 10 +++++----- src/tools/chip-cert/Cmd_GenCD.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/credentials/CertificationDeclaration.cpp b/src/credentials/CertificationDeclaration.cpp index 42bd9656b30750..9795270474fcc7 100644 --- a/src/credentials/CertificationDeclaration.cpp +++ b/src/credentials/CertificationDeclaration.cpp @@ -473,12 +473,12 @@ CHIP_ERROR EncodeSignerInfo(const ByteSpan & signerKeyId, const P256ECDSASignatu } ASN1_END_SEQUENCE; - uint8_t asn1SignatureBuf[kMax_ECDSA_Signature_Length_Der]; - MutableByteSpan asn1Signature(asn1SignatureBuf); - ReturnErrorOnFailure(EcdsaRawSignatureToAsn1(kP256_FE_Length, signature.Span(), asn1Signature)); - // signature OCTET STRING - ReturnErrorOnFailure(writer.PutOctetString(asn1Signature.data(), static_cast(asn1Signature.size()))); + ASN1_START_OCTET_STRING_ENCAPSULATED + { + ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan(signature.ConstBytes()), writer)); + } + ASN1_END_ENCAPSULATED; } ASN1_END_SEQUENCE; } diff --git a/src/tools/chip-cert/Cmd_GenCD.cpp b/src/tools/chip-cert/Cmd_GenCD.cpp index f851bf77cf0495..acea3c5a1c4239 100644 --- a/src/tools/chip-cert/Cmd_GenCD.cpp +++ b/src/tools/chip-cert/Cmd_GenCD.cpp @@ -1000,7 +1000,7 @@ CHIP_ERROR EncodeSignerInfo_Ignor_Error(const ByteSpan & signerKeyId, const P256 uint8_t asn1SignatureBuf[kMax_ECDSA_Signature_Length_Der]; MutableByteSpan asn1Signature(asn1SignatureBuf); - ReturnErrorOnFailure(EcdsaRawSignatureToAsn1(kP256_FE_Length, signature.Span(), asn1Signature)); + ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan(signature.ConstBytes()), asn1Signature)); if (!cdConfig.IsCMSSignatureCorrect()) { From 017a9db0d63d2fe2fa3d7140757844e665f76d35 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 21 Dec 2023 04:13:08 +0900 Subject: [PATCH 11/83] Add java empty event struct (#31128) --- .../java/ChipEventStructs_java.jinja | 4 +- .../devicecontroller/ChipEventStructs.java | 930 +++++++++++++++++- 2 files changed, 929 insertions(+), 5 deletions(-) diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja index 95f733f9b986b1..e3a8074bc11a6c 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja @@ -80,7 +80,6 @@ public class ChipEventStructs { {%- for cluster in clientClusters | sort(attribute='code') -%} {%- set typeLookup = idl | createLookupContext(cluster) %} {%- for event in cluster.events %} -{%- if event.fields %} public static class {{cluster.name}}Cluster{{event.name}}Event { {%- for field in event.fields %} {%- set encodable = field | asEncodable(typeLookup) %} @@ -133,6 +132,7 @@ public static class {{cluster.name}}Cluster{{event.name}}Event { {%- endif -%} ; {%- endfor %} +{%- if event.fields %} for (StructElement element: ((StructType)tlvValue).value()) { {%- for field in event.fields -%} {%- set encodable = field | asEncodable(typeLookup) %} @@ -146,6 +146,7 @@ public static class {{cluster.name}}Cluster{{event.name}}Event { } {%- endraw %} } +{%- endif %} return new {{cluster.name}}Cluster{{event.name}}Event( {%- for field in event.fields %} {{field.name}}{%- if loop.index0 < loop.length - 1 -%}{{","}}{%- endif %} @@ -177,7 +178,6 @@ public static class {{cluster.name}}Cluster{{event.name}}Event { return output.toString(); } } -{%- endif %} {%- endfor %} {%- endfor %} } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index b140401dcc6689..9d18a3e786d5b4 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -449,6 +449,34 @@ public String toString() { return output.toString(); } } +public static class BasicInformationClusterShutDownEvent { + + public BasicInformationClusterShutDownEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static BasicInformationClusterShutDownEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new BasicInformationClusterShutDownEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BasicInformationClusterShutDownEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class BasicInformationClusterLeaveEvent { public Integer fabricIndex; private static final long FABRIC_INDEX_ID = 0L; @@ -1532,6 +1560,34 @@ public String toString() { return output.toString(); } } +public static class TimeSynchronizationClusterDSTTableEmptyEvent { + + public TimeSynchronizationClusterDSTTableEmptyEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static TimeSynchronizationClusterDSTTableEmptyEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new TimeSynchronizationClusterDSTTableEmptyEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("TimeSynchronizationClusterDSTTableEmptyEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class TimeSynchronizationClusterDSTStatusEvent { public Boolean DSTOffsetActive; private static final long D_S_T_OFFSET_ACTIVE_ID = 0L; @@ -1639,6 +1695,62 @@ public String toString() { return output.toString(); } } +public static class TimeSynchronizationClusterTimeFailureEvent { + + public TimeSynchronizationClusterTimeFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static TimeSynchronizationClusterTimeFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new TimeSynchronizationClusterTimeFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("TimeSynchronizationClusterTimeFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class TimeSynchronizationClusterMissingTrustedTimeSourceEvent { + + public TimeSynchronizationClusterMissingTrustedTimeSourceEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static TimeSynchronizationClusterMissingTrustedTimeSourceEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new TimeSynchronizationClusterMissingTrustedTimeSourceEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("TimeSynchronizationClusterMissingTrustedTimeSourceEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class BridgedDeviceBasicInformationClusterStartUpEvent { public Long softwareVersion; private static final long SOFTWARE_VERSION_ID = 0L; @@ -1685,6 +1797,62 @@ public String toString() { return output.toString(); } } +public static class BridgedDeviceBasicInformationClusterShutDownEvent { + + public BridgedDeviceBasicInformationClusterShutDownEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static BridgedDeviceBasicInformationClusterShutDownEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new BridgedDeviceBasicInformationClusterShutDownEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BridgedDeviceBasicInformationClusterShutDownEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class BridgedDeviceBasicInformationClusterLeaveEvent { + + public BridgedDeviceBasicInformationClusterLeaveEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static BridgedDeviceBasicInformationClusterLeaveEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new BridgedDeviceBasicInformationClusterLeaveEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BridgedDeviceBasicInformationClusterLeaveEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class BridgedDeviceBasicInformationClusterReachableChangedEvent { public Boolean reachableNewValue; private static final long REACHABLE_NEW_VALUE_ID = 0L; @@ -2480,6 +2648,146 @@ public String toString() { return output.toString(); } } +public static class SmokeCoAlarmClusterHardwareFaultEvent { + + public SmokeCoAlarmClusterHardwareFaultEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterHardwareFaultEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterHardwareFaultEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterHardwareFaultEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterEndOfServiceEvent { + + public SmokeCoAlarmClusterEndOfServiceEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterEndOfServiceEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterEndOfServiceEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterEndOfServiceEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterSelfTestCompleteEvent { + + public SmokeCoAlarmClusterSelfTestCompleteEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterSelfTestCompleteEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterSelfTestCompleteEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterSelfTestCompleteEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterAlarmMutedEvent { + + public SmokeCoAlarmClusterAlarmMutedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterAlarmMutedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterAlarmMutedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterAlarmMutedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterMuteEndedEvent { + + public SmokeCoAlarmClusterMuteEndedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterMuteEndedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterMuteEndedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterMuteEndedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class SmokeCoAlarmClusterInterconnectSmokeAlarmEvent { public Integer alarmSeverityLevel; private static final long ALARM_SEVERITY_LEVEL_ID = 0L; @@ -2572,9 +2880,37 @@ public String toString() { return output.toString(); } } -public static class DishwasherAlarmClusterNotifyEvent { - public Long active; - public Long inactive; +public static class SmokeCoAlarmClusterAllClearEvent { + + public SmokeCoAlarmClusterAllClearEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterAllClearEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterAllClearEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterAllClearEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class DishwasherAlarmClusterNotifyEvent { + public Long active; + public Long inactive; public Long state; public Long mask; private static final long ACTIVE_ID = 0L; @@ -3424,6 +3760,34 @@ public String toString() { return output.toString(); } } +public static class DeviceEnergyManagementClusterPowerAdjustStartEvent { + + public DeviceEnergyManagementClusterPowerAdjustStartEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static DeviceEnergyManagementClusterPowerAdjustStartEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new DeviceEnergyManagementClusterPowerAdjustStartEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("DeviceEnergyManagementClusterPowerAdjustStartEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class DeviceEnergyManagementClusterPowerAdjustEndEvent { public Integer cause; public Long duration; @@ -3500,6 +3864,62 @@ public String toString() { return output.toString(); } } +public static class DeviceEnergyManagementClusterPausedEvent { + + public DeviceEnergyManagementClusterPausedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static DeviceEnergyManagementClusterPausedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new DeviceEnergyManagementClusterPausedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("DeviceEnergyManagementClusterPausedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class DeviceEnergyManagementClusterResumedEvent { + + public DeviceEnergyManagementClusterResumedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static DeviceEnergyManagementClusterResumedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new DeviceEnergyManagementClusterResumedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("DeviceEnergyManagementClusterResumedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class EnergyEvseClusterEVConnectedEvent { public Long sessionID; private static final long SESSION_I_D_ID = 0L; @@ -4441,6 +4861,482 @@ public String toString() { return output.toString(); } } +public static class PumpConfigurationAndControlClusterSupplyVoltageLowEvent { + + public PumpConfigurationAndControlClusterSupplyVoltageLowEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSupplyVoltageLowEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSupplyVoltageLowEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSupplyVoltageLowEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSupplyVoltageHighEvent { + + public PumpConfigurationAndControlClusterSupplyVoltageHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSupplyVoltageHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSupplyVoltageHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSupplyVoltageHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterPowerMissingPhaseEvent { + + public PumpConfigurationAndControlClusterPowerMissingPhaseEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterPowerMissingPhaseEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterPowerMissingPhaseEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterPowerMissingPhaseEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSystemPressureLowEvent { + + public PumpConfigurationAndControlClusterSystemPressureLowEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSystemPressureLowEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSystemPressureLowEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSystemPressureLowEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSystemPressureHighEvent { + + public PumpConfigurationAndControlClusterSystemPressureHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSystemPressureHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSystemPressureHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSystemPressureHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterDryRunningEvent { + + public PumpConfigurationAndControlClusterDryRunningEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterDryRunningEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterDryRunningEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterDryRunningEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterMotorTemperatureHighEvent { + + public PumpConfigurationAndControlClusterMotorTemperatureHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterMotorTemperatureHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterMotorTemperatureHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterMotorTemperatureHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent { + + public PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterElectronicTemperatureHighEvent { + + public PumpConfigurationAndControlClusterElectronicTemperatureHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterElectronicTemperatureHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterElectronicTemperatureHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterElectronicTemperatureHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterPumpBlockedEvent { + + public PumpConfigurationAndControlClusterPumpBlockedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterPumpBlockedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterPumpBlockedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterPumpBlockedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSensorFailureEvent { + + public PumpConfigurationAndControlClusterSensorFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSensorFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSensorFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSensorFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent { + + public PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterElectronicFatalFailureEvent { + + public PumpConfigurationAndControlClusterElectronicFatalFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterElectronicFatalFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterElectronicFatalFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterElectronicFatalFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterGeneralFaultEvent { + + public PumpConfigurationAndControlClusterGeneralFaultEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterGeneralFaultEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterGeneralFaultEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterGeneralFaultEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterLeakageEvent { + + public PumpConfigurationAndControlClusterLeakageEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterLeakageEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterLeakageEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterLeakageEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterAirDetectionEvent { + + public PumpConfigurationAndControlClusterAirDetectionEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterAirDetectionEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterAirDetectionEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterAirDetectionEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterTurbineOperationEvent { + + public PumpConfigurationAndControlClusterTurbineOperationEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterTurbineOperationEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterTurbineOperationEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterTurbineOperationEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class TargetNavigatorClusterTargetUpdatedEvent { public ArrayList targetList; public Integer currentTarget; @@ -4729,6 +5625,34 @@ public String toString() { return output.toString(); } } +public static class ContentControlClusterRemainingScreenTimeExpiredEvent { + + public ContentControlClusterRemainingScreenTimeExpiredEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static ContentControlClusterRemainingScreenTimeExpiredEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new ContentControlClusterRemainingScreenTimeExpiredEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ContentControlClusterRemainingScreenTimeExpiredEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class UnitTestingClusterTestEventEvent { public Integer arg1; public Integer arg2; From f7cd2d66150f5b0b21613f80e907f88191a1a753 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Wed, 20 Dec 2023 14:26:07 -0500 Subject: [PATCH 12/83] Introduce a Status + Cluster Code abstraction (#31121) * Introduce a Status + Cluster Code abstraction - Existing code always has to split IM status and cluster-specific status codes, which causes clumsy implementation of clusters (see issue #31120). - This PR introduces a value that encapsulates both the IM status and cluster-specific status, in an easy-to-pass-around abstraction, which can be directly used in place of Status. - Subsequent PR will implement usage in IM with overloads for common cases, such as for AddStatus. Issue #31120 Testing done: - Added unit tests - Other tests still pass * Restyled by clang-format * Restyled by gn * Address review comments * Rename ClusterStatus to ClusterStatusCode * Fix build deps * Restyled by gn --------- Co-authored-by: Restyled.io --- examples/darwin-framework-tool/BUILD.gn | 2 +- src/BUILD.gn | 1 + src/app/BUILD.gn | 1 + src/app/common/BUILD.gn | 1 + src/app/tests/TestStatusIB.cpp | 1 + .../commands/interaction_model/BUILD.gn | 2 +- src/protocols/BUILD.gn | 17 +-- src/protocols/interaction_model/BUILD.gn | 34 +++++ src/protocols/interaction_model/StatusCode.h | 109 ++++++++++++++ .../interaction_model/tests/BUILD.gn | 35 +++++ .../tests/TestStatusCode.cpp | 135 ++++++++++++++++++ 11 files changed, 320 insertions(+), 18 deletions(-) create mode 100644 src/protocols/interaction_model/BUILD.gn create mode 100644 src/protocols/interaction_model/tests/BUILD.gn create mode 100644 src/protocols/interaction_model/tests/TestStatusCode.cpp diff --git a/examples/darwin-framework-tool/BUILD.gn b/examples/darwin-framework-tool/BUILD.gn index e6b1a3e7654da3..7ee396dd04e24a 100644 --- a/examples/darwin-framework-tool/BUILD.gn +++ b/examples/darwin-framework-tool/BUILD.gn @@ -248,7 +248,7 @@ executable("darwin-framework-tool") { # pics is needed by tests "${chip_root}/src/app/tests/suites/pics", - "${chip_root}/src/protocols:im_status", + "${chip_root}/src/protocols/interaction_model", ] defines = [] diff --git a/src/BUILD.gn b/src/BUILD.gn index 532da2a4d8db3f..2d0204d49fa741 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -60,6 +60,7 @@ if (chip_build_tests) { "${chip_root}/src/lib/core/tests", "${chip_root}/src/messaging/tests", "${chip_root}/src/protocols/bdx/tests", + "${chip_root}/src/protocols/interaction_model/tests", "${chip_root}/src/protocols/user_directed_commissioning/tests", "${chip_root}/src/transport/retransmit/tests", ] diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index e053756a62c928..a96dc222b2aac3 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -250,6 +250,7 @@ static_library("app") { "${chip_root}/src/lib/address_resolve", "${chip_root}/src/lib/support", "${chip_root}/src/messaging", + "${chip_root}/src/protocols/interaction_model", "${chip_root}/src/protocols/secure_channel", "${chip_root}/src/system", "${nlio_root}:nlio", diff --git a/src/app/common/BUILD.gn b/src/app/common/BUILD.gn index fee9795dc5982c..c6c350e547fd86 100644 --- a/src/app/common/BUILD.gn +++ b/src/app/common/BUILD.gn @@ -27,6 +27,7 @@ static_library("cluster-objects") { public_deps = [ "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", + "${chip_root}/src/protocols/interaction_model", ] defines = [] diff --git a/src/app/tests/TestStatusIB.cpp b/src/app/tests/TestStatusIB.cpp index 4ff97e4b7ccbc3..3eb47f438f67df 100644 --- a/src/app/tests/TestStatusIB.cpp +++ b/src/app/tests/TestStatusIB.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include diff --git a/src/app/tests/suites/commands/interaction_model/BUILD.gn b/src/app/tests/suites/commands/interaction_model/BUILD.gn index e1329714c68772..ecefa4a854be15 100644 --- a/src/app/tests/suites/commands/interaction_model/BUILD.gn +++ b/src/app/tests/suites/commands/interaction_model/BUILD.gn @@ -16,7 +16,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") static_library("interaction_model") { - output_name = "libInteractionModel" + output_name = "libInteractionModelCommands" sources = [ "InteractionModel.cpp", diff --git a/src/protocols/BUILD.gn b/src/protocols/BUILD.gn index 10b48fb7e46cc3..2895334c3393ab 100644 --- a/src/protocols/BUILD.gn +++ b/src/protocols/BUILD.gn @@ -38,27 +38,12 @@ static_library("protocols") { cflags = [ "-Wconversion" ] public_deps = [ - ":im_status", ":type_definitions", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", "${chip_root}/src/messaging", "${chip_root}/src/protocols/bdx", + "${chip_root}/src/protocols/interaction_model", "${chip_root}/src/protocols/secure_channel", ] } - -static_library("im_status") { - sources = [ - "interaction_model/StatusCode.cpp", - "interaction_model/StatusCode.h", - ] - - cflags = [ "-Wconversion" ] - - public_deps = [ - ":type_definitions", - "${chip_root}/src/lib/core", - "${chip_root}/src/lib/support", - ] -} diff --git a/src/protocols/interaction_model/BUILD.gn b/src/protocols/interaction_model/BUILD.gn new file mode 100644 index 00000000000000..b8c3bd7be7f000 --- /dev/null +++ b/src/protocols/interaction_model/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +static_library("interaction_model") { + output_name = "libInteractionModel" + + sources = [ + "Constants.h", + "StatusCode.cpp", + "StatusCode.h", + "StatusCodeList.h", + ] + + cflags = [ "-Wconversion" ] + + public_deps = [ + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/protocols:type_definitions", + ] +} diff --git a/src/protocols/interaction_model/StatusCode.h b/src/protocols/interaction_model/StatusCode.h index 5d0453ec3dceaf..31615673d1140f 100644 --- a/src/protocols/interaction_model/StatusCode.h +++ b/src/protocols/interaction_model/StatusCode.h @@ -17,9 +17,12 @@ #pragma once +#include #include #include +#include +#include #include #if CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT @@ -48,6 +51,112 @@ enum class Status : uint8_t const char * StatusName(Status status); #endif // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT +/** + * @brief Class to encapsulate a Status code, including possibly a + * cluster-specific code for generic SUCCESS/FAILURE. + * + * This abstractions joins together Status and ClusterStatus, which + * are the components of a StatusIB, used in many IM actions, in a + * way which allows both of them to carry together. + * + * This can be used everywhere a `Status` is used, but it is lossy + * to the cluster-specific code if used in place of `Status` when + * the cluster-specific code is set. + * + * This class can only be directly constructed from a `Status`. To + * attach a cluster-specific-code, please use the `ClusterSpecificFailure()` + * and `ClusterSpecificSuccess()` factory methods. + */ +class ClusterStatusCode +{ +public: + explicit ClusterStatusCode(Status status) : mStatus(status) {} + + // We only have simple copyable members, so we should be trivially copyable. + ClusterStatusCode(const ClusterStatusCode & other) = default; + ClusterStatusCode & operator=(const ClusterStatusCode & other) = default; + + bool operator==(const ClusterStatusCode & other) + { + return (this->mStatus == other.mStatus) && (this->HasClusterSpecificCode() == other.HasClusterSpecificCode()) && + (this->GetClusterSpecificCode() == other.GetClusterSpecificCode()); + } + + bool operator!=(const ClusterStatusCode & other) { return !(*this == other); } + + ClusterStatusCode & operator=(const Status & status) + { + this->mStatus = status; + this->mClusterSpecificCode = chip::NullOptional; + return *this; + } + + /** + * @brief Builder for a cluster-specific failure status code. + * + * @tparam T - enum type for the cluster-specific status code + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum) + * @param cluster_specific_code - cluster-specific code to record with the failure + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen) + * @return a ClusterStatusCode instance properly configured. + */ + template + static ClusterStatusCode ClusterSpecificFailure(T cluster_specific_code) + { + static_assert(std::numeric_limits::max() <= std::numeric_limits::max(), "Type used must fit in uint8_t"); + return ClusterStatusCode(Status::Failure, chip::to_underlying(cluster_specific_code)); + } + + /** + * @brief Builder for a cluster-specific success status code. + * + * @tparam T - enum type for the cluster-specific status code + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum) + * @param cluster_specific_code - cluster-specific code to record with the success + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kBasicWindowOpen) + * @return a ClusterStatusCode instance properly configured. + */ + template + static ClusterStatusCode ClusterSpecificSuccess(T cluster_specific_code) + { + static_assert(std::numeric_limits::max() <= std::numeric_limits::max(), "Type used must fit in uint8_t"); + return ClusterStatusCode(Status::Success, chip::to_underlying(cluster_specific_code)); + } + + /// @return true if the core Status associated with this ClusterStatusCode is the one for success. + bool IsSuccess() const { return mStatus == Status::Success; } + + /// @return the core Status code associated withi this ClusterStatusCode. + Status GetStatus() const { return mStatus; } + + /// @return true if a cluster-specific code is associated with the ClusterStatusCode. + bool HasClusterSpecificCode() const { return mClusterSpecificCode.HasValue(); } + + /// @return the cluster-specific code associated with this ClusterStatusCode or chip::NullOptional if none is associated. + chip::Optional GetClusterSpecificCode() const + { + if ((mStatus != Status::Failure) && (mStatus != Status::Success)) + { + return chip::NullOptional; + } + return mClusterSpecificCode; + } + + // Automatic conversions to common types, using the status code alone. + operator Status() const { return mStatus; } + +private: + ClusterStatusCode() = delete; + ClusterStatusCode(Status status, ClusterStatus cluster_specific_code) : + mStatus(status), mClusterSpecificCode(chip::MakeOptional(cluster_specific_code)) + {} + + Status mStatus; + chip::Optional mClusterSpecificCode; +}; + +static_assert(sizeof(ClusterStatusCode) <= sizeof(uint32_t), "ClusterStatusCode must not grow to be larger than a uint32_t"); + } // namespace InteractionModel } // namespace Protocols } // namespace chip diff --git a/src/protocols/interaction_model/tests/BUILD.gn b/src/protocols/interaction_model/tests/BUILD.gn new file mode 100644 index 00000000000000..16792006e1eb8f --- /dev/null +++ b/src/protocols/interaction_model/tests/BUILD.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nlunit_test.gni") + +import("${chip_root}/build/chip/chip_test_suite.gni") + +chip_test_suite_using_nltest("tests") { + output_name = "libInteractionModelTests" + + test_sources = [ "TestStatusCode.cpp" ] + + public_deps = [ + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/lib/support:testing", + "${chip_root}/src/protocols/interaction_model", + "${nlunit_test_root}:nlunit-test", + ] + + cflags = [ "-Wconversion" ] +} diff --git a/src/protocols/interaction_model/tests/TestStatusCode.cpp b/src/protocols/interaction_model/tests/TestStatusCode.cpp new file mode 100644 index 00000000000000..4b89e0f4b1acfb --- /dev/null +++ b/src/protocols/interaction_model/tests/TestStatusCode.cpp @@ -0,0 +1,135 @@ +/* + * + * 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 +#include + +#include + +using namespace ::chip; +using namespace ::chip::Protocols::InteractionModel; + +namespace { + +void TestStatusBasicValues(nlTestSuite * inSuite, void * inContext) +{ + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::Success), 0); + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::Failure), 1); + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::UnsupportedEndpoint), 0x7f); + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::InvalidInState), 0xcb); +} + +void TestClusterStatusCode(nlTestSuite * inSuite, void * inContext) +{ + // Basic usage as a Status. + { + ClusterStatusCode status_code_success{ Status::Success }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success, Status::Success); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success.GetStatus(), Status::Success); + NL_TEST_ASSERT(inSuite, !status_code_success.HasClusterSpecificCode()); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success.GetClusterSpecificCode(), chip::NullOptional); + NL_TEST_ASSERT(inSuite, status_code_success.IsSuccess()); + + ClusterStatusCode status_code_failure{ Status::Failure }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure, Status::Failure); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure.GetStatus(), Status::Failure); + NL_TEST_ASSERT(inSuite, !status_code_failure.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, !status_code_failure.IsSuccess()); + + ClusterStatusCode status_code_unsupported_ep{ Status::UnsupportedEndpoint }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_unsupported_ep, Status::UnsupportedEndpoint); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_unsupported_ep.GetStatus(), Status::UnsupportedEndpoint); + NL_TEST_ASSERT(inSuite, !status_code_unsupported_ep.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, !status_code_unsupported_ep.IsSuccess()); + + ClusterStatusCode status_code_invalid_in_state{ Status::InvalidInState }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_invalid_in_state, Status::InvalidInState); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_invalid_in_state.GetStatus(), Status::InvalidInState); + NL_TEST_ASSERT(inSuite, !status_code_invalid_in_state.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, !status_code_invalid_in_state.IsSuccess()); + } + + enum RobotoClusterStatus : uint8_t + { + kSandwichError = 7, + kSauceSuccess = 81, + }; + + // Cluster-specific usage. + { + ClusterStatusCode status_code_success = ClusterStatusCode::ClusterSpecificSuccess(RobotoClusterStatus::kSauceSuccess); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success, Status::Success); + NL_TEST_ASSERT(inSuite, status_code_success.HasClusterSpecificCode()); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSauceSuccess)); + NL_TEST_ASSERT(inSuite, status_code_success.IsSuccess()); + + ClusterStatusCode status_code_failure = ClusterStatusCode::ClusterSpecificFailure(RobotoClusterStatus::kSandwichError); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure, Status::Failure); + NL_TEST_ASSERT(inSuite, status_code_failure.HasClusterSpecificCode()); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSandwichError)); + NL_TEST_ASSERT(inSuite, !status_code_failure.IsSuccess()); + } + + // Copy/Assignment + { + ClusterStatusCode status_code_failure1 = ClusterStatusCode::ClusterSpecificFailure(RobotoClusterStatus::kSandwichError); + ClusterStatusCode status_code_failure2(status_code_failure1); + + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure1, status_code_failure2); + NL_TEST_ASSERT(inSuite, status_code_failure1.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, status_code_failure2.HasClusterSpecificCode()); + + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure1.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSandwichError)); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure2.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSandwichError)); + + ClusterStatusCode status_code_failure3{ Status::InvalidCommand }; + NL_TEST_ASSERT(inSuite, status_code_failure2 != status_code_failure3); + + status_code_failure3 = status_code_failure2; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure2, status_code_failure3); + } +} + +// clang-format off +const nlTest sTests[] = +{ + NL_TEST_DEF("TestStatusBasicValues", TestStatusBasicValues), + NL_TEST_DEF("TestClusterStatusCode", TestClusterStatusCode), + NL_TEST_SENTINEL() +}; +// clang-format on + +nlTestSuite sSuite = { "Test IM Status Code abstractions", &sTests[0], nullptr, nullptr }; +} // namespace + +int TestClusterStatusCode() +{ + nlTestRunner(&sSuite, nullptr); + + return (nlTestRunnerStats(&sSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestClusterStatusCode) From ad98820b717f4e0d50c8f5c308790ccbdf02591f Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 20 Dec 2023 11:38:49 -0800 Subject: [PATCH 13/83] Return ConnectionFailureException which contains the connection state (#29305) --- src/app/OperationalSessionSetup.cpp | 62 +++++++++++++---- src/app/OperationalSessionSetup.h | 66 +++++++++++++++---- src/protocols/secure_channel/CASESession.cpp | 29 +++++++- src/protocols/secure_channel/CASESession.h | 2 + .../secure_channel/PairingSession.cpp | 4 +- src/protocols/secure_channel/PairingSession.h | 10 ++- .../SessionEstablishmentDelegate.h | 25 +++++++ 7 files changed, 169 insertions(+), 29 deletions(-) diff --git a/src/app/OperationalSessionSetup.cpp b/src/app/OperationalSessionSetup.cpp index 2996cf2dd891d4..179e2a3df5e120 100644 --- a/src/app/OperationalSessionSetup.cpp +++ b/src/app/OperationalSessionSetup.cpp @@ -92,7 +92,8 @@ bool OperationalSessionSetup::AttachToExistingSecureSession() } void OperationalSessionSetup::Connect(Callback::Callback * onConnection, - Callback::Callback * onFailure) + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure) { CHIP_ERROR err = CHIP_NO_ERROR; bool isConnected = false; @@ -102,7 +103,7 @@ void OperationalSessionSetup::Connect(Callback::Callback * on // If anything goes wrong below, we'll trigger failures (including any queued from // a previous iteration which in theory shouldn't happen, but this is written to be more defensive) // - EnqueueConnectionCallbacks(onConnection, onFailure); + EnqueueConnectionCallbacks(onConnection, onFailure, onSetupFailure); switch (mState) { @@ -178,6 +179,18 @@ void OperationalSessionSetup::Connect(Callback::Callback * on } } +void OperationalSessionSetup::Connect(Callback::Callback * onConnection, + Callback::Callback * onFailure) +{ + Connect(onConnection, onFailure, nullptr); +} + +void OperationalSessionSetup::Connect(Callback::Callback * onConnection, + Callback::Callback * onSetupFailure) +{ + Connect(onConnection, nullptr, onSetupFailure); +} + void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config) { #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES @@ -291,7 +304,8 @@ CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ReliableMessagePro } void OperationalSessionSetup::EnqueueConnectionCallbacks(Callback::Callback * onConnection, - Callback::Callback * onFailure) + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure) { if (onConnection != nullptr) { @@ -302,11 +316,17 @@ void OperationalSessionSetup::EnqueueConnectionCallbacks(Callback::CallbackCancel()); } + + if (onSetupFailure != nullptr) + { + mSetupFailure.Enqueue(onSetupFailure->Cancel()); + } } -void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior) +void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, SessionEstablishmentStage stage, + ReleaseBehavior releaseBehavior) { - Cancelable failureReady, successReady; + Cancelable failureReady, setupFailureReady, successReady; // // Dequeue both failure and success callback lists into temporary stack args before invoking either of them. @@ -314,6 +334,7 @@ void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, Relea // since the callee may destroy this object as part of that callback. // mConnectionFailure.DequeueAll(failureReady); + mSetupFailure.DequeueAll(setupFailureReady); mConnectionSuccess.DequeueAll(successReady); #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES @@ -339,13 +360,14 @@ void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, Relea // DO NOT touch any members of this object after this point. It's dead. - NotifyConnectionCallbacks(failureReady, successReady, error, peerId, performingAddressUpdate, exchangeMgr, - optionalSessionHandle); + NotifyConnectionCallbacks(failureReady, setupFailureReady, successReady, error, stage, peerId, performingAddressUpdate, + exchangeMgr, optionalSessionHandle); } -void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureReady, Cancelable & successReady, CHIP_ERROR error, - const ScopedNodeId & peerId, bool performingAddressUpdate, - Messaging::ExchangeManager * exchangeMgr, +void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureReady, Cancelable & setupFailureReady, + Cancelable & successReady, CHIP_ERROR error, + SessionEstablishmentStage stage, const ScopedNodeId & peerId, + bool performingAddressUpdate, Messaging::ExchangeManager * exchangeMgr, const Optional & optionalSessionHandle) { // @@ -367,6 +389,22 @@ void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureRead } } + while (setupFailureReady.mNext != &setupFailureReady) + { + // We expect that we only have callbacks if we are not performing just address update. + VerifyOrDie(!performingAddressUpdate); + Callback::Callback * cb = Callback::Callback::FromCancelable(setupFailureReady.mNext); + + cb->Cancel(); + + if (error != CHIP_NO_ERROR) + { + // Initialize the ConnnectionFailureInfo object + ConnnectionFailureInfo failureInfo(peerId, error, stage); + cb->mCall(cb->mContext, failureInfo); + } + } + while (successReady.mNext != &successReady) { // We expect that we only have callbacks if we are not performing just address update. @@ -383,7 +421,7 @@ void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureRead } } -void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error) +void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) { VerifyOrReturn(mState == State::Connecting, ChipLogError(Discovery, "OnSessionEstablishmentError was called while we were not connecting")); @@ -438,7 +476,7 @@ void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error) #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES } - DequeueConnectionCallbacks(error); + DequeueConnectionCallbacks(error, stage); // Do not touch `this` instance anymore; it has been destroyed in DequeueConnectionCallbacks. } diff --git a/src/app/OperationalSessionSetup.h b/src/app/OperationalSessionSetup.h index 2925259066e6db..45b571a08aa633 100644 --- a/src/app/OperationalSessionSetup.h +++ b/src/app/OperationalSessionSetup.h @@ -155,6 +155,19 @@ typedef void (*OnDeviceConnectionRetry)(void * context, const ScopedNodeId & pee class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, public AddressResolve::NodeListener { public: + struct ConnnectionFailureInfo + { + const ScopedNodeId peerId; + CHIP_ERROR error; + SessionEstablishmentStage sessionStage; + + ConnnectionFailureInfo(const ScopedNodeId & peer, CHIP_ERROR err, SessionEstablishmentStage stage) : + peerId(peer), error(err), sessionStage(stage) + {} + }; + + using OnSetupFailure = void (*)(void * context, const ConnnectionFailureInfo & failureInfo); + ~OperationalSessionSetup() override; OperationalSessionSetup(const CASEClientInitParams & params, CASEClientPoolDelegate * clientPool, ScopedNodeId peerId, @@ -180,8 +193,8 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, * The device is expected to have been commissioned, A CASE session * setup will be triggered. * - * On establishing the session, the callback function `onConnection` will be called. If the - * session setup fails, `onFailure` will be called. + * If session setup succeeds, the callback function `onConnection` will be called. + * If session setup fails, `onFailure` will be called. * * If the session already exists, `onConnection` will be called immediately, * before the Connect call returns. @@ -192,11 +205,28 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, */ void Connect(Callback::Callback * onConnection, Callback::Callback * onFailure); + /* + * This function can be called to establish a secure session with the device. + * + * The device is expected to have been commissioned, A CASE session + * setup will be triggered. + * + * If session setup succeeds, the callback function `onConnection` will be called. + * If session setup fails, `onSetupFailure` will be called. + * + * If the session already exists, `onConnection` will be called immediately, + * before the Connect call returns. + * + * `onSetupFailure` may be called before the Connect call returns, for error cases that are detected synchronously + * (e.g. inability to start an address lookup). + */ + void Connect(Callback::Callback * onConnection, Callback::Callback * onSetupFailure); + bool IsForAddressUpdate() const { return mPerformingAddressUpdate; } //////////// SessionEstablishmentDelegate Implementation /////////////// void OnSessionEstablished(const SessionHandle & session) override; - void OnSessionEstablishmentError(CHIP_ERROR error) override; + void OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) override; ScopedNodeId GetPeerId() const { return mPeerId; } @@ -264,6 +294,7 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, Callback::CallbackDeque mConnectionSuccess; Callback::CallbackDeque mConnectionFailure; + Callback::CallbackDeque mSetupFailure; OperationalSessionReleaseDelegate * mReleaseDelegate; @@ -306,8 +337,12 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, void CleanupCASEClient(); + void Connect(Callback::Callback * onConnection, Callback::Callback * onFailure, + Callback::Callback * onSetupFailure); + void EnqueueConnectionCallbacks(Callback::Callback * onConnection, - Callback::Callback * onFailure); + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure); enum class ReleaseBehavior { @@ -316,11 +351,13 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, }; /* - * This dequeues all failure and success callbacks and appropriately - * invokes either set depending on the value of error. + * This dequeues all failure and success callbacks and appropriately invokes either set depending + * on the value of error. + * + * If error == CHIP_NO_ERROR, only success callbacks are invoked. Otherwise, only failure callbacks are invoked. * - * If error == CHIP_NO_ERROR, only success callbacks are invoked. - * Otherwise, only failure callbacks are invoked. + * The state offers additional context regarding the failure, indicating the specific state in which + * the error occurs. It is only relayed through failure callbacks when the error is not equal to CHIP_NO_ERROR. * * If releaseBehavior is Release, this uses mReleaseDelegate to release * ourselves (aka `this`). As a result any caller should return right away @@ -328,15 +365,22 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, * * Setting releaseBehavior to DoNotRelease is meant for use from the destructor */ - void DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior = ReleaseBehavior::Release); + void DequeueConnectionCallbacks(CHIP_ERROR error, SessionEstablishmentStage stage, + ReleaseBehavior releaseBehavior = ReleaseBehavior::Release); + + void DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior = ReleaseBehavior::Release) + { + this->DequeueConnectionCallbacks(error, SessionEstablishmentStage::kNotInKeyExchange, releaseBehavior); + } /** * Helper for DequeueConnectionCallbacks that handles the actual callback * notifications. This happens after the object has been released, if it's * being released. */ - static void NotifyConnectionCallbacks(Callback::Cancelable & failureReady, Callback::Cancelable & successReady, - CHIP_ERROR error, const ScopedNodeId & peerId, bool performingAddressUpdate, + static void NotifyConnectionCallbacks(Callback::Cancelable & failureReady, Callback::Cancelable & setupFailureReady, + Callback::Cancelable & successReady, CHIP_ERROR error, SessionEstablishmentStage stage, + const ScopedNodeId & peerId, bool performingAddressUpdate, Messaging::ExchangeManager * exchangeMgr, const Optional & optionalSessionHandle); diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 6e51d000e3822c..296ba0848150c7 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -556,9 +556,11 @@ void CASESession::OnResponseTimeout(ExchangeContext * ec) void CASESession::AbortPendingEstablish(CHIP_ERROR err) { + // This needs to come before Clear() which will reset mState. + SessionEstablishmentStage state = MapCASEStateToSessionEstablishmentStage(mState); Clear(); // Do this last in case the delegate frees us. - NotifySessionEstablishmentError(err); + NotifySessionEstablishmentError(err, state); } CHIP_ERROR CASESession::DeriveSecureSession(CryptoContext & session) const @@ -2255,4 +2257,29 @@ bool CASESession::InvokeBackgroundWorkWatchdog() return watchdogFired; } +// Helper function to map CASESession::State to SessionEstablishmentStage +SessionEstablishmentStage CASESession::MapCASEStateToSessionEstablishmentStage(State caseState) +{ + switch (caseState) + { + case State::kInitialized: + return SessionEstablishmentStage::kNotInKeyExchange; + case State::kSentSigma1: + case State::kSentSigma1Resume: + return SessionEstablishmentStage::kSentSigma1; + case State::kSentSigma2: + case State::kSentSigma2Resume: + return SessionEstablishmentStage::kSentSigma2; + case State::kSendSigma3Pending: + return SessionEstablishmentStage::kReceivedSigma2; + case State::kSentSigma3: + return SessionEstablishmentStage::kSentSigma3; + case State::kHandleSigma3Pending: + return SessionEstablishmentStage::kReceivedSigma3; + // Add more mappings here for other states + default: + return SessionEstablishmentStage::kUnknown; // Default mapping + } +} + } // namespace chip diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index 7453b6b5002dc4..6fc58dfb90dc83 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -320,6 +320,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, #if CONFIG_BUILD_FOR_HOST_UNIT_TEST Optional mStopHandshakeAtState = Optional::Missing(); #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST + + SessionEstablishmentStage MapCASEStateToSessionEstablishmentStage(State caseState); }; } // namespace chip diff --git a/src/protocols/secure_channel/PairingSession.cpp b/src/protocols/secure_channel/PairingSession.cpp index 63a1701e66541f..23daea30f2800c 100644 --- a/src/protocols/secure_channel/PairingSession.cpp +++ b/src/protocols/secure_channel/PairingSession.cpp @@ -255,7 +255,7 @@ void PairingSession::Clear() mSessionManager = nullptr; } -void PairingSession::NotifySessionEstablishmentError(CHIP_ERROR error) +void PairingSession::NotifySessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) { if (mDelegate == nullptr) { @@ -265,7 +265,7 @@ void PairingSession::NotifySessionEstablishmentError(CHIP_ERROR error) auto * delegate = mDelegate; mDelegate = nullptr; - delegate->OnSessionEstablishmentError(error); + delegate->OnSessionEstablishmentError(error, stage); } void PairingSession::OnSessionReleased() diff --git a/src/protocols/secure_channel/PairingSession.h b/src/protocols/secure_channel/PairingSession.h index 844fa33a41ae68..ffbb6d9966485d 100644 --- a/src/protocols/secure_channel/PairingSession.h +++ b/src/protocols/secure_channel/PairingSession.h @@ -218,10 +218,14 @@ class DLL_EXPORT PairingSession : public SessionDelegate void Clear(); /** - * Notify our delegate about a session establishment error, if we have not - * notified it of an error or success before. + * Notify our delegate about a session establishment error and the stage when the error occurs + * if we have not already notified it of an error or success before. + * + * @param error The error code to report. + * @param stage The stage of the session when the error occurs, defaults to kNotInKeyExchange. */ - void NotifySessionEstablishmentError(CHIP_ERROR error); + void NotifySessionEstablishmentError(CHIP_ERROR error, + SessionEstablishmentStage stage = SessionEstablishmentStage::kNotInKeyExchange); protected: CryptoContext::SessionRole mRole; diff --git a/src/protocols/secure_channel/SessionEstablishmentDelegate.h b/src/protocols/secure_channel/SessionEstablishmentDelegate.h index dc73a0ffe6997d..640dfca745921f 100644 --- a/src/protocols/secure_channel/SessionEstablishmentDelegate.h +++ b/src/protocols/secure_channel/SessionEstablishmentDelegate.h @@ -32,6 +32,18 @@ namespace chip { +enum class SessionEstablishmentStage : uint8_t +{ + kUnknown = 0, + kNotInKeyExchange = 1, + kSentSigma1 = 2, + kReceivedSigma1 = 3, + kSentSigma2 = 4, + kReceivedSigma2 = 5, + kSentSigma3 = 6, + kReceivedSigma3 = 7, +}; + class DLL_EXPORT SessionEstablishmentDelegate { public: @@ -39,9 +51,22 @@ class DLL_EXPORT SessionEstablishmentDelegate * Called when session establishment fails with an error. This will be * called at most once per session establishment and will not be called if * OnSessionEstablished is called. + * + * This overload of OnSessionEstablishmentError is not called directly. It's only called from the default + *. implemetation of the two-argument overload. */ virtual void OnSessionEstablishmentError(CHIP_ERROR error) {} + /** + * Called when session establishment fails with an error and state at the + * failure. This will be called at most once per session establishment and + * will not be called if OnSessionEstablished is called. + */ + virtual void OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) + { + OnSessionEstablishmentError(error); + } + /** * Called on start of session establishment process */ From 2544b6e4163c6348a2f8f1ab7d4746a9867042d4 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 20 Dec 2023 16:13:28 -0500 Subject: [PATCH 14/83] TC-ACE_1.6: Rework test to use TH keys (#30896) * TC-ACE_1.6: Rework test to use TH keys * Restyled by prettier-yaml * renumber steps, fix one missed key --------- Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_ACE_1_6.yaml | 118 ++++++++++-------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml b/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml index 877d116305da25..7c353c2b2382b5 100644 --- a/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml @@ -51,7 +51,7 @@ tests: saveAs: commissionerNodeId - label: - "Step 1: TH sends KeySetWrite command in the GroupKeyManagement + "Step 1a: TH sends KeySetWrite command in the GroupKeyManagement cluster to DUT using a key that is pre-installed on the TH. GroupKeySet fields are as follows: GroupKeySetID: 0x01a3 GroupKeySecurityPolicy: TrustFirst (0) EpochKey0: @@ -74,11 +74,35 @@ tests: EpochKey2: "hex:d2d1d2d3d4d5d6d7d8d9dadbdcdddedf", EpochStartTime2: 2220002, } + - label: + "Step 1b: TH sends KeySetWrite command in the GroupKeyManagement + cluster to DUT using a key that is pre-installed on the TH. + GroupKeySet fields are as follows: GroupKeySetID: 0x01a1 + GroupKeySecurityPolicy: TrustFirst (0) EpochKey0: + a0d1d2d3d4d5d6d7d8d9dadbdcdddedf EpochStartTime0: 2220000 EpochKey1: + b1d1d2d3d4d5d6d7d8d9dadbdcdddedf EpochStartTime1: 2220001 EpochKey2: + c2d1d2d3d4d5d6d7d8d9dadbdcdddedf EpochStartTime2: 2220002" + cluster: "Group Key Management" + command: "KeySetWrite" + arguments: + values: + - name: GroupKeySet + value: + { + GroupKeySetID: 0x01a1, + GroupKeySecurityPolicy: 0, + EpochKey0: "hex:a0d1d2d3d4d5d6d7d8d9dadbdcdddedf", + EpochStartTime0: 2220000, + EpochKey1: "hex:b1d1d2d3d4d5d6d7d8d9dadbdcdddedf", + EpochStartTime1: 2220001, + EpochKey2: "hex:c2d1d2d3d4d5d6d7d8d9dadbdcdddedf", + EpochStartTime2: 2220002, + } - label: "Step 2: TH binds GroupId to GroupKeySet with entries as follows: List item 1: GroupId: 0x0103, GroupKeySetId: 0x01a3, List item 2: GroupId: - 0x0104, GroupKeySetId: 0x01a3, List item 3: GroupId: 0x0105, + 0x0104, GroupKeySetId: 0x01a4, List item 3: GroupId: 0x0105, GroupKeySetId: 0x01a3" cluster: "Group Key Management" command: "writeAttribute" @@ -86,9 +110,9 @@ tests: arguments: value: [ + { FabricIndex: 0, GroupId: 0x0101, GroupKeySetID: 0x01a1 }, + { FabricIndex: 0, GroupId: 0x0102, GroupKeySetID: 0x01a1 }, { FabricIndex: 0, GroupId: 0x0103, GroupKeySetID: 0x01a3 }, - { FabricIndex: 0, GroupId: 0x0104, GroupKeySetID: 0x01a3 }, - { FabricIndex: 0, GroupId: 0x0105, GroupKeySetID: 0x01a3 }, ] - label: @@ -151,7 +175,7 @@ tests: - label: "Step 5: TH sends a AddGroup Command to the Groups cluster on Endpoint - PIXIT.G.ENDPOINT over CASE with the GroupID field set to 0x0104 and + PIXIT.G.ENDPOINT over CASE with the GroupID field set to 0x0101 and the GroupName set to an empty string" cluster: "Groups" endpoint: Groups.Endpoint @@ -159,7 +183,7 @@ tests: arguments: values: - name: GroupID - value: 0x0104 + value: 0x0101 - name: GroupName value: "" response: @@ -167,7 +191,7 @@ tests: - label: "Step 6: TH sends a AddGroup Command to the Groups cluster with the - GroupID field set to 0x0104 and the GroupName set to an empty string. + GroupID field set to 0x0101 and the GroupName set to an empty string. The command is sent as a group command using GroupID 0x0103" cluster: "Groups" groupId: 0x0103 @@ -175,7 +199,7 @@ tests: arguments: values: - name: GroupID - value: 0x0104 + value: 0x0101 - name: GroupName value: "" @@ -188,26 +212,19 @@ tests: - name: "ms" value: 1000 - #Issue : https://github.com/project-chip/connectedhomeip/issues/27982 - label: "Step 7: TH sends a AddGroup Command to the Groups cluster with the - GroupID field set to 0x0105 and the GroupName set to an empty string. - The command is sent as a group command using GroupID 0x0104" - verification: | - ./chip-tool groups add-group 261 '' 0xffffffffffff0104 1 --trace_decode 1 - - This step does not have any expected outcome as per the spec, Hence no verification logs has been provided. - - Further continuation of this step has been validated using "view group" command in Step 10 - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP + GroupID field set to 0x0102 and the GroupName set to an empty string. + The command is sent as a group command using GroupID 0x0101" + cluster: "Groups" + groupId: 0x0101 + command: "AddGroup" arguments: values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" + - name: GroupID + value: 0x0102 + - name: GroupName + value: "" # multicast if the unicast packet is sent immediately after the multicast one. - label: "Wait for AddGroup" @@ -239,7 +256,7 @@ tests: - label: "Step 9: TH sends a ViewGroup Command to the Groups cluster on - Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0104 to + Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0101 to confirm that the AddGroup command from step 6 was successful" cluster: "Groups" endpoint: Groups.Endpoint @@ -247,43 +264,35 @@ tests: arguments: values: - name: GroupID - value: 0x0104 + value: 0x0101 response: values: - name: Status value: 0 - name: GroupID - value: 0x0104 + value: 0x0101 - name: GroupName value: "" - #Issue : https://github.com/project-chip/connectedhomeip/issues/27967 - label: "Step 10: TH sends a ViewGroup Command to the Groups cluster on - Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0105 to + Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0102 to confirm that the AddGroup command from step 7 was not successful" - verification: | - ./chip-tool groups view-group 0x0105 1 0 - - Verify DUT sends a ViewGroupResponse with Status is set to NOT_FOUND on TH(chip-tool) Logs: - - [1685009398.600925][39795:39797] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0004 Command=0x0000_0001 - [1685009398.600932][39795:39797] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 - [1685009398.600944][39795:39797] CHIP:TOO: ViewGroupResponse: { - [1685009398.600949][39795:39797] CHIP:TOO: status: 139 - [1685009398.600952][39795:39797] CHIP:TOO: groupID: 261 - [1685009398.600955][39795:39797] CHIP:TOO: groupName: - [1685009398.600957][39795:39797] CHIP:TOO: } - [1685009398.600964][39795:39797] CHIP:DMG: ICR moving to [AwaitingDe] - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP + cluster: "Groups" + endpoint: Groups.Endpoint + command: "ViewGroup" arguments: values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" + - name: GroupID + value: 0x0102 + response: + values: + - name: Status + value: 139 + - name: GroupID + value: 0x0102 + - name: GroupName + value: "" - label: "Step 11: TH sends a AddGroup Command to the Groups cluster with the @@ -346,3 +355,14 @@ tests: values: - name: GroupKeySetID value: 0x01a3 + + - label: + "Step 16: TH resets the key set by sending the KeySetRemove command to + the GroupKeyManagement cluster over CASE with the following fields: + GroupKeySetID: 0x01a1" + cluster: "Group Key Management" + command: "KeySetRemove" + arguments: + values: + - name: GroupKeySetID + value: 0x01a1 From bd24a657d4aae54febad477cb558d22686438315 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:02:36 -0500 Subject: [PATCH 15/83] [Report Scheduler] Empty node pool handling (#31136) * Changed check for no nodes in pool * Update src/app/reporting/SynchronizedReportSchedulerImpl.cpp Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- src/app/reporting/SynchronizedReportSchedulerImpl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp index 6627cf7116bec3..7dfa84c70e5343 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp @@ -182,6 +182,9 @@ void SynchronizedReportSchedulerImpl::TimerFired() Timestamp now = mTimerDelegate->GetCurrentMonotonicTimestamp(); bool firedEarly = true; + // If there are no handlers registered, no need to do anything. + VerifyOrReturn(mNodesPool.Allocated()); + mNodesPool.ForEachActiveObject([now, &firedEarly](ReadHandlerNode * node) { if (node->GetMinTimestamp() <= now) { @@ -201,8 +204,7 @@ void SynchronizedReportSchedulerImpl::TimerFired() return Loop::Continue; }); - // If there are no handlers registers, no need to schedule the next report - if (mNodesPool.Allocated() && firedEarly) + if (firedEarly) { Timeout timeout = Milliseconds32(0); ReturnOnFailure(CalculateNextReportTimeout(timeout, nullptr, now)); From b7e3bc003871a200439ec9e4525f1d7c94e93e71 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:46:14 +1300 Subject: [PATCH 16/83] Darwin: Consistently use ivars in MTRDeviceController and a few other places (#31141) --- .../commands/common/CHIPToolKeypair.mm | 15 ++-- .../pairing/DeviceControllerDelegateBridge.mm | 3 - .../CHIP/MTRAsyncCallbackWorkQueue.mm | 4 + src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 +- .../Framework/CHIP/MTRDeviceController.mm | 89 +++++++++---------- .../CHIP/MTRThreadOperationalDataset.mm | 13 +-- 6 files changed, 59 insertions(+), 69 deletions(-) diff --git a/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm b/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm index fccf3d2734407e..4d6f53de9aa08f 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm @@ -12,15 +12,14 @@ static NSString * const kOperationalCredentialsIssuerKeypairStorage = @"ChipToolOpCredsCAKey"; static NSString * const kOperationalCredentialsIPK = @"ChipToolOpCredsIPK"; -@interface CHIPToolKeypair () -@property (nonatomic) chip::Crypto::P256Keypair mKeyPair; -@property (nonatomic) chip::Crypto::P256Keypair mIssuer; -@property (nonatomic) NSData * ipk; -@property (atomic) uint32_t mNow; -@property (nonatomic, readonly) SecKeyRef mPublicKey; -@end +@implementation CHIPToolKeypair { + chip::Crypto::P256Keypair _mKeyPair; + chip::Crypto::P256Keypair _mIssuer; + NSData * _ipk; + uint32_t _mNow; + SecKeyRef _mPublicKey; +} -@implementation CHIPToolKeypair - (instancetype)init { if (self = [super init]) { diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm index b3476119c224b5..7b9f4369a79c7d 100644 --- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm +++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm @@ -19,9 +19,6 @@ #include "DeviceControllerDelegateBridge.h" #import -@interface CHIPToolDeviceControllerDelegate () -@end - @implementation CHIPToolDeviceControllerDelegate - (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status { diff --git a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm index ece651a21238de..00b6d33788f6c0 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm +++ b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm @@ -15,6 +15,10 @@ * limitations under the License. */ +// NOTE: This class was not intended to be part of the public Matter API; +// internally this class has been replaced by MTRAsyncWorkQueue. This code +// remains here simply to preserve API/ABI compatibility. + #import #import diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index d053cc8f007cf8..a4bcf3742c8d6e 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -2744,12 +2744,10 @@ - (id)copyWithZone:(NSZone *)zone @end -@interface MTREventReport () { +@implementation MTREventReport { NSNumber * _timestampValue; } -@end -@implementation MTREventReport + (void)initialize { // One of our init methods ends up doing Platform::MemoryAlloc. diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 04f92e8e3bdf1a..ba3ec1958a42fd 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -101,31 +101,27 @@ typedef id (^SyncWorkQueueBlockWithReturnValue)(void); typedef BOOL (^SyncWorkQueueBlockWithBoolReturnValue)(void); -@interface MTRDeviceController () { +@implementation MTRDeviceController { // Atomic because it can be touched from multiple threads. std::atomic _storedFabricIndex; -} - -// queue used to serialize all work performed by the MTRDeviceController -@property (atomic, readonly) dispatch_queue_t chipWorkQueue; -@property (readonly) chip::Controller::DeviceCommissioner * cppCommissioner; -@property (readonly) chip::Credentials::PartialDACVerifier * partialDACVerifier; -@property (readonly) chip::Credentials::DefaultDACVerifier * defaultDACVerifier; -@property (readonly) MTRDeviceControllerDelegateBridge * deviceControllerDelegateBridge; -@property (readonly) MTROperationalCredentialsDelegate * operationalCredentialsDelegate; -@property (readonly) MTRP256KeypairBridge signingKeypairBridge; -@property (readonly) MTRP256KeypairBridge operationalKeypairBridge; -@property (readonly) MTRDeviceAttestationDelegateBridge * deviceAttestationDelegateBridge; -@property (readonly) MTRDeviceControllerFactory * factory; -@property (readonly) NSMutableDictionary * nodeIDToDeviceMap; -@property (readonly) os_unfair_lock deviceMapLock; // protects nodeIDToDeviceMap -@property (readonly) MTRCommissionableBrowser * commissionableBrowser; -@property (readonly) MTRAttestationTrustStoreBridge * attestationTrustStoreBridge; + // queue used to serialize all work performed by the MTRDeviceController + dispatch_queue_t _chipWorkQueue; -@end - -@implementation MTRDeviceController + chip::Controller::DeviceCommissioner * _cppCommissioner; + chip::Credentials::PartialDACVerifier * _partialDACVerifier; + chip::Credentials::DefaultDACVerifier * _defaultDACVerifier; + MTRDeviceControllerDelegateBridge * _deviceControllerDelegateBridge; + MTROperationalCredentialsDelegate * _operationalCredentialsDelegate; + MTRP256KeypairBridge _signingKeypairBridge; + MTRP256KeypairBridge _operationalKeypairBridge; + MTRDeviceAttestationDelegateBridge * _deviceAttestationDelegateBridge; + MTRDeviceControllerFactory * _factory; + NSMutableDictionary * _nodeIDToDeviceMap; + os_unfair_lock _deviceMapLock; // protects nodeIDToDeviceMap + MTRCommissionableBrowser * _commissionableBrowser; + MTRAttestationTrustStoreBridge * _attestationTrustStoreBridge; +} - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error { @@ -249,7 +245,7 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory - (BOOL)isRunning { - return self.cppCommissioner != nullptr; + return _cppCommissioner != nullptr; } - (void)shutdown @@ -271,8 +267,8 @@ - (void)cleanupAfterStartup // while calling out into arbitrary invalidation code, snapshot the list of // devices before we start invalidating. os_unfair_lock_lock(&_deviceMapLock); - NSArray * devices = [self.nodeIDToDeviceMap allValues]; - [self.nodeIDToDeviceMap removeAllObjects]; + NSArray * devices = [_nodeIDToDeviceMap allValues]; + [_nodeIDToDeviceMap removeAllObjects]; os_unfair_lock_unlock(&_deviceMapLock); for (MTRDevice * device in devices) { @@ -590,7 +586,7 @@ - (BOOL)setupCommissioningSessionWithPayload:(MTRSetupPayload *)payload chip::NodeId nodeId = [newNodeID unsignedLongLongValue]; self->_operationalCredentialsDelegate->SetDeviceID(nodeId); - auto errorCode = self.cppCommissioner->EstablishPASEConnection(nodeId, [pairingCode UTF8String]); + auto errorCode = self->_cppCommissioner->EstablishPASEConnection(nodeId, [pairingCode UTF8String]); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -612,7 +608,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR auto pinCode = static_cast(payload.setupPasscode.unsignedLongValue); params.Value().SetSetupPINCode(pinCode); - errorCode = self.cppCommissioner->EstablishPASEConnection(nodeId, params.Value()); + errorCode = self->_cppCommissioner->EstablishPASEConnection(nodeId, params.Value()); } else { // Try to get a QR code if possible (because it has a better // discriminator, etc), then fall back to manual code if that fails. @@ -630,7 +626,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR continue; } - errorCode = self.cppCommissioner->EstablishPASEConnection( + errorCode = self->_cppCommissioner->EstablishPASEConnection( nodeId, [pairingCode UTF8String], chip::Controller::DiscoveryType::kDiscoveryNetworkOnly, resolutionData); if (CHIP_NO_ERROR != errorCode) { break; @@ -745,7 +741,7 @@ - (BOOL)commissionNodeWithID:(NSNumber *)nodeID chip::NodeId deviceId = [nodeID unsignedLongLongValue]; self->_operationalCredentialsDelegate->SetDeviceID(deviceId); - auto errorCode = self.cppCommissioner->Commission(deviceId, params); + auto errorCode = self->_cppCommissioner->Commission(deviceId, params); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -762,7 +758,7 @@ - (BOOL)continueCommissioningDevice:(void *)device : chip::Credentials::AttestationVerificationResult::kSuccess; auto deviceProxy = static_cast(device); - auto errorCode = self.cppCommissioner->ContinueCommissioningAfterDeviceAttestation(deviceProxy, + auto errorCode = self->_cppCommissioner->ContinueCommissioningAfterDeviceAttestation(deviceProxy, ignoreAttestationFailure ? chip::Credentials::AttestationVerificationResult::kSuccess : lastAttestationResult); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -774,7 +770,7 @@ - (BOOL)cancelCommissioningForNodeID:(NSNumber *)nodeID error:(NSError * __autor { auto block = ^BOOL { self->_operationalCredentialsDelegate->ResetDeviceID(); - auto errorCode = self.cppCommissioner->StopPairing([nodeID unsignedLongLongValue]); + auto errorCode = self->_cppCommissioner->StopPairing([nodeID unsignedLongLongValue]); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorStopPairing error:error]; }; @@ -784,7 +780,7 @@ - (BOOL)cancelCommissioningForNodeID:(NSNumber *)nodeID error:(NSError * __autor - (BOOL)startBrowseForCommissionables:(id)delegate queue:(dispatch_queue_t)queue { auto block = ^BOOL { - VerifyOrReturnValue(self.commissionableBrowser == nil, NO); + VerifyOrReturnValue(self->_commissionableBrowser == nil, NO); auto commissionableBrowser = [[MTRCommissionableBrowser alloc] initWithDelegate:delegate controller:self queue:queue]; VerifyOrReturnValue([commissionableBrowser start], NO); @@ -799,9 +795,9 @@ - (BOOL)startBrowseForCommissionables:(id)dele - (BOOL)stopBrowseForCommissionables { auto block = ^BOOL { - VerifyOrReturnValue(self.commissionableBrowser != nil, NO); + VerifyOrReturnValue(self->_commissionableBrowser != nil, NO); - auto commissionableBrowser = self.commissionableBrowser; + auto commissionableBrowser = self->_commissionableBrowser; VerifyOrReturnValue([commissionableBrowser stop], NO); self->_commissionableBrowser = nil; @@ -845,7 +841,7 @@ - (MTRBaseDevice *)baseDeviceForNodeID:(NSNumber *)nodeID - (MTRDevice *)deviceForNodeID:(NSNumber *)nodeID { os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * deviceToReturn = self.nodeIDToDeviceMap[nodeID]; + MTRDevice * deviceToReturn = _nodeIDToDeviceMap[nodeID]; if (!deviceToReturn) { deviceToReturn = [[MTRDevice alloc] initWithNodeID:nodeID controller:self]; // If we're not running, don't add the device to our map. That would @@ -853,7 +849,7 @@ - (MTRDevice *)deviceForNodeID:(NSNumber *)nodeID // which will be in exactly the state it would be in if it were created // while we were running and then we got shut down. if ([self isRunning]) { - self.nodeIDToDeviceMap[nodeID] = deviceToReturn; + _nodeIDToDeviceMap[nodeID] = deviceToReturn; } } os_unfair_lock_unlock(&_deviceMapLock); @@ -864,12 +860,13 @@ - (MTRDevice *)deviceForNodeID:(NSNumber *)nodeID - (void)removeDevice:(MTRDevice *)device { os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * deviceToRemove = self.nodeIDToDeviceMap[device.nodeID]; + auto * nodeID = device.nodeID; + MTRDevice * deviceToRemove = _nodeIDToDeviceMap[nodeID]; if (deviceToRemove == device) { [deviceToRemove invalidate]; - self.nodeIDToDeviceMap[device.nodeID] = nil; + _nodeIDToDeviceMap[nodeID] = nil; } else { - MTR_LOG_ERROR("Error: Cannot remove device %p with nodeID %llu", device, device.nodeID.unsignedLongLongValue); + MTR_LOG_ERROR("Error: Cannot remove device %p with nodeID %llu", device, nodeID.unsignedLongLongValue); } os_unfair_lock_unlock(&_deviceMapLock); } @@ -935,7 +932,7 @@ - (NSData * _Nullable)attestationChallengeForDeviceID:(NSNumber *)deviceID auto block = ^NSData * { chip::CommissioneeDeviceProxy * deviceProxy; - auto errorCode = self.cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); + auto errorCode = self->_cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetCommissionee error:nil], nil); uint8_t challengeBuffer[chip::Crypto::kAES_CCM128_Key_Length]; @@ -1098,7 +1095,7 @@ - (void)asyncGetCommissionerOnMatterQueue:(void (^)(chip::Controller::DeviceComm return; } - block(self.cppCommissioner); + block(self->_cppCommissioner); }); } @@ -1208,7 +1205,7 @@ - (void)operationalInstanceAdded:(chip::NodeId)nodeID // Don't use deviceForNodeID here, because we don't want to create the // device if it does not already exist. os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * device = self.nodeIDToDeviceMap[@(nodeID)]; + MTRDevice * device = _nodeIDToDeviceMap[@(nodeID)]; os_unfair_lock_unlock(&_deviceMapLock); if (device == nil) { @@ -1400,7 +1397,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorSetupCodeGen error:error], NO); self->_operationalCredentialsDelegate->SetDeviceID(deviceID); - errorCode = self.cppCommissioner->EstablishPASEConnection(deviceID, manualPairingCode.c_str()); + errorCode = self->_cppCommissioner->EstablishPASEConnection(deviceID, manualPairingCode.c_str()); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -1421,7 +1418,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID self->_operationalCredentialsDelegate->SetDeviceID(deviceID); auto params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode).SetPeerAddress(peerAddress); - auto errorCode = self.cppCommissioner->EstablishPASEConnection(deviceID, params); + auto errorCode = self->_cppCommissioner->EstablishPASEConnection(deviceID, params); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -1432,7 +1429,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID onboardingPayload:(NSString *)onboardingPa { auto block = ^BOOL { self->_operationalCredentialsDelegate->SetDeviceID(deviceID); - auto errorCode = self.cppCommissioner->EstablishPASEConnection(deviceID, [onboardingPayload UTF8String]); + auto errorCode = self->_cppCommissioner->EstablishPASEConnection(deviceID, [onboardingPayload UTF8String]); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -1468,7 +1465,7 @@ - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error auto block = ^BOOL { auto errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenBasicCommissioningWindow( - self.cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); + self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorOpenPairingWindow error:error]; }; @@ -1508,7 +1505,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID auto block = ^NSString * { chip::SetupPayload setupPayload; - auto errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenCommissioningWindow(self.cppCommissioner, deviceID, + auto errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenCommissioningWindow(self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration)), chip::Crypto::kSpake2p_Min_PBKDF_Iterations, static_cast(discriminator), chip::MakeOptional(static_cast(setupPIN)), chip::NullOptional, setupPayload); diff --git a/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm b/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm index bb5db0af9a977b..a547321d88c2e0 100644 --- a/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm +++ b/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm @@ -29,14 +29,9 @@ size_t const MTRSizeThreadPSKc = chip::Thread::kSizePSKc; size_t const MTRSizeThreadPANID = 2; // Thread's PAN ID is 2 bytes -@interface MTRThreadOperationalDataset () - -@property (readonly) chip::Thread::OperationalDataset cppThreadOperationalDataset; -@property (nonatomic, copy) NSNumber * channelNumber; - -@end - -@implementation MTRThreadOperationalDataset +@implementation MTRThreadOperationalDataset { + chip::Thread::OperationalDataset _cppThreadOperationalDataset; +} - (instancetype _Nullable)initWithNetworkName:(NSString *)networkName extendedPANID:(NSData *)extendedPANID @@ -157,7 +152,7 @@ @implementation MTRThreadOperationalDataset (Deprecated) - (void)setChannel:(uint16_t)channel { - self.channelNumber = @(channel); + _channelNumber = @(channel); } - (uint16_t)channel From 711ca50d4f2937b62799e89dd80218a4f94ff3be Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:00:52 -0500 Subject: [PATCH 17/83] [ReportScheduler] Renaming mTestNextReportTimestamp (#31137) * Renaming mTestNextReportTimestamp since we now use it outside of tests * Updated member description in .h * Update src/app/reporting/SynchronizedReportSchedulerImpl.h Co-authored-by: Boris Zbarsky * Restyled by clang-format --------- Co-authored-by: Boris Zbarsky Co-authored-by: Restyled.io --- .../SynchronizedReportSchedulerImpl.cpp | 6 ++-- .../SynchronizedReportSchedulerImpl.h | 5 ++-- src/app/tests/TestReportScheduler.cpp | 28 +++++++++---------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp index 7dfa84c70e5343..a4066303cf23f1 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp @@ -48,8 +48,8 @@ void SynchronizedReportSchedulerImpl::OnTransitionToIdle() { Timestamp now = mTimerDelegate->GetCurrentMonotonicTimestamp(); uint32_t targetIdleInterval = static_cast(ICD_SLEEP_TIME_JITTER_MS); - VerifyOrReturn(now >= mTestNextReportTimestamp); - if (((mTestNextReportTimestamp - now) < Seconds16(targetIdleInterval)) && (now > mNextMinTimestamp)) + VerifyOrReturn(now >= mNextReportTimestamp); + if (((mNextReportTimestamp - now) < Seconds16(targetIdleInterval)) && (now > mNextMinTimestamp)) { // If the next report is due in less than the idle mode interval and we are past the min interval, we can just send it now CancelReport(); @@ -67,7 +67,7 @@ CHIP_ERROR SynchronizedReportSchedulerImpl::ScheduleReport(Timeout timeout, Read return CHIP_NO_ERROR; } ReturnErrorOnFailure(mTimerDelegate->StartTimer(this, timeout)); - mTestNextReportTimestamp = now + timeout; + mNextReportTimestamp = now + timeout; return CHIP_NO_ERROR; } diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.h b/src/app/reporting/SynchronizedReportSchedulerImpl.h index 1240395bb0fcea..59a675fab02c31 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.h +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.h @@ -58,8 +58,9 @@ class SynchronizedReportSchedulerImpl : public ReportSchedulerImpl, public Timer Timestamp mNextMaxTimestamp = Milliseconds64(0); Timestamp mNextMinTimestamp = Milliseconds64(0); - // Timestamp of the next report to be scheduled, only used for testing - Timestamp mTestNextReportTimestamp = Milliseconds64(0); + // Timestamp of the next report to be scheduled, used by OnTransitionToIdle to determine whether we should emit a report before + // the device goes to idle mode + Timestamp mNextReportTimestamp = Milliseconds64(0); }; } // namespace reporting diff --git a/src/app/tests/TestReportScheduler.cpp b/src/app/tests/TestReportScheduler.cpp index 1c4d96660171f4..af6f367af8ccc6 100644 --- a/src/app/tests/TestReportScheduler.cpp +++ b/src/app/tests/TestReportScheduler.cpp @@ -494,7 +494,7 @@ class TestReportScheduler // Validates that the highest reportable min is selected as the common min interval (0 here) NL_TEST_ASSERT(aSuite, syncScheduler.mNextMinTimestamp == node1->GetMinTimestamp()); // Validates that the next report emission is scheduled on the common max timestamp - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == syncScheduler.mNextMaxTimestamp); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == syncScheduler.mNextMaxTimestamp); // Simulate waiting for the max interval to expire (2s) sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(2000)); @@ -515,7 +515,7 @@ class TestReportScheduler // Validate that the max timestamp for both readhandlers got updated and that the next report emission is scheduled on // the new max timestamp for readhandler1 NL_TEST_ASSERT(aSuite, node1->GetMaxTimestamp() > sTestTimerSynchronizedDelegate.GetCurrentMonotonicTimestamp()); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Confirm behavior when a read handler becomes dirty readHandler2->ForceDirtyState(); @@ -530,7 +530,7 @@ class TestReportScheduler // Confirm that the next report emission is scheduled on the min timestamp of readHandler2 (now) as it is the highest // reportable - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node2->GetMinTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node2->GetMinTimestamp()); NL_TEST_ASSERT(aSuite, node1->CanBeSynced() == true); // Simulate a report emission for readHandler1 @@ -570,7 +570,7 @@ class TestReportScheduler // Validate next report scheduled on the max timestamp of readHandler1 NL_TEST_ASSERT(aSuite, node1->GetMaxTimestamp() > sTestTimerSynchronizedDelegate.GetCurrentMonotonicTimestamp()); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Simulate readHandler1 becoming dirty after less than 1 seconds, since it is reportable now, this will Schedule an Engine // run immediately @@ -586,7 +586,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); // The next report should be scheduler on the max timestamp of readHandler1 - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(2000)); // Confirm node 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler1 @@ -598,7 +598,7 @@ class TestReportScheduler readHandler2->mObserver->OnSubscriptionReportSent(readHandler2); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler1)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Simulate a new ReadHandler being added with a min timestamp that will force a conflict @@ -615,7 +615,7 @@ class TestReportScheduler // Since the min interval on readHandler3 is 2, it should be above the current max timestamp, therefore the next report // should still happen on the max timestamp of readHandler1 and the sync should be done on future reports - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // The min timestamp should also not have changed since the min of readhandler3 is higher than the current max NL_TEST_ASSERT(aSuite, syncScheduler.mNextMinTimestamp == node2->GetMinTimestamp()); @@ -635,7 +635,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); // Confirm that next report is scheduled on the max timestamp of readHandler3 and other 2 readHandlers are synced - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node3->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node3->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(2000)); // Confirm nodes 1 and 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler1 @@ -655,7 +655,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler1)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler3)); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Now simulate a new readHandler being added with a max forcing a conflict ReadHandler * readHandler4 = @@ -667,7 +667,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, syncScheduler.GetNumReadHandlers() == 4); // Confirm next report is scheduled on the max timestamp of readHandler4 - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node4->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node4->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1100)); // Confirm node 1 and 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler4 @@ -714,7 +714,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler4)); // Next emission should be scheduled on the max timestamp of readHandler4 as it is the most restrictive - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node4->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node4->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1000)); // Confirm node 1 and 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler4 @@ -761,7 +761,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); // Confirm next report is scheduled on the max timestamp of readHandler1 and readhandler2 is not synced - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Node 2's sync timestamp should have remained unaffected since its min is higher NL_TEST_ASSERT(aSuite, node2->CanBeSynced() == false); @@ -775,7 +775,7 @@ class TestReportScheduler syncScheduler.OnSubscriptionReportSent(readHandler1); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler1)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node2->GetMinTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node2->GetMinTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1000)); NL_TEST_ASSERT(aSuite, node1->CanBeSynced() == true); @@ -786,7 +786,7 @@ class TestReportScheduler syncScheduler.OnSubscriptionReportSent(readHandler1); syncScheduler.OnSubscriptionReportSent(readHandler2); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); NL_TEST_ASSERT(aSuite, node2->CanBeSynced() == false); syncScheduler.UnregisterAllHandlers(); From b22a39645b72b26621467dd161209fc08c83fad6 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:23:20 +0900 Subject: [PATCH 18/83] [ICD] Skip Get RegistrationInfo when parameter is already added (#31123) * Skip Get RegistrationInfo when param is already added * Remove onICDRegistrationInfoRequired callback in chip-tool * Restyled by clang-format * Add comment * Restyled by whitespace --------- Co-authored-by: Restyled.io --- examples/chip-tool/commands/pairing/PairingCommand.cpp | 9 ++------- examples/chip-tool/commands/pairing/PairingCommand.h | 1 - src/controller/AutoCommissioner.cpp | 5 +++++ src/controller/DevicePairingDelegate.h | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index e15be0a1e8ae3c..e480b7a7c707c5 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -403,13 +403,6 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) SetCommandExitStatus(err); } -void PairingCommand::OnICDRegistrationInfoRequired() -{ - // Since we compute our ICD Registration info up front, we can call ICDRegistrationInfoReady() directly. - CurrentCommissioner().ICDRegistrationInfoReady(); - mDeviceIsICD = true; -} - void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) { char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; @@ -437,6 +430,8 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte return; } + mDeviceIsICD = true; + ChipLogProgress(chipTool, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId)); ChipLogProgress(chipTool, "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index be4722228a2bc8..145aa6ffd901ae 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -195,7 +195,6 @@ class PairingCommand : public CHIPCommand, void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; - void OnICDRegistrationInfoRequired() override; void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; /////////// DeviceDiscoveryDelegate Interface ///////// diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 1b286a400bccdb..5f289c662e696a 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -409,6 +409,11 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio case CommissioningStage::kConfigureTrustedTimeSource: if (mNeedIcdRegistration) { + if (mParams.GetICDCheckInNodeId().HasValue() && mParams.GetICDMonitoredSubject().HasValue() && + mParams.GetICDSymmetricKey().HasValue()) + { + return CommissioningStage::kICDRegistration; + } return CommissioningStage::kICDGetRegistrationInfo; } return GetNextCommissioningStageInternal(CommissioningStage::kICDSendStayActive, lastErr); diff --git a/src/controller/DevicePairingDelegate.h b/src/controller/DevicePairingDelegate.h index 31a906485fd904..6cf28d95892f79 100644 --- a/src/controller/DevicePairingDelegate.h +++ b/src/controller/DevicePairingDelegate.h @@ -125,7 +125,7 @@ class DLL_EXPORT DevicePairingDelegate * using CommissioningDelegate.SetCommissioningParameters(), and then call DeviceCommissioner.ICDRegistrationInfoReady() * in order to resume the commissioning process. * - * The implementation may set the credentials before start commissioning, and call ICDRegistrationInfoReady() directly. + * Not called if the ICD registration info is provided up front. */ virtual void OnICDRegistrationInfoRequired() {} From adafaf2b1eb28d980b12915e2af7b4e6e1ff2ea9 Mon Sep 17 00:00:00 2001 From: bhmanda-silabs <107180296+bhmanda-silabs@users.noreply.github.com> Date: Thu, 21 Dec 2023 21:22:22 +0530 Subject: [PATCH 19/83] [Silabs] - Support for 917 SoC combined OTA upgrade (#30335) * Added OTA support for 917 SoC platform * Added SIWX_917 macro for OTAConfig.cpp * Addressed review comments * Remove commented code * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Added fix for NotifyupdateApplied command and TA alone image upgrade reset issue * Modified config file as per slc_1.2 * Restyled by whitespace * Restyled by clang-format * Removed SLC file Specific changes --------- Co-authored-by: Restyled.io Co-authored-by: kirankha --- examples/platform/silabs/OTAConfig.cpp | 12 +- examples/platform/silabs/SiWx917/BUILD.gn | 9 +- .../silabs/SiWx917/SiWx917/sl_wifi_if.c | 10 ++ src/platform/silabs/OTAImageProcessorImpl.h | 1 + src/platform/silabs/SiWx917/BUILD.gn | 5 +- .../silabs/SiWx917/OTAImageProcessorImpl.cpp | 113 ++++++++++-------- third_party/silabs/SiWx917_sdk.gni | 10 ++ 7 files changed, 104 insertions(+), 56 deletions(-) diff --git a/examples/platform/silabs/OTAConfig.cpp b/examples/platform/silabs/OTAConfig.cpp index 91c84054220b9c..adc6f23abb4606 100644 --- a/examples/platform/silabs/OTAConfig.cpp +++ b/examples/platform/silabs/OTAConfig.cpp @@ -17,10 +17,18 @@ */ #include "OTAConfig.h" +#include + +#ifndef SIWX_917 #include "application_properties.h" -#include +#if defined(SL_COMPONENT_CATALOG_PRESENT) +#include "sl_component_catalog.h" +#endif + +// Only include app properties if the Gecko SDK component that does it automatically isn't present +#if !defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT) // Header used for building the image GBL file #define APP_PROPERTIES_VERSION 1 #define APP_PROPERTIES_ID \ @@ -65,6 +73,8 @@ __attribute__((used)) ApplicationProperties_t sl_app_properties = { /// Pointer to Long Token Data Section .longTokenSectionAddress = NULL, }; +#endif // SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT +#endif // SIWX_917 // Global OTA objects chip::DefaultOTARequestor gRequestorCore; diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 36a5aef1a860c1..99be69fbbc9b14 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -144,10 +144,9 @@ config("siwx917-common-config") { defines += [ "QR_CODE_ENABLED" ] } - # TODO: Renable once ota is supported - # if (chip_enable_ota_requestor) { - # defines += [ "SILABS_OTA_ENABLED" ] - # } + if (chip_enable_ota_requestor) { + defines += [ "SILABS_OTA_ENABLED" ] + } if (enable_heap_monitoring) { defines += [ "HEAP_MONITORING" ] @@ -229,7 +228,7 @@ source_set("siwx917-common") { } if (chip_enable_ota_requestor) { - # TODO: OTA For CCP Platform + sources += [ "${silabs_common_plat_dir}/OTAConfig.cpp" ] } if (!disable_lcd) { diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c index 27b677432b30d5..4c3df704dcae38 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c @@ -265,6 +265,16 @@ static sl_status_t wfx_rsi_init(void) return status; } #endif + + sl_wifi_version_string_t version = { 0 }; + status = sl_wifi_get_firmware_version(&version); + if (status != SL_STATUS_OK) + { + SILABS_LOG("Get fw version failed: %s", version.version); + return status; + } + SILABS_LOG("Get current fw version: %s", version.version); + status = sl_wifi_get_mac_address(SL_WIFI_CLIENT_INTERFACE, (sl_mac_address_t *) &wfx_rsi.sta_mac.octet[0]); if (status != SL_STATUS_OK) { diff --git a/src/platform/silabs/OTAImageProcessorImpl.h b/src/platform/silabs/OTAImageProcessorImpl.h index 30709bd7f32f3a..46b78b063f2172 100644 --- a/src/platform/silabs/OTAImageProcessorImpl.h +++ b/src/platform/silabs/OTAImageProcessorImpl.h @@ -75,6 +75,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4))); // Offset indicates how far the write buffer has been filled static uint16_t writeBufOffset; + static bool mReset; }; } // namespace chip diff --git a/src/platform/silabs/SiWx917/BUILD.gn b/src/platform/silabs/SiWx917/BUILD.gn index 039794e680e852..151c6e93bc5f40 100644 --- a/src/platform/silabs/SiWx917/BUILD.gn +++ b/src/platform/silabs/SiWx917/BUILD.gn @@ -66,11 +66,10 @@ static_library("SiWx917") { "PlatformManagerImpl.cpp", ] - # TODO: OTA on CCP platform if (chip_enable_ota_requestor) { sources += [ - #"OTAImageProcessorImpl.cpp", - #"${silabs_platform_dir}/OTAImageProcessorImpl.h", + "${silabs_platform_dir}/OTAImageProcessorImpl.h", + "OTAImageProcessorImpl.cpp", ] } diff --git a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp index 2cfcc9694267e9..075317fb9cb2f3 100644 --- a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp @@ -20,19 +20,30 @@ #include #include +#include + +#ifdef __cplusplus extern "C" { -#include "btl_interface.h" -#include "em_bus.h" // For CORE_CRITICAL_SECTION +#endif +#include "sl_si91x_driver.h" +#ifdef RSI_M4_INTERFACE +#include "sl_si91x_hal_soc_soft_reset.h" +#endif +#ifdef __cplusplus } +#endif -#include - +#define RPS_HEADER 1 +#define RPS_DATA 2 /// No error, operation OK #define SL_BOOTLOADER_OK 0L +#define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND +uint8_t flag = RPS_HEADER; namespace chip { // Define static memebers +bool OTAImageProcessorImpl::mReset = false; uint8_t OTAImageProcessorImpl::mSlotId = 0; uint32_t OTAImageProcessorImpl::mWriteOffset = 0; uint16_t OTAImageProcessorImpl::writeBufOffset = 0; @@ -129,7 +140,7 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload"); - CORE_CRITICAL_SECTION(bootloader_init();) + mReset = false; mSlotId = 0; // Single slot until we support multiple images writeBufOffset = 0; mWriteOffset = 0; @@ -139,39 +150,39 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) // Not calling bootloader_eraseStorageSlot(mSlotId) here because we erase during each write - imageProcessor->mDownloader->OnPreparedForDownload(err == SL_BOOTLOADER_OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL); + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); } void OTAImageProcessorImpl::HandleFinalize(intptr_t context) { uint32_t err = SL_BOOTLOADER_OK; + int32_t status = 0; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) { return; } - - // Pad the remainder of the write buffer with zeros and write it to bootloader storage if (writeBufOffset != 0) { // Account for last bytes of the image not yet written to storage imageProcessor->mParams.downloadedBytes += writeBufOffset; + status = sl_si91x_fwup_load(writeBuffer, writeBufOffset); + ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status); - while (writeBufOffset != kAlignmentBytes) - { - writeBuffer[writeBufOffset] = 0; - writeBufOffset++; - } - - CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);) - if (err) + if (status != SL_STATUS_OK) { - ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize bootloader_eraseWriteStorage() error %ld", err); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; + if (status == SL_STATUS_FW_UPDATE_DONE) + { + mReset = true; + } + else + { + ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } } } - imageProcessor->ReleaseBlock(); ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully"); @@ -186,28 +197,16 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) // Force KVS to store pending keys such as data from StoreCurrentUpdateInfo() chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().ForceKeyMapSave(); - CORE_CRITICAL_SECTION(err = bootloader_verifyImage(mSlotId, NULL);) - if (err != SL_BOOTLOADER_OK) - { - ChipLogError(SoftwareUpdate, "ERROR: bootloader_verifyImage() error %ld", err); - // Call the OTARequestor API to reset the state - GetRequestorInstance()->CancelImageUpdate(); + ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleApply"); - return; - } - - CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);) - if (err != SL_BOOTLOADER_OK) + if (mReset) { - ChipLogError(SoftwareUpdate, "ERROR: bootloader_setImageToBootload() error %ld", err); - // Call the OTARequestor API to reset the state - GetRequestorInstance()->CancelImageUpdate(); - - return; + ChipLogProgress(SoftwareUpdate, "M4 Firmware update complete"); + // send system reset request to reset the MCU and upgrade the m4 image + ChipLogProgress(SoftwareUpdate, "SoC Soft Reset initiated!"); + // Reboots the device + sl_si91x_soc_soft_reset(); } - - // This reboots the device - CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();) } void OTAImageProcessorImpl::HandleAbort(intptr_t context) @@ -225,6 +224,8 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) { uint32_t err = SL_BOOTLOADER_OK; + int32_t status = 0; + int32_t content_block = 0; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) { @@ -258,19 +259,37 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) if (writeBufOffset == kAlignmentBytes) { writeBufOffset = 0; - - CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);) - if (err) + if (flag == RPS_HEADER) { - ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock bootloader_eraseWriteStorage() error %ld", err); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; + // Send RPS header which is received as first chunk + status = sl_si91x_fwup_start(writeBuffer); + status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes); + flag = RPS_DATA; } - mWriteOffset += kAlignmentBytes; + else if (flag == RPS_DATA) + { + // Send RPS content + status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes); + if (status != SL_STATUS_OK) + { + // If the last chunk of last block-writeBufOffset length is exactly kAlignmentBytes(64) bytes then mReset value + // should be set to true in HandleProcessBlock + if (status == SL_STATUS_FW_UPDATE_DONE) + { + mReset = true; + } + else + { + ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + } + } + // ChipLogProgress(SoftwareUpdate, "HandleProcessBlock status: 0x%lX", status); imageProcessor->mParams.downloadedBytes += kAlignmentBytes; } } - imageProcessor->mDownloader->FetchNextData(); } diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 932ccebe79904c..b049d4b4b24073 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -130,6 +130,11 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/service/iostream/inc", "${wifi_sdk_root}/components/siwx917_soc/drivers/hardware_drivers/button/inc", + + # OTA + "${wifi_sdk_root}/components/si91x/sl_net/protocols/firmware_upgrade", + "${wifi_sdk_root}/components/siwx917_soc/hal/inc", + "${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/inc", ] if (silabs_board == "BRD4338A") { @@ -452,6 +457,11 @@ template("siwx917_sdk") { "${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509write_csr.c", "${sdk_support_root}/matter/si91x/siwx917/${sdk_support_board}/autogen/sl_si91x_button_instances.c", "${wifi_sdk_root}/components/siwx917_soc/drivers/hardware_drivers/button/src/sl_si91x_button.c", + + # OTA + "${wifi_sdk_root}/components/si91x/sl_net/protocols/firmware_upgrade/firmware_upgradation.c", + "${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/src/rsi_wwdt.c", + "${wifi_sdk_root}/components/siwx917_soc/hal/src/sl_si91x_hal_soc_soft_reset.c", ] # nvm3 ans startup From ca577f49474a985316df49e5c854536ea6b6b07c Mon Sep 17 00:00:00 2001 From: srningap <107042150+srningap@users.noreply.github.com> Date: Thu, 21 Dec 2023 21:33:10 +0530 Subject: [PATCH 20/83] [Silabs] Fix for wifi apps build issue (#31157) * Adds fix for wifi apps build failure * Restyled by whitespace --------- Co-authored-by: Restyled.io --- src/platform/silabs/CHIPDevicePlatformConfig.h | 2 ++ third_party/silabs/SiWx917_sdk.gni | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/CHIPDevicePlatformConfig.h b/src/platform/silabs/CHIPDevicePlatformConfig.h index 0ba1cecc6bef31..12aadb24400691 100644 --- a/src/platform/silabs/CHIPDevicePlatformConfig.h +++ b/src/platform/silabs/CHIPDevicePlatformConfig.h @@ -160,6 +160,7 @@ ICD Configuration Defines */ +#if SL_ICD_ENABLED #ifndef CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL #define CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL chip::System::Clock::Milliseconds32(SL_OT_IDLE_INTERVAL) #endif // CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL @@ -167,3 +168,4 @@ #ifndef CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL #define CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL chip::System::Clock::Milliseconds32(SL_OT_ACTIVE_INTERVAL) #endif // CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL +#endif // SL_ICD_ENABLED diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index b049d4b4b24073..bc8b8c23bf67ab 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -276,8 +276,12 @@ template("siwx917_sdk") { if (chip_enable_icd_server) { defines += [ - "SL_CATALOG_POWER_MANAGER_PRESENT", - "SL_CATALOG_SLEEPTIMER_PRESENT", + "WIFI_DEBUG_ENABLED=1", + "SL_ICD_ENABLED=1", + "SL_ACTIVE_MODE_THRESHOLD=${sl_active_mode_threshold_ms}", + "SL_ACTIVE_MODE_INTERVAL=${sl_active_mode_interval_ms}", + "SL_IDLE_MODE_INTERVAL=${sl_idle_mode_interval_s}", + "SL_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${sl_icd_supported_clients_per_fabric}", ] } From 3e8aeeb7d6cb58811b7ec5be57f576aef7855e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kr=C3=B3lik?= <66667989+Damian-Nordic@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:06:02 +0100 Subject: [PATCH 21/83] [app] Fix DeferredAttributePersister memory leak (#31075) * [app] Fix DeferredAttributePerister memory leak ScopedMemoryBuffer's Release() method was used instead of Free(). Add CHECK_RETURN_VALUE annotation to the Release() method to prevent from making such a mistake in the future. Signed-off-by: Damian Krolik * Code review --------- Signed-off-by: Damian Krolik --- .../DeferredAttributePersistenceProvider.cpp | 2 +- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 +-- src/lib/support/ScopedBuffer.h | 30 +++++++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/app/DeferredAttributePersistenceProvider.cpp b/src/app/DeferredAttributePersistenceProvider.cpp index 62d5c446fe2091..82652792806d5e 100644 --- a/src/app/DeferredAttributePersistenceProvider.cpp +++ b/src/app/DeferredAttributePersistenceProvider.cpp @@ -39,7 +39,7 @@ void DeferredAttribute::Flush(AttributePersistenceProvider & persister) { VerifyOrReturn(IsArmed()); persister.WriteValue(mPath, ByteSpan(mValue.Get(), mValue.AllocatedSize())); - mValue.Release(); + mValue.Free(); } CHIP_ERROR DeferredAttributePersistenceProvider::WriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index a4bcf3742c8d6e..09a8e07b0e34da 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1142,8 +1142,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // callback->AdoptReadClient(std::move(readClient)); callback.release(); - attributePathParamsList.Release(); - eventPathParamsList.Release(); + IgnoreUnusedVariable(attributePathParamsList.Release()); + IgnoreUnusedVariable(eventPathParamsList.Release()); return err; }); std::move(*bridge).DispatchAction(self); diff --git a/src/lib/support/ScopedBuffer.h b/src/lib/support/ScopedBuffer.h index 258b7f262935fb..7a3c0aaca5902c 100644 --- a/src/lib/support/ScopedBuffer.h +++ b/src/lib/support/ScopedBuffer.h @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include @@ -84,10 +85,11 @@ class ScopedMemoryBufferBase const void * Ptr() const { return mBuffer; } /** - * Releases the undelying buffer. Buffer stops being managed and will not be - * auto-freed. + * Releases the underlying buffer. + * + * The buffer stops being managed and will not be auto-freed. */ - void * Release() + CHECK_RETURN_VALUE void * Release() { void * buffer = mBuffer; mBuffer = nullptr; @@ -139,13 +141,18 @@ class ScopedMemoryBuffer : public Impl::ScopedMemoryBufferBase static_assert(std::is_trivially_destructible::value, "Destructors won't get run"); - inline T * Get() { return static_cast(Base::Ptr()); } - inline T & operator[](size_t index) { return Get()[index]; } + T * Get() { return static_cast(Base::Ptr()); } + T & operator[](size_t index) { return Get()[index]; } - inline const T * Get() const { return static_cast(Base::Ptr()); } - inline const T & operator[](size_t index) const { return Get()[index]; } + const T * Get() const { return static_cast(Base::Ptr()); } + const T & operator[](size_t index) const { return Get()[index]; } - inline T * Release() { return static_cast(Base::Release()); } + /** + * Releases the underlying buffer. + * + * The buffer stops being managed and will not be auto-freed. + */ + CHECK_RETURN_VALUE T * Release() { return static_cast(Base::Release()); } ScopedMemoryBuffer & Calloc(size_t elementCount) { @@ -222,7 +229,12 @@ class ScopedMemoryBufferWithSize : public ScopedMemoryBuffer ScopedMemoryBuffer::Free(); } - T * Release() + /** + * Releases the underlying buffer. + * + * The buffer stops being managed and will not be auto-freed. + */ + CHECK_RETURN_VALUE T * Release() { T * buffer = ScopedMemoryBuffer::Release(); mCount = 0; From 6d05eb62049ca18733e50fffa7ef90a513a9f295 Mon Sep 17 00:00:00 2001 From: Lazar Kovacic Date: Thu, 21 Dec 2023 20:19:40 +0100 Subject: [PATCH 22/83] TV Matter Media: Resolve items from Issue 30807 (#31108) * Update TV&TV casting app per issue 30807 * ZAP Regen Script * Remove unused GetNodeId method Add provisional labels Updated ContentAppObserver to pass test cases --- .../all-clusters-minimal-app.matter | 2 +- ...ootnode_basicvideoplayer_0ff86e943b.matter | 2 +- .../placeholder/linux/apps/app1/config.matter | 4 +- .../placeholder/linux/apps/app2/config.matter | 4 +- .../ContentAppObserver.cpp | 7 +- examples/tv-app/tv-common/tv-app.matter | 43 +-- examples/tv-app/tv-common/tv-app.zap | 332 +++++++----------- .../tv-casting-common/tv-casting-app.matter | 129 ++++++- .../tv-casting-common/tv-casting-app.zap | 269 +++++++++++++- .../account-login-server.cpp | 27 -- .../zcl/data-model/chip/channel-cluster.xml | 4 +- .../chip/content-app-observer-cluster.xml | 8 +- .../chip/media-playback-cluster.xml | 4 +- .../data_model/controller-clusters.matter | 8 +- .../chip/devicecontroller/ChipClusters.java | 30 +- .../devicecontroller/ClusterInfoMapping.java | 14 +- .../cluster/clusters/ChannelCluster.kt | 16 +- .../clusters/ContentAppObserverCluster.kt | 34 +- .../zap-generated/CHIPInvokeCallbacks.cpp | 240 +++++++++++-- .../python/chip/clusters/Objects.py | 16 +- .../zap-generated/MTRCommandPayloadsObjc.h | 8 +- .../zap-generated/MTRCommandPayloadsObjc.mm | 108 ++++-- .../zap-generated/cluster-objects.cpp | 6 +- .../zap-generated/cluster-objects.h | 20 +- .../cluster/logging/DataModelLogger.cpp | 2 +- 25 files changed, 940 insertions(+), 397 deletions(-) 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 1e2f06d1039962..95dddce935ea21 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 @@ -4502,7 +4502,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index 54d007ef366a95..9157827f8f1311 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -1370,7 +1370,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 8239122a760eb7..141c16cf46e6e3 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -6224,7 +6224,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -6398,7 +6398,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index 3ed94e2c150b82..da0c83939f94a1 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -6181,7 +6181,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -6355,7 +6355,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp index 0b5c949216ed55..a6010a54b0a0f5 100644 --- a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp @@ -43,9 +43,8 @@ void ContentAppObserverManager::HandleContentAppMessage(chip::app::CommandRespon ContentAppMessageResponse response; // TODO: Insert code here - // TODO: optional and mandatory are swapped - response.data = CharSpan::fromCharString("exampleData"); - response.encodingHint = CharSpan::fromCharString(encodingHintString.c_str()); - response.status = chip::MakeOptional(StatusEnum::kSuccess); + response.data = chip::MakeOptional(CharSpan::fromCharString("exampleData")); + response.encodingHint = chip::MakeOptional(CharSpan::fromCharString(encodingHintString.c_str())); + response.status = StatusEnum::kSuccess; helper.Success(response); } diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 13177041efa673..3f0d6b09e1f33b 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -2179,7 +2179,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -3048,9 +3048,9 @@ cluster ContentAppObserver = 1296 { } response struct ContentAppMessageResponse = 1 { - optional StatusEnum status = 0; - char_string data = 1; - char_string encodingHint = 2; + StatusEnum status = 0; + optional char_string data = 1; + optional char_string encodingHint = 2; } /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ @@ -3593,18 +3593,6 @@ endpoint 1 { handle command SetOnDemandRatingThreshold; handle command SetScheduledContentRatingThreshold; } - - server cluster ContentAppObserver { - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; - - handle command ContentAppMessage; - handle command ContentAppMessageResponse; - } } endpoint 2 { device type ma_speaker = 34, version 1; @@ -3660,6 +3648,7 @@ endpoint 2 { endpoint 3 { device type ma_contentapp = 36, version 1; + binding cluster ContentAppObserver; server cluster Descriptor { callback attribute deviceTypeList; @@ -3670,6 +3659,16 @@ endpoint 3 { callback attribute clusterRevision; } + server cluster Binding { + callback attribute binding; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster Channel { callback attribute channelList; callback attribute lineup; @@ -3825,18 +3824,6 @@ endpoint 3 { handle command SetOnDemandRatingThreshold; handle command SetScheduledContentRatingThreshold; } - - server cluster ContentAppObserver { - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; - - handle command ContentAppMessage; - handle command ContentAppMessageResponse; - } } diff --git a/examples/tv-app/tv-common/tv-app.zap b/examples/tv-app/tv-common/tv-app.zap index ee3c171287a754..d49bfd9717a7bf 100644 --- a/examples/tv-app/tv-common/tv-app.zap +++ b/examples/tv-app/tv-common/tv-app.zap @@ -17,6 +17,12 @@ } ], "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -24,12 +30,6 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" - }, - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" } ], "endpointTypes": [ @@ -6295,130 +6295,6 @@ "included": 1 } ] - }, - { - "name": "Content App Observer", - "code": 1296, - "mfgCode": null, - "define": "CONTENT_APP_OBSERVER_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ - { - "name": "ContentAppMessage", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ContentAppMessageResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - } - ] } ] }, @@ -7106,6 +6982,128 @@ } ] }, + { + "name": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Binding", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Channel", "code": 1284, @@ -8747,7 +8745,7 @@ "code": 1296, "mfgCode": null, "define": "CONTENT_APP_OBSERVER_CLUSTER", - "side": "server", + "side": "client", "enabled": 1, "commands": [ { @@ -8755,7 +8753,7 @@ "code": 0, "mfgCode": null, "source": "client", - "isIncoming": 1, + "isIncoming": 0, "isEnabled": 1 }, { @@ -8763,80 +8761,16 @@ "code": 1, "mfgCode": null, "source": "server", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 } ], "attributes": [ - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "FeatureMap", "code": 65532, "mfgCode": null, - "side": "server", + "side": "client", "type": "bitmap32", "included": 1, "storageOption": "RAM", @@ -8852,7 +8786,7 @@ "name": "ClusterRevision", "code": 65533, "mfgCode": null, - "side": "server", + "side": "client", "type": "int16u", "included": 1, "storageOption": "RAM", diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index a8ed90807d29ba..d6d5b3f023d6ef 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -1641,7 +1641,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -2405,6 +2405,120 @@ cluster AccountLogin = 1294 { fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } +/** This cluster is used for managing the content control (including "parental control") settings on a media device such as a TV, or Set-top Box. */ +cluster ContentControl = 1295 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kScreenTime = 0x1; + kPINManagement = 0x2; + kBlockUnrated = 0x3; + kOnDemandContentRating = 0x4; + kScheduledContentRating = 0x5; + } + + struct RatingNameStruct { + char_string ratingName = 0; + optional char_string ratingNameDesc = 1; + } + + info event RemainingScreenTimeExpired = 0 { + } + + readonly attribute boolean enabled = 0; + readonly attribute optional RatingNameStruct onDemandRatings[] = 1; + readonly attribute optional char_string<8> onDemandRatingThreshold = 2; + readonly attribute optional RatingNameStruct scheduledContentRatings[] = 3; + readonly attribute optional char_string<8> scheduledContentRatingThreshold = 4; + readonly attribute optional elapsed_s screenDailyTime = 5; + readonly attribute optional elapsed_s remainingScreenTime = 6; + readonly attribute boolean blockUnrated = 7; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct UpdatePINRequest { + optional char_string oldPIN = 0; + char_string newPIN = 1; + } + + response struct ResetPINResponse = 2 { + char_string PINCode = 0; + } + + request struct AddBonusTimeRequest { + optional char_string PINCode = 0; + optional elapsed_s bonusTime = 1; + } + + request struct SetScreenDailyTimeRequest { + elapsed_s screenTime = 0; + } + + request struct SetOnDemandRatingThresholdRequest { + char_string rating = 0; + } + + request struct SetScheduledContentRatingThresholdRequest { + char_string rating = 0; + } + + /** The purpose of this command is to update the PIN used for protecting configuration of the content control settings. Upon success, the old PIN SHALL no longer work. The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The PIN is composed of a numeric string of up to 6 human readable characters (displayable) . Upon receipt of this command, the media device SHALL check if the OldPIN field of this command is the same as the current PIN. If the PINs are the same, then the PIN code SHALL be set to NewPIN. Otherwise a response with InvalidPINCode error status SHALL be returned. The media device MAY provide a default PIN to the User via an out of band mechanism. For security reasons, it is recommended that a client encourage the user to update the PIN from its default value when performing configuration of the Content Control settings exposed by this cluster. The ResetPIN command can also be used to obtain the default PIN. */ + command UpdatePIN(UpdatePINRequest): DefaultSuccess = 0; + /** The purpose of this command is to reset the PIN. If this command is executed successfully, a ResetPINResponse command with a new PIN SHALL be returned. */ + command ResetPIN(): ResetPINResponse = 1; + /** The purpose of this command is to turn on the Content Control feature on a media device. On receipt of the Enable command, the media device SHALL set the Enabled attribute to TRUE. */ + command Enable(): DefaultSuccess = 3; + /** The purpose of this command is to turn off the Content Control feature on a media device. On receipt of the Disable command, the media device SHALL set the Enabled attribute to FALSE. */ + command Disable(): DefaultSuccess = 4; + /** The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. */ + command AddBonusTime(AddBonusTimeRequest): DefaultSuccess = 5; + /** The purpose of this command is to set the ScreenDailyTime attribute. On receipt of the SetScreenDailyTime command, the media device SHALL set the ScreenDailyTime attribute to the ScreenTime value. */ + command SetScreenDailyTime(SetScreenDailyTimeRequest): DefaultSuccess = 6; + /** The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the BlockUnratedContent command, the media device SHALL set the BlockUnrated attribute to TRUE. */ + command BlockUnratedContent(): DefaultSuccess = 7; + /** The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the UnblockUnratedContent command, the media device SHALL set the BlockUnrated attribute to FALSE. */ + command UnblockUnratedContent(): DefaultSuccess = 8; + /** The purpose of this command is to set the OnDemandRatingThreshold attribute. On receipt of the SetOnDemandRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the OnDemandRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. */ + command SetOnDemandRatingThreshold(SetOnDemandRatingThresholdRequest): DefaultSuccess = 9; + /** The purpose of this command is to set ScheduledContentRatingThreshold attribute. On receipt of the SetScheduledContentRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. */ + command SetScheduledContentRatingThreshold(SetScheduledContentRatingThresholdRequest): DefaultSuccess = 10; +} + +/** This cluster provides an interface for sending targeted commands to an Observer of a Content App on a Video Player device such as a Streaming Media Player, Smart TV or Smart Screen. The cluster server for Content App Observer is implemented by an endpoint that communicates with a Content App, such as a Casting Video Client. The cluster client for Content App Observer is implemented by a Content App endpoint. A Content App is informed of the NodeId of an Observer when a binding is set on the Content App. The Content App can then send the ContentAppMessage to the Observer (server cluster), and the Observer responds with a ContentAppMessageResponse. */ +cluster ContentAppObserver = 1296 { + revision 1; // NOTE: Default/not specifically set + + enum StatusEnum : enum8 { + kSuccess = 0; + kUnexpectedData = 1; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ContentAppMessageRequest { + optional char_string data = 0; + char_string encodingHint = 1; + } + + response struct ContentAppMessageResponse = 1 { + StatusEnum status = 0; + optional char_string data = 1; + optional char_string encodingHint = 2; + } + + /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ + command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -2660,6 +2774,7 @@ endpoint 1 { binding cluster ApplicationLauncher; binding cluster ApplicationBasic; binding cluster AccountLogin; + binding cluster ContentControl; server cluster Identify { ram attribute identifyTime default = 0x0000; @@ -2721,6 +2836,18 @@ endpoint 1 { ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } + + server cluster ContentAppObserver { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ContentAppMessage; + handle command ContentAppMessageResponse; + } } diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap index abe20a454df785..de57d237e94c1c 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap @@ -17,6 +17,12 @@ } ], "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -24,12 +30,6 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" - }, - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" } ], "endpointTypes": [ @@ -3141,6 +3141,7 @@ "define": "BINARY_INPUT_BASIC_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "deprecated", "attributes": [ { "name": "out of service", @@ -4395,6 +4396,262 @@ "reportableChange": 0 } ] + }, + { + "name": "Content Control", + "code": 1295, + "mfgCode": null, + "define": "CONTENT_CONTROL_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "UpdatePIN", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ResetPIN", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ResetPINResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Enable", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "Disable", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddBonusTime", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetScreenDailyTime", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "BlockUnratedContent", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UnblockUnratedContent", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetOnDemandRatingThreshold", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetScheduledContentRatingThreshold", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Content App Observer", + "code": 1296, + "mfgCode": null, + "define": "CONTENT_APP_OBSERVER_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ContentAppMessage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ContentAppMessageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] } ] } diff --git a/src/app/clusters/account-login-server/account-login-server.cpp b/src/app/clusters/account-login-server/account-login-server.cpp index b9727a9ad9561f..1ba2218a69f737 100644 --- a/src/app/clusters/account-login-server/account-login-server.cpp +++ b/src/app/clusters/account-login-server/account-login-server.cpp @@ -52,33 +52,6 @@ static constexpr size_t kAccountLoginDeletageTableSize = EMBER_AF_ACCOUNT_LOGIN_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; static_assert(kAccountLoginDeletageTableSize <= kEmberInvalidEndpointIndex, "AccountLogin Delegate table size error"); -NodeId getNodeId(const chip::app::CommandHandler * commandObj) -{ - // TODO: Why are we doing all these checks? At all the callsites we have - // just received a command, so we better have a handler, exchange, session, - // etc. The only thing we should be checking is that it's a CASE session. - if (nullptr == commandObj || nullptr == commandObj->GetExchangeContext()) - { - ChipLogError(Zcl, "Cannot access ExchangeContext of Command Object for Node ID"); - return kUndefinedNodeId; - } - - if (!commandObj->GetExchangeContext()->HasSessionHandle()) - { - ChipLogError(Zcl, "Cannot access session of Command Object for Node ID"); - return kUndefinedNodeId; - } - - auto descriptor = commandObj->GetExchangeContext()->GetSessionHandle()->GetSubjectDescriptor(); - if (descriptor.authMode != Access::AuthMode::kCase) - { - ChipLogError(Zcl, "Cannot get Node ID from non-CASE session of Command Object"); - return kUndefinedNodeId; - } - - return descriptor.subject; -} - // ----------------------------------------------------------------------------- // Delegate Implementation diff --git a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml index 5dc01df19f65f5..c5731ef9cd3a5f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml @@ -61,9 +61,9 @@ limitations under the License. - + This command is a response to the GetProgramGuide command. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml index 89d72eb768e519..c4fb56ecef7077 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml @@ -31,11 +31,11 @@ limitations under the License. - + This command SHALL be generated in response to ContentAppMessage command. - - - + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml index 1d9b56dc9a1385..76c80819b279c2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml @@ -34,9 +34,9 @@ limitations under the License. SeekRangeEnd SeekRangeStart ActiveAudioTrack - AvailableAudioTracks + AvailableAudioTracks ActiveTextTrack - AvailableTextTracks + AvailableTextTracks diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 1d0fcc7ec86b61..b78cbfa007eca0 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -7313,7 +7313,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -8182,9 +8182,9 @@ cluster ContentAppObserver = 1296 { } response struct ContentAppMessageResponse = 1 { - optional StatusEnum status = 0; - char_string data = 1; - char_string encodingHint = 2; + StatusEnum status = 0; + optional char_string data = 1; + optional char_string encodingHint = 2; } /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 201229af2f710c..d9b1143464b577 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -48973,15 +48973,15 @@ public void getProgramGuide(ProgramGuideResponseCallback callback, Optional programList = null; for (StructElement element: invokeStructValue.value()) { - if (element.contextTagNum() == channelPagingStructFieldID) { - if (element.value(BaseTLVType.class).type() == TLVType.Int) { - IntType castingValue = element.value(IntType.class); - channelPagingStruct = castingValue.value(Integer.class); + if (element.contextTagNum() == pagingFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + paging = ChipStructs.ChannelClusterChannelPagingStruct.decodeTlv(castingValue); } } else if (element.contextTagNum() == programListFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.Array) { @@ -48990,7 +48990,7 @@ public void onResponse(StructType invokeStructValue) { } } } - callback.onSuccess(channelPagingStruct, programList); + callback.onSuccess(paging, programList); }}, commandId, value, timedInvokeTimeoutMs); } @@ -49063,7 +49063,7 @@ public interface ChangeChannelResponseCallback extends BaseClusterCallback { } public interface ProgramGuideResponseCallback extends BaseClusterCallback { - void onSuccess(Integer channelPagingStruct, ArrayList programList); + void onSuccess(ChipStructs.ChannelClusterChannelPagingStruct paging, ArrayList programList); } public interface ChannelListAttributeCallback extends BaseAttributeCallback { @@ -53614,26 +53614,26 @@ public void contentAppMessage(ContentAppMessageResponseCallback callback, Option @Override public void onResponse(StructType invokeStructValue) { final long statusFieldID = 0L; - Optional status = Optional.empty(); + Integer status = null; final long dataFieldID = 1L; - String data = null; + Optional data = Optional.empty(); final long encodingHintFieldID = 2L; - String encodingHint = null; + Optional encodingHint = Optional.empty(); for (StructElement element: invokeStructValue.value()) { if (element.contextTagNum() == statusFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - status = Optional.of(castingValue.value(Integer.class)); + status = castingValue.value(Integer.class); } } else if (element.contextTagNum() == dataFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.String) { StringType castingValue = element.value(StringType.class); - data = castingValue.value(String.class); + data = Optional.of(castingValue.value(String.class)); } } else if (element.contextTagNum() == encodingHintFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.String) { StringType castingValue = element.value(StringType.class); - encodingHint = castingValue.value(String.class); + encodingHint = Optional.of(castingValue.value(String.class)); } } } @@ -53642,7 +53642,7 @@ public void onResponse(StructType invokeStructValue) { } public interface ContentAppMessageResponseCallback extends BaseClusterCallback { - void onSuccess(Optional status, String data, String encodingHint); + void onSuccess(Integer status, Optional data, Optional encodingHint); } public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 6860b30cff08ad..187400cba467b4 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -16126,11 +16126,11 @@ public void setCallbackDelegate(ClusterCommandCallback callback) { } @Override - public void onSuccess(Integer channelPagingStruct, ArrayList programList) { + public void onSuccess(ChipStructs.ChannelClusterChannelPagingStruct paging, ArrayList programList) { Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo channelPagingStructResponseValue = new CommandResponseInfo("channelPagingStruct", "Integer"); - responseValues.put(channelPagingStructResponseValue, channelPagingStruct); + // paging: Struct ChannelPagingStruct + // Conversion from this type to Java is not properly implemented yet // programList: ProgramStruct // Conversion from this type to Java is not properly implemented yet @@ -17783,14 +17783,14 @@ public void setCallbackDelegate(ClusterCommandCallback callback) { } @Override - public void onSuccess(Optional status, String data, String encodingHint) { + public void onSuccess(Integer status, Optional data, Optional encodingHint) { Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Optional"); + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); responseValues.put(statusResponseValue, status); - CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "String"); + CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "Optional"); responseValues.put(dataResponseValue, data); - CommandResponseInfo encodingHintResponseValue = new CommandResponseInfo("encodingHint", "String"); + CommandResponseInfo encodingHintResponseValue = new CommandResponseInfo("encodingHint", "Optional"); responseValues.put(encodingHintResponseValue, encodingHint); callback.onSuccess(responseValues); } diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt index 7825944363b1aa..653f118fc66440 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt @@ -43,7 +43,7 @@ class ChannelCluster(private val controller: MatterController, private val endpo class ChangeChannelResponse(val status: UByte, val data: String?) class ProgramGuideResponse( - val channelPagingStruct: Short, + val paging: ChannelClusterChannelPagingStruct, val programList: List ) @@ -294,8 +294,8 @@ class ChannelCluster(private val controller: MatterController, private val endpo val tlvReader = TlvReader(response.payload) tlvReader.enterStructure(AnonymousTag) - val TAG_CHANNEL_PAGING_STRUCT: Int = 0 - var channelPagingStruct_decoded: Short? = null + val TAG_PAGING: Int = 0 + var paging_decoded: ChannelClusterChannelPagingStruct? = null val TAG_PROGRAM_LIST: Int = 1 var programList_decoded: List? = null @@ -303,8 +303,8 @@ class ChannelCluster(private val controller: MatterController, private val endpo while (!tlvReader.isEndOfContainer()) { val tag = tlvReader.peekElement().tag - if (tag == ContextSpecificTag(TAG_CHANNEL_PAGING_STRUCT)) { - channelPagingStruct_decoded = tlvReader.getShort(tag) + if (tag == ContextSpecificTag(TAG_PAGING)) { + paging_decoded = ChannelClusterChannelPagingStruct.fromTlv(tag, tlvReader) } if (tag == ContextSpecificTag(TAG_PROGRAM_LIST)) { @@ -321,8 +321,8 @@ class ChannelCluster(private val controller: MatterController, private val endpo } } - if (channelPagingStruct_decoded == null) { - throw IllegalStateException("channelPagingStruct not found in TLV") + if (paging_decoded == null) { + throw IllegalStateException("paging not found in TLV") } if (programList_decoded == null) { @@ -331,7 +331,7 @@ class ChannelCluster(private val controller: MatterController, private val endpo tlvReader.exitContainer() - return ProgramGuideResponse(channelPagingStruct_decoded, programList_decoded) + return ProgramGuideResponse(paging_decoded, programList_decoded) } suspend fun recordProgram( diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt index 68ca2fa84898cb..4c08eb6499a918 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt @@ -43,7 +43,7 @@ class ContentAppObserverCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ContentAppMessageResponse(val status: UByte?, val data: String, val encodingHint: String) + class ContentAppMessageResponse(val status: UByte, val data: String?, val encodingHint: String?) class GeneratedCommandListAttribute(val value: List) @@ -127,36 +127,42 @@ class ContentAppObserverCluster( val tag = tlvReader.peekElement().tag if (tag == ContextSpecificTag(TAG_STATUS)) { - status_decoded = + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = if (tlvReader.isNull()) { tlvReader.getNull(tag) null } else { if (tlvReader.isNextTag(tag)) { - tlvReader.getUByte(tag) + tlvReader.getString(tag) } else { null } } } - if (tag == ContextSpecificTag(TAG_DATA)) { - data_decoded = tlvReader.getString(tag) - } - if (tag == ContextSpecificTag(TAG_ENCODING_HINT)) { - encodingHint_decoded = tlvReader.getString(tag) + encodingHint_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } } else { tlvReader.skipElement() } } - if (data_decoded == null) { - throw IllegalStateException("data not found in TLV") - } - - if (encodingHint_decoded == null) { - throw IllegalStateException("encodingHint not found in TLV") + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } tlvReader.exitContainer() diff --git a/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp b/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp index 2b5fa3ff8429ea..097ba520f805e3 100644 --- a/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp +++ b/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp @@ -5093,17 +5093,200 @@ void CHIPChannelClusterProgramGuideResponseCallback::CallbackFn( // Java callback is allowed to be null, exit early if this is the case. VerifyOrReturn(javaCallbackRef != nullptr); - err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/ArrayList;)V", - &javaMethod); + err = JniReferences::GetInstance().FindMethod( + env, javaCallbackRef, "onSuccess", + "(Lchip/devicecontroller/ChipStructs$ChannelClusterChannelPagingStruct;Ljava/util/ArrayList;)V", &javaMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err))); - jobject ChannelPagingStruct; - std::string ChannelPagingStructClassName = "java/lang/Integer"; - std::string ChannelPagingStructCtorSignature = "(I)V"; - jint jniChannelPagingStruct = static_cast(dataResponse.channelPagingStruct); - chip::JniReferences::GetInstance().CreateBoxedObject(ChannelPagingStructClassName.c_str(), - ChannelPagingStructCtorSignature.c_str(), jniChannelPagingStruct, - ChannelPagingStruct); + jobject Paging; + jobject Paging_previousToken; + if (!dataResponse.paging.previousToken.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousToken); + } + else + { + jobject Paging_previousTokenInsideOptional; + if (dataResponse.paging.previousToken.Value().IsNull()) + { + Paging_previousTokenInsideOptional = nullptr; + } + else + { + jobject Paging_previousTokenInsideOptional_limit; + if (!dataResponse.paging.previousToken.Value().Value().limit.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousTokenInsideOptional_limit); + } + else + { + jobject Paging_previousTokenInsideOptional_limitInsideOptional; + std::string Paging_previousTokenInsideOptional_limitInsideOptionalClassName = "java/lang/Integer"; + std::string Paging_previousTokenInsideOptional_limitInsideOptionalCtorSignature = "(I)V"; + jint jniPaging_previousTokenInsideOptional_limitInsideOptional = + static_cast(dataResponse.paging.previousToken.Value().Value().limit.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + Paging_previousTokenInsideOptional_limitInsideOptionalClassName.c_str(), + Paging_previousTokenInsideOptional_limitInsideOptionalCtorSignature.c_str(), + jniPaging_previousTokenInsideOptional_limitInsideOptional, + Paging_previousTokenInsideOptional_limitInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional_limitInsideOptional, + Paging_previousTokenInsideOptional_limit); + } + jobject Paging_previousTokenInsideOptional_after; + if (!dataResponse.paging.previousToken.Value().Value().after.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousTokenInsideOptional_after); + } + else + { + jobject Paging_previousTokenInsideOptional_afterInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF( + dataResponse.paging.previousToken.Value().Value().after.Value(), + Paging_previousTokenInsideOptional_afterInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional_afterInsideOptional, + Paging_previousTokenInsideOptional_after); + } + jobject Paging_previousTokenInsideOptional_before; + if (!dataResponse.paging.previousToken.Value().Value().before.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousTokenInsideOptional_before); + } + else + { + jobject Paging_previousTokenInsideOptional_beforeInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF( + dataResponse.paging.previousToken.Value().Value().before.Value(), + Paging_previousTokenInsideOptional_beforeInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional_beforeInsideOptional, + Paging_previousTokenInsideOptional_before); + } + + jclass pageTokenStructStructClass_3; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$ChannelClusterPageTokenStruct", pageTokenStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterPageTokenStruct"); + return; + } + jmethodID pageTokenStructStructCtor_3 = env->GetMethodID( + pageTokenStructStructClass_3, "", "(Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V"); + if (pageTokenStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterPageTokenStruct constructor"); + return; + } + + Paging_previousTokenInsideOptional = + env->NewObject(pageTokenStructStructClass_3, pageTokenStructStructCtor_3, Paging_previousTokenInsideOptional_limit, + Paging_previousTokenInsideOptional_after, Paging_previousTokenInsideOptional_before); + } + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional, Paging_previousToken); + } + jobject Paging_nextToken; + if (!dataResponse.paging.nextToken.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextToken); + } + else + { + jobject Paging_nextTokenInsideOptional; + if (dataResponse.paging.nextToken.Value().IsNull()) + { + Paging_nextTokenInsideOptional = nullptr; + } + else + { + jobject Paging_nextTokenInsideOptional_limit; + if (!dataResponse.paging.nextToken.Value().Value().limit.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextTokenInsideOptional_limit); + } + else + { + jobject Paging_nextTokenInsideOptional_limitInsideOptional; + std::string Paging_nextTokenInsideOptional_limitInsideOptionalClassName = "java/lang/Integer"; + std::string Paging_nextTokenInsideOptional_limitInsideOptionalCtorSignature = "(I)V"; + jint jniPaging_nextTokenInsideOptional_limitInsideOptional = + static_cast(dataResponse.paging.nextToken.Value().Value().limit.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + Paging_nextTokenInsideOptional_limitInsideOptionalClassName.c_str(), + Paging_nextTokenInsideOptional_limitInsideOptionalCtorSignature.c_str(), + jniPaging_nextTokenInsideOptional_limitInsideOptional, Paging_nextTokenInsideOptional_limitInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional_limitInsideOptional, + Paging_nextTokenInsideOptional_limit); + } + jobject Paging_nextTokenInsideOptional_after; + if (!dataResponse.paging.nextToken.Value().Value().after.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextTokenInsideOptional_after); + } + else + { + jobject Paging_nextTokenInsideOptional_afterInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.paging.nextToken.Value().Value().after.Value(), + Paging_nextTokenInsideOptional_afterInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional_afterInsideOptional, + Paging_nextTokenInsideOptional_after); + } + jobject Paging_nextTokenInsideOptional_before; + if (!dataResponse.paging.nextToken.Value().Value().before.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextTokenInsideOptional_before); + } + else + { + jobject Paging_nextTokenInsideOptional_beforeInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.paging.nextToken.Value().Value().before.Value(), + Paging_nextTokenInsideOptional_beforeInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional_beforeInsideOptional, + Paging_nextTokenInsideOptional_before); + } + + jclass pageTokenStructStructClass_3; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$ChannelClusterPageTokenStruct", pageTokenStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterPageTokenStruct"); + return; + } + jmethodID pageTokenStructStructCtor_3 = env->GetMethodID( + pageTokenStructStructClass_3, "", "(Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V"); + if (pageTokenStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterPageTokenStruct constructor"); + return; + } + + Paging_nextTokenInsideOptional = + env->NewObject(pageTokenStructStructClass_3, pageTokenStructStructCtor_3, Paging_nextTokenInsideOptional_limit, + Paging_nextTokenInsideOptional_after, Paging_nextTokenInsideOptional_before); + } + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional, Paging_nextToken); + } + + jclass channelPagingStructStructClass_0; + err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$ChannelClusterChannelPagingStruct", + channelPagingStructStructClass_0); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterChannelPagingStruct"); + return; + } + jmethodID channelPagingStructStructCtor_0 = + env->GetMethodID(channelPagingStructStructClass_0, "", "(Ljava/util/Optional;Ljava/util/Optional;)V"); + if (channelPagingStructStructCtor_0 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterChannelPagingStruct constructor"); + return; + } + + Paging = + env->NewObject(channelPagingStructStructClass_0, channelPagingStructStructCtor_0, Paging_previousToken, Paging_nextToken); jobject ProgramList; chip::JniReferences::GetInstance().CreateArrayList(ProgramList); @@ -5591,7 +5774,7 @@ void CHIPChannelClusterProgramGuideResponseCallback::CallbackFn( chip::JniReferences::GetInstance().AddToList(ProgramList, newElement_0); } - env->CallVoidMethod(javaCallbackRef, javaMethod, ChannelPagingStruct, ProgramList); + env->CallVoidMethod(javaCallbackRef, javaMethod, Paging, ProgramList); } CHIPTargetNavigatorClusterNavigateTargetResponseCallback::CHIPTargetNavigatorClusterNavigateTargetResponseCallback( jobject javaCallback) : Callback::Callback(CallbackFn, this) @@ -6112,29 +6295,38 @@ void CHIPContentAppObserverClusterContentAppMessageResponseCallback::CallbackFn( VerifyOrReturn(javaCallbackRef != nullptr); err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", - "(Ljava/util/Optional;Ljava/lang/String;Ljava/lang/String;)V", &javaMethod); + "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;)V", &javaMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err))); jobject Status; - if (!dataResponse.status.HasValue()) + std::string StatusClassName = "java/lang/Integer"; + std::string StatusCtorSignature = "(I)V"; + jint jniStatus = static_cast(dataResponse.status); + chip::JniReferences::GetInstance().CreateBoxedObject(StatusClassName.c_str(), StatusCtorSignature.c_str(), jniStatus, + Status); + jobject Data; + if (!dataResponse.data.HasValue()) { - chip::JniReferences::GetInstance().CreateOptional(nullptr, Status); + chip::JniReferences::GetInstance().CreateOptional(nullptr, Data); } else { - jobject StatusInsideOptional; - std::string StatusInsideOptionalClassName = "java/lang/Integer"; - std::string StatusInsideOptionalCtorSignature = "(I)V"; - jint jniStatusInsideOptional = static_cast(dataResponse.status.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(StatusInsideOptionalClassName.c_str(), - StatusInsideOptionalCtorSignature.c_str(), - jniStatusInsideOptional, StatusInsideOptional); - chip::JniReferences::GetInstance().CreateOptional(StatusInsideOptional, Status); + jobject DataInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data.Value(), DataInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data); } - jobject Data; - LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data, Data)); jobject EncodingHint; - LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.encodingHint, EncodingHint)); + if (!dataResponse.encodingHint.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, EncodingHint); + } + else + { + jobject EncodingHintInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.encodingHint.Value(), EncodingHintInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(EncodingHintInsideOptional, EncodingHint); + } env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data, EncodingHint); } diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index c5ca57c4ac6653..c5874b2aaec964 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -38338,11 +38338,11 @@ class ProgramGuideResponse(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="channelPagingStruct", Tag=0, Type=int), + ClusterObjectFieldDescriptor(Label="paging", Tag=0, Type=Channel.Structs.ChannelPagingStruct), ClusterObjectFieldDescriptor(Label="programList", Tag=1, Type=typing.List[Channel.Structs.ProgramStruct]), ]) - channelPagingStruct: 'int' = 0 + paging: 'Channel.Structs.ChannelPagingStruct' = field(default_factory=lambda: Channel.Structs.ChannelPagingStruct()) programList: 'typing.List[Channel.Structs.ProgramStruct]' = field(default_factory=lambda: []) @dataclass @@ -42079,14 +42079,14 @@ class ContentAppMessageResponse(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=typing.Optional[ContentAppObserver.Enums.StatusEnum]), - ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=str), - ClusterObjectFieldDescriptor(Label="encodingHint", Tag=2, Type=str), + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ContentAppObserver.Enums.StatusEnum), + ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="encodingHint", Tag=2, Type=typing.Optional[str]), ]) - status: 'typing.Optional[ContentAppObserver.Enums.StatusEnum]' = None - data: 'str' = "" - encodingHint: 'str' = "" + status: 'ContentAppObserver.Enums.StatusEnum' = 0 + data: 'typing.Optional[str]' = None + encodingHint: 'typing.Optional[str]' = None class Attributes: @dataclass diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index a59c89efbeacd1..b504710419a283 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -8564,7 +8564,7 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRChannelClusterProgramGuideResponseParams : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull channelPagingStruct MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) MTRChannelClusterChannelPagingStruct * _Nonnull paging MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSArray * _Nonnull programList MTR_PROVISIONALLY_AVAILABLE; @@ -10201,11 +10201,11 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRContentAppObserverClusterContentAppMessageResponseParams : NSObject -@property (nonatomic, copy) NSNumber * _Nullable status MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSString * _Nonnull data MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable data MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSString * _Nonnull encodingHint MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable encodingHint MTR_PROVISIONALLY_AVAILABLE; /** * Initialize an MTRContentAppObserverClusterContentAppMessageResponseParams with a response-value dictionary diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index b82bb7872fbb24..35c71e8afd4c3f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -23857,7 +23857,7 @@ - (instancetype)init { if (self = [super init]) { - _channelPagingStruct = @(0); + _paging = [MTRChannelClusterChannelPagingStruct new]; _programList = [NSArray array]; } @@ -23868,7 +23868,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; { auto other = [[MTRChannelClusterProgramGuideResponseParams alloc] init]; - other.channelPagingStruct = self.channelPagingStruct; + other.paging = self.paging; other.programList = self.programList; return other; @@ -23876,7 +23876,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: channelPagingStruct:%@; programList:%@; >", NSStringFromClass([self class]), _channelPagingStruct, _programList]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: paging:%@; programList:%@; >", NSStringFromClass([self class]), _paging, _programList]; return descriptionString; } @@ -23927,7 +23927,71 @@ @implementation MTRChannelClusterProgramGuideResponseParams (InternalMethods) - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::Channel::Commands::ProgramGuideResponse::DecodableType &)decodableStruct { { - self.channelPagingStruct = [NSNumber numberWithShort:decodableStruct.channelPagingStruct]; + self.paging = [MTRChannelClusterChannelPagingStruct new]; + if (decodableStruct.paging.previousToken.HasValue()) { + if (decodableStruct.paging.previousToken.Value().IsNull()) { + self.paging.previousToken = nil; + } else { + self.paging.previousToken = [MTRChannelClusterPageTokenStruct new]; + if (decodableStruct.paging.previousToken.Value().Value().limit.HasValue()) { + self.paging.previousToken.limit = [NSNumber numberWithUnsignedShort:decodableStruct.paging.previousToken.Value().Value().limit.Value()]; + } else { + self.paging.previousToken.limit = nil; + } + if (decodableStruct.paging.previousToken.Value().Value().after.HasValue()) { + self.paging.previousToken.after = AsString(decodableStruct.paging.previousToken.Value().Value().after.Value()); + if (self.paging.previousToken.after == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.previousToken.after = nil; + } + if (decodableStruct.paging.previousToken.Value().Value().before.HasValue()) { + self.paging.previousToken.before = AsString(decodableStruct.paging.previousToken.Value().Value().before.Value()); + if (self.paging.previousToken.before == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.previousToken.before = nil; + } + } + } else { + self.paging.previousToken = nil; + } + if (decodableStruct.paging.nextToken.HasValue()) { + if (decodableStruct.paging.nextToken.Value().IsNull()) { + self.paging.nextToken = nil; + } else { + self.paging.nextToken = [MTRChannelClusterPageTokenStruct new]; + if (decodableStruct.paging.nextToken.Value().Value().limit.HasValue()) { + self.paging.nextToken.limit = [NSNumber numberWithUnsignedShort:decodableStruct.paging.nextToken.Value().Value().limit.Value()]; + } else { + self.paging.nextToken.limit = nil; + } + if (decodableStruct.paging.nextToken.Value().Value().after.HasValue()) { + self.paging.nextToken.after = AsString(decodableStruct.paging.nextToken.Value().Value().after.Value()); + if (self.paging.nextToken.after == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.nextToken.after = nil; + } + if (decodableStruct.paging.nextToken.Value().Value().before.HasValue()) { + self.paging.nextToken.before = AsString(decodableStruct.paging.nextToken.Value().Value().before.Value()); + if (self.paging.nextToken.before == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.nextToken.before = nil; + } + } + } else { + self.paging.nextToken = nil; + } } { { // Scope for our temporary variables @@ -28702,11 +28766,11 @@ - (instancetype)init { if (self = [super init]) { - _status = nil; + _status = @(0); - _data = @""; + _data = nil; - _encodingHint = @""; + _encodingHint = nil; } return self; } @@ -28775,24 +28839,28 @@ @implementation MTRContentAppObserverClusterContentAppMessageResponseParams (Int - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::DecodableType &)decodableStruct { { - if (decodableStruct.status.HasValue()) { - self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status.Value())]; - } else { - self.status = nil; - } + self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status)]; } { - self.data = AsString(decodableStruct.data); - if (self.data == nil) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - return err; + if (decodableStruct.data.HasValue()) { + self.data = AsString(decodableStruct.data.Value()); + if (self.data == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.data = nil; } } { - self.encodingHint = AsString(decodableStruct.encodingHint); - if (self.encodingHint == nil) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - return err; + if (decodableStruct.encodingHint.HasValue()) { + self.encodingHint = AsString(decodableStruct.encodingHint.Value()); + if (self.encodingHint == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.encodingHint = nil; } } return CHIP_NO_ERROR; 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 770ec90ad04adb..7d25bcce933bb4 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 @@ -22108,7 +22108,7 @@ namespace ProgramGuideResponse { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kChannelPagingStruct), channelPagingStruct); + encoder.Encode(to_underlying(Fields::kPaging), paging); encoder.Encode(to_underlying(Fields::kProgramList), programList); return encoder.Finalize(); } @@ -22127,9 +22127,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kChannelPagingStruct)) + if (__context_tag == to_underlying(Fields::kPaging)) { - err = DataModel::Decode(reader, channelPagingStruct); + err = DataModel::Decode(reader, paging); } else if (__context_tag == to_underlying(Fields::kProgramList)) { 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 703f14128611ae..c292a11f999cd8 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 @@ -33376,8 +33376,8 @@ struct DecodableType namespace ProgramGuideResponse { enum class Fields : uint8_t { - kChannelPagingStruct = 0, - kProgramList = 1, + kPaging = 0, + kProgramList = 1, }; struct Type @@ -33387,7 +33387,7 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::ProgramGuideResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::Channel::Id; } - int16_t channelPagingStruct = static_cast(0); + Structs::ChannelPagingStruct::Type paging; DataModel::List programList; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -33403,7 +33403,7 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::ProgramGuideResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::Channel::Id; } - int16_t channelPagingStruct = static_cast(0); + Structs::ChannelPagingStruct::DecodableType paging; DataModel::DecodableList programList; CHIP_ERROR Decode(TLV::TLVReader & reader); }; @@ -37276,9 +37276,9 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::ContentAppMessageResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ContentAppObserver::Id; } - Optional status; - chip::CharSpan data; - chip::CharSpan encodingHint; + StatusEnum status = static_cast(0); + Optional data; + Optional encodingHint; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -37293,9 +37293,9 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::ContentAppMessageResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ContentAppObserver::Id; } - Optional status; - chip::CharSpan data; - chip::CharSpan encodingHint; + StatusEnum status = static_cast(0); + Optional data; + Optional encodingHint; CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace ContentAppMessageResponse 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 e0e24074789701..6089c40e02e3fd 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -7064,7 +7064,7 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const Channel::Commands::ProgramGuideResponse::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); - ReturnErrorOnFailure(DataModelLogger::LogValue("channelPagingStruct", indent + 1, value.channelPagingStruct)); + ReturnErrorOnFailure(DataModelLogger::LogValue("paging", indent + 1, value.paging)); ReturnErrorOnFailure(DataModelLogger::LogValue("programList", indent + 1, value.programList)); DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; From 52f66e146765cb3f75d6a801a891afa70ab2537a Mon Sep 17 00:00:00 2001 From: Song GUO Date: Fri, 22 Dec 2023 04:43:19 +0800 Subject: [PATCH 23/83] [icd] read UserActiveModeTrigger during commissioning (#31039) * [icd] read UserActiveModeTrigger during commissioning * Update CommissionerMain.cpp fix typo --------- Co-authored-by: yunhanw-google --- .../commands/pairing/PairingCommand.cpp | 25 +++++++ .../commands/pairing/PairingCommand.h | 1 + examples/platform/linux/CommissionerMain.cpp | 23 +++++- src/controller/AutoCommissioner.cpp | 2 +- src/controller/CHIPDeviceController.cpp | 71 ++++++++++++++++--- src/controller/CommissioningDelegate.h | 23 +++++- 6 files changed, 133 insertions(+), 12 deletions(-) diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index e480b7a7c707c5..27edae038eb3a7 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -403,6 +403,31 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) SetCommandExitStatus(err); } +void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioningInfo & info) +{ + ChipLogProgress(AppServer, "OnReadCommissioningInfo - vendorId=0x%04X productId=0x%04X", info.basic.vendorId, + info.basic.productId); + + // The string in CharSpan received from the device is not null-terminated, we use std::string here for coping and + // appending a numm-terminator at the end of the string. + std::string userActiveModeTriggerInstruction; + + // Note: the callback doesn't own the buffer, should make a copy if it will be used it later. + if (info.icd.userActiveModeTriggerInstruction.size() != 0) + { + userActiveModeTriggerInstruction = + std::string(info.icd.userActiveModeTriggerInstruction.data(), info.icd.userActiveModeTriggerInstruction.size()); + } + + if (info.icd.userActiveModeTriggerHint.HasAny()) + { + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerHint=0x%08x", + info.icd.userActiveModeTriggerHint.Raw()); + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerInstruction=%s", + userActiveModeTriggerInstruction.c_str()); + } +} + void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) { char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 145aa6ffd901ae..c1df17282022b1 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -194,6 +194,7 @@ class PairingCommand : public CHIPCommand, void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override; void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; + void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; diff --git a/examples/platform/linux/CommissionerMain.cpp b/examples/platform/linux/CommissionerMain.cpp index 2b3f98ba5868b2..beaf915cf559c3 100644 --- a/examples/platform/linux/CommissionerMain.cpp +++ b/examples/platform/linux/CommissionerMain.cpp @@ -19,6 +19,8 @@ #include #include +#include + #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE #include @@ -342,10 +344,29 @@ void PairingCommand::OnCommissioningStatusUpdate(PeerId peerId, CommissioningSta } } -void PairingCommand::OnReadCommissioningInfo(const ReadCommissioningInfo & info) +void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioningInfo & info) { ChipLogProgress(AppServer, "OnReadCommissioningInfo - vendorId=0x%04X productId=0x%04X", info.basic.vendorId, info.basic.productId); + + // The string in CharSpan received from the device is not null-terminated, we use std::string here for coping and + // appending a numm-terminator at the end of the string. + std::string userActiveModeTriggerInstruction; + + // Note: the callback doesn't own the buffer, should make a copy if it will be used it later. + if (info.icd.userActiveModeTriggerInstruction.size() != 0) + { + userActiveModeTriggerInstruction = + std::string(info.icd.userActiveModeTriggerInstruction.data(), info.icd.userActiveModeTriggerInstruction.size()); + } + + if (info.icd.userActiveModeTriggerHint.HasAny()) + { + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerHint=0x%08x", + info.icd.userActiveModeTriggerHint.Raw()); + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerInstruction=%s", + userActiveModeTriggerInstruction.c_str()); + } } void PairingCommand::OnFabricCheck(NodeId matchingNodeId) diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 5f289c662e696a..69a9c9b9c6bbf3 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -764,7 +764,7 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore) { - if (commissioningInfo.isLIT && commissioningInfo.checkInProtocolSupport) + if (commissioningInfo.icd.isLIT && commissioningInfo.icd.checkInProtocolSupport) { mNeedIcdRegistration = true; ChipLogDetail(Controller, "AutoCommissioner: ICD supports the check-in protocol."); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index e69546161e661e..99cd69a5284bc7 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1950,7 +1950,13 @@ void DeviceCommissioner::ParseCommissioningInfo() err = ParseCommissioningInfo2(info); } - mAttributeCache = nullptr; + // Move ownership of mAttributeCache to the stack, but don't release it until this function returns. + // This way we don't have to make a copy while parsing commissioning info, and it won't + // affect future commissioning steps. + // + // The stack reference needs to survive until CommissioningStageComplete and OnReadCommissioningInfo + // return. + auto attributeCache = std::move(mAttributeCache); if (mPairingDelegate != nullptr) { @@ -2265,21 +2271,24 @@ CHIP_ERROR DeviceCommissioner::ParseFabrics(ReadCommissioningInfo & info) CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info) { + using chip::app::Clusters::IcdManagement::UserActiveModeTriggerBitmap; + CHIP_ERROR err; IcdManagement::Attributes::FeatureMap::TypeInfo::DecodableType featureMap; + bool hasUserActiveModeTrigger = false; err = mAttributeCache->Get(kRootEndpointId, featureMap); if (err == CHIP_NO_ERROR) { - info.isLIT = true; - info.checkInProtocolSupport = !!(featureMap & to_underlying(IcdManagement::Feature::kCheckInProtocolSupport)); + info.icd.isLIT = !!(featureMap & to_underlying(IcdManagement::Feature::kLongIdleTimeSupport)); + info.icd.checkInProtocolSupport = !!(featureMap & to_underlying(IcdManagement::Feature::kCheckInProtocolSupport)); + hasUserActiveModeTrigger = !!(featureMap & to_underlying(IcdManagement::Feature::kUserActiveModeTrigger)); } else if (err == CHIP_ERROR_KEY_NOT_FOUND) { // This key is optional so not an error - err = CHIP_NO_ERROR; - info.isLIT = false; - err = CHIP_NO_ERROR; + info.icd.isLIT = false; + err = CHIP_NO_ERROR; } else if (err == CHIP_ERROR_IM_STATUS_CODE_RECEIVED) { @@ -2290,7 +2299,7 @@ CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info) { if (statusIB.mStatus == Protocols::InteractionModel::Status::UnsupportedCluster) { - info.isLIT = false; + info.icd.isLIT = false; } else { @@ -2299,6 +2308,45 @@ CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info) } } + ReturnErrorOnFailure(err); + + info.icd.userActiveModeTriggerHint.ClearAll(); + info.icd.userActiveModeTriggerInstruction = CharSpan(); + if (hasUserActiveModeTrigger) + { + // Intentionally ignore errors since they are not mandatory. + bool activeModeTriggerInstructionRequired = false; + + err = mAttributeCache->Get( + kRootEndpointId, info.icd.userActiveModeTriggerHint); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "IcdManagement.UserActiveModeTriggerHint expected, but failed to read."); + return err; + } + + activeModeTriggerInstructionRequired = info.icd.userActiveModeTriggerHint.HasAny( + UserActiveModeTriggerBitmap::kCustomInstruction, UserActiveModeTriggerBitmap::kActuateSensorSeconds, + UserActiveModeTriggerBitmap::kActuateSensorTimes, UserActiveModeTriggerBitmap::kActuateSensorLightsBlink, + UserActiveModeTriggerBitmap::kResetButtonLightsBlink, UserActiveModeTriggerBitmap::kResetButtonSeconds, + UserActiveModeTriggerBitmap::kResetButtonTimes, UserActiveModeTriggerBitmap::kSetupButtonSeconds, + UserActiveModeTriggerBitmap::kSetupButtonTimes, UserActiveModeTriggerBitmap::kSetupButtonTimes, + UserActiveModeTriggerBitmap::kAppDefinedButton); + + if (activeModeTriggerInstructionRequired) + { + err = mAttributeCache->Get( + kRootEndpointId, info.icd.userActiveModeTriggerInstruction); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, + "IcdManagement.UserActiveModeTriggerInstruction expected for given active mode trigger hint, but " + "failed to read."); + return err; + } + } + } + return err; } @@ -2565,7 +2613,9 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio // This is done in a separate step since we've already used up all the available read paths in the previous read step // NOTE: this array cannot have more than 9 entries, since the spec mandates that server only needs to support 9 // See R1.1, 2.11.2 Interaction Model Limits - app::AttributePathParams readPaths[3]; + + // Currently, we have at most 5 attributes to read in this stage. + app::AttributePathParams readPaths[5]; // Mandatory attribute readPaths[numberOfAttributes++] = @@ -2584,6 +2634,11 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio readPaths[numberOfAttributes++] = app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::FeatureMap::Id); } + // Always read the active mode trigger hint attributes to notify users about it. + readPaths[numberOfAttributes++] = + app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::UserActiveModeTriggerHint::Id); + readPaths[numberOfAttributes++] = + app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::UserActiveModeTriggerInstruction::Id); SendCommissioningReadRequest(proxy, timeout, readPaths, numberOfAttributes); } diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 67fe2e69878dfb..175c246e908f9d 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -679,6 +679,26 @@ struct GeneralCommissioningInfo ; }; +// ICDManagementClusterInfo is populated when the controller reads information from +// the ICD Management cluster, and is used to communicate that information. +struct ICDManagementClusterInfo +{ + // Whether the ICD is capable of functioning as a LIT device. If false, the ICD can only be a SIT device. + bool isLIT; + // Whether the ICD supports the check-in protocol. LIT devices have to support it, but SIT devices + // might or might not. + bool checkInProtocolSupport; + + // userActiveModeTriggerHint indicates which user action(s) will trigger the ICD to switch to Active mode. + // For a LIT: The device is required to provide a value for the bitmap. + // For a SIT: The device may not provide a value. In that case, none of the bits will be set. + // + // userActiveModeTriggerInstruction may provide additional information for users for some specific + // userActiveModeTriggerHint values. + BitMask userActiveModeTriggerHint; + CharSpan userActiveModeTriggerInstruction; +}; + struct ReadCommissioningInfo { NetworkClusters network; @@ -691,9 +711,8 @@ struct ReadCommissioningInfo uint8_t maxTimeZoneSize = 1; uint8_t maxDSTSize = 1; NodeId remoteNodeId = kUndefinedNodeId; - bool isLIT = false; - bool checkInProtocolSupport = false; bool supportsConcurrentConnection = true; + ICDManagementClusterInfo icd; }; struct TimeZoneResponseInfo From ab58186f11c00f9df117f5905bfd47750fa9ae2d Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 21 Dec 2023 21:01:56 -0500 Subject: [PATCH 24/83] Restore Darwin APIs that went missing. (#31163) We were inconsistent about our checks for the "allowed to not have params" case: some places used "command has no fields" as the check, and some used "command has only optional fields". This caused some APIs (for invoking commands with no params) to disappear when commands that used to have no fields got optional fields added to them. The fix: 1. Fixes the checks to consistently be "command has only optional fields" so the no-params APIs continue to exist for the commands that had optional fields added to them. 2. Fixes availability annotations for pre-existing commands with only optional fields so that we will not claim the no-params API is available before it was actually available, by basically listing all such commands in config-data.yaml. 3. Avoids generating deprecated overloads for the thins listed in item 2. 4. Moves the Darwin-only bits from the config-data.yaml in src/app into the Darwin version we are adding, and starts using that config file. --- src/app/common/templates/config-data.yaml | 7 -- .../CHIP/templates/MTRBaseClusters-src.zapt | 8 +- .../CHIP/templates/MTRBaseClusters.zapt | 15 +++- .../CHIP/templates/MTRClusters-src.zapt | 8 +- .../Framework/CHIP/templates/MTRClusters.zapt | 15 +++- .../Framework/CHIP/templates/config-data.yaml | 20 +++++ .../Framework/CHIP/templates/templates.json | 2 +- .../CHIP/zap-generated/MTRBaseClusters.h | 44 ++++++++++ .../CHIP/zap-generated/MTRBaseClusters.mm | 88 +++++++++++++++++++ .../CHIP/zap-generated/MTRClusters.h | 39 ++++++++ .../CHIP/zap-generated/MTRClusters.mm | 88 +++++++++++++++++++ 11 files changed, 318 insertions(+), 16 deletions(-) create mode 100644 src/darwin/Framework/CHIP/templates/config-data.yaml diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 577e04ab04a856..5586614c6d7186 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -1,10 +1,3 @@ -DarwinForceWritable: - # Work-around for not allowing changes from writable to read-only - # happened in https://github.com/project-chip/connectedhomeip/pull/30134 - - ApplicationLauncher::CurrentApp - - ContentLauncher::SupportedStreamingProtocols - - FanControl::FanModeSequence - EnumsNotUsedAsTypeInXML: # List of enums that are not used as a type in XML. By adding an enum # to this list you prevent incorrectly assuming from code that you are diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt index fb303d5589d2be..42b20c0c6cb0ef 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt @@ -63,7 +63,7 @@ MTR{{compatClusterNameRemapping parent.name}}Cluster{{compatCommandNameRemapping MTR{{cluster}}Cluster{{command}}Params {{/unless}} {{/inline}} -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithCompletion:({{>command_completion_type command=.}})completion { [self {{asLowerCamelCase name}}WithParams:nil completion:completion]; @@ -246,7 +246,10 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value {{/if}} ]; } -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} @@ -256,6 +259,7 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value } {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandImpl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt index edd4f05e4a27b4..affc28304b89c8 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt @@ -30,15 +30,21 @@ NS_ASSUME_NONNULL_BEGIN * {{description}} */ - (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="First major API revamp"}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithCompletion:({{>command_completion_type command=.}})completion {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#if (and (isStrEqual command "KeySetReadAllIndices") (isStrEqual cluster "GroupKeyManagement"))}} {{availability cluster command=command minimalRelease="Fall 2023"}}; {{else}} +{{#if (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} +{{availability cluster command=command minimalRelease="Future"}}; {{! TODO: Use the right thing here when we know what it's called }} +{{else}} {{availability cluster command=command minimalRelease="First major API revamp"}}; {{/if}} +{{/if}} {{/unless}} {{/if}} {{/inline}} @@ -217,7 +223,11 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:completion:")}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{! No need for these backwards-compat APIs for commands that never shipped them. }} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} @@ -225,6 +235,7 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithCompletion:")}}; {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandDecl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt index 9cefaa1a510b13..41027b72fa8cc2 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt @@ -44,7 +44,7 @@ MTR{{compatClusterNameRemapping parent.name}}Cluster{{compatCommandNameRemapping MTR{{cluster}}Cluster{{command}}Params {{/unless}} {{/inline}} -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion { [self {{asLowerCamelCase name}}WithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; @@ -171,7 +171,10 @@ MTR{{cluster}}Cluster{{command}}Params {{/if}} ]; } -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} @@ -181,6 +184,7 @@ MTR{{cluster}}Cluster{{command}}Params } {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandImpl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt index c089804986d154..85ef7ad74a6ed4 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt @@ -25,15 +25,21 @@ NS_ASSUME_NONNULL_BEGIN {{#*inline "commandDecl"}} {{#if (isSupported cluster command=command)}} - (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="First major API revamp"}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#if (and (isStrEqual command "KeySetReadAllIndices") (isStrEqual cluster "GroupKeyManagement"))}} {{availability cluster command=command minimalRelease="Fall 2023"}}; {{else}} +{{#if (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} +{{availability cluster command=command minimalRelease="Future"}}; {{! TODO: Use the right thing here when we know what it's called }} +{{else}} {{availability cluster command=command minimalRelease="First major API revamp"}}; {{/if}} +{{/if}} {{/unless}} {{/if}} {{/inline}} @@ -113,13 +119,18 @@ NS_ASSUME_NONNULL_BEGIN {{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command) (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:expectedValues:expectedValueInterval:completion:")}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{! No need for these backwards-compat APIs for commands that never shipped them. }} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} - (void){{asLowerCamelCase command}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithExpectedValues:expectedValueInterval:completion:")}}; {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandDecl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/config-data.yaml b/src/darwin/Framework/CHIP/templates/config-data.yaml new file mode 100644 index 00000000000000..575ce0ffc4b91d --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/config-data.yaml @@ -0,0 +1,20 @@ +DarwinForceWritable: + # Work-around for not allowing changes from writable to read-only + # happened in https://github.com/project-chip/connectedhomeip/pull/30134 + - ApplicationLauncher::CurrentApp + - ContentLauncher::SupportedStreamingProtocols + - FanControl::FanModeSequence + +# A list of commands that used to have only optional arguments before we started +# generating the no-params-needed variants of methods for that case. These +# declarations need to have availability based on when we started generating +# those variants, not the command's own availability. +LegacyCommandsWithOnlyOptionalArguments: + - NetworkCommissioning::ScanNetworks + - DoorLock::LockDoor + - DoorLock::UnlockDoor + - ApplicationLauncher::LaunchApp + - ApplicationLauncher::StopApp + - ApplicationLauncher::HideApp + - UnitTesting::TestNullableOptionalRequest + - UnitTesting::TestSimpleOptionalArgumentRequest diff --git a/src/darwin/Framework/CHIP/templates/templates.json b/src/darwin/Framework/CHIP/templates/templates.json index 83b001285cfcf2..59a06b83c2fd99 100644 --- a/src/darwin/Framework/CHIP/templates/templates.json +++ b/src/darwin/Framework/CHIP/templates/templates.json @@ -12,7 +12,7 @@ ], "resources": { "availability-data": "availability.yaml", - "config-data": "../../../../app/common/templates/config-data.yaml" + "config-data": "config-data.yaml" }, "override": "../../../../../src/app/zap-templates/common/override.js", "partials": [ diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 9526a2cd3230c4..046e4442fa8725 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -2481,6 +2481,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Detemine the set of networks the device sees as available. */ - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)scanNetworksWithCompletion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command AddOrUpdateWiFiNetwork * @@ -5750,6 +5752,8 @@ MTR_PROVISIONALLY_AVAILABLE * Set Temperature */ - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setTemperatureWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeTemperatureSetpointWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeTemperatureSetpointWithParams:(MTRSubscribeParams *)params @@ -6418,6 +6422,8 @@ MTR_PROVISIONALLY_AVAILABLE * Set Cooking Parameters */ - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setCookingParametersWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command AddMoreTime * @@ -7122,6 +7128,8 @@ MTR_PROVISIONALLY_AVAILABLE * This command is used to set the valve to its open position. */ - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)openWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command Close * @@ -8010,12 +8018,16 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * This command causes the lock device to lock the door. */ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)lockDoorWithCompletion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; /** * Command UnlockDoor * * This command causes the lock device to unlock the door. */ - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)unlockDoorWithCompletion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; /** * Command UnlockWithTimeout * @@ -8118,6 +8130,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * This command causes the lock device to unlock the door without pulling the latch. */ - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)unboltDoorWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeLockStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeLockStateWithParams:(MTRSubscribeParams *)params @@ -12364,6 +12378,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getProgramGuideWithCompletion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command RecordProgram * @@ -12590,12 +12606,16 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)rewindWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Command FastForward * * Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)fastForwardWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Command SkipForward * @@ -13182,18 +13202,24 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Upon receipt, this SHALL launch the specified app with optional data. The TV Device SHALL launch and bring to foreground the identified application in the command if the application is not already launched and in foreground. The TV Device SHALL update state attribute on the Application Basic cluster of the Endpoint corresponding to the launched application. This command returns a Launch Response. */ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)launchAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command StopApp * * Upon receipt on a Video Player endpoint this SHALL stop the specified application if it is running. */ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)stopAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command HideApp * * Upon receipt on a Video Player endpoint this SHALL hide the specified application if it is running and visible. */ - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)hideAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)readAttributeCatalogListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeCatalogListWithParams:(MTRSubscribeParams *)params @@ -13397,6 +13423,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)logoutWithCompletion:(MTRStatusCompletion)completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (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 @@ -13495,6 +13523,8 @@ MTR_PROVISIONALLY_AVAILABLE * The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. */ - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)addBonusTimeWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command SetScreenDailyTime * @@ -14688,6 +14718,8 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) if that' false the argument it received. */ - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testNullableOptionalRequestWithCompletion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command TestComplexNullableOptionalRequest * @@ -14718,6 +14750,8 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * Command that takes an optional argument which is bool. It responds with a success value if the optional is set to any value. */ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testSimpleOptionalArgumentRequestWithCompletion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; /** * Command TestEmitTestEventRequest * @@ -25949,8 +25983,12 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use nextWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use rewindWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)rewindWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler + MTR_DEPRECATED("Please use rewindWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use fastForwardWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)fastForwardWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler + MTR_DEPRECATED("Please use fastForwardWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use skipForwardWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler @@ -26511,6 +26549,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use loginWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use logoutWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)logoutWithCompletionHandler:(MTRStatusCompletion)completionHandler + MTR_DEPRECATED("Please use logoutWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use readAttributeGeneratedCommandListWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval maxInterval:(NSNumber * _Nonnull)maxInterval @@ -27557,6 +27597,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use testEnumsRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testNullableOptionalRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testNullableOptionalRequestWithCompletionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler + MTR_DEPRECATED("Please use testNullableOptionalRequestWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testComplexNullableOptionalRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)simpleStructEchoRequestWithParams:(MTRTestClusterClusterSimpleStructEchoRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error))completionHandler @@ -27567,6 +27609,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use timedInvokeRequestWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testSimpleOptionalArgumentRequestWithCompletionHandler:(MTRStatusCompletion)completionHandler + MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEmitTestEventRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index ff63771e70e0f4..19b00a2c799aaa 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -20065,6 +20065,10 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterNetworkCommissioning +- (void)scanNetworksWithCompletion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self scanNetworksWithParams:nil completion:completion]; +} - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -43591,6 +43595,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterTemperatureControl +- (void)setTemperatureWithCompletion:(MTRStatusCompletion)completion +{ + [self setTemperatureWithParams:nil completion:completion]; +} - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -46541,6 +46549,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterMicrowaveOvenControl +- (void)setCookingParametersWithCompletion:(MTRStatusCompletion)completion +{ + [self setCookingParametersWithParams:nil completion:completion]; +} - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -49669,6 +49681,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterValveConfigurationAndControl +- (void)openWithCompletion:(MTRStatusCompletion)completion +{ + [self openWithParams:nil completion:completion]; +} - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -53968,6 +53984,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterDoorLock +- (void)lockDoorWithCompletion:(MTRStatusCompletion)completion +{ + [self lockDoorWithParams:nil completion:completion]; +} - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -53995,6 +54015,10 @@ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params queue:self.callbackQueue completion:responseHandler]; } +- (void)unlockDoorWithCompletion:(MTRStatusCompletion)completion +{ + [self unlockDoorWithParams:nil completion:completion]; +} - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -54421,6 +54445,10 @@ - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)par queue:self.callbackQueue completion:responseHandler]; } +- (void)unboltDoorWithCompletion:(MTRStatusCompletion)completion +{ + [self unboltDoorWithParams:nil completion:completion]; +} - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -90354,6 +90382,10 @@ - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params compl queue:self.callbackQueue completion:responseHandler]; } +- (void)getProgramGuideWithCompletion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getProgramGuideWithParams:nil completion:completion]; +} - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -91815,6 +91847,10 @@ - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params com queue:self.callbackQueue completion:responseHandler]; } +- (void)rewindWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self rewindWithParams:nil completion:completion]; +} - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -91839,6 +91875,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params queue:self.callbackQueue completion:responseHandler]; } +- (void)fastForwardWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self fastForwardWithParams:nil completion:completion]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -92708,6 +92748,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completionHandler(static_cast(data), error); }]; } +- (void)rewindWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self rewindWithParams:nil completionHandler:completionHandler]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self fastForwardWithParams:params completion: @@ -92716,6 +92760,10 @@ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nulla completionHandler(static_cast(data), error); }]; } +- (void)fastForwardWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self fastForwardWithParams:nil completionHandler:completionHandler]; +} - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self skipForwardWithParams:params completion: @@ -95997,6 +96045,10 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterApplicationLauncher +- (void)launchAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self launchAppWithParams:nil completion:completion]; +} - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -96021,6 +96073,10 @@ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nul queue:self.callbackQueue completion:responseHandler]; } +- (void)stopAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self stopAppWithParams:nil completion:completion]; +} - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -96045,6 +96101,10 @@ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullabl queue:self.callbackQueue completion:responseHandler]; } +- (void)hideAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self hideAppWithParams:nil completion:completion]; +} - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -97717,6 +97777,10 @@ - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params completion:( queue:self.callbackQueue completion:responseHandler]; } +- (void)logoutWithCompletion:(MTRStatusCompletion)completion +{ + [self logoutWithParams:nil completion:completion]; +} - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -97983,6 +98047,10 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params [self logoutWithParams:params completion: completionHandler]; } +- (void)logoutWithCompletionHandler:(MTRStatusCompletion)completionHandler +{ + [self logoutWithParams:nil completionHandler:completionHandler]; +} - (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler { @@ -98278,6 +98346,10 @@ - (void)disableWithParams:(MTRContentControlClusterDisableParams * _Nullable)par queue:self.callbackQueue completion:responseHandler]; } +- (void)addBonusTimeWithCompletion:(MTRStatusCompletion)completion +{ + [self addBonusTimeWithParams:nil completion:completion]; +} - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -109410,6 +109482,10 @@ - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams queue:self.callbackQueue completion:responseHandler]; } +- (void)testNullableOptionalRequestWithCompletion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self testNullableOptionalRequestWithParams:nil completion:completion]; +} - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -109513,6 +109589,10 @@ - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestPar queue:self.callbackQueue completion:responseHandler]; } +- (void)testSimpleOptionalArgumentRequestWithCompletion:(MTRStatusCompletion)completion +{ + [self testSimpleOptionalArgumentRequestWithParams:nil completion:completion]; +} - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -115711,6 +115791,10 @@ - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullable completionHandler(static_cast(data), error); }]; } +- (void)testNullableOptionalRequestWithCompletionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self testNullableOptionalRequestWithParams:nil completionHandler:completionHandler]; +} - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testComplexNullableOptionalRequestWithParams:params completion: @@ -115741,6 +115825,10 @@ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSi [self testSimpleOptionalArgumentRequestWithParams:params completion: completionHandler]; } +- (void)testSimpleOptionalArgumentRequestWithCompletionHandler:(MTRStatusCompletion)completionHandler +{ + [self testSimpleOptionalArgumentRequestWithParams:nil completionHandler:completionHandler]; +} - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testEmitTestEventRequestWithParams:params completion: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 912cb7f36a1bc4..d9b141845086a7 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -1186,6 +1186,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterNetworkCommissioning : MTRGenericCluster - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)scanNetworksWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateWiFiNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateThreadNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -2704,6 +2706,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterTemperatureControl : MTRGenericCluster - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setTemperatureWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeTemperatureSetpointWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3039,6 +3043,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterMicrowaveOvenControl : MTRGenericCluster - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setCookingParametersWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)addMoreTimeWithParams:(MTRMicrowaveOvenControlClusterAddMoreTimeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeCookTimeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3375,6 +3381,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterValveConfigurationAndControl : MTRGenericCluster - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)openWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)closeWithParams:(MTRValveConfigurationAndControlClusterCloseParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)closeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; @@ -3768,7 +3776,11 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterDoorLock : MTRGenericCluster - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)lockDoorWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)unlockDoorWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; - (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -3786,6 +3798,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)unboltDoorWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeLockStateWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5713,6 +5727,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getProgramGuideWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; - (void)recordProgramWithParams:(MTRChannelClusterRecordProgramParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)cancelRecordProgramWithParams:(MTRChannelClusterCancelRecordProgramParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; @@ -5819,7 +5835,11 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)nextWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)rewindWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)fastForwardWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -6103,8 +6123,14 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterApplicationLauncher : MTRGenericCluster - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)launchAppWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)stopAppWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)hideAppWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeCatalogListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6203,6 +6229,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)logoutWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6251,6 +6279,8 @@ MTR_PROVISIONALLY_AVAILABLE - (void)disableWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)addBonusTimeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)setScreenDailyTimeWithParams:(MTRContentControlClusterSetScreenDailyTimeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)blockUnratedContentWithParams:(MTRContentControlClusterBlockUnratedContentParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)blockUnratedContentWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion @@ -6688,12 +6718,16 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)testListInt8UReverseRequestWithParams:(MTRUnitTestingClusterTestListInt8UReverseRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestListInt8UReverseResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestEnumsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)testComplexNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestComplexNullableOptionalRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)simpleStructEchoRequestWithParams:(MTRUnitTestingClusterSimpleStructEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)timedInvokeRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; - (void)testEmitTestEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7750,7 +7784,9 @@ MTR_DEPRECATED("Please use MTRClusterUnitTesting", ios(16.1, 16.4), macos(13.0, - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use nextWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)nextWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use nextWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use rewindWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)rewindWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use rewindWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use fastForwardWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)fastForwardWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use fastForwardWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use skipForwardWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use skipBackwardWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use seekWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @@ -7837,6 +7873,7 @@ MTR_DEPRECATED("Please use MTRClusterUnitTesting", ios(16.1, 16.4), macos(13.0, - (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use getSetupPINWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use loginWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use logoutWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)logoutWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use logoutWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @end @interface MTRClusterElectricalMeasurement (Deprecated) @@ -7876,11 +7913,13 @@ MTR_DEPRECATED("Please use MTRClusterUnitTesting", ios(16.1, 16.4), macos(13.0, - (void)testListInt8UReverseRequestWithParams:(MTRTestClusterClusterTestListInt8UReverseRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestListInt8UReverseResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testListInt8UReverseRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEnumsRequestWithParams:(MTRTestClusterClusterTestEnumsRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEnumsResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEnumsRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testNullableOptionalRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testNullableOptionalRequestWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testComplexNullableOptionalRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)simpleStructEchoRequestWithParams:(MTRTestClusterClusterSimpleStructEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use simpleStructEchoRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)timedInvokeRequestWithParams:(MTRTestClusterClusterTimedInvokeRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use timedInvokeRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)timedInvokeRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use timedInvokeRequestWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEmitTestEventRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEmitTestFabricScopedEventRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index d319e14799a619..0ab55d5776856e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -3737,6 +3737,10 @@ - (void)commissioningCompleteWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self scanNetworksWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -7674,6 +7678,10 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD @implementation MTRClusterTemperatureControl +- (void)setTemperatureWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self setTemperatureWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -8249,6 +8257,10 @@ @implementation MTRClusterMicrowaveOvenMode @implementation MTRClusterMicrowaveOvenControl +- (void)setCookingParametersWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self setCookingParametersWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -9089,6 +9101,10 @@ - (void)writeAttributeCurrentSensitivityLevelWithValue:(NSDictionary *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self openWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -10308,6 +10324,10 @@ - (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self lockDoorWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -10338,6 +10358,10 @@ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:responseHandler]; } +- (void)unlockDoorWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self unlockDoorWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -10815,6 +10839,10 @@ - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)par completion:responseHandler]; } +- (void)unboltDoorWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self unboltDoorWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -16139,6 +16167,10 @@ - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params expec completion:responseHandler]; } +- (void)getProgramGuideWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getProgramGuideWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -16570,6 +16602,10 @@ - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params exp completion:responseHandler]; } +- (void)rewindWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self rewindWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -16597,6 +16633,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completion:responseHandler]; } +- (void)fastForwardWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self fastForwardWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -16964,6 +17004,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completionHandler(static_cast(data), error); }]; } +- (void)rewindWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self rewindWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self fastForwardWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: @@ -16972,6 +17016,10 @@ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nulla completionHandler(static_cast(data), error); }]; } +- (void)fastForwardWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self fastForwardWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self skipForwardWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: @@ -17609,6 +17657,10 @@ - (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params @implementation MTRClusterApplicationLauncher +- (void)launchAppWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self launchAppWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -17636,6 +17688,10 @@ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nul completion:responseHandler]; } +- (void)stopAppWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self stopAppWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -17663,6 +17719,10 @@ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullabl completion:responseHandler]; } +- (void)hideAppWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self hideAppWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -17921,6 +17981,10 @@ - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValu completion:responseHandler]; } +- (void)logoutWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self logoutWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -18008,6 +18072,10 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params [self logoutWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: completionHandler]; } +- (void)logoutWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler +{ + [self logoutWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} @end @implementation MTRClusterContentControl @@ -18132,6 +18200,10 @@ - (void)disableWithParams:(MTRContentControlClusterDisableParams * _Nullable)par completion:responseHandler]; } +- (void)addBonusTimeWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self addBonusTimeWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -19701,6 +19773,10 @@ - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams completion:responseHandler]; } +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self testNullableOptionalRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -19816,6 +19892,10 @@ - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestPar completion:responseHandler]; } +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self testSimpleOptionalArgumentRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -21388,6 +21468,10 @@ - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullable completionHandler(static_cast(data), error); }]; } +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self testNullableOptionalRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testComplexNullableOptionalRequestWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: @@ -21418,6 +21502,10 @@ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSi [self testSimpleOptionalArgumentRequestWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: completionHandler]; } +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler +{ + [self testSimpleOptionalArgumentRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testEmitTestEventRequestWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: From d0d95d319016b07b6b0cd80742ac28b7593fc51a Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 21 Dec 2023 22:02:48 -0500 Subject: [PATCH 25/83] MTRSetupPayload initWithSetupPasscode should not produce invalid payloads. (#31132) It's using a long discriminator, so has to have discovery capabilities available. Fixes https://github.com/project-chip/connectedhomeip/issues/31129 --- src/darwin/Framework/CHIP/MTRSetupPayload.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRSetupPayload.mm b/src/darwin/Framework/CHIP/MTRSetupPayload.mm index adfeb7cd3a9ac4..d7b08c7c0a44a4 100644 --- a/src/darwin/Framework/CHIP/MTRSetupPayload.mm +++ b/src/darwin/Framework/CHIP/MTRSetupPayload.mm @@ -139,7 +139,10 @@ - (instancetype)initWithSetupPasscode:(NSNumber *)setupPasscode discriminator:(N _vendorID = @(0); // Not available. _productID = @(0); // Not available. _commissioningFlow = MTRCommissioningFlowStandard; - _discoveryCapabilities = MTRDiscoveryCapabilitiesUnknown; + // We are using a long discriminator, so have to have a known + // discoveryCapabilities to be a valid payload. Just default to "try + // all discovery methods". + _discoveryCapabilities = MTRDiscoveryCapabilitiesAllMask; _hasShortDiscriminator = NO; _discriminator = discriminator; _setupPasscode = setupPasscode; From c349debda6be01c03b28751017da8755b7945833 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 21 Dec 2023 23:25:53 -0500 Subject: [PATCH 26/83] Explicitly mark EnergyPreference as not-yet-ready-for-release on Darwin. (#31165) --- src/darwin/Framework/CHIP/templates/availability.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 935a3889eea738..a546dfed9c956d 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -8260,6 +8260,7 @@ - ContentAppObserver - DeviceEnergyManagement - ElectricalEnergyMeasurement + - EnergyPreference attributes: NetworkCommissioning: # Targeting Spring 2024 Matter release From 4cc18bb24fc7b0a95104846fdf746cbba7cebaf2 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 22 Dec 2023 12:41:22 +0530 Subject: [PATCH 27/83] [ESP32] Added an API to set the CD in DAC providers and some documentation changes (#31104) * [ESP32] Added an API to set the CD in DAC providers * Usage of SetCertificationDeclaration() API in lighting-app/esp32 * [docs] Added some references for production workflows * fix the readme files * Add some docs for the lifetime of data * adjustment to the API documentation --- config/esp32/components/chip/Kconfig | 9 +++++++ docs/guides/esp32/factory_data.md | 27 ++++++++++++++++++- docs/guides/esp32/secure_cert_partition.md | 23 ++++++++++++++++ examples/lighting-app/esp32/README.md | 16 +++++------ .../lighting-app/esp32/main/CMakeLists.txt | 4 +++ examples/lighting-app/esp32/main/main.cpp | 14 +++++++++- .../ESP32/ESP32FactoryDataProvider.cpp | 4 +++ src/platform/ESP32/ESP32FactoryDataProvider.h | 27 +++++++++++++++++++ .../ESP32/ESP32SecureCertDACProvider.cpp | 4 +++ .../ESP32/ESP32SecureCertDACProvider.h | 27 +++++++++++++++++++ 10 files changed, 144 insertions(+), 11 deletions(-) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index ec2ab1a6b26d64..d616603c6bb03d 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -867,6 +867,15 @@ menu "CHIP Device Layer" then this option gets enabled. Also, please disable ESP_SECURE_CERT_DS_PERIPHERAL from the menuconfig when this option is disabled + config ENABLE_SET_CERT_DECLARATION_API + depends on ENABLE_ESP32_FACTORY_DATA_PROVIDER || SEC_CERT_DAC_PROVIDER + bool "Enable Set CD API" + default n + help + By default, the implementation reads the Certification Declaration (CD) from the 'chip-factory' + NVS namespace. If this option is enabled, the application can use an API to set a CD, + the configured CD will be used for subsequent CD reads. + config ENABLE_ESP_INSIGHTS_TRACE bool "Enable Matter ESP Insights" depends on ESP_INSIGHTS_ENABLED diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 179fb2e315a9c0..9ea2e12d1a87d3 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -1,5 +1,19 @@ ## Using ESP32 Factory Data Provider +**WARNING:** The following steps outline the development workflow for building a +matter device. + +Please take a look at +[security considerations](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/security.html) +and review the security guidelines outlined in +[security workflow](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/host-based-security-workflows.html) +for production workflows. + +Ensure to select the appropriate SoC from the menu on the left-hand side, as the +provided references are specific to ESP32. + +--- + By default applications uses test-mode or default commissionable data provider, device attestation credentials provider, device instance info provider, and device info provider. @@ -47,6 +61,15 @@ specific implementation of `CommissionableDataProvider` and [Component config → CHIP Device Layer → Commissioning options → Use ESP32 Factory Data Provider] +By default, the factory data provider implementation reads the Certification +Declaration (CD) from the 'chip-factory' NVS namespace. Enable +`CONFIG_ENABLE_SET_CERT_DECLARATION_API` option to enable an API which lets you +set the CD from the application and the configured CD will be used for +subsequent CD reads. + +[Component config -> CHIP Device Layer -> Commissioning options -> Enable Set CD +API] + Enable config option `CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER` to use ESP32 specific implementation of `DeviceInstanceInfoProvider`. @@ -107,4 +130,6 @@ appropriate address. ### Securing NVS binary image with NVS Encryption -Please check [Flash and NVS encryption guide](flash_nvs_encryption.md) +WARNING: NVS binary image may contain the sensitive information and it must be +secured using NVS encryption. For more details please check +[Flash and NVS encryption guide](flash_nvs_encryption.md) diff --git a/docs/guides/esp32/secure_cert_partition.md b/docs/guides/esp32/secure_cert_partition.md index 40d40d92d4432a..cef971f30f0910 100644 --- a/docs/guides/esp32/secure_cert_partition.md +++ b/docs/guides/esp32/secure_cert_partition.md @@ -1,5 +1,19 @@ # Using esp_secure_cert partition +**WARNING:** The following steps outline the development workflow for building a +matter device. + +Please take a look at +[security considerations](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/security.html) +and review the security guidelines outlined in +[security workflow](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/host-based-security-workflows.html) +for production workflows. + +Ensure to select the appropriate SoC from the menu on the left-hand side, as the +provided references are specific to ESP32. + +--- + ## 1.1 ESP Secure Cert Partition - When a device is pre-provisioned, PKI credentials are generated for the @@ -177,6 +191,15 @@ CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER=y CONFIG_CHIP_FACTORY_NAMESPACE_PARTITION_LABEL="fctry" ``` +By default, the secure cert DAC provider implementation reads the Certification +Declaration (CD) from the 'chip-factory' NVS namespace. Enable +`CONFIG_ENABLE_SET_CERT_DECLARATION_API` option to enable an API which lets you +set the CD from the application and the configured CD will be used for +subsequent CD reads. + +[Component config -> CHIP Device Layer -> Commissioning options -> Enable Set CD +API] + In order to use the esp_secure_cert_partition, in addition to enabling the above config options, you should also have the esp_secure_cert_partition and factory partition in your app. For reference, refer to partitions.csv file of diff --git a/examples/lighting-app/esp32/README.md b/examples/lighting-app/esp32/README.md index 5a6f9be37d286a..3e3dc5ee0a27cf 100644 --- a/examples/lighting-app/esp32/README.md +++ b/examples/lighting-app/esp32/README.md @@ -16,8 +16,8 @@ guides to get started. - Create a file named insights_auth_key.txt in the main directory of the example. -- Follow the steps - present[here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) +- Follow the steps present + [here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) to set up an insights_account and the auth key created while setting it up will be used in the example. @@ -27,13 +27,6 @@ guides to get started. cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/main/insights_auth_key.txt ``` ---- - -- [Cluster Control](#cluster-control) -- [Matter OTA guide](../../../docs/guides/esp32/ota.md) - ---- - ### Cluster Control - After successful commissioning, use the OnOff cluster command to control the @@ -50,3 +43,8 @@ cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/mai control the color attributes: $ ./out/debug/chip-tool colorcontrol move-to-hue-and-saturation 240 100 0 0 0 1 + +### Matter OTA + +For Matter OTA please take a look at +[Matter OTA guide](../../../docs/guides/esp32/ota.md). diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index 96279bd4d83dde..a7cc4136145981 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -111,6 +111,10 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE) target_add_binary_data(${COMPONENT_TARGET} "insights_auth_key.txt" TEXT) endif() +if (CONFIG_ENABLE_SET_CERT_DECLARATION_API) + target_add_binary_data(${COMPONENT_TARGET} "certification_declaration.der" BINARY) +endif() + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp index adb2bafd84f577..120c004782c895 100644 --- a/examples/lighting-app/esp32/main/main.cpp +++ b/examples/lighting-app/esp32/main/main.cpp @@ -100,13 +100,25 @@ DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; DeviceLayer::ESP32SecureCertDACProvider gSecureCertDACProvider; #endif // CONFIG_SEC_CERT_DAC_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API +extern const uint8_t cd_start[] asm("_binary_certification_declaration_der_start"); +extern const uint8_t cd_end[] asm("_binary_certification_declaration_der_end"); +ByteSpan cdSpan(cd_start, static_cast(cd_end - cd_start)); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void) { #if CONFIG_SEC_CERT_DAC_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + gSecureCertDACProvider.SetCertificationDeclaration(cdSpan); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API return &gSecureCertDACProvider; #elif CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + sFactoryDataProvider.SetCertificationDeclaration(cdSpan); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API return &sFactoryDataProvider; -#else // EXAMPLE_DAC_PROVIDER +#else // EXAMPLE_DAC_PROVIDER return chip::Credentials::Examples::GetExampleDACProvider(); #endif } diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 1066955292d6fd..4ff4f9d2d29678 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -123,11 +123,15 @@ CHIP_ERROR ESP32FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & CHIP_ERROR ESP32FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_PAICert, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index d69e64ffd1fcc1..1d78f2c2e8fa0b 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -60,6 +60,28 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + /** + * @brief API to set the Certification Declaration (CD). + * + * The GetCertificationDeclaration() API implementation reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different location, e.g., embedded in the firmware. + * Subsequent reads after calling this API will return the set CD. + * + * @param[in] cd ByteSpan containing the Certification Declaration. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. + * + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) + { + VerifyOrReturnError(!cd.empty(), CHIP_ERROR_INVALID_ARGUMENT); + mCD = cd; + return CHIP_NO_ERROR; + } +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + #if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER // ===== Members functions that implement the GenericDeviceInstanceInfoProvider CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; @@ -75,6 +97,11 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; #endif // CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER + +private: +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + ByteSpan mCD; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API }; } // namespace DeviceLayer diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.cpp b/src/platform/ESP32/ESP32SecureCertDACProvider.cpp index 1b06224318231c..a1bdedf03e1711 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.cpp +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.cpp @@ -55,11 +55,15 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P CHIP_ERROR ESP32SecureCertDACProvider ::GetCertificationDeclaration(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CertDeclaration, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32SecureCertDACProvider ::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.h b/src/platform/ESP32/ESP32SecureCertDACProvider.h index 997695aec0ec74..4e09c1efa1c5c0 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.h +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.h @@ -31,6 +31,33 @@ class ESP32SecureCertDACProvider : public Credentials::DeviceAttestationCredenti CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + /** + * @brief API to set the Certification Declaration (CD). + * + * The GetCertificationDeclaration() API implementation reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different location, e.g., embedded in the firmware. + * Subsequent reads after calling this API will return the set CD. + * + * @param[in] cd ByteSpan containing the Certification Declaration. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. + * + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) + { + VerifyOrReturnError(!cd.empty(), CHIP_ERROR_INVALID_ARGUMENT); + mCD = cd; + return CHIP_NO_ERROR; + } +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + +private: +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + ByteSpan mCD; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API }; } // namespace DeviceLayer } // namespace chip From cd815ef5921bc796eb636b1f91397666dc1f918c Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 22 Dec 2023 13:57:00 +0530 Subject: [PATCH 28/83] [ESP32] Config option for opening basic commissioning window on boot (#31158) --- config/esp32/components/chip/Kconfig | 7 +++++++ src/platform/ESP32/CHIPDevicePlatformConfig.h | 1 + 2 files changed, 8 insertions(+) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index d616603c6bb03d..e0576a38051650 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -250,6 +250,13 @@ menu "CHIP Core" help The delay time for OTA reboot on applying. + config CHIP_ENABLE_PAIRING_AUTOSTART + bool "Open commissioning window on boot" + default y + help + Opens the commissioning window automatically at application boot time if + the node is not yet commissioned. + endmenu # "System Options" menu "Security Options" diff --git a/src/platform/ESP32/CHIPDevicePlatformConfig.h b/src/platform/ESP32/CHIPDevicePlatformConfig.h index 0c4f036f5177a4..f0f28408a3ce12 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -105,6 +105,7 @@ #define CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER #define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS CONFIG_CHIP_DISCOVERY_TIMEOUT_SECS #define CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE CONFIG_ENABLE_ESP32_BLE_CONTROLLER +#define CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART // Options for background chip task #define CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING CONFIG_ENABLE_BG_EVENT_PROCESSING From 1939c35ca76252752107b4d9f86bd8577935ef7e Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 22 Dec 2023 14:23:52 +0530 Subject: [PATCH 29/83] [ESP32] fix the unsafe access to chip stack in lock-app (#31171) --- examples/lock-app/esp32/main/AppTask.cpp | 6 +++--- examples/lock-app/esp32/main/include/AppTask.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/lock-app/esp32/main/AppTask.cpp b/examples/lock-app/esp32/main/AppTask.cpp index 8b251a305e809c..52650e5c2d2652 100644 --- a/examples/lock-app/esp32/main/AppTask.cpp +++ b/examples/lock-app/esp32/main/AppTask.cpp @@ -99,7 +99,7 @@ CHIP_ERROR AppTask::Init() sLockLED.Set(!BoltLockMgr().IsUnlocked()); - chip::DeviceLayer::SystemLayer().ScheduleWork(UpdateClusterState, nullptr); + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr)); ConfigurationMgr().LogDeviceConfig(); @@ -424,7 +424,7 @@ void AppTask::ActionCompleted(BoltLockManager::Action_t aAction) } if (sAppTask.mSyncClusterToButtonAction) { - chip::DeviceLayer::SystemLayer().ScheduleWork(UpdateClusterState, nullptr); + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr)); sAppTask.mSyncClusterToButtonAction = false; } } @@ -463,7 +463,7 @@ void AppTask::DispatchEvent(AppEvent * aEvent) } /* if unlocked then it locked it first*/ -void AppTask::UpdateClusterState(chip::System::Layer *, void * context) +void AppTask::UpdateClusterState(intptr_t context) { uint8_t newValue = !BoltLockMgr().IsUnlocked(); diff --git a/examples/lock-app/esp32/main/include/AppTask.h b/examples/lock-app/esp32/main/include/AppTask.h index 7a1aad3e221800..3c32cb8704aa0e 100644 --- a/examples/lock-app/esp32/main/include/AppTask.h +++ b/examples/lock-app/esp32/main/include/AppTask.h @@ -66,7 +66,7 @@ class AppTask static void LockActionEventHandler(AppEvent * aEvent); static void TimerEventHandler(TimerHandle_t xTimer); - static void UpdateClusterState(chip::System::Layer *, void * context); + static void UpdateClusterState(intptr_t context); void StartTimer(uint32_t aTimeoutMs); From 83c1b73f918565152be19f2d240e5b3993401c1f Mon Sep 17 00:00:00 2001 From: RJ030 <127305878+RJ030@users.noreply.github.com> Date: Fri, 22 Dec 2023 10:11:14 +0100 Subject: [PATCH 30/83] Add documentation about the usage of the --storage-directory flag. (#31172) --- docs/guides/chip_tool_guide.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/guides/chip_tool_guide.md b/docs/guides/chip_tool_guide.md index 32ce669d538a68..31aa29353c91ab 100644 --- a/docs/guides/chip_tool_guide.md +++ b/docs/guides/chip_tool_guide.md @@ -18,6 +18,10 @@ directory. > `/tmp/chip_tool_config.ini` file. Deleting this and other `.ini` files in the > `/tmp` directory can sometimes resolve issues related to stale configuration. +> **Note:** To make the configuration persistent (since `/tmp` directory might +> be flushed at each reboot) you can change the directory where CHIP Tool caches +> its configuration by using the option `--storage-directory` +
## Building and running the CHIP Tool @@ -676,6 +680,30 @@ The following flags are available:
+##### Changing storage directory + +By default, CHIP Tool stores its configuration into the `/tmp` directory. You +can change the storage directory by using the `--storage-directory` flag. + +Usage: + +``` +--storage-directory +``` + +Here, __ is the path to the directory where the configuration is +stored. + +**Example of usage:** + +``` +$ ./chip-tool pairing ble-wifi --storage-directory +$ ./chip-tool temperaturemeasurement read measured-value --storage-directory + +``` + +
+ ### Commissioner name and ID flags All CHIP Tool commands can be used together with the following From 061ff86a22f054b40e9e243fc4673b07afd07b47 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Fri, 22 Dec 2023 11:06:59 +0000 Subject: [PATCH 31/83] Remove duplicate energy management files from all clusters app (#31155) * Updated CMakeLists.txt to remove duplicate energy-management files. * Updated BUILD.gn to remove duplicated files from all-clusters-common and energy-management-common * Updated BUILD.gn to remove duplicated files from all-clusters-common and energy-management-common * Restyled by gn * Updated build files to remove duplicate copies from all-clusters-common to energy-management-common * Fixed ESP32 include path * Restyled by gn * Removed DeviceEnergyManagement files from PR * Removed DeviceEnergyManagement files from PR (ameba/chip_main.cmake) --------- Co-authored-by: Restyled.io --- .../include/EVSECallbacks.h | 84 -- .../include/EnergyEvseDelegateImpl.h | 206 ----- .../include/EnergyEvseManager.h | 57 -- .../src/EnergyEvseDelegateImpl.cpp | 847 ------------------ .../src/EnergyEvseManager.cpp | 33 - .../all-clusters-app/ameba/chip_main.cmake | 6 +- examples/all-clusters-app/asr/BUILD.gn | 5 +- .../all-clusters-app/cc13x2x7_26x2x7/BUILD.gn | 5 +- .../all-clusters-app/cc13x4_26x4/BUILD.gn | 5 +- .../esp32/main/CMakeLists.txt | 1 + .../all-clusters-app/infineon/psoc6/BUILD.gn | 5 +- examples/all-clusters-app/linux/BUILD.gn | 10 +- examples/all-clusters-app/mbed/CMakeLists.txt | 6 +- .../nrfconnect/CMakeLists.txt | 6 +- examples/all-clusters-app/nxp/mw320/BUILD.gn | 5 +- .../openiotsdk/CMakeLists.txt | 6 +- .../all-clusters-app/telink/CMakeLists.txt | 6 +- examples/all-clusters-app/tizen/BUILD.gn | 10 +- .../esp32/main/CMakeLists.txt | 2 + examples/shell/shell_common/BUILD.gn | 10 +- 20 files changed, 56 insertions(+), 1259 deletions(-) delete mode 100644 examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h delete mode 100644 examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h delete mode 100644 examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h delete mode 100644 examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp delete mode 100644 examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp diff --git a/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h b/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h deleted file mode 100644 index 5bdac2f8e853d6..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -namespace chip { -namespace app { -namespace Clusters { - -using namespace chip::app::Clusters::EnergyEvse; - -/* This callbacks mechanism is intended to allow different delegates to - * dispatch notifications that something has changed. - * - * This is not specific to the EnergyEVSE cluster, but includes DeviceEnergyManagement - * and potential future clusters. - */ -enum EVSECallbackType -{ - /* - * The State has changed (e.g. from Disabled to Charging, or vice-versa) - */ - StateChanged, - /* - * ChargeCurrent has changed - */ - ChargeCurrentChanged, - /* - * Charging Preferences have changed - */ - ChargingPreferencesChanged, - /* - * DeviceEnergyManagement has changed - */ - DeviceEnergyManagementChanged, -}; - -struct EVSECbInfo -{ - EVSECallbackType type; - - union - { - /* for type = StateChanged */ - struct - { - StateEnum state; - SupplyStateEnum supplyState; - } StateChange; - - /* for type = ChargeCurrentChanged */ - struct - { - int64_t maximumChargeCurrent; - } ChargingCurrent; - }; -}; - -typedef void (*EVSECallbackFunc)(const EVSECbInfo * cb, intptr_t arg); - -struct EVSECallbackWrapper -{ - EVSECallbackFunc handler; - intptr_t arg; -}; - -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h b/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h deleted file mode 100644 index f3c003d081fc6e..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "app/clusters/energy-evse-server/energy-evse-server.h" -#include - -#include -#include -#include - -using chip::Protocols::InteractionModel::Status; -namespace chip { -namespace app { -namespace Clusters { -namespace EnergyEvse { - -/** - * The application delegate. - */ - -class EnergyEvseDelegate : public EnergyEvse::Delegate -{ -public: - ~EnergyEvseDelegate(); - - /** - * @brief Called when EVSE cluster receives Disable command - */ - Status Disable() override; - - /** - * @brief Called when EVSE cluster receives EnableCharging command - * - * @param chargingEnabledUntil - * @param minimumChargeCurrent (in mA) - * @param maximumChargeCurrent (in mA) - */ - Status EnableCharging(const DataModel::Nullable & chargingEnabledUntil, const int64_t & minimumChargeCurrent, - const int64_t & maximumChargeCurrent) override; - - /** - * @brief Called when EVSE cluster receives EnableDischarging command - * - * @param dischargingEnabledUntil - * @param maximumChargeCurrent (in mA) - */ - Status EnableDischarging(const DataModel::Nullable & dischargingEnabledUntil, - const int64_t & maximumDischargeCurrent) override; - - /** - * @brief Called when EVSE cluster receives StartDiagnostics command - */ - Status StartDiagnostics() override; - - /** - * @brief Called by EVSE Hardware to register a single callback handler - */ - Status HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg); - - // ----------------------------------------------------------------- - // Internal API to allow an EVSE to change its internal state etc - Status HwSetMaxHardwareCurrentLimit(int64_t currentmA); - Status HwSetCircuitCapacity(int64_t currentmA); - Status HwSetCableAssemblyLimit(int64_t currentmA); - Status HwSetState(StateEnum state); - Status HwSetFault(FaultStateEnum fault); - Status HwSetRFID(ByteSpan uid); - Status HwSetVehicleID(const CharSpan & vehID); - - // ------------------------------------------------------------------ - // Get attribute methods - StateEnum GetState() override; - CHIP_ERROR SetState(StateEnum); - - SupplyStateEnum GetSupplyState() override; - CHIP_ERROR SetSupplyState(SupplyStateEnum); - - FaultStateEnum GetFaultState() override; - CHIP_ERROR SetFaultState(FaultStateEnum); - - DataModel::Nullable GetChargingEnabledUntil() override; - CHIP_ERROR SetChargingEnabledUntil(uint32_t); - - DataModel::Nullable GetDischargingEnabledUntil() override; - CHIP_ERROR SetDischargingEnabledUntil(uint32_t); - - int64_t GetCircuitCapacity() override; - CHIP_ERROR SetCircuitCapacity(int64_t); - - int64_t GetMinimumChargeCurrent() override; - CHIP_ERROR SetMinimumChargeCurrent(int64_t); - - int64_t GetMaximumChargeCurrent() override; - CHIP_ERROR SetMaximumChargeCurrent(int64_t); - - int64_t GetMaximumDischargeCurrent() override; - CHIP_ERROR SetMaximumDischargeCurrent(int64_t); - - int64_t GetUserMaximumChargeCurrent() override; - CHIP_ERROR SetUserMaximumChargeCurrent(int64_t) override; - - uint32_t GetRandomizationDelayWindow() override; - CHIP_ERROR SetRandomizationDelayWindow(uint32_t) override; - - /* PREF attributes */ - uint8_t GetNumberOfWeeklyTargets() override; - uint8_t GetNumberOfDailyTargets() override; - DataModel::Nullable GetNextChargeStartTime() override; - DataModel::Nullable GetNextChargeTargetTime() override; - DataModel::Nullable GetNextChargeRequiredEnergy() override; - DataModel::Nullable GetNextChargeTargetSoC() override; - - DataModel::Nullable GetApproximateEVEfficiency() override; - CHIP_ERROR SetApproximateEVEfficiency(uint16_t) override; - - /* SOC attributes */ - DataModel::Nullable GetStateOfCharge() override; - DataModel::Nullable GetBatteryCapacity() override; - /* PNC attributes*/ - DataModel::Nullable GetVehicleID() override; - /* Session SESS attributes */ - DataModel::Nullable GetSessionID() override; - DataModel::Nullable GetSessionDuration() override; - DataModel::Nullable GetSessionEnergyCharged() override; - DataModel::Nullable GetSessionEnergyDischarged() override; - -private: - /* Constants */ - static constexpr int DEFAULT_MIN_CHARGE_CURRENT = 6000; /* 6A */ - static constexpr int DEFAULT_USER_MAXIMUM_CHARGE_CURRENT = kMaximumChargeCurrent; /* 80A */ - static constexpr int DEFAULT_RANDOMIZATION_DELAY_WINDOW = 600; /* 600s */ - static constexpr int kMaxVehicleIDBufSize = 32; - - /* private variables for controlling the hardware - these are not attributes */ - int64_t mMaxHardwareCurrentLimit = 0; /* Hardware current limit in mA */ - int64_t mCableAssemblyCurrentLimit = 0; /* Cable limit detected when cable is plugged in, in mA */ - int64_t mMaximumChargingCurrentLimitFromCommand = 0; /* Value of current maximum limit when charging enabled */ - int64_t mActualChargingCurrentLimit = 0; - StateEnum mHwState = StateEnum::kNotPluggedIn; /* Hardware state */ - - /* Callback related */ - EVSECallbackWrapper mCallbacks = { .handler = nullptr, .arg = 0 }; /* Wrapper to allow callbacks to be registered */ - Status NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent); - Status NotifyApplicationStateChange(); - - /** - * @brief Helper function to work out the charge limit based on conditions and settings - */ - Status ComputeMaxChargeCurrentLimit(); - - /* Attributes */ - StateEnum mState = StateEnum::kNotPluggedIn; - SupplyStateEnum mSupplyState = SupplyStateEnum::kDisabled; - FaultStateEnum mFaultState = FaultStateEnum::kNoError; - DataModel::Nullable mChargingEnabledUntil; // TODO Default to 0 to indicate disabled - DataModel::Nullable mDischargingEnabledUntil; // TODO Default to 0 to indicate disabled - int64_t mCircuitCapacity = 0; - int64_t mMinimumChargeCurrent = DEFAULT_MIN_CHARGE_CURRENT; - int64_t mMaximumChargeCurrent = 0; - int64_t mMaximumDischargeCurrent = 0; - int64_t mUserMaximumChargeCurrent = DEFAULT_USER_MAXIMUM_CHARGE_CURRENT; // TODO update spec - uint32_t mRandomizationDelayWindow = DEFAULT_RANDOMIZATION_DELAY_WINDOW; - /* PREF attributes */ - uint8_t mNumberOfWeeklyTargets = 0; - uint8_t mNumberOfDailyTargets = 1; - DataModel::Nullable mNextChargeStartTime; - DataModel::Nullable mNextChargeTargetTime; - DataModel::Nullable mNextChargeRequiredEnergy; - DataModel::Nullable mNextChargeTargetSoC; - DataModel::Nullable mApproximateEVEfficiency; - - /* SOC attributes */ - DataModel::Nullable mStateOfCharge; - DataModel::Nullable mBatteryCapacity; - - /* PNC attributes*/ - DataModel::Nullable mVehicleID; - - /* Session SESS attributes */ - DataModel::Nullable mSessionID; - DataModel::Nullable mSessionDuration; - DataModel::Nullable mSessionEnergyCharged; - DataModel::Nullable mSessionEnergyDischarged; -}; - -} // namespace EnergyEvse -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h b/examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h deleted file mode 100644 index 9875c397990ef2..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include - -namespace chip { -namespace app { -namespace Clusters { - -using namespace chip::app::Clusters::EnergyEvse; -class EnergyEvseManager : public Instance -{ -public: - EnergyEvseManager(EndpointId aEndpointId, EnergyEvseDelegate & aDelegate, Feature aFeature, OptionalAttributes aOptionalAttrs, - OptionalCommands aOptionalCmds) : - EnergyEvse::Instance(aEndpointId, aDelegate, aFeature, aOptionalAttrs, aOptionalCmds) - { - mDelegate = &aDelegate; - } - - // Delete copy constructor and assignment operator. - EnergyEvseManager(const EnergyEvseManager &) = delete; - EnergyEvseManager(const EnergyEvseManager &&) = delete; - EnergyEvseManager & operator=(const EnergyEvseManager &) = delete; - - CHIP_ERROR Init(); - void Shutdown(); - - EnergyEvseDelegate * GetDelegate() { return mDelegate; }; - -private: - EnergyEvseDelegate * mDelegate; -}; - -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp b/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp deleted file mode 100644 index 4cc83eaaf8a835..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp +++ /dev/null @@ -1,847 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -using namespace chip; -using namespace chip::app; -using namespace chip::app::DataModel; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::EnergyEvse; -using namespace chip::app::Clusters::EnergyEvse::Attributes; - -using chip::app::LogEvent; -using chip::Protocols::InteractionModel::Status; - -EnergyEvseDelegate::~EnergyEvseDelegate() -{ - // TODO Fix this as part of issue #30993 refactoring - if (!mVehicleID.IsNull()) - { - ChipLogDetail(AppServer, "Freeing VehicleID"); - delete[] mVehicleID.Value().data(); - } -} - -/** - * @brief Called when EVSE cluster receives Disable command - */ -Status EnergyEvseDelegate::Disable() -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::Disable()"); - - /* Update State */ - switch (mHwState) - { - case StateEnum::kNotPluggedIn: - SetState(StateEnum::kNotPluggedIn); - break; - - case StateEnum::kPluggedInNoDemand: - SetState(StateEnum::kPluggedInNoDemand); - break; - - case StateEnum::kPluggedInDemand: - SetState(StateEnum::kPluggedInDemand); - break; - - default: - ChipLogError(AppServer, "Unexpected EVSE hardware state"); - SetState(StateEnum::kFault); - break; - } - - /* update SupplyState */ - SetSupplyState(SupplyStateEnum::kDisabled); - - /* update ChargingEnabledUntil & DischargingEnabledUntil to show 0 */ - SetChargingEnabledUntil(0); - SetDischargingEnabledUntil(0); - - /* update MinimumChargeCurrent & MaximumChargeCurrent to 0 */ - SetMinimumChargeCurrent(0); - SetMaximumChargeCurrent(0); - - /* update MaximumDischargeCurrent to 0 */ - SetMaximumDischargeCurrent(0); - - NotifyApplicationStateChange(); - // TODO: Generate events - - return Status::Success; -} - -/** - * @brief Called when EVSE cluster receives EnableCharging command - * - * @param chargingEnabledUntil (can be null to indefinite charging) - * @param minimumChargeCurrent (in mA) - * @param maximumChargeCurrent (in mA) - */ -Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & chargingEnabledUntil, - const int64_t & minimumChargeCurrent, const int64_t & maximumChargeCurrent) -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::EnableCharging()"); - - if (maximumChargeCurrent < kMinimumChargeCurrent || maximumChargeCurrent > kMaximumChargeCurrent) - { - ChipLogError(AppServer, "Maximum Current outside limits"); - return Status::ConstraintError; - } - - if (minimumChargeCurrent < kMinimumChargeCurrent || minimumChargeCurrent > kMaximumChargeCurrent) - { - ChipLogError(AppServer, "Maximum Current outside limits"); - return Status::ConstraintError; - } - - if (minimumChargeCurrent > maximumChargeCurrent) - { - ChipLogError(AppServer, "Minium Current > Maximum Current!"); - return Status::ConstraintError; - } - - if (chargingEnabledUntil.IsNull()) - { - /* Charging enabled indefinitely */ - ChipLogError(AppServer, "Charging enabled indefinitely"); - } - else - { - /* check chargingEnabledUntil is in the future */ - ChipLogError(AppServer, "Charging enabled until: %lu", static_cast(chargingEnabledUntil.Value())); - // TODO - // if (checkChargingEnabled) - } - - /* Check current state isn't already enabled */ - - /* If charging is already enabled, check that the parameters may have - changed, these may override an existing charging command */ - switch (mHwState) - { - case StateEnum::kNotPluggedIn: - // TODO handle errors here - SetState(StateEnum::kNotPluggedIn); - break; - - case StateEnum::kPluggedInNoDemand: - // TODO handle errors here - // TODO REFACTOR per Andrei's comment in PR30857 - can we collapse this switch statement? - SetState(StateEnum::kPluggedInNoDemand); - break; - - case StateEnum::kPluggedInDemand: - /* If the EVSE is asking for demand then enable charging */ - SetState(StateEnum::kPluggedInCharging); - break; - - default: - ChipLogError(AppServer, "Unexpected EVSE hardware state"); - SetState(StateEnum::kFault); - break; - } - - /* update SupplyState to say that charging is now enabled */ - SetSupplyState(SupplyStateEnum::kChargingEnabled); - - /* If it looks ok, store the min & max charging current */ - mMaximumChargingCurrentLimitFromCommand = maximumChargeCurrent; - SetMinimumChargeCurrent(minimumChargeCurrent); - // TODO persist these to KVS - - // TODO: Generate events - - NotifyApplicationStateChange(); - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called when EVSE cluster receives EnableDischarging command - * - * @param dischargingEnabledUntil (can be null to indefinite discharging) - * @param maximumChargeCurrent (in mA) - */ -Status EnergyEvseDelegate::EnableDischarging(const DataModel::Nullable & dischargingEnabledUntil, - const int64_t & maximumDischargeCurrent) -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::EnableDischarging() called."); - - /* update SupplyState */ - SetSupplyState(SupplyStateEnum::kDischargingEnabled); - - // TODO: Generate events - - NotifyApplicationStateChange(); - - return Status::Success; -} - -/** - * @brief Called when EVSE cluster receives StartDiagnostics command - */ -Status EnergyEvseDelegate::StartDiagnostics() -{ - /* For EVSE manufacturers to customize */ - ChipLogProgress(AppServer, "EnergyEvseDelegate::StartDiagnostics()"); - - /* update SupplyState to indicate we are now in Diagnostics mode */ - SetSupplyState(SupplyStateEnum::kDisabledDiagnostics); - - // TODO: Generate events - - // TODO: Notify Application to implement Diagnostics - - NotifyApplicationStateChange(); - - return Status::Success; -} - -/* --------------------------------------------------------------------------- - * EVSE Hardware interface below - */ - -/** - * @brief Called by EVSE Hardware to register a callback handler mechanism - * - * This is normally called at start-up. - * - * @param EVSECallbackFunct - function pointer to call - * @param intptr_t - optional context to provide back to callback handler - */ -Status EnergyEvseDelegate::HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg) -{ - if (mCallbacks.handler != nullptr) - { - ChipLogError(AppServer, "Callback handler already initialized"); - return Status::Failure; - } - mCallbacks.handler = handler; - mCallbacks.arg = arg; - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to notify the delegate of the maximum - * current limit supported by the hardware. - * - * This is normally called at start-up. - * - * @param currentmA - Maximum current limit supported by the hardware - */ -Status EnergyEvseDelegate::HwSetMaxHardwareCurrentLimit(int64_t currentmA) -{ - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) - { - return Status::ConstraintError; - } - - /* there is no attribute to store this so store in private variable */ - mMaxHardwareCurrentLimit = currentmA; - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called by EVSE Hardware to notify the delegate of maximum electrician - * set current limit. - * - * This is normally called at start-up when reading from DIP-switch - * settings. - * - * @param currentmA - Maximum current limit specified by electrician - */ -Status EnergyEvseDelegate::HwSetCircuitCapacity(int64_t currentmA) -{ - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) - { - return Status::ConstraintError; - } - - mCircuitCapacity = currentmA; - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, CircuitCapacity::Id); - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called by EVSE Hardware to notify the delegate of the cable assembly - * current limit. - * - * This is normally called when the EV is plugged into the EVSE and the - * PP voltage is measured by the EVSE. A pull-up resistor in the cable - * causes a voltage drop. Different current limits can be indicated - * using different resistors, which results in different voltages - * measured by the EVSE. - * - * @param currentmA - Maximum current limit detected from Cable assembly - */ -Status EnergyEvseDelegate::HwSetCableAssemblyLimit(int64_t currentmA) -{ - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) - { - return Status::ConstraintError; - } - - /* there is no attribute to store this so store in private variable */ - mCableAssemblyCurrentLimit = currentmA; - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called by EVSE Hardware to indicate if EV is detected - * - * The only allowed states that the EVSE hardware can set are: - * kNotPluggedIn - * kPluggedInNoDemand - * kPluggedInDemand - * - * @param StateEnum - the state of the EV being plugged in and asking for demand etc - */ -Status EnergyEvseDelegate::HwSetState(StateEnum state) -{ - switch (state) - { - case StateEnum::kNotPluggedIn: - // TODO - work out logic here - mHwState = state; - break; - case StateEnum::kPluggedInNoDemand: - // TODO - work out logic here - mHwState = state; - break; - case StateEnum::kPluggedInDemand: - // TODO - work out logic here - mHwState = state; - break; - - default: - /* All other states should be managed by the Delegate */ - // TODO (assert?) - break; - } - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to indicate a fault - * - * @param FaultStateEnum - the fault condition detected - */ -Status EnergyEvseDelegate::HwSetFault(FaultStateEnum fault) -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::Fault()"); - - if (fault == FaultStateEnum::kNoError) - { - /* Update State to previous state */ - // TODO: need to work out the logic here! - - /* Update SupplyState to previous state */ - } - else - { - /* Update State & SupplyState */ - SetState(StateEnum::kFault); - SetSupplyState(SupplyStateEnum::kDisabledError); - } - - /* Update FaultState */ - SetFaultState(fault); - - // TODO: Generate events - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to Send a RFID event - * - * @param ByteSpan RFID tag value (max 10 octets) - */ -Status EnergyEvseDelegate::HwSetRFID(ByteSpan uid) -{ - Events::Rfid::Type event{ .uid = uid }; - EventNumber eventNumber; - CHIP_ERROR error = LogEvent(event, mEndpointId, eventNumber); - if (CHIP_NO_ERROR != error) - { - ChipLogError(Zcl, "[Notify] Unable to send notify event: %s [endpointId=%d]", error.AsString(), mEndpointId); - return Status::Failure; - } - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to share the VehicleID - * - * This routine will make a copy of the string so the callee doesn't - * have to hold onto it forever. - * - * @param CharSpan containing up to 32 chars. - */ -Status EnergyEvseDelegate::HwSetVehicleID(const CharSpan & newValue) -{ - // TODO this code to be refactored - See Issue #30993 - if (!mVehicleID.IsNull() && newValue.data_equal(mVehicleID.Value())) - { - return Status::Success; - } - - /* create a copy of the string so the callee doesn't have to keep it */ - char * destinationBuffer = new char[kMaxVehicleIDBufSize]; - - MutableCharSpan destinationString(destinationBuffer, kMaxVehicleIDBufSize); - CHIP_ERROR err = CopyCharSpanToMutableCharSpan(newValue, destinationString); - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "HwSetVehicleID - could not copy vehicleID"); - delete[] destinationBuffer; - return Status::Failure; - } - - if (!mVehicleID.IsNull()) - { - delete[] mVehicleID.Value().data(); - } - - mVehicleID = MakeNullable(static_cast(destinationString)); - - ChipLogDetail(AppServer, "VehicleID updated %.*s", static_cast(mVehicleID.Value().size()), mVehicleID.Value().data()); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, VehicleID::Id); - - return Status::Success; -} - -/* --------------------------------------------------------------------------- - * Functions below are private helper functions internal to the delegate - */ - -/** - * @brief Called to compute the safe charging current limit - * - * mActualChargingCurrentLimit is the minimum of: - * - MaxHardwareCurrentLimit (of the hardware) - * - CircuitCapacity (set by the electrician - less than the hardware) - * - CableAssemblyLimit (detected when the cable is inserted) - * - MaximumChargeCurrent (from charging command) - * - UserMaximumChargeCurrent (could dynamically change) - * - */ -Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit() -{ - int64_t oldValue; - - oldValue = mActualChargingCurrentLimit; - mActualChargingCurrentLimit = mMaxHardwareCurrentLimit; - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mCircuitCapacity); - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mCableAssemblyCurrentLimit); - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mMaximumChargingCurrentLimitFromCommand); - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mUserMaximumChargeCurrent); - - /* Set the actual max charging current attribute */ - mMaximumChargeCurrent = mActualChargingCurrentLimit; - - if (oldValue != mMaximumChargeCurrent) - { - ChipLogDetail(AppServer, "MaximumChargeCurrent updated to %ld", static_cast(mMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); - - /* Call the EV Charger hardware current limit callback */ - NotifyApplicationCurrentLimitChange(mMaximumChargeCurrent); - } - return Status::Success; -} - -Status EnergyEvseDelegate::NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent) -{ - EVSECbInfo cbInfo; - - cbInfo.type = EVSECallbackType::ChargeCurrentChanged; - cbInfo.ChargingCurrent.maximumChargeCurrent = maximumChargeCurrent; - - if (mCallbacks.handler != nullptr) - { - mCallbacks.handler(&cbInfo, mCallbacks.arg); - } - - return Status::Success; -} - -Status EnergyEvseDelegate::NotifyApplicationStateChange() -{ - EVSECbInfo cbInfo; - - cbInfo.type = EVSECallbackType::StateChanged; - cbInfo.StateChange.state = mState; - cbInfo.StateChange.supplyState = mSupplyState; - - if (mCallbacks.handler != nullptr) - { - mCallbacks.handler(&cbInfo, mCallbacks.arg); - } - - return Status::Success; -} - -/** - * Attribute methods - */ -/* State */ -StateEnum EnergyEvseDelegate::GetState() -{ - return mState; -} - -CHIP_ERROR EnergyEvseDelegate::SetState(StateEnum newValue) -{ - StateEnum oldValue = mState; - if (newValue >= StateEnum::kUnknownEnumValue) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mState = newValue; - if (oldValue != mState) - { - ChipLogDetail(AppServer, "State updated to %d", static_cast(mState)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, State::Id); - } - - return CHIP_NO_ERROR; -} - -/* SupplyState */ -SupplyStateEnum EnergyEvseDelegate::GetSupplyState() -{ - return mSupplyState; -} - -CHIP_ERROR EnergyEvseDelegate::SetSupplyState(SupplyStateEnum newValue) -{ - SupplyStateEnum oldValue = mSupplyState; - - if (newValue >= SupplyStateEnum::kUnknownEnumValue) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mSupplyState = newValue; - if (oldValue != mSupplyState) - { - ChipLogDetail(AppServer, "SupplyState updated to %d", static_cast(mSupplyState)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SupplyState::Id); - } - return CHIP_NO_ERROR; -} - -/* FaultState */ -FaultStateEnum EnergyEvseDelegate::GetFaultState() -{ - return mFaultState; -} - -CHIP_ERROR EnergyEvseDelegate::SetFaultState(FaultStateEnum newValue) -{ - FaultStateEnum oldValue = mFaultState; - - if (newValue >= FaultStateEnum::kUnknownEnumValue) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mFaultState = newValue; - if (oldValue != mFaultState) - { - ChipLogDetail(AppServer, "FaultState updated to %d", static_cast(mFaultState)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, FaultState::Id); - } - return CHIP_NO_ERROR; -} - -/* ChargingEnabledUntil */ -DataModel::Nullable EnergyEvseDelegate::GetChargingEnabledUntil() -{ - return mChargingEnabledUntil; -} - -CHIP_ERROR EnergyEvseDelegate::SetChargingEnabledUntil(uint32_t newValue) -{ - DataModel::Nullable oldValue = mChargingEnabledUntil; - - mChargingEnabledUntil = MakeNullable(newValue); - if ((oldValue.IsNull()) || (oldValue.Value() != newValue)) - { - ChipLogDetail(AppServer, "ChargingEnabledUntil updated to %lu", - static_cast(mChargingEnabledUntil.Value())); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, ChargingEnabledUntil::Id); - } - return CHIP_NO_ERROR; -} - -/* DischargingEnabledUntil */ -DataModel::Nullable EnergyEvseDelegate::GetDischargingEnabledUntil() -{ - return mDischargingEnabledUntil; -} - -CHIP_ERROR EnergyEvseDelegate::SetDischargingEnabledUntil(uint32_t newValue) -{ - DataModel::Nullable oldValue = mDischargingEnabledUntil; - - mDischargingEnabledUntil = MakeNullable(newValue); - if ((oldValue.IsNull()) || (oldValue.Value() != newValue)) - { - ChipLogDetail(AppServer, "DischargingEnabledUntil updated to %lu", - static_cast(mDischargingEnabledUntil.Value())); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, DischargingEnabledUntil::Id); - } - return CHIP_NO_ERROR; -} - -/* CircuitCapacity */ -int64_t EnergyEvseDelegate::GetCircuitCapacity() -{ - return mCircuitCapacity; -} - -CHIP_ERROR EnergyEvseDelegate::SetCircuitCapacity(int64_t newValue) -{ - int64_t oldValue = mCircuitCapacity; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mCircuitCapacity = newValue; - if (oldValue != mCircuitCapacity) - { - ChipLogDetail(AppServer, "CircuitCapacity updated to %ld", static_cast(mCircuitCapacity)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, CircuitCapacity::Id); - } - return CHIP_NO_ERROR; -} - -/* MinimumChargeCurrent */ -int64_t EnergyEvseDelegate::GetMinimumChargeCurrent() -{ - return mMinimumChargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetMinimumChargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMinimumChargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMinimumChargeCurrent = newValue; - if (oldValue != mMinimumChargeCurrent) - { - ChipLogDetail(AppServer, "MinimumChargeCurrent updated to %ld", static_cast(mMinimumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MinimumChargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - -/* MaximumChargeCurrent */ -int64_t EnergyEvseDelegate::GetMaximumChargeCurrent() -{ - return mMaximumChargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetMaximumChargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMaximumChargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMaximumChargeCurrent = newValue; - if (oldValue != mMaximumChargeCurrent) - { - ChipLogDetail(AppServer, "MaximumChargeCurrent updated to %ld", static_cast(mMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - -/* MaximumDischargeCurrent */ -int64_t EnergyEvseDelegate::GetMaximumDischargeCurrent() -{ - return mMaximumDischargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetMaximumDischargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMaximumDischargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMaximumDischargeCurrent = newValue; - if (oldValue != mMaximumDischargeCurrent) - { - ChipLogDetail(AppServer, "MaximumDischargeCurrent updated to %ld", static_cast(mMaximumDischargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumDischargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - -/* UserMaximumChargeCurrent */ -int64_t EnergyEvseDelegate::GetUserMaximumChargeCurrent() -{ - return mUserMaximumChargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetUserMaximumChargeCurrent(int64_t newValue) -{ - if ((newValue < 0) || (newValue > kMaximumChargeCurrent)) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - int64_t oldValue = mUserMaximumChargeCurrent; - mUserMaximumChargeCurrent = newValue; - if (oldValue != newValue) - { - ChipLogDetail(AppServer, "UserMaximumChargeCurrent updated to %ld", static_cast(mUserMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, UserMaximumChargeCurrent::Id); - } - - return CHIP_NO_ERROR; -} - -/* RandomizationDelayWindow */ -uint32_t EnergyEvseDelegate::GetRandomizationDelayWindow() -{ - return mRandomizationDelayWindow; -} - -CHIP_ERROR EnergyEvseDelegate::SetRandomizationDelayWindow(uint32_t newValue) -{ - uint32_t oldValue = mRandomizationDelayWindow; - if (newValue > kMaxRandomizationDelayWindow) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mRandomizationDelayWindow = newValue; - if (oldValue != newValue) - { - ChipLogDetail(AppServer, "RandomizationDelayWindow updated to %lu", - static_cast(mRandomizationDelayWindow)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, RandomizationDelayWindow::Id); - } - return CHIP_NO_ERROR; -} - -/* PREF attributes */ -uint8_t EnergyEvseDelegate::GetNumberOfWeeklyTargets() -{ - return mNumberOfWeeklyTargets; -} -uint8_t EnergyEvseDelegate::GetNumberOfDailyTargets() -{ - return mNumberOfDailyTargets; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeStartTime() -{ - return mNextChargeStartTime; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeTargetTime() -{ - return mNextChargeTargetTime; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeRequiredEnergy() -{ - return mNextChargeRequiredEnergy; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeTargetSoC() -{ - return mNextChargeTargetSoC; -} - -/* ApproximateEVEfficiency */ -DataModel::Nullable EnergyEvseDelegate::GetApproximateEVEfficiency() -{ - return mApproximateEVEfficiency; -} - -CHIP_ERROR EnergyEvseDelegate::SetApproximateEVEfficiency(uint16_t newValue) -{ - DataModel::Nullable oldValue = mApproximateEVEfficiency; - - mApproximateEVEfficiency = MakeNullable(newValue); - if ((oldValue.IsNull()) || (oldValue.Value() != newValue)) - { - ChipLogDetail(AppServer, "ApproximateEVEfficiency updated to %d", mApproximateEVEfficiency.Value()); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, ApproximateEVEfficiency::Id); - } - - return CHIP_NO_ERROR; -} - -/* SOC attributes */ -DataModel::Nullable EnergyEvseDelegate::GetStateOfCharge() -{ - return mStateOfCharge; -} -DataModel::Nullable EnergyEvseDelegate::GetBatteryCapacity() -{ - return mBatteryCapacity; -} - -/* PNC attributes*/ -DataModel::Nullable EnergyEvseDelegate::GetVehicleID() -{ - return mVehicleID; -} - -/* Session SESS attributes */ -DataModel::Nullable EnergyEvseDelegate::GetSessionID() -{ - return mSessionID; -} -DataModel::Nullable EnergyEvseDelegate::GetSessionDuration() -{ - return mSessionDuration; -} -DataModel::Nullable EnergyEvseDelegate::GetSessionEnergyCharged() -{ - return mSessionEnergyCharged; -} -DataModel::Nullable EnergyEvseDelegate::GetSessionEnergyDischarged() -{ - return mSessionEnergyDischarged; -} diff --git a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp b/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp deleted file mode 100644 index 0d84d8856212e0..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -using namespace chip::app; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::EnergyEvse; - -CHIP_ERROR EnergyEvseManager::Init() -{ - return Instance::Init(); -} - -void EnergyEvseManager::Shutdown() -{ - Instance::Shutdown(); -} diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake index f3c6a54854c475..2ba95602857620 100755 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -156,8 +156,6 @@ list( ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp - ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp - ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp @@ -176,6 +174,9 @@ list( ${chip_dir}/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp + ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_hook.c ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_table.c @@ -220,6 +221,7 @@ target_include_directories( ${chip_dir}/zzz_generated/app-common ${chip_dir}/examples/all-clusters-app/all-clusters-common ${chip_dir}/examples/all-clusters-app/all-clusters-common/include + ${chip_dir}/examples/energy-management-app/energy-management-common/include ${chip_dir}/examples/all-clusters-app/ameba/main/include ${chip_dir}/examples/platform/ameba ${chip_dir}/examples/platform/ameba/route_hook diff --git a/examples/all-clusters-app/asr/BUILD.gn b/examples/all-clusters-app/asr/BUILD.gn index 75c4a3171cfd4a..4774d48e93952c 100755 --- a/examples/all-clusters-app/asr/BUILD.gn +++ b/examples/all-clusters-app/asr/BUILD.gn @@ -71,8 +71,6 @@ asr_executable("clusters_app") { output_name = "chip-asr-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", @@ -82,6 +80,8 @@ asr_executable("clusters_app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${examples_plat_dir}/ButtonHandler.cpp", "${examples_plat_dir}/CHIPDeviceManager.cpp", "${examples_plat_dir}/LEDWidget.cpp", @@ -111,6 +111,7 @@ asr_executable("clusters_app") { "${examples_plat_dir}", "${asr_project_dir}/include", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/src", "${chip_root}/src/lib", "${chip_root}/src/lib/support", diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn index ad07e2c7a0da32..dec41e71dc265c 100644 --- a/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn +++ b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn @@ -75,8 +75,6 @@ ti_simplelink_executable("all-clusters-app") { output_name = "chip-${ti_simplelink_board}-all-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -87,6 +85,8 @@ ti_simplelink_executable("all-clusters-app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/ClusterManager.cpp", @@ -112,6 +112,7 @@ ti_simplelink_executable("all-clusters-app") { "${project_dir}", "${project_dir}/main", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/examples/providers/", ] diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn index c35afae97aabba..0fd26ca07fdc5f 100644 --- a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn +++ b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn @@ -78,8 +78,6 @@ ti_simplelink_executable("all-clusters-app") { output_name = "chip-${ti_simplelink_board}-all-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -90,6 +88,8 @@ ti_simplelink_executable("all-clusters-app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/ClusterManager.cpp", @@ -116,6 +116,7 @@ ti_simplelink_executable("all-clusters-app") { "${project_dir}", "${project_dir}/main", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/examples/providers/", ] diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 5680634c786678..e8851aa5a4d3d5 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -18,6 +18,7 @@ # The list of src and include dirs must be in sync with that in all-clusters-app/esp32/main/component.mk set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/energy-management-common/include" "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" diff --git a/examples/all-clusters-app/infineon/psoc6/BUILD.gn b/examples/all-clusters-app/infineon/psoc6/BUILD.gn index b99dc84405e841..f406b3ac5d6eab 100644 --- a/examples/all-clusters-app/infineon/psoc6/BUILD.gn +++ b/examples/all-clusters-app/infineon/psoc6/BUILD.gn @@ -107,8 +107,6 @@ psoc6_executable("clusters_app") { output_name = "chip-psoc6-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", @@ -118,6 +116,8 @@ psoc6_executable("clusters_app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${examples_plat_dir}/LEDWidget.cpp", "${examples_plat_dir}/init_psoc6Platform.cpp", "src/AppTask.cpp", @@ -141,6 +141,7 @@ psoc6_executable("clusters_app") { "${examples_plat_dir}", "${psoc6_project_dir}/include", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", ] defines = [] diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index b3eb61c29f875a..af9414529ca76e 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -21,8 +21,6 @@ import("${chip_root}/src/platform/device.gni") source_set("chip-all-clusters-common") { sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -41,6 +39,8 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "AllClustersCommandDelegate.cpp", "AppOptions.cpp", "WindowCoveringManager.cpp", @@ -57,8 +57,10 @@ source_set("chip-all-clusters-common") { "${chip_root}/third_party/jsoncpp", ] - include_dirs = - [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include" ] + include_dirs = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] cflags = [ "-Wconversion" ] diff --git a/examples/all-clusters-app/mbed/CMakeLists.txt b/examples/all-clusters-app/mbed/CMakeLists.txt index 79a48c85938f78..7a240a57dc8424 100644 --- a/examples/all-clusters-app/mbed/CMakeLists.txt +++ b/examples/all-clusters-app/mbed/CMakeLists.txt @@ -7,6 +7,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(ALL_CLUSTERS_COMMON ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) configure_file( @@ -49,6 +50,7 @@ target_include_directories(${APP_TARGET} PRIVATE main/include/ ${MBED_COMMON}/util/include ${ALL_CLUSTERS_COMMON}/include + ${ENERGY_MANAGEMENT_COMMON}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${NLIO_ROOT} @@ -63,13 +65,13 @@ target_sources(${APP_TARGET} PRIVATE ${ALL_CLUSTERS_COMMON}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON}/src/resource-monitoring-delegates.cpp ${ALL_CLUSTERS_COMMON}/src/smco-stub.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-temperature-levels.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseManager.cpp ) chip_configure_data_model(${APP_TARGET} diff --git a/examples/all-clusters-app/nrfconnect/CMakeLists.txt b/examples/all-clusters-app/nrfconnect/CMakeLists.txt index 72b93e0647724c..f9d635bdd2c3a9 100644 --- a/examples/all-clusters-app/nrfconnect/CMakeLists.txt +++ b/examples/all-clusters-app/nrfconnect/CMakeLists.txt @@ -19,6 +19,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connect get_filename_component(NRFCONNECT_COMMON ${CHIP_ROOT}/examples/platform/nrfconnect REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON_DIR ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) @@ -49,6 +50,7 @@ include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_include_directories(app PRIVATE main/include ${ALL_CLUSTERS_COMMON_DIR}/include + ${ENERGY_MANAGEMENT_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${NRFCONNECT_COMMON}/util/include) @@ -61,13 +63,13 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseManager.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp) chip_configure_data_model(app diff --git a/examples/all-clusters-app/nxp/mw320/BUILD.gn b/examples/all-clusters-app/nxp/mw320/BUILD.gn index ab7be5a04d64c1..89c8b05b9a842e 100644 --- a/examples/all-clusters-app/nxp/mw320/BUILD.gn +++ b/examples/all-clusters-app/nxp/mw320/BUILD.gn @@ -71,11 +71,10 @@ mw320_executable("shell_mw320") { "${chip_root}/src", "${chip_root}/src/app/util", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/examples/all-clusters-app/nxp/mw320/include", ] sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", @@ -85,6 +84,8 @@ mw320_executable("shell_mw320") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/src/lib/shell/streamer_mw320.cpp", "binding-handler.cpp", "include/CHIPProjectConfig.h", diff --git a/examples/all-clusters-app/openiotsdk/CMakeLists.txt b/examples/all-clusters-app/openiotsdk/CMakeLists.txt index dce8295b300cb4..6f8b679f52a52b 100644 --- a/examples/all-clusters-app/openiotsdk/CMakeLists.txt +++ b/examples/all-clusters-app/openiotsdk/CMakeLists.txt @@ -20,6 +20,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(OPEN_IOT_SDK_CONFIG ${CHIP_ROOT}/config/openiotsdk REALPATH) get_filename_component(OPEN_IOT_SDK_EXAMPLE_COMMON ${CHIP_ROOT}/examples/platform/openiotsdk REALPATH) get_filename_component(ALL_CLUSTERS_COMMON ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) @@ -47,6 +48,7 @@ target_include_directories(${APP_TARGET} PRIVATE main/include ${ALL_CLUSTERS_COMMON}/include + ${ENERGY_MANAGEMENT_COMMON}/include ) target_sources(${APP_TARGET} @@ -57,12 +59,12 @@ target_sources(${APP_TARGET} ${ALL_CLUSTERS_COMMON}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON}/src/resource-monitoring-delegates.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON}/src/binding-handler.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseManager.cpp ) target_link_libraries(${APP_TARGET} diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt index fa279aa4c8a90f..7448fd76c4d91f 100644 --- a/examples/all-clusters-app/telink/CMakeLists.txt +++ b/examples/all-clusters-app/telink/CMakeLists.txt @@ -19,6 +19,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connect get_filename_component(TELINK_COMMON ${CHIP_ROOT}/examples/platform/telink REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON_DIR ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay") set(LOCAL_DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay") @@ -65,6 +66,7 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include ${ALL_CLUSTERS_COMMON_DIR}/include + ${ENERGY_MANAGEMENT_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${TELINK_COMMON}/common/include @@ -84,10 +86,10 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseManager.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp diff --git a/examples/all-clusters-app/tizen/BUILD.gn b/examples/all-clusters-app/tizen/BUILD.gn index 6960ec6aa6d516..6af51a7f176b8a 100644 --- a/examples/all-clusters-app/tizen/BUILD.gn +++ b/examples/all-clusters-app/tizen/BUILD.gn @@ -23,8 +23,6 @@ assert(chip_build_tools) source_set("chip-all-clusters-common") { sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -35,6 +33,8 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", ] deps = [ @@ -43,8 +43,10 @@ source_set("chip-all-clusters-common") { "${chip_root}/src/lib/shell:shell_core", ] - include_dirs = - [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include" ] + include_dirs = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] } executable("chip-all-clusters-app") { diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt index 33582927c19d26..cb38515a1a8770 100644 --- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt @@ -19,6 +19,7 @@ # The list of src and include dirs must be in sync with that in all-clusters-minimal-app/esp32/main/component.mk set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/energy-management-common/include" "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" @@ -80,6 +81,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/diagnostic-logs-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/door-lock-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/energy-evse-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ethernet-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/localization-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-format-localization-server" diff --git a/examples/shell/shell_common/BUILD.gn b/examples/shell/shell_common/BUILD.gn index b870628717d8e5..a54df29c798955 100644 --- a/examples/shell/shell_common/BUILD.gn +++ b/examples/shell/shell_common/BUILD.gn @@ -64,17 +64,19 @@ static_library("shell_common") { import("${chip_root}/src/app/chip_data_model.gni") sources += [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", ] - include_dirs = - [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include" ] + include_dirs = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] public_deps += [ "${chip_root}/examples/all-clusters-app/all-clusters-common" ] From b096c88aab8ad3bf1165222ec947aaa333ef7bbb Mon Sep 17 00:00:00 2001 From: eahove Date: Fri, 22 Dec 2023 09:06:41 -0600 Subject: [PATCH 32/83] Laundry dryer controls cluster sdk (#30285) * Steps 1.1, 1.2 * update cluster list and build.gn This reverts commit feabe0b2fe2fafbd9dcd0a1a1f2d6cd6c2d5c9dd. run zap and update build, clusters list zap_regen_all & build chip-tool regen zap updated zap and regen updated zap and regen zap_regen_all & build chip-tool Revert "regen zap" This reverts commit f259abfaf960804273ff45a6ab3c16aaaae0622e. * controller-clusters.zap and regen_all * setting optional=false for clusters * zap_regen_all * run zap and update build, clusters list * zap_regen_all & build chip-tool * Fisrt Pass at SDK code * SDK is building and running * now registers laundry controls delegate added function definitions to override weak definitions that do nothing. * adding the cluster to preAttributeChange list * Restyled by clang-format * Restyled by gn * regenerated all zap * reverting submodule changes * regenerate_zap_all * update all-clusters zap * Updated cluster-enums.h path * Revert "run zap and update build, clusters list" This reverts commit 17642c9951b85d230ee5b1a9b4f4c7988d5b71e2. * Restyled by clang-format * update zap * Attribute fix for SelectedDrynessLevel * Added Attribute in zcl.json * Revert "Added Attribute in zcl.json" This reverts commit 4ee377fa04fb0ea942d244fcaff92a699bb398c0. * adding SupportedDrynessLevels to JSON bits * Updated zcl test json * Fix Dryer delegate init on Linux all-clusters * Restyled by clang-format * Added static assert for Enum and removed dryer from .json bits --------- Co-authored-by: Restyled.io Co-authored-by: OmAmbalkar <36728913+OmAmbalkar@users.noreply.github.com> Co-authored-by: tennessee.carmelveilleux@gmail.com --- .../all-clusters-app.matter | 33 ++++ .../all-clusters-common/all-clusters-app.zap | 141 ++++++++++++- .../laundry-dryer-controls-delegate-impl.h | 53 +++++ .../laundry-dryer-controls-delegate-impl.cpp | 40 ++++ .../esp32/main/CMakeLists.txt | 3 +- examples/all-clusters-app/esp32/main/main.cpp | 18 ++ examples/all-clusters-app/linux/BUILD.gn | 1 + .../all-clusters-app/linux/main-common.cpp | 8 + .../laundry-dryer-controls-delegate.h | 49 +++++ .../laundry-dryer-controls-server.cpp | 187 ++++++++++++++++++ .../laundry-dryer-controls-server.h | 62 ++++++ src/app/common/templates/config-data.yaml | 1 + src/app/zap_cluster_list.json | 1 + 13 files changed, 595 insertions(+), 2 deletions(-) create mode 100644 examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h create mode 100644 examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h 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 59090b662d6486..71bb489e6a3c21 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 @@ -2785,6 +2785,28 @@ cluster BooleanState = 69 { readonly attribute int16u clusterRevision = 65533; } +/** This cluster supports remotely monitoring and controling the different typs of + functionality available to a drying device, such as a laundry dryer. */ +cluster LaundryDryerControls = 74 { + revision 1; // NOTE: Default/not specifically set + + enum DrynessLevelEnum : enum8 { + kLow = 0; + kNormal = 1; + kExtra = 2; + kMax = 3; + } + + readonly attribute DrynessLevelEnum supportedDrynessLevels[] = 0; + attribute nullable DrynessLevelEnum selectedDrynessLevel = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ cluster ModeSelect = 80 { revision 2; @@ -7038,6 +7060,17 @@ endpoint 1 { ram attribute clusterRevision default = 1; } + server cluster LaundryDryerControls { + callback attribute supportedDrynessLevels; + ram attribute selectedDrynessLevel; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster ModeSelect { ram attribute description default = "Coffee"; ram attribute standardNamespace default = 0; 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 6f35331ee14640..8f1d73386c7465 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 @@ -8408,6 +8408,144 @@ } ] }, + { + "name": "Laundry Dryer Controls", + "code": 74, + "mfgCode": null, + "define": "LAUNDRY_DRYER_CONTROLS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "SupportedDrynessLevels", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SelectedDrynessLevel", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "DrynessLevelEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Mode Select", "code": 80, @@ -22522,4 +22660,5 @@ } ], "log": [] -} \ No newline at end of file +} + diff --git a/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h new file mode 100644 index 00000000000000..898cf8806f4111 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h @@ -0,0 +1,53 @@ +/* + * + * 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 + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** + * The application delegate to statically define the options. + */ + +class LaundryDryerControlDelegate : public Delegate +{ + static const DrynessLevelEnum supportedDrynessLevelOptions[]; + static LaundryDryerControlDelegate instance; + +public: + CHIP_ERROR GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDrynessLevel); + + LaundryDryerControlDelegate() = default; + ~LaundryDryerControlDelegate() = default; + + static inline LaundryDryerControlDelegate & getLaundryDryerControlDelegate() { return instance; } +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp new file mode 100644 index 00000000000000..d404680f2a87d2 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp @@ -0,0 +1,40 @@ +/* + * + * 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 + +using namespace chip; +using namespace chip::app::Clusters::LaundryDryerControls; + +const DrynessLevelEnum LaundryDryerControlDelegate::supportedDrynessLevelOptions[] = { DrynessLevelEnum::kLow, + DrynessLevelEnum::kNormal, + DrynessLevelEnum::kMax }; + +LaundryDryerControlDelegate LaundryDryerControlDelegate::instance; + +// TODO: Add EndpointId to the API so that different values per endpoint may be possible in some implementations. +CHIP_ERROR LaundryDryerControlDelegate::GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDrynessLevel) +{ + if (index >= ArraySize(supportedDrynessLevelOptions)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + supportedDrynessLevel = supportedDrynessLevelOptions[index]; + return CHIP_NO_ERROR; +} diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index e8851aa5a4d3d5..d1b795e47d1e99 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -86,7 +86,8 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/temperature-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/dishwasher-alarm-server" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-dryer-controls-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/electrical-energy-measurement-server" ) diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index 9972f95b95f546..4893cf1b8f1475 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -133,6 +133,24 @@ static void InitServer(intptr_t context) app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); } +// #include +#include +#include + +using namespace chip::app::Clusters::LaundryWasherControls; +void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryWasherControlsServer::SetDefaultDelegate(1, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); +} + +#include +#include +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} + extern "C" void app_main() { // Initialize the ESP NVS layer. diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index af9414529ca76e..6feba8becbe31b 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -29,6 +29,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp", diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index f53b6aa68c8057..bf47dae4646b4b 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -21,6 +21,7 @@ #include "air-quality-instance.h" #include "dishwasher-mode.h" #include "include/tv-callbacks.h" +#include "laundry-dryer-controls-delegate-impl.h" #include "laundry-washer-controls-delegate-impl.h" #include "laundry-washer-mode.h" #include "microwave-oven-mode.h" @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +250,12 @@ void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); } +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} + void emberAfLowPowerClusterInitCallback(EndpointId endpoint) { ChipLogProgress(NotSpecified, "Setting LowPower default delegate to global manager"); diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h new file mode 100644 index 00000000000000..253ad62ca549fe --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h @@ -0,0 +1,49 @@ +/* + * + * 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 { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** @brief + * Defines methods for implementing application-specific logic for the laundry dryer controls cluster. + */ +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + /** + * Get the supported dryness value at the given index in the list. + * @param index The index of the supported dryness with 0 representing the first one. + * @param supportedDryness The supported dryness at the given index + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the list of supported dryness. + */ + virtual CHIP_ERROR GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDryness) = 0; +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp new file mode 100644 index 00000000000000..3f9e1646f1ec11 --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp @@ -0,0 +1,187 @@ +/** + * + * 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. + */ + +#include +#include +#include + +#include "laundry-dryer-controls-delegate.h" +#include "laundry-dryer-controls-server.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::LaundryDryerControls; +using namespace chip::app::Clusters::LaundryDryerControls::Attributes; +using chip::Protocols::InteractionModel::Status; + +static constexpr size_t kLaundryDryerControlsDelegateTableSize = + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +// ----------------------------------------------------------------------------- +// Delegate Implementation +// +namespace { +Delegate * gDelegateTable[kLaundryDryerControlsDelegateTableSize] = { nullptr }; +} + +namespace { +Delegate * GetDelegate(EndpointId endpoint) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryDryerControls::Id, + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kLaundryDryerControlsDelegateTableSize ? nullptr : gDelegateTable[ep]); +} + +} // namespace + +LaundryDryerControlsServer LaundryDryerControlsServer::sInstance; + +/********************************************************** + * LaundryDryerControlsServer public methods + *********************************************************/ +void LaundryDryerControlsServer::SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryDryerControls::Id, + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found + if (ep < kLaundryDryerControlsDelegateTableSize) + { + gDelegateTable[ep] = delegate; + } +} + +LaundryDryerControlsServer & LaundryDryerControlsServer::Instance() +{ + return sInstance; +} + +EmberAfStatus LaundryDryerControlsServer::SetSelectedDrynessLevel(EndpointId endpointId, DrynessLevelEnum newSelectedDrynessLevel) +{ + DataModel::Nullable selectedDrynessLevel; + EmberAfStatus res = SelectedDrynessLevel::Get(endpointId, selectedDrynessLevel); + + if ((res == EMBER_ZCL_STATUS_SUCCESS) && (selectedDrynessLevel != newSelectedDrynessLevel)) + { + res = SelectedDrynessLevel::Set(endpointId, newSelectedDrynessLevel); + } + + return res; +} + +EmberAfStatus LaundryDryerControlsServer::GetSelectedDrynessLevel(EndpointId endpointId, + DataModel::Nullable & selectedDrynessLevel) +{ + return SelectedDrynessLevel::Get(endpointId, selectedDrynessLevel); +} + +/********************************************************** + * LaundryDryerControlsServer private methods + *********************************************************/ +CHIP_ERROR LaundryDryerControlsServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != LaundryDryerControls::Id) + { + // We shouldn't have been called at all. + return CHIP_ERROR_INVALID_ARGUMENT; + } + switch (aPath.mAttributeId) + { + case Attributes::SupportedDrynessLevels::Id: + return ReadSupportedDrynessLevels(aPath, aEncoder); + default: + break; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR LaundryDryerControlsServer::ReadSupportedDrynessLevels(const ConcreteReadAttributePath & aPath, + AttributeValueEncoder & aEncoder) +{ + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is nullptr")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + DrynessLevelEnum supportedDrynessLevel; + auto err = delegate->GetSupportedDrynessLevelAtIndex(i, supportedDrynessLevel); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(supportedDrynessLevel)); + } + }); +} + +/********************************************************** + * Register LaundryDryerControlsServer + *********************************************************/ + +void MatterLaundryDryerControlsPluginServerInitCallback() +{ + LaundryDryerControlsServer & laundryDryerControlsServer = LaundryDryerControlsServer::Instance(); + registerAttributeAccessOverride(&laundryDryerControlsServer); +} + +Status MatterLaundryDryerControlsClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, + uint8_t * value) +{ + Delegate * delegate = GetDelegate(attributePath.mEndpointId); + VerifyOrDie((delegate != nullptr) && "Dryer Controls implementation requires a registered delegate for validation."); + switch (attributePath.mAttributeId) + { + case Attributes::SelectedDrynessLevel::Id: { + uint8_t drynessLevelIdx = 0; + while (true) + { + DrynessLevelEnum supportedDryness; + auto err = delegate->GetSupportedDrynessLevelAtIndex(drynessLevelIdx, supportedDryness); + if (err != CHIP_NO_ERROR) + { + // Can't find the attribute to be written in the supported list (CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + // Or can't get the correct supported list + return Status::InvalidInState; + } + static_assert(sizeof(DrynessLevelEnum) == sizeof(*value), "Enum size doesn't match parameter size"); + if (supportedDryness == static_cast(*value)) + { + // The written attribute is one of the supported item + return Status::Success; + } + drynessLevelIdx++; + } + } + } + return Status::Success; +} diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h new file mode 100644 index 00000000000000..454c029e21fc52 --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h @@ -0,0 +1,62 @@ +/** + * + * 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. + */ + +#pragma once + +#include "laundry-dryer-controls-delegate.h" +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** + * @brief LaundryDryerControls Server Plugin class + */ +class LaundryDryerControlsServer : public AttributeAccessInterface +{ +public: + LaundryDryerControlsServer() : AttributeAccessInterface(Optional::Missing(), LaundryDryerControls::Id) {} + static LaundryDryerControlsServer & Instance(); + + /** + * Set the default delegate of laundry dryer server at endpoint x + * @param endpoint ID of the endpoint + * @param delegate The default delegate at the endpoint + */ + static void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + + /** + * API to set/get the SelectedDrynessLevel attribute + */ + EmberAfStatus SetSelectedDrynessLevel(EndpointId endpointId, DrynessLevelEnum newSelectedDrynessLevel); + EmberAfStatus GetSelectedDrynessLevel(EndpointId endpointId, DataModel::Nullable & selectedDrynessLevel); + +private: + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR ReadSupportedDrynessLevels(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder); + + static LaundryDryerControlsServer sInstance; +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 5586614c6d7186..8c8300d9c20e4a 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -77,3 +77,4 @@ ClustersWithPreAttributeChangeFunctions: - Fan Control - Thermostat - Laundry Washer Controls + - Laundry Dryer Controls diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 15df401e161d4f..a7f1c8e58dca6f 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -288,6 +288,7 @@ "VALVE_CONFIGURATION_AND_CONTROL_CLUSTER": [], "WAKE_ON_LAN_CLUSTER": ["wake-on-lan-server"], "LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"], + "LAUNDRY_DRYER_CONTROLS_CLUSTER": ["laundry-dryer-controls-server"], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], "ZLL_COMMISSIONING_CLUSTER": [] From 70ac7e07a0a1fbecee2bef2dfc2af532d4678167 Mon Sep 17 00:00:00 2001 From: eahove Date: Fri, 22 Dec 2023 09:07:13 -0600 Subject: [PATCH 33/83] added the descriptor (#31143) --- src/app/zap-templates/zcl/data-model/chip/matter-devices.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index f76a7bb4be5fba..85805353abb9ca 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -1979,6 +1979,7 @@ limitations under the License. Endpoint +
From adf6ce5290fcde7f129214985b35741411843c03 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 22 Dec 2023 13:04:25 -0500 Subject: [PATCH 34/83] Mark some RVC bits that people are trying to remove/deprecate provisional on Darwin. (#31170) See https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/8637 --- .../CHIP/templates/availability.yaml | 22 ++++++++++------- .../CHIP/zap-generated/MTRBaseClusters.h | 24 +++++++++---------- .../CHIP/zap-generated/MTRClusterConstants.h | 4 ++-- .../CHIP/zap-generated/MTRClusters.h | 12 +++++----- .../zap-generated/cluster/Commands.h | 12 ++++++++++ 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index a546dfed9c956d..f131b3cd09a06f 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -7491,6 +7491,12 @@ FanControl: # New Fan Control bits not stable yet. - AirflowDirection + RVCCleanMode: + # People are trying to deprecate this one + - OnMode + RVCRunMode: + # People are trying to deprecate this one + - OnMode commands: FanControl: # Not stable yet @@ -7543,6 +7549,14 @@ Feature: - Step - AirflowDirection + RVCRunMode: + Feature: + # People are trying to deprecate this one + - OnOff + RVCCleanMode: + Feature: + # People are trying to deprecate this one + - OnOff global attributes: - EventList # Once we actually unmark TimeSynchronization as provisional, all these bits except EventList should go away too, and we should instead @@ -7801,7 +7815,6 @@ RVCRunMode: - SupportedModes - CurrentMode - - OnMode - GeneratedCommandList - AcceptedCommandList - AttributeList @@ -7810,7 +7823,6 @@ RVCCleanMode: - SupportedModes - CurrentMode - - OnMode - GeneratedCommandList - AcceptedCommandList - AttributeList @@ -8186,12 +8198,6 @@ OptionsBitmap: - ExecuteIfOff - CoupleColorTempToLevel - RVCRunMode: - Feature: - - OnOff - RVCCleanMode: - Feature: - - OnOff Thermostat: ScheduleDayOfWeekBitmap: - Sunday diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 046e4442fa8725..8f1afd460544f8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -5588,13 +5588,13 @@ MTR_NEWLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params @@ -5677,13 +5677,13 @@ MTR_NEWLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params @@ -16757,7 +16757,7 @@ typedef NS_ENUM(uint8_t, MTRRVCRunModeStatusCode) { } MTR_NEWLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRRVCRunModeFeature) { - MTRRVCRunModeFeatureOnOff MTR_NEWLY_AVAILABLE = 0x1, + MTRRVCRunModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_NEWLY_AVAILABLE; typedef NS_ENUM(uint16_t, MTRRVCCleanModeModeTag) { @@ -16771,7 +16771,7 @@ typedef NS_ENUM(uint8_t, MTRRVCCleanModeStatusCode) { } MTR_NEWLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRRVCCleanModeFeature) { - MTRRVCCleanModeFeatureOnOff MTR_NEWLY_AVAILABLE = 0x1, + MTRRVCCleanModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_NEWLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRTemperatureControlFeature) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index e2e41259e4f052..8e221a71fa9f7a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -2400,7 +2400,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster RVCRunMode attributes MTRAttributeIDTypeClusterRVCRunModeAttributeSupportedModesID MTR_NEWLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterRVCRunModeAttributeCurrentModeID MTR_NEWLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterRVCRunModeAttributeOnModeID MTR_NEWLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterRVCRunModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterRVCRunModeAttributeGeneratedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCRunModeAttributeAcceptedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterRVCRunModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -2411,7 +2411,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster RVCCleanMode attributes MTRAttributeIDTypeClusterRVCCleanModeAttributeSupportedModesID MTR_NEWLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterRVCCleanModeAttributeCurrentModeID MTR_NEWLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterRVCCleanModeAttributeOnModeID MTR_NEWLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterRVCCleanModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterRVCCleanModeAttributeGeneratedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeAcceptedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index d9b141845086a7..9f64d2739f357a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -2619,9 +2619,9 @@ MTR_NEWLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_NEWLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; @@ -2665,9 +2665,9 @@ MTR_NEWLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_NEWLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; 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 049ecbb65d29d5..61c9dc61e9bd56 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -59025,6 +59025,8 @@ class SubscribeAttributeRvcRunModeCurrentMode : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + /* * Attribute OnMode */ @@ -59151,6 +59153,8 @@ class SubscribeAttributeRvcRunModeOnMode : public SubscribeAttribute { } }; +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute GeneratedCommandList */ @@ -59884,6 +59888,8 @@ class SubscribeAttributeRvcCleanModeCurrentMode : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + /* * Attribute OnMode */ @@ -60010,6 +60016,8 @@ class SubscribeAttributeRvcCleanModeOnMode : public SubscribeAttribute { } }; +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute GeneratedCommandList */ @@ -176701,9 +176709,11 @@ void registerClusterRvcRunMode(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -176738,9 +176748,11 @@ void registerClusterRvcCleanMode(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // From 0aa3a0c272b33ea694d618c56cafaa1ba7a1ad6d Mon Sep 17 00:00:00 2001 From: Hyukjin Kwon Date: Sat, 23 Dec 2023 03:08:46 +0900 Subject: [PATCH 35/83] Minor typo fixes in README.md (#31167) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 72d4337af2061a..1dad5ef6fe4d4f 100644 --- a/README.md +++ b/README.md @@ -210,18 +210,18 @@ The Matter repository is structured as follows: | credentials | Development and test credentials | | docs | Documentation, including guides. Visit the [Matter SDK documentation page](https://project-chip.github.io/connectedhomeip-doc/index.html) to read it. | | examples | Example firmware applications that demonstrate use of Matter | -| integrations | 3rd Party integrations | +| integrations | 3rd party integrations | | scripts | Scripts needed to work with the Matter repository | | src | Implementation of Matter | | third_party | 3rd party code used by Matter | -| zzz_generated | zap generated template code - Revolving around cluster information | -| BUILD.gn | Build file for the gn build system | +| zzz_generated | ZAP generated template code - Revolving around cluster information | +| BUILD.gn | Build file for the GN build system | | CODE_OF_CONDUCT.md | Code of conduct for Matter and contribution to it | | CONTRIBUTING.md | Guidelines for contributing to Matter | | LICENSE | Matter license file | | REVIEWERS.md | PR reviewers | | gn_build.sh | Build script for specific projects such as Android, EFR32, etc. | -| README.md | This File | +| README.md | This file | # License From 6484d4de0adad9c7605b9f1d9ae58ba69814dc3e Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 23 Dec 2023 03:20:19 +0900 Subject: [PATCH 36/83] [Android] Implement for supporting ICD device (#31055) * Implement for supporting ICD device in Android Controller * Add exception TooManyFunctions * Restyled by google-java-format * Restyled by clang-format * Add comment * Modify typo, use static_cast * Modify comments * Add default parameter for ICD * Add java test for ICD * Remove 'p' * Restyled by google-java-format * Update comment * Restyled by google-java-format --------- Co-authored-by: Restyled.io --- .github/workflows/java-tests.yaml | 12 ++ .../chiptool/GenericChipDeviceListener.kt | 8 + .../DeviceProvisioningFragment.kt | 12 ++ .../commands/pairing/PairingCommand.kt | 14 ++ .../commands/pairing/PairingCommand.kt | 11 ++ kotlin-detect-config.yaml | 1 + .../java/AndroidDeviceControllerWrapper.cpp | 85 ++++++++++ .../java/AndroidDeviceControllerWrapper.h | 8 + src/controller/java/BUILD.gn | 1 + .../java/CHIPDeviceController-JNI.cpp | 61 ++++++- .../ChipDeviceController.java | 149 ++++++++++++++++-- .../devicecontroller/ICDRegistrationInfo.java | 88 +++++++++++ .../controller/CompletionListenerAdapter.kt | 5 + .../src/matter/controller/MatterController.kt | 9 ++ 14 files changed, 452 insertions(+), 12 deletions(-) create mode 100644 src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index 9e800ba2e7ef99..72df162e06b3b9 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -90,6 +90,7 @@ jobs: "./scripts/build/build_examples.py \ --target linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-java-matter-controller \ + --target linux-x64-lit-icd-ipv6only \ build \ " - name: Build Kotlin Matter Controller @@ -210,6 +211,17 @@ jobs: --tool-args "code --nodeid 1 --setup-payload 34970112332 --discover-once 1 --use-only-onnetwork-discovery 0 -t 1000" \ --factoryreset \ ' + - name: Run Pairing ICD Onnetwork Test + run: | + scripts/run_in_python_env.sh out/venv \ + './scripts/tests/run_java_test.py \ + --app out/linux-x64-lit-icd-ipv6only/lit-icd-app \ + --app-args "--discriminator 3840 --interface-id -1" \ + --tool-path out/linux-x64-java-matter-controller \ + --tool-cluster "pairing" \ + --tool-args "onnetwork-long --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \ + --factoryreset \ + ' - name: Run Pairing Onnetwork Test run: | scripts/run_in_python_env.sh out/venv \ diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt index 1d62115547e305..12e17998fa7c15 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt @@ -51,4 +51,12 @@ open class GenericChipDeviceListener : ChipDeviceController.CompletionListener { override fun onOpCSRGenerationComplete(csr: ByteArray) { // No op } + + override fun onICDRegistrationInfoRequired() { + // No op + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + // No op + } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt index 999bc6bc1b5513..16a411bc5eba05 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt @@ -32,6 +32,7 @@ import androidx.lifecycle.lifecycleScope import chip.devicecontroller.AttestationInfo import chip.devicecontroller.ChipDeviceController import chip.devicecontroller.DeviceAttestationDelegate +import chip.devicecontroller.ICDRegistrationInfo import chip.devicecontroller.NetworkCredentials import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener @@ -284,6 +285,17 @@ class DeviceProvisioningFragment : Fragment() { override fun onError(error: Throwable?) { Log.d(TAG, "onError: $error") } + + override fun onICDRegistrationInfoRequired() { + Log.d(TAG, "onICDRegistrationInfoRequired") + deviceController.updateCommissioningICDRegistrationInfo( + ICDRegistrationInfo.newBuilder().build() + ) + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + Log.d(TAG, "onICDRegistrationComplete - icdNodeId : $icdNodeId, icdCounter : $icdCounter") + } } /** Callback from [DeviceProvisioningFragment] notifying any registered listeners. */ diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 0fc62cae9187db..572b309f02b74b 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -18,6 +18,7 @@ package com.matter.controller.commands.pairing import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.ICDRegistrationInfo import chip.devicecontroller.NetworkCredentials import com.matter.controller.commands.common.CredentialsIssuer import com.matter.controller.commands.common.IPAddress @@ -178,6 +179,19 @@ abstract class PairingCommand( } } + override fun onICDRegistrationInfoRequired() { + logger.log(Level.INFO, "onICDRegistrationInfoRequired") + currentCommissioner() + .updateCommissioningICDRegistrationInfo(ICDRegistrationInfo.newBuilder().build()) + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + logger.log( + Level.INFO, + "onICDRegistrationComplete with icdNodeId: $icdNodeId, icdCounter: $icdCounter" + ) + } + fun getNodeId(): Long { return nodeId.get() } diff --git a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 96b856568ccbc5..0e84ff7ceabf41 100644 --- a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -173,6 +173,17 @@ abstract class PairingCommand( } } + override fun onICDRegistrationInfoRequired() { + logger.log(Level.INFO, "onICDRegistrationInfoRequired") + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + logger.log( + Level.INFO, + "onICDRegistrationComplete with icdNodeId: $icdNodeId, icdCounter: $icdCounter" + ) + } + fun getNodeId(): Long { return nodeId.get() } diff --git a/kotlin-detect-config.yaml b/kotlin-detect-config.yaml index 5dcc9f99a6b3cd..4dee3c56abb918 100644 --- a/kotlin-detect-config.yaml +++ b/kotlin-detect-config.yaml @@ -300,6 +300,7 @@ complexity: - "**/src/controller/java/src/matter/tlv/TlvWriter.kt" - "**/src/controller/java/src/matter/controller/MatterControllerImpl.kt" - "**/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt" + - "**/src/controller/java/src/matter/controller/MatterController.kt" - "**/src/controller/java/tests/matter/jsontlv/JsonToTlvToJsonTest.kt" - "**/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt" - "**/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt" diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 1a601ba8504dbc..e1579009f74175 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -444,6 +444,66 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyNetworkCredentials(chip::Control return err; } +CHIP_ERROR AndroidDeviceControllerWrapper::ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params, + jobject icdRegistrationInfo) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(icdRegistrationInfo != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jmethodID getCheckInNodeIdMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getCheckInNodeId", "()Ljava/lang/Long;", + &getCheckInNodeIdMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jobject jCheckInNodeId = env->CallObjectMethod(icdRegistrationInfo, getCheckInNodeIdMethod); + + jmethodID getMonitoredSubjectMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getMonitoredSubject", "()Ljava/lang/Long;", + &getMonitoredSubjectMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jobject jMonitoredSubject = env->CallObjectMethod(icdRegistrationInfo, getMonitoredSubjectMethod); + + jmethodID getSymmetricKeyMethod; + err = + chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getSymmetricKey", "()[B", &getSymmetricKeyMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jbyteArray jSymmetricKey = static_cast(env->CallObjectMethod(icdRegistrationInfo, getSymmetricKeyMethod)); + + chip::NodeId checkInNodeId = chip::kUndefinedNodeId; + if (jCheckInNodeId != nullptr) + { + checkInNodeId = static_cast(chip::JniReferences::GetInstance().LongToPrimitive(jCheckInNodeId)); + } + else + { + checkInNodeId = mController->GetNodeId(); + } + params.SetICDCheckInNodeId(checkInNodeId); + + uint64_t monitoredSubject = static_cast(checkInNodeId); + if (jMonitoredSubject != nullptr) + { + monitoredSubject = static_cast(chip::JniReferences::GetInstance().LongToPrimitive(jMonitoredSubject)); + } + params.SetICDMonitoredSubject(monitoredSubject); + + if (jSymmetricKey != nullptr) + { + JniByteArray jniSymmetricKey(env, jSymmetricKey); + VerifyOrReturnError(jniSymmetricKey.size() == sizeof(mICDSymmetricKey), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mICDSymmetricKey, jniSymmetricKey.data(), sizeof(mICDSymmetricKey)); + } + else + { + chip::Crypto::DRBG_get_bytes(mICDSymmetricKey, sizeof(mICDSymmetricKey)); + } + params.SetICDSymmetricKey(chip::ByteSpan(mICDSymmetricKey)); + + return err; +} + CHIP_ERROR AndroidDeviceControllerWrapper::UpdateCommissioningParameters(const chip::Controller::CommissioningParameters & params) { // this will wipe out any custom attestationNonce and csrNonce that was being used. @@ -814,6 +874,31 @@ void AndroidDeviceControllerWrapper::OnScanNetworksFailure(CHIP_ERROR error) CallJavaMethod("onScanNetworksFailure", static_cast(error.AsInteger())); } +void AndroidDeviceControllerWrapper::OnICDRegistrationInfoRequired() +{ + chip::DeviceLayer::StackUnlock unlock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + jmethodID onICDRegistrationInfoRequiredMethod; + CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationInfoRequired", "()V", + &onICDRegistrationInfoRequiredMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format())); + + env->CallVoidMethod(mJavaObjectRef, onICDRegistrationInfoRequiredMethod); +} + +void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) +{ + chip::DeviceLayer::StackUnlock unlock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + jmethodID onICDRegistrationCompleteMethod; + CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationComplete", "(JJ)V", + &onICDRegistrationCompleteMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format())); + + env->CallVoidMethod(mJavaObjectRef, onICDRegistrationCompleteMethod, static_cast(icdNodeId), + static_cast(icdCounter)); +} + CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { ChipLogProgress(chipTool, "KVS: Getting key %s", StringOrNullMarker(key)); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index d78d4803a697c0..6594c41fcdd66f 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -87,6 +87,11 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel */ CHIP_ERROR ApplyNetworkCredentials(chip::Controller::CommissioningParameters & params, jobject networkCredentials); + /** + * Convert ICD Registration Infomations from Java, and apply them to the commissioning parameters object. + */ + CHIP_ERROR ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params, jobject icdRegistrationInfo); + /** * Update the CommissioningParameters used by the active device commissioner */ @@ -103,6 +108,8 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel void OnScanNetworksSuccess( const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse) override; void OnScanNetworksFailure(CHIP_ERROR error) override; + void OnICDRegistrationInfoRequired() override; + void OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) override; // PersistentStorageDelegate implementation CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; @@ -242,6 +249,7 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel #if CHIP_DEVICE_CONFIG_DYNAMIC_SERVER OTAProviderDelegateBridge * mOtaProviderBridge = nullptr; #endif + uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; AndroidDeviceControllerWrapper(ChipDeviceControllerPtr controller, #ifdef JAVA_MATTER_CONTROLLER_TEST diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 1a3b05c73f7ce2..a538afefc744c5 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -444,6 +444,7 @@ android_library("java") { "src/chip/devicecontroller/DiscoveredDevice.java", "src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java", "src/chip/devicecontroller/GroupKeySecurityPolicy.java", + "src/chip/devicecontroller/ICDRegistrationInfo.java", "src/chip/devicecontroller/InvokeCallback.java", "src/chip/devicecontroller/InvokeCallbackJni.java", "src/chip/devicecontroller/KeypairDelegate.java", diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 93a4e239a9b9ae..ecbaa7fc91657a 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -627,7 +627,7 @@ JNI_METHOD(void, commissionDevice) JNI_METHOD(void, pairDevice) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint connObj, jlong pinCode, jbyteArray csrNonce, - jobject networkCredentials) + jobject networkCredentials, jobject icdRegistrationInfo) { chip::DeviceLayer::StackLock lock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -656,6 +656,13 @@ JNI_METHOD(void, pairDevice) JniByteArray jniCsrNonce(env, csrNonce); commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); } + + commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + if (icdRegistrationInfo != nullptr) + { + wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + } + if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr) { commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge()); @@ -671,7 +678,7 @@ JNI_METHOD(void, pairDevice) JNI_METHOD(void, pairDeviceWithAddress) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring address, jint port, jint discriminator, jlong pinCode, - jbyteArray csrNonce) + jbyteArray csrNonce, jobject icdRegistrationInfo) { chip::DeviceLayer::StackLock lock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -699,6 +706,13 @@ JNI_METHOD(void, pairDeviceWithAddress) JniByteArray jniCsrNonce(env, csrNonce); commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); } + + commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + if (icdRegistrationInfo != nullptr) + { + wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + } + if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr) { commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge()); @@ -714,7 +728,7 @@ JNI_METHOD(void, pairDeviceWithAddress) JNI_METHOD(void, pairDeviceWithCode) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring setUpCode, jboolean discoverOnce, - jboolean useOnlyOnNetworkDiscovery, jbyteArray csrNonce, jobject networkCredentials) + jboolean useOnlyOnNetworkDiscovery, jbyteArray csrNonce, jobject networkCredentials, jobject icdRegistrationInfo) { chip::DeviceLayer::StackLock lock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -748,6 +762,12 @@ JNI_METHOD(void, pairDeviceWithCode) wrapper->ApplyNetworkCredentials(commissioningParams, networkCredentials); } + commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + if (icdRegistrationInfo != nullptr) + { + wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + } + if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr) { commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge()); @@ -899,6 +919,41 @@ JNI_METHOD(void, updateCommissioningNetworkCredentials) } } +JNI_METHOD(void, updateCommissioningICDRegistrationInfo) +(JNIEnv * env, jobject self, jlong handle, jobject icdRegistrationInfo) +{ + ChipLogProgress(Controller, "updateCommissioningICDRegistrationInfo() called"); + chip::DeviceLayer::StackLock lock; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters(); + CHIP_ERROR err = wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "ApplyICDRegistrationInfo failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + return; + } + err = wrapper->UpdateCommissioningParameters(commissioningParams); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "UpdateCommissioningParameters failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + return; + } + + // Only invoke ICDRegistrationInfoReady when called in ICDRegistartionInfo stage. + if (wrapper->Controller()->GetCommissioningStage() == CommissioningStage::kICDGetRegistrationInfo) + { + err = wrapper->Controller()->ICDRegistrationInfoReady(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "ICDRegistrationInfoReady failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + } + } +} + jint GetCalendarFieldID(JNIEnv * env, const char * method) { jclass calendarCls = env->FindClass("java/util/Calendar"); diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 846ed32a84c6b1..ba3a7091e26e5f 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -141,7 +141,28 @@ public void pairDevice( long deviceId, long setupPincode, NetworkCredentials networkCredentials) { - pairDevice(bleServer, connId, deviceId, setupPincode, null, networkCredentials); + pairDevice(bleServer, connId, deviceId, setupPincode, null, networkCredentials, null); + } + + public void pairDevice( + BluetoothGatt bleServer, + int connId, + long deviceId, + long setupPincode, + NetworkCredentials networkCredentials, + ICDRegistrationInfo registrationInfo) { + pairDevice( + bleServer, connId, deviceId, setupPincode, null, networkCredentials, registrationInfo); + } + + public void pairDevice( + BluetoothGatt bleServer, + int connId, + long deviceId, + long setupPincode, + @Nullable byte[] csrNonce, + NetworkCredentials networkCredentials) { + pairDevice(bleServer, connId, deviceId, setupPincode, csrNonce, networkCredentials, null); } /** @@ -153,6 +174,11 @@ public void pairDevice( * @param setupPincode the pincode for the device * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly * generated CSR nonce. + * @param networkCredentials the credentials (Wi-Fi or Thread) to be provisioned + * @param icdRegistrationInfo the informations for ICD registration. For detailed information + * {@link ICDRegistrationInfo}. If this value is null when commissioning an ICD device, {@link + * CompletionListener.onICDRegistrationInfoRequired} is called to request the + * ICDRegistrationInfo value. */ public void pairDevice( BluetoothGatt bleServer, @@ -160,7 +186,8 @@ public void pairDevice( long deviceId, long setupPincode, @Nullable byte[] csrNonce, - NetworkCredentials networkCredentials) { + NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo) { if (connectionId == 0) { connectionId = connId; @@ -173,7 +200,13 @@ public void pairDevice( Log.d(TAG, "Bluetooth connection added with ID: " + connectionId); Log.d(TAG, "Pairing device with ID: " + deviceId); pairDevice( - deviceControllerPtr, deviceId, connectionId, setupPincode, csrNonce, networkCredentials); + deviceControllerPtr, + deviceId, + connectionId, + setupPincode, + csrNonce, + networkCredentials, + icdRegistrationInfo); } else { Log.e(TAG, "Bluetooth connection already in use."); completionListener.onError(new Exception("Bluetooth connection already in use.")); @@ -188,7 +221,59 @@ public void pairDeviceWithAddress( long pinCode, @Nullable byte[] csrNonce) { pairDeviceWithAddress( - deviceControllerPtr, deviceId, address, port, discriminator, pinCode, csrNonce); + deviceControllerPtr, deviceId, address, port, discriminator, pinCode, csrNonce, null); + } + + /** + * Pair a device connected using IP Address. + * + * @param deviceId the node ID to assign to the device + * @param address IP Address of the connecting device + * @param port the port of the connecting device + * @param discriminator the discriminator for connecting device + * @param pinCode the pincode for connecting device + * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly + * generated CSR nonce. + * @param icdRegistrationInfo the informations for ICD registration. For detailed information + * {@link ICDRegistrationInfo}. If this value is null when commissioning an ICD device, {@link + * CompletionListener.onICDRegistrationInfoRequired} is called to request the + * ICDRegistrationInfo value. + */ + public void pairDeviceWithAddress( + long deviceId, + String address, + int port, + int discriminator, + long pinCode, + @Nullable byte[] csrNonce, + @Nullable ICDRegistrationInfo icdRegistrationInfo) { + pairDeviceWithAddress( + deviceControllerPtr, + deviceId, + address, + port, + discriminator, + pinCode, + csrNonce, + icdRegistrationInfo); + } + + public void pairDeviceWithCode( + long deviceId, + String setupCode, + boolean discoverOnce, + boolean useOnlyOnNetworkDiscovery, + @Nullable byte[] csrNonce, + @Nullable NetworkCredentials networkCredentials) { + pairDeviceWithCode( + deviceControllerPtr, + deviceId, + setupCode, + discoverOnce, + useOnlyOnNetworkDiscovery, + csrNonce, + networkCredentials, + null); } /** @@ -202,6 +287,10 @@ public void pairDeviceWithAddress( * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly * generated CSR nonce. * @param networkCredentials the credentials (Wi-Fi or Thread) to be provisioned + * @param icdRegistrationInfo the informations for ICD registration. For detailed information + * {@link ICDRegistrationInfo}. If this value is null when commissioning an ICD device, {@link + * CompletionListener.onICDRegistrationInfoRequired} is called to request the + * ICDRegistrationInfo value. */ public void pairDeviceWithCode( long deviceId, @@ -209,7 +298,8 @@ public void pairDeviceWithCode( boolean discoverOnce, boolean useOnlyOnNetworkDiscovery, @Nullable byte[] csrNonce, - @Nullable NetworkCredentials networkCredentials) { + @Nullable NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo) { pairDeviceWithCode( deviceControllerPtr, deviceId, @@ -217,7 +307,8 @@ public void pairDeviceWithCode( discoverOnce, useOnlyOnNetworkDiscovery, csrNonce, - networkCredentials); + networkCredentials, + icdRegistrationInfo); } public void establishPaseConnection(long deviceId, int connId, long setupPincode) { @@ -325,6 +416,19 @@ public void updateCommissioningNetworkCredentials(NetworkCredentials networkCred updateCommissioningNetworkCredentials(deviceControllerPtr, networkCredentials); } + /** + * Update the ICD registration information held by the commissioner for the current commissioning + * session. + * + *

Its expected that this method will be called in response the onICDRegistrationInfoRequired + * callbacks. + * + * @param ICDRegistrationInfo the ICD registration information to use in commissioning + */ + public void updateCommissioningICDRegistrationInfo(ICDRegistrationInfo icdRegistrationInfo) { + updateCommissioningICDRegistrationInfo(deviceControllerPtr, icdRegistrationInfo); + } + public void unpairDevice(long deviceId) { unpairDevice(deviceControllerPtr, deviceId); } @@ -496,6 +600,18 @@ public void onError(Throwable error) { completionListener.onError(error); } + public void onICDRegistrationInfoRequired() { + if (completionListener != null) { + completionListener.onICDRegistrationInfoRequired(); + } + } + + public void onICDRegistrationComplete(long icdNodeId, long icdCounter) { + if (completionListener != null) { + completionListener.onICDRegistrationComplete(icdNodeId, icdCounter); + } + } + public void onNOCChainGenerationNeeded(CSRInfo csrInfo, AttestationInfo attestationInfo) { if (nocChainIssuer != null) { nocChainIssuer.onNOCChainGenerationNeeded(csrInfo, attestationInfo); @@ -1248,7 +1364,8 @@ private native void pairDevice( int connectionId, long pinCode, @Nullable byte[] csrNonce, - NetworkCredentials networkCredentials); + NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo); private native void pairDeviceWithAddress( long deviceControllerPtr, @@ -1257,7 +1374,8 @@ private native void pairDeviceWithAddress( int port, int discriminator, long pinCode, - @Nullable byte[] csrNonce); + @Nullable byte[] csrNonce, + @Nullable ICDRegistrationInfo icdRegistrationInfo); private native void pairDeviceWithCode( long deviceControllerPtr, @@ -1266,7 +1384,8 @@ private native void pairDeviceWithCode( boolean discoverOnce, boolean useOnlyOnNetworkDiscovery, @Nullable byte[] csrNonce, - @Nullable NetworkCredentials networkCredentials); + @Nullable NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo); private native void establishPaseConnection( long deviceControllerPtr, long deviceId, int connId, long setupPincode); @@ -1364,6 +1483,9 @@ private native void setUseJavaCallbackForNOCRequest( private native void updateCommissioningNetworkCredentials( long deviceControllerPtr, NetworkCredentials networkCredentials); + private native void updateCommissioningICDRegistrationInfo( + long deviceControllerPtr, ICDRegistrationInfo icdRegistrationInfo); + private native int onNOCChainGeneration(long deviceControllerPtr, ControllerParams params); private native int getFabricIndex(long deviceControllerPtr); @@ -1475,5 +1597,14 @@ void onReadCommissioningInfo( /** Notifies the Commissioner when the OpCSR for the Comissionee is generated. */ void onOpCSRGenerationComplete(byte[] csr); + + /** + * Notifies when the ICD registration information (ICD symmetric key, check-in node ID and + * monitored subject) is required. + */ + void onICDRegistrationInfoRequired(); + + /** Notifies when the registration flow for the ICD completes. */ + void onICDRegistrationComplete(long icdNodeId, long icdCounter); } } diff --git a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java new file mode 100644 index 00000000000000..be978fae28fee6 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020-2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +import javax.annotation.Nullable; + +/** Class for holding ICD registration infomation. */ +public class ICDRegistrationInfo { + @Nullable private final Long checkInNodeId; + @Nullable private final Long monitoredSubject; + @Nullable private final byte[] symmetricKey; + + private ICDRegistrationInfo(Builder builder) { + this.checkInNodeId = builder.checkInNodeId; + this.monitoredSubject = builder.monitoredSubject; + this.symmetricKey = builder.symmetricKey; + } + + /** Returns the check in node ID. */ + public Long getCheckInNodeId() { + return checkInNodeId; + } + + /** Returns the monitored subject of the ICD. */ + public Long getMonitoredSubject() { + return monitoredSubject; + } + + /** Returns the 16 bytes ICD symmetric key. */ + public byte[] getSymmetricKey() { + return symmetricKey; + } + + public static Builder newBuilder() { + return new Builder(); + } + + /** Builder for {@link ICDRegistrationInfo}. */ + public static class Builder { + @Nullable private Long checkInNodeId = null; + @Nullable private Long monitoredSubject = null; + @Nullable private byte[] symmetricKey = null; + + private Builder() {} + + /** The check-in node id for the ICD. If not set this value, node id of the commissioner. */ + public Builder setCheckInNodeId(long checkInNodeId) { + this.checkInNodeId = checkInNodeId; + return this; + } + + /** + * The monitored subject of the ICD. If not set this value, the node id used for + * icd-check-in-nodeid + */ + public Builder setMonitoredSubject(long monitoredSubject) { + this.monitoredSubject = monitoredSubject; + return this; + } + + /** + * The 16 bytes ICD symmetric key, If not set this value, this value will be randomly generated. + */ + public Builder setSymmetricKey(byte[] symmetricKey) { + this.symmetricKey = symmetricKey; + return this; + } + + public ICDRegistrationInfo build() { + return new ICDRegistrationInfo(this); + } + } +} diff --git a/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt b/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt index c1956154115d89..f536fae311edaf 100644 --- a/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt +++ b/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt @@ -49,6 +49,11 @@ class CompletionListenerAdapter(val listener: MatterController.CompletionListene override fun onOpCSRGenerationComplete(csr: ByteArray) = listener.onOpCSRGenerationComplete(csr) + override fun onICDRegistrationInfoRequired() = listener.onICDRegistrationInfoRequired() + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) = + listener.onICDRegistrationComplete(icdNodeId, icdCounter) + override fun onError(error: Throwable) = listener.onError(error) override fun onCloseBleComplete() { diff --git a/src/controller/java/src/matter/controller/MatterController.kt b/src/controller/java/src/matter/controller/MatterController.kt index 5ac5a85020db98..1487446ba455f4 100644 --- a/src/controller/java/src/matter/controller/MatterController.kt +++ b/src/controller/java/src/matter/controller/MatterController.kt @@ -57,6 +57,15 @@ interface MatterController : Closeable, InteractionClient { /** Notifies the Commissioner when the OpCSR for the Comissionee is generated. */ fun onOpCSRGenerationComplete(csr: ByteArray) + + /** + * Notifies when the ICD registration information (ICD symmetric key, check-in node ID and + * monitored subject) is required. + */ + fun onICDRegistrationInfoRequired() + + /** Notifies when the registration flow for the ICD completes. */ + fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) } /** From b364ee6ea8a36a368d7b28983cadd08317db4d10 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 22 Dec 2023 10:32:05 -0800 Subject: [PATCH 37/83] =?UTF-8?q?[Android]=20Return=20ConnectionFailureExc?= =?UTF-8?q?eption=20which=20contains=20the=20connection=20state=E2=80=A6?= =?UTF-8?q?=20(#31149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Return ConnectionFailureException which contains the connection state info in onConnectionFailure * Update src/app/CASESessionManager.h Co-authored-by: Boris Zbarsky * Address review comments * Allow onFailure and onSetupFailure to be null * Update src/app/CASESessionManager.cpp Co-authored-by: Boris Zbarsky * Address review comments --------- Co-authored-by: Boris Zbarsky --- src/app/CASESessionManager.cpp | 68 +++++++++++++++++- src/app/CASESessionManager.h | 65 +++++++++++++++++ src/controller/CHIPDeviceController.h | 28 +++++++- src/controller/java/AndroidCallbacks.cpp | 10 +-- src/controller/java/AndroidCallbacks.h | 4 +- .../AndroidConnectionFailureExceptions.cpp | 44 ++++++++++++ .../java/AndroidConnectionFailureExceptions.h | 47 ++++++++++++ src/controller/java/BUILD.gn | 3 + .../ConnectionFailureException.java | 71 +++++++++++++++++++ 9 files changed, 330 insertions(+), 10 deletions(-) create mode 100644 src/controller/java/AndroidConnectionFailureExceptions.cpp create mode 100644 src/controller/java/AndroidConnectionFailureExceptions.h create mode 100644 src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp index 52c48f102672b3..382d2620fcfa6a 100644 --- a/src/app/CASESessionManager.cpp +++ b/src/app/CASESessionManager.cpp @@ -36,6 +36,56 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal uint8_t attemptCount, Callback::Callback * onRetry #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES ) +{ + FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + attemptCount, onRetry +#endif + ); +} + +void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, + Callback::Callback * onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount, Callback::Callback * onRetry +#endif +) +{ + FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + attemptCount, onRetry +#endif + ); +} + +void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, + nullptr_t +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount, Callback::Callback * onRetry +#endif +) +{ + FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + attemptCount, onRetry +#endif + ); +} + +void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerId, + Callback::Callback * onConnection, + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount, Callback::Callback * onRetry +#endif +) { ChipLogDetail(CASESessionManager, "FindOrEstablishSession: PeerId = [%d:" ChipLogFormatX64 "]", peerId.GetFabricIndex(), ChipLogValueX64(peerId.GetNodeId())); @@ -45,7 +95,6 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal if (session == nullptr) { ChipLogDetail(CASESessionManager, "FindOrEstablishSession: No existing OperationalSessionSetup instance found"); - session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this); if (session == nullptr) @@ -54,6 +103,13 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal { onFailure->mCall(onFailure->mContext, peerId, CHIP_ERROR_NO_MEMORY); } + + if (onSetupFailure != nullptr) + { + OperationalSessionSetup::ConnnectionFailureInfo failureInfo(peerId, CHIP_ERROR_NO_MEMORY, + SessionEstablishmentStage::kUnknown); + onSetupFailure->mCall(onSetupFailure->mContext, failureInfo); + } return; } } @@ -66,7 +122,15 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal } #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES - session->Connect(onConnection, onFailure); + if (onFailure != nullptr) + { + session->Connect(onConnection, onFailure); + } + + if (onSetupFailure != nullptr) + { + session->Connect(onConnection, onSetupFailure); + } } void CASESessionManager::ReleaseSessionsForFabric(FabricIndex fabricIndex) diff --git a/src/app/CASESessionManager.h b/src/app/CASESessionManager.h index 7094c88f42e104..92fb7a9ba783c7 100644 --- a/src/app/CASESessionManager.h +++ b/src/app/CASESessionManager.h @@ -87,6 +87,63 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES ); + /** + * Find an existing session for the given node ID or trigger a new session request. + * + * The caller can optionally provide `onConnection` and `onSetupFailure` + * callback objects. If provided, these will be used to inform the caller about successful or + * failed connection establishment. + * + * If the connection is already established, the `onConnection` callback will be immediately called, + * before `FindOrEstablishSession` returns. + * + * The `onSetupFailure` callback may be called before the `FindOrEstablishSession` + * call returns, for error cases that are detected synchronously. + * + * The `attemptCount` parameter can be used to automatically retry multiple times if session setup is + * not successful. + * + * @param peerId The node ID to find or establish a session with. + * @param onConnection A callback to be called upon successful connection establishment. + * @param onSetupFailure A callback to be called upon an extended device connection failure. + * @param attemptCount The number of retry attempts if session setup fails (default is 1). + * @param onRetry A callback to be called on a retry attempt (enabled by a config flag). + */ + void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, + Callback::Callback * onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount = 1, Callback::Callback * onRetry = nullptr +#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + ); + + /** + * Find an existing session for the given node ID or trigger a new session request. + * + * The caller can optionally provide `onConnection` + * callback objects. If provided, these will be used to inform the caller about successful connection establishment. + * + * If the connection is already established, the `onConnection` callback will be immediately called, + * before `FindOrEstablishSession` returns. + * + * The `attemptCount` parameter can be used to automatically retry multiple times if session setup is + * not successful. + * + * This function allows passing 'nullptr' for the error handler to compile, which is useful in scenarios where error + * handling is not needed. + * + * @param peerId The node ID to find or establish a session with. + * @param onConnection A callback to be called upon successful connection establishment. + * @param attemptCount The number of retry attempts if session setup fails (default is 1). + * @param onRetry A callback to be called on a retry attempt (enabled by a config flag). + */ + void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, nullptr_t +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount = 1, Callback::Callback * onRetry = nullptr +#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + ); + void ReleaseSessionsForFabric(FabricIndex fabricIndex); void ReleaseAllSessions(); @@ -112,6 +169,14 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess Optional FindExistingSession(const ScopedNodeId & peerId) const; + void FindOrEstablishSessionHelper(const ScopedNodeId & peerId, Callback::Callback * onConnection, + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure, +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + uint8_t attemptCount, Callback::Callback * onRetry +#endif + ); + CASESessionManagerConfig mConfig; }; diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 2007d8424b2f88..a7e6f6dac4bcb9 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -220,11 +220,11 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController * This function finds the device corresponding to deviceId, and establishes * a CASE session with it. * - * Once the CASE session is successfully established the `onConnectedDevice` + * Once the CASE session is successfully established the `onConnection` * callback is called. This can happen before GetConnectedDevice returns if * there is an existing CASE session. * - * If a CASE sessions fails to be established, the `onError` callback will + * If a CASE sessions fails to be established, the `onFailure` callback will * be called. This can also happen before GetConnectedDevice returns. * * An error return from this function means that neither callback has been @@ -238,6 +238,30 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController return CHIP_NO_ERROR; } + /** + * This function finds the device corresponding to deviceId, and establishes + * a CASE session with it. + * + * Once the CASE session is successfully established the `onConnection` + * callback is called. This can happen before GetConnectedDevice returns if + * there is an existing CASE session. + * + * If a CASE sessions fails to be established, the `onSetupFailure` callback will + * be called. This can also happen before GetConnectedDevice returns. + * + * An error return from this function means that neither callback has been + * called yet, and neither callback will be called in the future. + */ + CHIP_ERROR + GetConnectedDevice(NodeId peerNodeId, Callback::Callback * onConnection, + chip::Callback::Callback * onSetupFailure) + { + VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); + mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection, + onSetupFailure); + return CHIP_NO_ERROR; + } + /** * @brief * Compute a PASE verifier and passcode ID for the desired setup pincode. diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index 85c948404343ab..b19e50b24e06f6 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "AndroidCallbacks.h" +#include #include #ifdef USE_JAVA_TLV_ENCODE_DECODE #include @@ -114,7 +115,8 @@ void GetConnectedDeviceCallback::OnDeviceConnectedFn(void * context, Messaging:: VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } -void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) +void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, + const OperationalSessionSetup::ConnnectionFailureInfo & failureInfo) { JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); @@ -135,15 +137,15 @@ void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, con VerifyOrReturn(failureMethod != nullptr, ChipLogError(Controller, "Could not find onConnectionFailure method")); jthrowable exception; - CHIP_ERROR err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, ErrorStr(error), - error.AsInteger(), exception); + CHIP_ERROR err = AndroidConnectionFailureExceptions::GetInstance().CreateAndroidConnectionFailureException( + env, failureInfo.error.Format(), failureInfo.error.AsInteger(), failureInfo.sessionStage, exception); VerifyOrReturn( err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create AndroidControllerException on GetConnectedDeviceCallback::OnDeviceConnectionFailureFn: %s", ErrorStr(err))); DeviceLayer::StackUnlock unlock; - env->CallVoidMethod(javaCallback, failureMethod, peerId.GetNodeId(), exception); + env->CallVoidMethod(javaCallback, failureMethod, failureInfo.peerId.GetNodeId(), exception); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } diff --git a/src/controller/java/AndroidCallbacks.h b/src/controller/java/AndroidCallbacks.h index b622fc3294832e..f00075258bea8f 100644 --- a/src/controller/java/AndroidCallbacks.h +++ b/src/controller/java/AndroidCallbacks.h @@ -39,10 +39,10 @@ struct GetConnectedDeviceCallback ~GetConnectedDeviceCallback(); static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle); - static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error); + static void OnDeviceConnectionFailureFn(void * context, const OperationalSessionSetup::ConnnectionFailureInfo & failureInfo); Callback::Callback mOnSuccess; - Callback::Callback mOnFailure; + Callback::Callback mOnFailure; JniGlobalReference mWrapperCallbackRef; JniGlobalReference mJavaCallbackRef; }; diff --git a/src/controller/java/AndroidConnectionFailureExceptions.cpp b/src/controller/java/AndroidConnectionFailureExceptions.cpp new file mode 100644 index 00000000000000..1e4bcd4a452ac1 --- /dev/null +++ b/src/controller/java/AndroidConnectionFailureExceptions.cpp @@ -0,0 +1,44 @@ +/* + * + * 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. + */ + +#include "AndroidConnectionFailureExceptions.h" + +#include +#include +#include +#include + +namespace chip { + +CHIP_ERROR AndroidConnectionFailureExceptions::CreateAndroidConnectionFailureException(JNIEnv * env, const char * message, + uint32_t errorCode, + SessionEstablishmentStage state, + jthrowable & outEx) +{ + jclass controllerExceptionCls; + CHIP_ERROR err = JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/ConnectionFailureException", + controllerExceptionCls); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_JNI_ERROR_TYPE_NOT_FOUND); + + jmethodID exceptionConstructor = env->GetMethodID(controllerExceptionCls, "", "(JILjava/lang/String;)V"); + outEx = static_cast(env->NewObject(controllerExceptionCls, exceptionConstructor, static_cast(errorCode), + static_cast(state), env->NewStringUTF(message))); + VerifyOrReturnError(outEx != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND); + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/controller/java/AndroidConnectionFailureExceptions.h b/src/controller/java/AndroidConnectionFailureExceptions.h new file mode 100644 index 00000000000000..54baacac9e3326 --- /dev/null +++ b/src/controller/java/AndroidConnectionFailureExceptions.h @@ -0,0 +1,47 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include + +namespace chip { +class AndroidConnectionFailureExceptions +{ +public: + AndroidConnectionFailureExceptions(const AndroidConnectionFailureExceptions &) = delete; + AndroidConnectionFailureExceptions(const AndroidConnectionFailureExceptions &&) = delete; + AndroidConnectionFailureExceptions & operator=(const AndroidConnectionFailureExceptions &) = delete; + + static AndroidConnectionFailureExceptions & GetInstance() + { + static AndroidConnectionFailureExceptions androidConnectionFailureExceptions; + return androidConnectionFailureExceptions; + } + + /** + * Creates a Java ConnectionFailureException object in outEx. + */ + CHIP_ERROR CreateAndroidConnectionFailureException(JNIEnv * env, const char * message, uint32_t errorCode, + SessionEstablishmentStage state, jthrowable & outEx); + +private: + AndroidConnectionFailureExceptions() {} +}; +} // namespace chip diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index a538afefc744c5..e481e74feeda1c 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -45,6 +45,8 @@ shared_library("jni") { "AndroidClusterExceptions.h", "AndroidCommissioningWindowOpener.cpp", "AndroidCommissioningWindowOpener.h", + "AndroidConnectionFailureExceptions.cpp", + "AndroidConnectionFailureExceptions.h", "AndroidControllerExceptions.cpp", "AndroidControllerExceptions.h", "AndroidCurrentFabricRemover.cpp", @@ -439,6 +441,7 @@ android_library("java") { "src/chip/devicecontroller/ChipCommandType.java", "src/chip/devicecontroller/ChipDeviceController.java", "src/chip/devicecontroller/ChipDeviceControllerException.java", + "src/chip/devicecontroller/ConnectionFailureException.java", "src/chip/devicecontroller/ControllerParams.java", "src/chip/devicecontroller/DeviceAttestationDelegate.java", "src/chip/devicecontroller/DiscoveredDevice.java", diff --git a/src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java b/src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java new file mode 100644 index 00000000000000..4b5121bdcc6331 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +@SuppressWarnings("serial") +public class ConnectionFailureException extends ChipDeviceControllerException { + public enum ConnectionState { + UNKNOWN, // Unknown state + NOT_IN_KEY_EXCHANGE, // Not currently in key exchange process + SENT_SIGMA1, // Sigma1 message sent + RECEIVED_SIGMA1, // Sigma1 message received + SENT_SIGMA2, // Sigma2 message sent + RECEIVED_SIGMA2, // Sigma2 message received + SENT_SIGMA3, // Sigma3 message sent + RECEIVED_SIGMA3 // Sigma3 message received + } + + private ConnectionState connectionState; + + public ConnectionFailureException() { + super(); + } + + public ConnectionFailureException(long errorCode, int connectionState, String message) { + super(errorCode, message); + this.connectionState = mapIntToConnectionState(connectionState); + } + + public ConnectionState getConnectionState() { + return connectionState; + } + + // Helper method to map an int to ConnectionState enum + private ConnectionState mapIntToConnectionState(int value) { + switch (value) { + case 0: + return ConnectionState.UNKNOWN; + case 1: + return ConnectionState.NOT_IN_KEY_EXCHANGE; + case 2: + return ConnectionState.SENT_SIGMA1; + case 3: + return ConnectionState.RECEIVED_SIGMA1; + case 4: + return ConnectionState.SENT_SIGMA2; + case 5: + return ConnectionState.RECEIVED_SIGMA2; + case 6: + return ConnectionState.SENT_SIGMA3; + case 7: + return ConnectionState.RECEIVED_SIGMA3; + default: + throw new IllegalArgumentException("Invalid connection state value: " + value); + } + } +} From 4855f580034348e98a4c4259c6d50f784a432c36 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Thu, 28 Dec 2023 17:22:05 +0530 Subject: [PATCH 38/83] Add space after %p format specifier (#31194) --- src/app/util/attribute-table.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/util/attribute-table.cpp b/src/app/util/attribute-table.cpp index a4829d5d98719d..58430ac5aebab6 100644 --- a/src/app/util/attribute-table.cpp +++ b/src/app/util/attribute-table.cpp @@ -172,7 +172,7 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu // if we dont support that attribute if (metadata == nullptr) { - ChipLogProgress(Zcl, "%pep %x clus " ChipLogFormatMEI " attr " ChipLogFormatMEI " not supported", "WRITE ERR: ", endpoint, + ChipLogProgress(Zcl, "%p ep %x clus " ChipLogFormatMEI " attr " ChipLogFormatMEI " not supported", "WRITE ERR: ", endpoint, ChipLogValueMEI(cluster), ChipLogValueMEI(attributeID)); return status; } @@ -182,13 +182,13 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu { if (dataType != metadata->attributeType) { - ChipLogProgress(Zcl, "%pinvalid data type", "WRITE ERR: "); + ChipLogProgress(Zcl, "%p invalid data type", "WRITE ERR: "); return EMBER_ZCL_STATUS_INVALID_DATA_TYPE; } if (metadata->IsReadOnly()) { - ChipLogProgress(Zcl, "%pattr not writable", "WRITE ERR: "); + ChipLogProgress(Zcl, "%p attr not writable", "WRITE ERR: "); return EMBER_ZCL_STATUS_UNSUPPORTED_WRITE; } } From 420e6d424c00aed3ead4015eafd71a1632c5e540 Mon Sep 17 00:00:00 2001 From: Philip Gregor <147669098+pgregorr-amazon@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:30:43 -0800 Subject: [PATCH 39/83] tv-casting-app: simplified Android discovery API (#31112) * tv-casting-app: simplified android discovery API * Addressed comments by sharadb-amazon * Addressed comments by sharadb-amazon - 2nd review * Fixing style issue --- .../App/app/src/main/AndroidManifest.xml | 7 +- .../com/chip/casting/app/CastingContext.java | 1 + .../chip/casting/app/CertTestFragment.java | 1 + .../app/CommissionerDiscoveryFragment.java | 14 +- .../chip/casting/app/ConnectionFragment.java | 1 + .../casting/app/ContentLauncherFragment.java | 1 + .../com/chip/casting/app/MainActivity.java | 20 +- .../casting/app/MediaPlaybackFragment.java | 1 + .../casting/app/SelectClusterFragment.java | 1 + .../casting/DiscoveryExampleFragment.java | 371 ++++++++++++++++++ .../matter/casting/core/CastingPlayer.java | 78 ++++ .../casting/core/CastingPlayerDiscovery.java | 133 +++++++ .../casting/core/MatterCastingPlayer.java | 140 +++++++ .../core/MatterCastingPlayerDiscovery.java | 87 ++++ .../src/main/jni/cpp/core/CastingApp-JNI.cpp | 6 +- .../cpp/core/CastingPlayerDiscovery-JNI.cpp | 283 +++++++++++++ .../jni/cpp/core/CastingPlayerDiscovery-JNI.h | 41 ++ .../support/CastingPlayerConverter-JNI.cpp | 92 +++++ .../cpp/support/CastingPlayerConverter-JNI.h | 41 ++ .../jni/cpp/support/ErrorConverter-JNI.cpp | 2 +- .../app/src/main/res/layout/activity_main.xml | 2 +- .../layout/fragment_cert_test_launcher.xml | 2 +- .../fragment_commissioner_discovery.xml | 2 +- .../main/res/layout/fragment_connection.xml | 2 +- .../res/layout/fragment_content_launcher.xml | 2 +- .../fragment_matter_discovery_example.xml | 53 +++ .../res/layout/fragment_media_playback.xml | 2 +- .../res/layout/fragment_select_cluster.xml | 2 +- .../App/app/src/main/res/values/strings.xml | 7 + examples/tv-casting-app/android/BUILD.gn | 8 + .../tv-casting-common/core/CastingApp.cpp | 4 + .../tv-casting-common/core/CastingPlayer.cpp | 2 +- .../core/CastingPlayerDiscovery.cpp | 8 +- .../core/CastingPlayerDiscovery.h | 3 +- 34 files changed, 1395 insertions(+), 25 deletions(-) create mode 100644 examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayerDiscovery.java create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayerDiscovery.java create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.cpp create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.h create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.cpp create mode 100644 examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.h create mode 100644 examples/tv-casting-app/android/App/app/src/main/res/layout/fragment_matter_discovery_example.xml diff --git a/examples/tv-casting-app/android/App/app/src/main/AndroidManifest.xml b/examples/tv-casting-app/android/App/app/src/main/AndroidManifest.xml index 55c3e48357d58b..e551de818eb5b0 100644 --- a/examples/tv-casting-app/android/App/app/src/main/AndroidManifest.xml +++ b/examples/tv-casting-app/android/App/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com"> @@ -10,7 +10,6 @@ - - diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CastingContext.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CastingContext.java index 2ad1d29faf4382..acab829034bd56 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CastingContext.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CastingContext.java @@ -3,6 +3,7 @@ import android.content.Context; import android.widget.LinearLayout; import androidx.fragment.app.FragmentActivity; +import com.R; public class CastingContext { private FragmentActivity fragmentActivity; diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CertTestFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CertTestFragment.java index 16070eb1dfe59e..340563c28b322c 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CertTestFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CertTestFragment.java @@ -10,6 +10,7 @@ import android.widget.ListView; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.R; import com.chip.casting.ContentApp; import com.chip.casting.ContentLauncherTypes; import com.chip.casting.FailureCallback; diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java index dbb95e88806a92..3a119940b64839 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java @@ -14,6 +14,7 @@ import android.widget.Toast; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.R; import com.chip.casting.DiscoveredNodeData; import com.chip.casting.FailureCallback; import com.chip.casting.MatterError; @@ -67,6 +68,7 @@ public View onCreateView( @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + Log.d(TAG, "onViewCreated() called"); super.onViewCreated(view, savedInstanceState); Button manualCommissioningButton = getView().findViewById(R.id.manualCommissioningButton); @@ -103,7 +105,10 @@ public void onClick(View v) { new SuccessCallback() { @Override public void handle(DiscoveredNodeData discoveredNodeData) { - Log.d(TAG, "Discovered a Video Player Commissioner: " + discoveredNodeData); + Log.d( + TAG, + "SuccessCallback handle() Discovered a Video Player Commissioner: " + + discoveredNodeData); new Handler(Looper.getMainLooper()) .post( () -> { @@ -129,7 +134,10 @@ public void handle(DiscoveredNodeData discoveredNodeData) { new FailureCallback() { @Override public void handle(MatterError matterError) { - Log.e(TAG, "Error occurred during video player commissioner discovery: " + matterError); + Log.e( + TAG, + "FailureCallback handle() Error occurred during video player commissioner discovery: " + + matterError); if (MatterError.DISCOVERY_SERVICE_LOST == matterError) { Log.d(TAG, "Attempting to restart service"); tvCastingApp.discoverVideoPlayerCommissioners(successCallback, this); @@ -148,7 +156,7 @@ public void handle(MatterError matterError) { @Override public void onResume() { super.onResume(); - Log.d(TAG, "Auto discovering"); + Log.d(TAG, "onResume() called. Auto discovering"); poller = executor.scheduleAtFixedRate( diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ConnectionFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ConnectionFragment.java index d2a0f7952b6485..09ba31b2c8776c 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ConnectionFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ConnectionFragment.java @@ -8,6 +8,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.R; import com.chip.casting.CommissioningCallbacks; import com.chip.casting.ContentApp; import com.chip.casting.DiscoveredNodeData; diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ContentLauncherFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ContentLauncherFragment.java index 2c3db2bc01f6d2..d1c3c9f957f394 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ContentLauncherFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ContentLauncherFragment.java @@ -9,6 +9,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.R; import com.chip.casting.ContentApp; import com.chip.casting.MatterCallbackHandler; import com.chip.casting.MatterError; diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java index de1b547f929dd5..c0b1bcb5a860df 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java @@ -5,18 +5,22 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; +import com.R; import com.chip.casting.AppParameters; import com.chip.casting.DiscoveredNodeData; import com.chip.casting.TvCastingApp; import com.chip.casting.util.GlobalCastingConstants; import com.chip.casting.util.PreferencesConfigurationManager; +import com.matter.casting.DiscoveryExampleFragment; import com.matter.casting.InitializationExample; +import com.matter.casting.core.CastingPlayer; import java.util.Random; public class MainActivity extends AppCompatActivity implements CommissionerDiscoveryFragment.Callback, ConnectionFragment.Callback, - SelectClusterFragment.Callback { + SelectClusterFragment.Callback, + DiscoveryExampleFragment.Callback { private static final String TAG = MainActivity.class.getSimpleName(); @@ -36,7 +40,12 @@ protected void onCreate(Bundle savedInstanceState) { return; } - Fragment fragment = CommissionerDiscoveryFragment.newInstance(tvCastingApp); + Fragment fragment = null; + if (GlobalCastingConstants.ChipCastingSimplified) { + fragment = DiscoveryExampleFragment.newInstance(); + } else { + fragment = CommissionerDiscoveryFragment.newInstance(tvCastingApp); + } getSupportFragmentManager() .beginTransaction() .add(R.id.main_fragment_container, fragment, fragment.getClass().getSimpleName()) @@ -48,6 +57,13 @@ public void handleCommissioningButtonClicked(DiscoveredNodeData commissioner) { showFragment(ConnectionFragment.newInstance(tvCastingApp, commissioner)); } + @Override + public void handleConnectionButtonClicked(CastingPlayer player) { + Log.i(TAG, "MainActivity.handleConnectionButtonClicked() called"); + // TODO: In future PR, show fragment that connects to the player. + // showFragment(ConnectionFragment.newInstance(CastingPlayer player)); + } + @Override public void handleCommissioningComplete() { showFragment(SelectClusterFragment.newInstance(tvCastingApp)); diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MediaPlaybackFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MediaPlaybackFragment.java index 325b33e85b79f4..a9c38443a7d91e 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MediaPlaybackFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MediaPlaybackFragment.java @@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; +import com.R; import com.chip.casting.ContentApp; import com.chip.casting.FailureCallback; import com.chip.casting.MatterError; diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/SelectClusterFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/SelectClusterFragment.java index 7f5277aeb81138..f89fc36009e404 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/SelectClusterFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/SelectClusterFragment.java @@ -7,6 +7,7 @@ import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.R; import com.chip.casting.TvCastingApp; /** An interstitial {@link Fragment} to select one of the supported media actions to perform */ diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java new file mode 100644 index 00000000000000..4c5d68fdb60654 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.matter.casting; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TextView; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import com.R; +import com.matter.casting.core.CastingPlayer; +import com.matter.casting.core.CastingPlayerDiscovery; +import com.matter.casting.core.MatterCastingPlayerDiscovery; +import com.matter.casting.support.MatterError; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; + +public class DiscoveryExampleFragment extends Fragment { + private static final String TAG = DiscoveryExampleFragment.class.getSimpleName(); + // 35 represents device type of Matter Casting Player + private static final Long DISCOVERY_TARGET_DEVICE_TYPE = 35L; + private static final int DISCOVERY_RUNTIME_SEC = 15; + private TextView matterDiscoveryMessageTextView; + private static final ScheduledExecutorService executorService = + Executors.newSingleThreadScheduledExecutor(); + private ScheduledFuture scheduledFutureTask; + private static final List castingPlayerList = new ArrayList<>(); + private static ArrayAdapter arrayAdapter; + + // Get a singleton instance of the MatterCastingPlayerDiscovery + private static final CastingPlayerDiscovery matterCastingPlayerDiscovery = + MatterCastingPlayerDiscovery.getInstance(); + + /** + * Implementation of a CastingPlayerChangeListener used to listen to changes in the discovered + * CastingPlayers + */ + private static final CastingPlayerDiscovery.CastingPlayerChangeListener + castingPlayerChangeListener = + new CastingPlayerDiscovery.CastingPlayerChangeListener() { + private final String TAG = + CastingPlayerDiscovery.CastingPlayerChangeListener.class.getSimpleName(); + + @Override + public void onAdded(CastingPlayer castingPlayer) { + Log.i( + TAG, + "onAdded() Discovered CastingPlayer deviceId: " + castingPlayer.getDeviceId()); + // Display CastingPlayer info on the screen + new Handler(Looper.getMainLooper()) + .post( + () -> { + arrayAdapter.add(castingPlayer); + }); + } + + @Override + public void onChanged(CastingPlayer castingPlayer) { + Log.i( + TAG, + "onChanged() Discovered changes to CastingPlayer with deviceId: " + + castingPlayer.getDeviceId()); + // Update the CastingPlayer on the screen + new Handler(Looper.getMainLooper()) + .post( + () -> { + final Optional playerInList = + castingPlayerList + .stream() + .filter(node -> castingPlayer.equals(node)) + .findFirst(); + if (playerInList.isPresent()) { + Log.d( + TAG, + "onChanged() Updating existing CastingPlayer entry " + + playerInList.get().getDeviceId() + + " in castingPlayerList list"); + arrayAdapter.remove(playerInList.get()); + } + arrayAdapter.add(castingPlayer); + }); + } + + @Override + public void onRemoved(CastingPlayer castingPlayer) { + Log.i( + TAG, + "onRemoved() Removed CastingPlayer with deviceId: " + + castingPlayer.getDeviceId()); + // Remove CastingPlayer from the screen + new Handler(Looper.getMainLooper()) + .post( + () -> { + final Optional playerInList = + castingPlayerList + .stream() + .filter(node -> castingPlayer.equals(node)) + .findFirst(); + if (playerInList.isPresent()) { + Log.d( + TAG, + "onRemoved() Removing existing CastingPlayer entry " + + playerInList.get().getDeviceId() + + " in castingPlayerList list"); + arrayAdapter.remove(playerInList.get()); + } + }); + } + }; + + public static DiscoveryExampleFragment newInstance() { + Log.i(TAG, "newInstance() called"); + return new DiscoveryExampleFragment(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.i(TAG, "onCreate() called"); + } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Log.i(TAG, "onCreateView() called"); + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_matter_discovery_example, container, false); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Log.i(TAG, "onViewCreated() called"); + + matterDiscoveryMessageTextView = + getActivity().findViewById(R.id.matterDiscoveryMessageTextView); + matterDiscoveryMessageTextView.setText( + getString(R.string.matter_discovery_message_initializing_text)); + + arrayAdapter = new CastingPlayerArrayAdapter(getActivity(), castingPlayerList); + final ListView list = getActivity().findViewById(R.id.castingPlayerList); + list.setAdapter(arrayAdapter); + + Log.d(TAG, "onViewCreated() creating callbacks"); + + // TODO: In following PRs. Enable startDiscoveryButton and stopDiscoveryButton when + // stopDiscovery is implemented in the core Matter SDK DNS-SD API. Enable in + // fragment_matter_discovery_example.xml + Button startDiscoveryButton = getView().findViewById(R.id.startDiscoveryButton); + startDiscoveryButton.setOnClickListener( + v -> { + Log.i( + TAG, "onViewCreated() startDiscoveryButton button clicked. Calling startDiscovery()"); + if (!startDiscovery()) { + Log.e(TAG, "onViewCreated() startDiscovery() call Failed"); + } + }); + + Button stopDiscoveryButton = getView().findViewById(R.id.stopDiscoveryButton); + stopDiscoveryButton.setOnClickListener( + v -> { + Log.i(TAG, "onViewCreated() stopDiscoveryButton button clicked. Calling stopDiscovery()"); + stopDiscovery(); + Log.i(TAG, "onViewCreated() stopDiscoveryButton button clicked. Canceling future task"); + scheduledFutureTask.cancel(true); + }); + + Button clearDiscoveryResultsButton = getView().findViewById(R.id.clearDiscoveryResultsButton); + clearDiscoveryResultsButton.setOnClickListener( + v -> { + Log.i( + TAG, "onViewCreated() clearDiscoveryResultsButton button clicked. Clearing results"); + arrayAdapter.clear(); + }); + } + + @Override + public void onResume() { + super.onResume(); + Log.i(TAG, "onResume() called. Calling startDiscovery()"); + if (!startDiscovery()) { + Log.e(TAG, "onResume() Warning: startDiscovery() call Failed"); + } + } + + @Override + public void onPause() { + super.onPause(); + Log.i(TAG, "onPause() called"); + // stopDiscovery(); + // Don't crash the app + if (scheduledFutureTask != null) { + scheduledFutureTask.cancel(true); + } + } + + /** Interface for notifying the host. */ + public interface Callback { + /** Notifies listener of Connection Button click. */ + // TODO: In following PRs. Implement CastingPlayer connection + void handleConnectionButtonClicked(CastingPlayer castingPlayer); + } + + private boolean startDiscovery() { + Log.i(TAG, "startDiscovery() called"); + + arrayAdapter.clear(); + + // Add the implemented CastingPlayerChangeListener to listen to changes in the discovered + // CastingPlayers + MatterError err = + matterCastingPlayerDiscovery.addCastingPlayerChangeListener(castingPlayerChangeListener); + if (err.hasError()) { + Log.e(TAG, "startDiscovery() addCastingPlayerChangeListener() called, err Add: " + err); + return false; + } + // Start discovery + Log.i(TAG, "startDiscovery() calling CastingPlayerDiscovery.startDiscovery()"); + err = matterCastingPlayerDiscovery.startDiscovery(DISCOVERY_TARGET_DEVICE_TYPE); + if (err.hasError()) { + Log.e(TAG, "startDiscovery() startDiscovery() called, err Start: " + err); + return false; + } + + Log.i(TAG, "startDiscovery() started discovery"); + + matterDiscoveryMessageTextView.setText( + getString(R.string.matter_discovery_message_discovering_text)); + Log.d( + TAG, + "startDiscovery() text set to: " + + getString(R.string.matter_discovery_message_discovering_text)); + + // TODO: In following PRs. Enable this to auto-stop discovery after stopDiscovery is + // implemented in the core Matter SKD DNS-SD API. + // Schedule a service to stop discovery and remove the CastingPlayerChangeListener + // Safe to call if discovery is not running + // scheduledFutureTask = + // executorService.schedule( + // () -> { + // Log.i( + // TAG, + // "startDiscovery() executorService " + // + DISCOVERY_RUNTIME_SEC + // + " seconds timer expired. Auto-calling stopDiscovery()"); + // stopDiscovery(); + // }, + // DISCOVERY_RUNTIME_SEC, + // TimeUnit.SECONDS); + + return true; + } + + private void stopDiscovery() { + Log.i(TAG, "stopDiscovery() called"); + + // Stop discovery + MatterError err = matterCastingPlayerDiscovery.stopDiscovery(); + if (err.hasError()) { + Log.e( + TAG, + "stopDiscovery() MatterCastingPlayerDiscovery.stopDiscovery() called, err Stop: " + err); + } else { + // TODO: In following PRs. Implement stop discovery in the Android core API. + Log.d(TAG, "stopDiscovery() MatterCastingPlayerDiscovery.stopDiscovery() success"); + } + + matterDiscoveryMessageTextView.setText( + getString(R.string.matter_discovery_message_stopped_text)); + Log.d( + TAG, + "stopDiscovery() text set to: " + + getString(R.string.matter_discovery_message_stopped_text)); + + // Remove the CastingPlayerChangeListener + Log.i(TAG, "stopDiscovery() removing CastingPlayerChangeListener"); + err = + matterCastingPlayerDiscovery.removeCastingPlayerChangeListener(castingPlayerChangeListener); + if (err.hasError()) { + Log.e( + TAG, + "stopDiscovery() matterCastingPlayerDiscovery.removeCastingPlayerChangeListener() called, err Remove: " + + err); + } + } +} + +class CastingPlayerArrayAdapter extends ArrayAdapter { + private final List playerList; + private final Context context; + private LayoutInflater inflater; + private static final String TAG = CastingPlayerArrayAdapter.class.getSimpleName(); + + public CastingPlayerArrayAdapter(Context context, List playerList) { + super(context, 0, playerList); + Log.i(TAG, "CastingPlayerArrayAdapter() constructor called"); + this.context = context; + this.playerList = playerList; + inflater = (LayoutInflater.from(context)); + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + view = inflater.inflate(R.layout.commissionable_player_list_item, null); + String buttonText = getCastingPlayerButtonText(playerList.get(i)); + Button playerDescription = view.findViewById(R.id.commissionable_player_description); + playerDescription.setText(buttonText); + + View.OnClickListener clickListener = + v -> { + CastingPlayer castingPlayer = playerList.get(i); + Log.d( + TAG, + "OnItemClickListener.onClick() called for castingPlayer with deviceId: " + + castingPlayer.getDeviceId()); + DiscoveryExampleFragment.Callback callback1 = (DiscoveryExampleFragment.Callback) context; + // TODO: In following PRs. Implement CastingPlayer connection + // callback1.handleCommissioningButtonClicked(castingPlayer); + }; + playerDescription.setOnClickListener(clickListener); + return view; + } + + private String getCastingPlayerButtonText(CastingPlayer player) { + String main = player.getDeviceName() != null ? player.getDeviceName() : ""; + String aux = "" + (player.getDeviceId() != null ? "Device ID: " + player.getDeviceId() : ""); + aux += + player.getProductId() > 0 + ? (aux.isEmpty() ? "" : ", ") + "Product ID: " + player.getProductId() + : ""; + aux += + player.getVendorId() > 0 + ? (aux.isEmpty() ? "" : ", ") + "Vendor ID: " + player.getVendorId() + : ""; + aux += + player.getDeviceType() > 0 + ? (aux.isEmpty() ? "" : ", ") + "Device Type: " + player.getDeviceType() + : ""; + aux += (aux.isEmpty() ? "" : ", ") + "Resolved IP?: " + (player.getIpAddresses().size() > 0); + + aux = aux.isEmpty() ? aux : "\n" + aux; + return main + aux; + } +} diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java new file mode 100644 index 00000000000000..71ea4767a03994 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.matter.casting.core; + +import java.net.InetAddress; +import java.util.List; + +/** + * The CastingPlayer interface defines a Matter commissioner that is able to play media to a + * physical output or to a display screen which is part of the device (e.g. TV). It is discovered on + * the local network using Matter Commissioner discovery over DNS. It contains all the information + * about the service discovered/resolved. + */ +public interface CastingPlayer { + boolean isConnected(); + + String getDeviceId(); + + String getHostName(); + + String getDeviceName(); + + String getInstanceName(); + + List getIpAddresses(); + + int getPort(); + + int getVendorId(); + + int getProductId(); + + long getDeviceType(); + + @Override + String toString(); + + @Override + boolean equals(Object o); + + @Override + int hashCode(); + + // TODO: Implement in following PRs. Related to player connection implementation. + // List getEndpoints(); + // + // ConnectionState getConnectionState(); + // + // CompletableFuture connect(long timeout); + // + // static class ConnectionState extends Observable { + // private boolean connected; + // + // void setConnected(boolean connected) { + // this.connected = connected; + // setChanged(); + // notifyObservers(this.connected); + // } + // + // boolean isConnected() { + // return connected; + // } + // } +} diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayerDiscovery.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayerDiscovery.java new file mode 100644 index 00000000000000..fcde7bc55adbe0 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayerDiscovery.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.matter.casting.core; + +import android.util.Log; +import com.matter.casting.support.MatterError; +import java.util.List; + +/** + * The CastingPlayerDiscovery interface defines the client API to control Matter Casting Player + * discovery over DNS-SD, and to collect discovery results. This interface defines the methods to + * add and remove a CastingPlayerChangeListener. It also defines the CastingPlayerChangeListener + * handler class which must be implemented by the API client. The handler contains the methods + * called when Casting Players are discovered, updated, or lost from the network. + */ +public interface CastingPlayerDiscovery { + + /** + * @return a list of Casting Players discovered during the current discovery session. This list is + * cleared when discovery stops. + */ + List getCastingPlayers(); + + /** + * Starts Casting Players discovery or returns an error. + * + * @param discoveryTargetDeviceType the target device type to be discovered using DNS-SD. For + * example: 35 represents device type of Matter Casting Video Player. If "null" is passed in, + * discovery will default to all "_matterd._udp" device types. + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + MatterError startDiscovery(Long discoveryTargetDeviceType); + + /** + * Stops Casting Players discovery or returns an error. + * + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + MatterError stopDiscovery(); + + /** + * Adds a CastingPlayerChangeListener instance to be used during discovery. The + * CastingPlayerChangeListener defines the handler methods for when Casting Players are + * discovered, updated, or lost from the network. Should be called prior to calling + * MatterCastingPlayerDiscovery.startDiscovery(). + * + * @param listener an instance of the CastingPlayerChangeListener to be implemented by the APIs + * consumer. + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + MatterError addCastingPlayerChangeListener(CastingPlayerChangeListener listener); + + /** + * Removes CastingPlayerChangeListener added by addCastingPlayerChangeListener(). + * + * @param listener the specific instance of CastingPlayerChangeListener to be removed. + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + MatterError removeCastingPlayerChangeListener(CastingPlayerChangeListener listener); + + /** + * The CastingPlayerChangeListener can discover CastingPlayers by implementing the onAdded(), + * onChanged() and onRemoved() callbacks which are called as CastingPlayers, are discovered, + * updated, or lost from the network. The onAdded(), onChanged() and onRemoved() handlers must be + * implemented by the API client. + */ + abstract class CastingPlayerChangeListener { + static final String TAG = CastingPlayerChangeListener.class.getSimpleName(); + + /** + * This handler is called when a Casting Player is added to the network. + * + * @param castingPlayer the Casting Player added. + */ + public abstract void onAdded(CastingPlayer castingPlayer); + + /** + * This handler is called when a Casting Player previously detected on the network is changed. + * + * @param castingPlayer the Casting Player changed. + */ + public abstract void onChanged(CastingPlayer castingPlayer); + + /** + * This handler is called when a Casting Player previously detected on the network is removed. + * + * @param castingPlayer the Casting Player removed. + */ + public abstract void onRemoved(CastingPlayer castingPlayer); + + /** + * The following methods are used to catch possible exceptions thrown by the methods above + * (onAdded(), onChanged() and onRemoved()), when not implemented correctly by the client. + */ + protected final void _onAdded(CastingPlayer castingPlayer) { + try { + onAdded(castingPlayer); + } catch (Throwable t) { + Log.e(TAG, "_onAdded() Caught an unhandled Throwable from the client: " + t); + } + }; + + protected final void _onChanged(CastingPlayer castingPlayer) { + try { + onChanged(castingPlayer); + } catch (Throwable t) { + Log.e(TAG, "_onChanged() Caught an unhandled Throwable from the client: " + t); + } + }; + + protected final void _onRemoved(CastingPlayer castingPlayer) { + try { + onRemoved(castingPlayer); + } catch (Throwable t) { + Log.e(TAG, "_onRemoved() Caught an unhandled Throwable from the client: " + t); + } + }; + } +} diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java new file mode 100644 index 00000000000000..ecc76a575a115b --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.matter.casting.core; + +import java.net.InetAddress; +import java.util.List; +import java.util.Objects; + +/** + * A Matter Casting Player represents a Matter commissioner that is able to play media to a physical + * output or to a display screen which is part of the device (e.g. TV). It is discovered on the + * local network using Matter Commissioner discovery over DNS. It contains all the information about + * the service discovered/resolved. + */ +public class MatterCastingPlayer implements CastingPlayer { + private boolean connected; + private String deviceId; + private String deviceName; + private String hostName; + private String instanceName; + private List ipAddresses; + private int port; + private int productId; + private int vendorId; + private long deviceType; + + public MatterCastingPlayer( + boolean connected, + String deviceId, + String hostName, + String deviceName, + String instanceName, + List ipAddresses, + int port, + int productId, + int vendorId, + long deviceType) { + this.connected = connected; + this.deviceId = deviceId; + this.hostName = hostName; + this.deviceName = deviceName; + this.instanceName = instanceName; + this.ipAddresses = ipAddresses; + this.port = port; + this.productId = productId; + this.vendorId = vendorId; + this.deviceType = deviceType; + } + + /** + * @return a boolean indicating whether a Casting Player instance is connected to the TV Casting + * App. + */ + @Override + public boolean isConnected() { + return this.connected; + } + + /** + * @return a String representing the Casting Player device ID which is a concatenation of the + * device's IP address and port number. + */ + @Override + public String getDeviceId() { + return this.deviceId; + } + + @Override + public String getHostName() { + return this.hostName; + } + + @Override + public String getDeviceName() { + return this.deviceName; + } + + @Override + public String getInstanceName() { + return this.instanceName; + } + + /** @return a list of valid IP addresses for this Casting PLayer. */ + @Override + public List getIpAddresses() { + return this.ipAddresses; + } + + @Override + public int getPort() { + return this.port; + } + + @Override + public int getVendorId() { + return this.vendorId; + } + + @Override + public int getProductId() { + return this.productId; + } + + @Override + public long getDeviceType() { + return this.deviceType; + } + + @Override + public String toString() { + return this.deviceId; + } + + @Override + public int hashCode() { + return this.deviceId.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MatterCastingPlayer that = (MatterCastingPlayer) o; + return Objects.equals(this.deviceId, that.deviceId); + } +} diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayerDiscovery.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayerDiscovery.java new file mode 100644 index 00000000000000..bf7df60ef74d79 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayerDiscovery.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.matter.casting.core; + +import com.matter.casting.support.MatterError; +import java.util.List; + +/** + * MatterCastingPlayerDiscovery provides an API to control Matter Casting Player discovery over + * DNS-SD, and to collect discovery results. This class provides methods to add and remove a + * CastingPlayerChangeListener, which contains the handlers for when Casting Players are discovered, + * updated, or lost from the network. This class is a singleton. + */ +public final class MatterCastingPlayerDiscovery implements CastingPlayerDiscovery { + private static final String TAG = MatterCastingPlayerDiscovery.class.getSimpleName(); + private static MatterCastingPlayerDiscovery matterCastingPlayerDiscoveryInstance; + + // Methods: + public static MatterCastingPlayerDiscovery getInstance() { + if (matterCastingPlayerDiscoveryInstance == null) { + matterCastingPlayerDiscoveryInstance = new MatterCastingPlayerDiscovery(); + } + return matterCastingPlayerDiscoveryInstance; + }; + + /** + * @return a list of Casting Players discovered during the current discovery session. This list is + * cleared when discovery stops. + */ + @Override + public native List getCastingPlayers(); + + /** + * Starts Casting Players discovery or returns an error. + * + * @param discoveryTargetDeviceType the target device type to be discovered using DNS-SD. For + * example: 35 represents device type of Matter Casting Video Player. If "null" is passed in, + * discovery will default to all "_matterd._udp" device types. + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + @Override + public native MatterError startDiscovery(Long discoveryTargetDeviceType); + + /** + * Stops Casting Players discovery or returns an error. + * + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + @Override + public native MatterError stopDiscovery(); + + /** + * Adds a CastingPlayerChangeListener instance to be used during discovery. The + * CastingPlayerChangeListener defines the handler methods for when Casting Players are + * discovered, updated, or lost from the network. Should be called prior to calling + * MatterCastingPlayerDiscovery.startDiscovery(). + * + * @param listener an instance of the CastingPlayerChangeListener to be implemented by the APIs + * consumer. + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + @Override + public native MatterError addCastingPlayerChangeListener(CastingPlayerChangeListener listener); + + /** + * Removes CastingPlayerChangeListener from the native layer. + * + * @param listener the specific instance of CastingPlayerChangeListener to be removed. + * @return a specific MatterError if the the operation failed or NO_ERROR if succeeded. + */ + @Override + public native MatterError removeCastingPlayerChangeListener(CastingPlayerChangeListener listener); +} diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingApp-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingApp-JNI.cpp index 90a36bbfec92ca..be8a35a195403a 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingApp-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingApp-JNI.cpp @@ -47,7 +47,7 @@ jobject extractJAppParameter(jobject jAppParameters, const char * methodName, co JNI_METHOD(jobject, finishInitialization)(JNIEnv *, jobject, jobject jAppParameters) { chip::DeviceLayer::StackLock lock; - ChipLogProgress(AppServer, "JNI_METHOD CastingAppJNI.finishInitialization called"); + ChipLogProgress(AppServer, "JNI_METHOD CastingApp-JNI::finishInitialization() called"); VerifyOrReturnValue(jAppParameters != nullptr, support::createJMatterError(CHIP_ERROR_INVALID_ARGUMENT)); CHIP_ERROR err = CHIP_NO_ERROR; @@ -81,7 +81,7 @@ JNI_METHOD(jobject, finishInitialization)(JNIEnv *, jobject, jobject jAppParamet JNI_METHOD(jobject, finishStartup)(JNIEnv *, jobject) { chip::DeviceLayer::StackLock lock; - ChipLogProgress(AppServer, "JNI_METHOD CastingAppJNI.finishStartup called"); + ChipLogProgress(AppServer, "JNI_METHOD CastingAppJNI::finishStartup() called"); CHIP_ERROR err = CHIP_NO_ERROR; auto & server = chip::Server::GetInstance(); @@ -107,7 +107,7 @@ JNI_METHOD(jobject, finishStartup)(JNIEnv *, jobject) jobject extractJAppParameter(jobject jAppParameters, const char * methodName, const char * methodSig) { - ChipLogProgress(AppServer, "JNI_METHOD extractJAppParameter called"); + ChipLogProgress(AppServer, "JNI_METHOD CastingApp-JNI::extractJAppParameter() called"); JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); jclass jAppParametersClass; diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.cpp new file mode 100644 index 00000000000000..255ba570082e16 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.cpp @@ -0,0 +1,283 @@ +/* + * 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 "CastingPlayerDiscovery-JNI.h" + +#include "../JNIDACProvider.h" +#include "../support/CastingPlayerConverter-JNI.h" +#include "../support/ErrorConverter-JNI.h" +#include "../support/RotatingDeviceIdUniqueIdProvider-JNI.h" +#include "core/CastingApp.h" // from tv-casting-common +#include "core/CastingPlayerDiscovery.h" // from tv-casting-common + +#include +#include +#include +#include +#include + +using namespace chip; + +#define JNI_METHOD(RETURN, METHOD_NAME) \ + extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_casting_core_MatterCastingPlayerDiscovery_##METHOD_NAME + +namespace matter { +namespace casting { +namespace core { + +/** + * @brief React to CastingPlayer discovery results with this singleton + */ +class DiscoveryDelegateImpl : public DiscoveryDelegate +{ +private: + DiscoveryDelegateImpl() {} + static DiscoveryDelegateImpl * discoveryDelegateImplSingletonInstance; + DiscoveryDelegateImpl(DiscoveryDelegateImpl & other) = delete; + void operator=(const DiscoveryDelegateImpl &) = delete; + +public: + jobject castingPlayerChangeListenerJavaObject = nullptr; + jmethodID onAddedCallbackJavaMethodID = nullptr; + jmethodID onChangedCallbackJavaMethodID = nullptr; + // jmethodID onRemovedCallbackJavaMethodID = nullptr; + + static DiscoveryDelegateImpl * GetInstance() + { + if (DiscoveryDelegateImpl::discoveryDelegateImplSingletonInstance == nullptr) + { + DiscoveryDelegateImpl::discoveryDelegateImplSingletonInstance = new DiscoveryDelegateImpl(); + } + return DiscoveryDelegateImpl::discoveryDelegateImplSingletonInstance; + } + + void HandleOnAdded(matter::casting::memory::Strong player) override + { + ChipLogProgress(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnAdded() called with CastingPlayer, ID: %s", + player->GetId()); + + VerifyOrReturn(castingPlayerChangeListenerJavaObject != nullptr, + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnAdded() Warning: Not set, " + "CastingPlayerChangeListener == nullptr")); + VerifyOrReturn(onAddedCallbackJavaMethodID != nullptr, + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnAdded() Warning: Not set, " + "onAddedCallbackJavaMethodID == nullptr")); + + jobject matterCastingPlayerJavaObject = support::createJCastingPlayer(player); + VerifyOrReturn(matterCastingPlayerJavaObject != nullptr, + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnAdded() Warning: Could not create " + "CastingPlayer jobject")); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + env->CallVoidMethod(castingPlayerChangeListenerJavaObject, onAddedCallbackJavaMethodID, matterCastingPlayerJavaObject); + } + + void HandleOnUpdated(matter::casting::memory::Strong player) override + { + ChipLogProgress(AppServer, + "CastingPlayerDiscovery-JNI DiscoveryDelegateImpl::HandleOnUpdated() called with CastingPlayer, ID: %s", + player->GetId()); + + VerifyOrReturn(castingPlayerChangeListenerJavaObject != nullptr, + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnUpdated() Warning: Not set, " + "CastingPlayerChangeListener == nullptr")); + VerifyOrReturn(onChangedCallbackJavaMethodID != nullptr, + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnUpdated() Warning: Not set, " + "onChangedCallbackJavaMethodID == nullptr")); + + jobject matterCastingPlayerJavaObject = support::createJCastingPlayer(player); + VerifyOrReturn(matterCastingPlayerJavaObject != nullptr, + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::DiscoveryDelegateImpl::HandleOnUpdated() Warning: Could not " + "create CastingPlayer jobject")); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + env->CallVoidMethod(castingPlayerChangeListenerJavaObject, onChangedCallbackJavaMethodID, matterCastingPlayerJavaObject); + } + + // TODO: In following PRs. Implement HandleOnRemoved after implemented in tv-casting-commom CastingPlayerDiscovery.h/cpp + // void HandleOnRemoved(matter::casting::memory::Strong player) override + // { + // ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI DiscoveryDelegateImpl::HandleOnRemoved() called with + // CastingPlayer, ID: %s", player->GetId()); + // } +}; + +// Initialize the static instance to nullptr +DiscoveryDelegateImpl * DiscoveryDelegateImpl::discoveryDelegateImplSingletonInstance = nullptr; + +JNI_METHOD(jobject, startDiscovery)(JNIEnv * env, jobject, jobject targetDeviceTypeLong = nullptr) +{ + chip::DeviceLayer::StackLock lock; + ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI::startDiscovery() called"); + CastingPlayerDiscovery::GetInstance()->SetDelegate(DiscoveryDelegateImpl::GetInstance()); + + // Start CastingPlayer discovery + CHIP_ERROR err = CHIP_NO_ERROR; + if (targetDeviceTypeLong == nullptr) + { + ChipLogProgress(AppServer, + "CastingPlayerDiscovery-JNI::startDiscovery() received null target device type. Using default type."); + err = CastingPlayerDiscovery::GetInstance()->StartDiscovery(); + } + else + { + // Get the long value from the Java Long object + jclass longClass = env->GetObjectClass(targetDeviceTypeLong); + jmethodID longValueMethod = env->GetMethodID(longClass, "longValue", "()J"); + jlong jTargetDeviceType = env->CallLongMethod(targetDeviceTypeLong, longValueMethod); + env->DeleteLocalRef(longClass); + + ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI::startDiscovery() discovery target device type: %u", + static_cast(jTargetDeviceType)); + err = CastingPlayerDiscovery::GetInstance()->StartDiscovery(static_cast(jTargetDeviceType)); + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "CastingPlayerDiscovery-JNI startDiscovery() err: %" CHIP_ERROR_FORMAT, err.Format()); + return support::createJMatterError(err); + } + + return support::createJMatterError(CHIP_NO_ERROR); +} + +JNI_METHOD(jobject, stopDiscovery)(JNIEnv * env, jobject) +{ + chip::DeviceLayer::StackLock lock; + ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI::stopDiscovery() called"); + + // Stop CastingPlayer discovery + CHIP_ERROR err = CastingPlayerDiscovery::GetInstance()->StopDiscovery(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "CastingPlayerDiscovery-JNI::StopDiscovery() err: %" CHIP_ERROR_FORMAT, err.Format()); + return support::createJMatterError(err); + } + + return support::createJMatterError(CHIP_NO_ERROR); +} + +JNI_METHOD(jobject, addCastingPlayerChangeListener)(JNIEnv * env, jobject, jobject castingPlayerChangeListenerJavaObject) +{ + chip::DeviceLayer::StackLock lock; + ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI::addCastingPlayerChangeListener() called"); + VerifyOrReturnValue(castingPlayerChangeListenerJavaObject != nullptr, support::createJMatterError(CHIP_ERROR_INCORRECT_STATE)); + + if (DiscoveryDelegateImpl::GetInstance()->castingPlayerChangeListenerJavaObject != nullptr) + { + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::addCastingPlayerChangeListener() Warning: Call removeCastingPlayerChangeListener " + "before adding a new one"); + return support::createJMatterError(CHIP_ERROR_INCORRECT_STATE); + } + + // Get the class and method IDs for the CastingPlayerChangeListener Java class + jclass castingPlayerChangeListenerJavaClass = env->GetObjectClass(castingPlayerChangeListenerJavaObject); + VerifyOrReturnValue(castingPlayerChangeListenerJavaClass != nullptr, support::createJMatterError(CHIP_ERROR_INCORRECT_STATE)); + + jmethodID onAddedJavaMethodID = + env->GetMethodID(castingPlayerChangeListenerJavaClass, "_onAdded", "(Lcom/matter/casting/core/CastingPlayer;)V"); + VerifyOrReturnValue(onAddedJavaMethodID != nullptr, support::createJMatterError(CHIP_ERROR_INCORRECT_STATE)); + jmethodID onChangedJavaMethodID = + env->GetMethodID(castingPlayerChangeListenerJavaClass, "_onChanged", "(Lcom/matter/casting/core/CastingPlayer;)V"); + VerifyOrReturnValue(onChangedJavaMethodID != nullptr, support::createJMatterError(CHIP_ERROR_INCORRECT_STATE)); + // jmethodID onRemovedJavaMethodID = env->GetMethodID(castingPlayerChangeListenerJavaClass, "_onRemoved", + // "(Lcom/matter/casting/core/CastingPlayer;)V"); VerifyOrReturnValue(onRemovedJavaMethodID != nullptr, + // support::createJMatterError(CHIP_ERROR_INCORRECT_STATE)); + + // Set Java callbacks in the DiscoveryDelegateImpl Singleton + DiscoveryDelegateImpl::GetInstance()->castingPlayerChangeListenerJavaObject = + env->NewGlobalRef(castingPlayerChangeListenerJavaObject); + DiscoveryDelegateImpl::GetInstance()->onAddedCallbackJavaMethodID = onAddedJavaMethodID; + DiscoveryDelegateImpl::GetInstance()->onChangedCallbackJavaMethodID = onChangedJavaMethodID; + // DiscoveryDelegateImpl::GetInstance()->onRemovedCallbackJavaMethodID = onRemovedJavaMethodID; + + return support::createJMatterError(CHIP_NO_ERROR); +} + +JNI_METHOD(jobject, removeCastingPlayerChangeListener)(JNIEnv * env, jobject, jobject castingPlayerChangeListenerJavaObject) +{ + chip::DeviceLayer::StackLock lock; + ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI::removeCastingPlayerChangeListener() called"); + + // Check if the passed object is the same as the one added in addCastingPlayerChangeListener() JNI method + jboolean isSameObject = env->IsSameObject(castingPlayerChangeListenerJavaObject, + DiscoveryDelegateImpl::GetInstance()->castingPlayerChangeListenerJavaObject); + + if ((bool) isSameObject) + { + // Delete the global reference to the Java object + env->DeleteGlobalRef(DiscoveryDelegateImpl::GetInstance()->castingPlayerChangeListenerJavaObject); + // Remove the Java callbacks in the DiscoveryDelegateImpl Singleton + DiscoveryDelegateImpl::GetInstance()->castingPlayerChangeListenerJavaObject = nullptr; + // No explicit cleanup required + DiscoveryDelegateImpl::GetInstance()->onAddedCallbackJavaMethodID = nullptr; + DiscoveryDelegateImpl::GetInstance()->onChangedCallbackJavaMethodID = nullptr; + // DiscoveryDelegateImpl::GetInstance()->onRemovedCallbackJavaMethodID = nullptr; + + return support::createJMatterError(CHIP_NO_ERROR); + } + else + { + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::removeCastingPlayerChangeListener() Warning: Cannot remove listener. Received a " + "different CastingPlayerChangeListener object"); + return support::createJMatterError(CHIP_ERROR_INCORRECT_STATE); + } +} + +JNI_METHOD(jobject, getCastingPlayers)(JNIEnv * env, jobject) +{ + chip::DeviceLayer::StackLock lock; + ChipLogProgress(AppServer, "CastingPlayerDiscovery-JNI::getCastingPlayers() called"); + + // Create a new ArrayList + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + jmethodID arrayListConstructor = env->GetMethodID(arrayListClass, "", "()V"); + jobject arrayList = env->NewObject(arrayListClass, arrayListConstructor); + jmethodID addMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); + + std::vector> castingPlayersList = CastingPlayerDiscovery::GetInstance()->GetCastingPlayers(); + + for (const auto & player : castingPlayersList) + { + jobject matterCastingPlayerJavaObject = support::createJCastingPlayer(player); + if (matterCastingPlayerJavaObject != nullptr) + { + jboolean added = env->CallBooleanMethod(arrayList, addMethod, matterCastingPlayerJavaObject); + if (!((bool) added)) + { + ChipLogError(AppServer, + "CastingPlayerDiscovery-JNI::getCastingPlayers() Warning: Unable to add CastingPlayer with ID: %s", + player->GetId()); + } + } + } + + return arrayList; +} + +}; // namespace core +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.h b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.h new file mode 100644 index 00000000000000..94fb568b813960 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/CastingPlayerDiscovery-JNI.h @@ -0,0 +1,41 @@ +/* + * + * 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 + +namespace matter { +namespace casting { +namespace core { + +class CastingPlayerDiscoveryJNI +{ +public: +private: + friend CastingPlayerDiscoveryJNI & CastingAppJNIMgr(); + static CastingPlayerDiscoveryJNI sInstance; +}; + +inline class CastingPlayerDiscoveryJNI & CastingAppJNIMgr() +{ + return CastingPlayerDiscoveryJNI::sInstance; +} +}; // namespace core +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.cpp new file mode 100644 index 00000000000000..a993a501bd6aa0 --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.cpp @@ -0,0 +1,92 @@ +/* + * 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 "CastingPlayerConverter-JNI.h" +#include + +namespace matter { +namespace casting { +namespace support { + +using namespace chip; + +jobject createJCastingPlayer(matter::casting::memory::Strong player) +{ + ChipLogProgress(AppServer, "CastingPlayerConverter-JNI.createJCastingPlayer() called"); + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + + // Get a reference to the MatterCastingPlayer Java class + jclass matterCastingPlayerJavaClass = env->FindClass("com/matter/casting/core/MatterCastingPlayer"); + if (matterCastingPlayerJavaClass == nullptr) + { + ChipLogError(AppServer, + "CastingPlayerConverter-JNI.createJCastingPlayer() could not locate MatterCastingPlayer Java class"); + return nullptr; + } + + // Get the constructor for the com/matter/casting/core/MatterCastingPlayer Java class + jmethodID constructor = + env->GetMethodID(matterCastingPlayerJavaClass, "", + "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;IIIJ)V"); + if (constructor == nullptr) + { + ChipLogError( + AppServer, + "CastingPlayerConverter-JNI.createJCastingPlayer() could not locate MatterCastingPlayer Java class constructor"); + return nullptr; + } + + // Convert the CastingPlayer fields to MatterCastingPlayer Java types + jobject jIpAddressList = nullptr; + const chip::Inet::IPAddress * ipAddresses = player->GetIPAddresses(); + if (ipAddresses != nullptr) + { + chip::JniReferences::GetInstance().CreateArrayList(jIpAddressList); + for (size_t i = 0; i < player->GetNumIPs() && i < chip::Dnssd::CommonResolutionData::kMaxIPAddresses; i++) + { + char addrCString[chip::Inet::IPAddress::kMaxStringLength]; + ipAddresses[i].ToString(addrCString, chip::Inet::IPAddress::kMaxStringLength); + jstring jIPAddressStr = env->NewStringUTF(addrCString); + + jclass jIPAddressClass = env->FindClass("java/net/InetAddress"); + jmethodID jGetByNameMid = + env->GetStaticMethodID(jIPAddressClass, "getByName", "(Ljava/lang/String;)Ljava/net/InetAddress;"); + jobject jIPAddress = env->CallStaticObjectMethod(jIPAddressClass, jGetByNameMid, jIPAddressStr); + + chip::JniReferences::GetInstance().AddToList(jIpAddressList, jIPAddress); + } + } + + // Create a new instance of the MatterCastingPlayer Java class + jobject jMatterCastingPlayer = nullptr; + jMatterCastingPlayer = env->NewObject(matterCastingPlayerJavaClass, constructor, static_cast(player->IsConnected()), + env->NewStringUTF(player->GetId()), env->NewStringUTF(player->GetHostName()), + env->NewStringUTF(player->GetDeviceName()), env->NewStringUTF(player->GetInstanceName()), + jIpAddressList, (jint) (player->GetPort()), (jint) (player->GetProductId()), + (jint) (player->GetVendorId()), (jlong) (player->GetDeviceType())); + if (jMatterCastingPlayer == nullptr) + { + ChipLogError(AppServer, + "CastingPlayerConverter-JNI.createJCastingPlayer() Warning: Could not create MatterCastingPlayer Java object"); + } + return jMatterCastingPlayer; +} + +}; // namespace support +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.h b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.h new file mode 100644 index 00000000000000..91b0ac6c79b92f --- /dev/null +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/CastingPlayerConverter-JNI.h @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2023-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 "core/CastingPlayer.h" + +#include + +#include + +namespace matter { +namespace casting { +namespace support { + +/** + * @brief Convertes a native CastingPlayer into a MatterCastingPlayer jobject + * + * @param CastingPlayer represents a Matter commissioner that is able to play media to a physical + * output or to a display screen which is part of the device. + * + * @return pointer to the CastingPlayer jobject if created successfully, nullptr otherwise. + */ +jobject createJCastingPlayer(matter::casting::memory::Strong player); + +}; // namespace support +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/ErrorConverter-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/ErrorConverter-JNI.cpp index 171a44dc793f9f..9cec7897488103 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/ErrorConverter-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/ErrorConverter-JNI.cpp @@ -35,7 +35,7 @@ jobject createJMatterError(CHIP_ERROR inErr) jmethodID jMatterErrorConstructor = env->GetMethodID(jMatterErrorClass, "", "(JLjava/lang/String;)V"); - return env->NewObject(jMatterErrorClass, jMatterErrorConstructor, err.AsInteger(), nullptr); + return env->NewObject(jMatterErrorClass, jMatterErrorConstructor, inErr.AsInteger(), nullptr); } }; // namespace support diff --git a/examples/tv-casting-app/android/App/app/src/main/res/layout/activity_main.xml b/examples/tv-casting-app/android/App/app/src/main/res/layout/activity_main.xml index 1a8bfe110a0495..ff56873cb23c22 100644 --- a/examples/tv-casting-app/android/App/app/src/main/res/layout/activity_main.xml +++ b/examples/tv-casting-app/android/App/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="MainActivity"> + tools:context=".chip.casting.app.MainActivity"> + tools:context=".chip.casting.app.CertTestFragment"> + tools:context=".chip.casting.app.CommissionerDiscoveryFragment"> + tools:context=".chip.casting.app.ContentLauncherFragment"> + + + + +