diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt index 0662ec08dc2146..f38cacbd259073 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt @@ -17,6 +17,7 @@ import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -191,8 +192,8 @@ class BasicClientFragment : Fragment() { Log.e(TAG, "Write ${attribute.name} failure", ex) } - override fun onResponse(attributePath: ChipAttributePath?) { - showMessage("Write ${attribute.name} success") + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + showMessage("Write ${attribute.name} response: $status") } }, devicePtr, diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt index 87735856fa4844..c27159193ed2dc 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt @@ -32,6 +32,7 @@ import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -223,9 +224,9 @@ class OtaProviderClientFragment : Fragment() { showMessage("Error : ${e.toString()}") } - override fun onResponse(attributePath: ChipAttributePath?) { + override fun onResponse(attributePath: ChipAttributePath, status: Status) { Log.d(TAG, "onResponse") - showMessage("write Success") + showMessage("$attributePath : Write response: $status") } }, ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), @@ -350,9 +351,9 @@ class OtaProviderClientFragment : Fragment() { showMessage("error : ${e.toString()}") } - override fun onResponse(attributePath: ChipAttributePath?) { + override fun onResponse(attributePath: ChipAttributePath, status: Status) { Log.d(TAG, "onResponse") - showMessage("write success") + showMessage("$attributePath : Write response: $status") } }, ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt index 1978951e02e210..af119581a7047f 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt @@ -27,6 +27,7 @@ import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.ChipPathId import chip.devicecontroller.model.InvokeElement import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.R import com.google.chip.chiptool.databinding.WildcardFragmentBinding @@ -92,8 +93,8 @@ class WildcardFragment : Fragment() { Log.e(TAG, "Report error for $attributePath: $ex") } - override fun onResponse(attributePath: ChipAttributePath?) { - val text = "$attributePath : Write Success" + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + val text = "$attributePath : Write response: $status" requireActivity().runOnUiThread { binding.outputTv.text = text } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt index e0a95d584130eb..1758fbd868fbfb 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt @@ -67,13 +67,12 @@ class PairOnNetworkLongImReadCommand( } fun checkUnitTestClusterGeneralStatus(status: Status): Boolean = - (status.getStatus() == CLUSTER_ID_TEST_GENERAL_ERROR_STATUS) && - !status.getClusterStatus().isPresent() + (status.getStatus() == Status.Code.InvalidDataType) && !status.getClusterStatus().isPresent() fun checkUnitTestClusterClusterStatus(status: Status): Boolean = - (status.getStatus() == CLUSTER_ID_TEST_CLUSTER_ERROR_STATUS) && + (status.getStatus() == Status.Code.Failure) && status.getClusterStatus().isPresent() && - status.getClusterStatus().get() == CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS + (status.getClusterStatus().get() == CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS) private fun validateResponse(nodeState: NodeState) { val endpointZero = @@ -243,8 +242,6 @@ class PairOnNetworkLongImReadCommand( private const val CLUSTER_ID_BASIC_VERSION = 0L private const val CLUSTER_ID_TEST_GENERAL_ERROR_BOOLEAN = 0x0031L private const val CLUSTER_ID_TEST_CLUSTER_ERROR_BOOLEAN = 0x0032L - private const val CLUSTER_ID_TEST_GENERAL_ERROR_STATUS = 0x8d - private const val CLUSTER_ID_TEST_CLUSTER_ERROR_STATUS = 1 private const val CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS = 17 } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt index 3e90935d22268e..fdb74c5d065b5c 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt @@ -22,6 +22,7 @@ import chip.devicecontroller.GetConnectedDeviceCallbackJni.GetConnectedDeviceCal import chip.devicecontroller.WriteAttributesCallback import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath +import chip.devicecontroller.model.Status import com.matter.controller.commands.common.CredentialsIssuer import java.util.logging.Level import java.util.logging.Logger @@ -51,11 +52,8 @@ class PairOnNetworkLongImWriteCommand( setFailure("write failure") } - override fun onResponse(attributePath: ChipAttributePath?) { - logger.log(Level.INFO, "Write receive OnResponse on ") - if (attributePath != null) { - logger.log(Level.INFO, attributePath.toString()) - } + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + logger.log(Level.INFO, "$attributePath : Write response: $status") setSuccess() } } diff --git a/kotlin-detect-config.yaml b/kotlin-detect-config.yaml index 6de03b283f7065..2ad54a05d6c483 100644 --- a/kotlin-detect-config.yaml +++ b/kotlin-detect-config.yaml @@ -36,8 +36,8 @@ style: - "**/src/controller/java/src/matter/tlv/types.kt" - "**/src/controller/java/src/matter/tlv/utils.kt" - "**/src/controller/java/src/matter/tlv/values.kt" - - "**/src/controller/java/src/chip/WildcardImport - examples/android/CHIPTest/app/src/androidTest/java/com/tcl/chip/chiptest/ExampleInstrumentedTest.kt" + - "**/src/controller/java/src/matter/tlv/values.kt" + - "**/src/controller/java/src/matter/controller/model/Status.kt" - "**/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt" - "**/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt" - "**/src/controller/java/tests/matter/jsontlv/JsonToTlvToJsonTest.kt" diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja index ba0abf5976f49c..6c8ad742068684 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja @@ -102,6 +102,7 @@ import chip.devicecontroller.model.ClusterState; import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -318,8 +319,15 @@ public class ChipClusters { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java index 9b6287a9a954ae..37c5c031b5c5ae 100644 --- a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java +++ b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java @@ -25,6 +25,7 @@ import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -241,8 +242,15 @@ static class WriteAttributesCallbackImpl implements WriteAttributesCallback { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index eb6e8b1a5f255b..eb1584b531e292 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -669,23 +669,27 @@ void WriteAttributesCallback::OnResponse(const app::WriteClient * apWriteClient, JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); JniLocalReferenceScope scope(env); - - if (aStatus.mStatus != Protocols::InteractionModel::Status::Success) - { - ReportError(&aPath, aStatus.mStatus); - return; - } - jmethodID onResponseMethod; VerifyOrReturn(mWrapperCallbackRef.HasValidObjectRef(), ChipLogError(Controller, "mWrapperCallbackRef is not valid in %s", __func__)); jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); - err = JniReferences::GetInstance().FindMethod(env, wrapperCallback, "onResponse", "(IJJ)V", &onResponseMethod); + err = JniReferences::GetInstance().FindMethod(env, wrapperCallback, "onResponse", "(IJJILjava/lang/Integer;)V", + &onResponseMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to find onError method: %s", ErrorStr(err))); + jobject jClusterState = nullptr; + if (aStatus.mClusterStatus.HasValue()) + { + err = JniReferences::GetInstance().CreateBoxedObject( + "java/lang/Integer", "(I)V", static_cast(aStatus.mClusterStatus.Value()), jClusterState); + VerifyOrReturn(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Could not CreateBoxedObject with error %" CHIP_ERROR_FORMAT, err.Format())); + } + DeviceLayer::StackUnlock unlock; env->CallVoidMethod(wrapperCallback, onResponseMethod, static_cast(aPath.mEndpointId), - static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId), aStatus.mStatus, + jClusterState); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index b2ec93cb67f160..bf41b962b4cc3d 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -391,6 +391,7 @@ kotlin_library("kotlin_matter_controller") { "src/matter/controller/WriteAttributesCallbackJni.kt", "src/matter/controller/model/Paths.kt", "src/matter/controller/model/States.kt", + "src/matter/controller/model/Status.kt", ] sources += matter_structs_sources @@ -477,6 +478,7 @@ android_library("java") { "src/chip/devicecontroller/ReportCallback.java", "src/chip/devicecontroller/ReportCallbackJni.java", "src/chip/devicecontroller/ResubscriptionAttemptCallback.java", + "src/chip/devicecontroller/StatusException.java", "src/chip/devicecontroller/SubscriptionEstablishedCallback.java", "src/chip/devicecontroller/ThreadScanResult.java", "src/chip/devicecontroller/UnpairDeviceCallback.java", diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 6e479c5f37094c..fcc9154511d2b7 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -25,6 +25,7 @@ import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -241,8 +242,15 @@ static class WriteAttributesCallbackImpl implements WriteAttributesCallback { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/src/controller/java/src/chip/devicecontroller/StatusException.java b/src/controller/java/src/chip/devicecontroller/StatusException.java new file mode 100644 index 00000000000000..6a97e5b0e19aeb --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/StatusException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +import chip.devicecontroller.model.Status; + +/** Exception class holding error codes defined by Interaction Model */ +public class StatusException extends Exception { + private static final long serialVersionUID = 1L; + + public Status.Code code = Status.Code.Success; + + public StatusException() {} + + public StatusException(Status.Code code) { + super(String.format("CHIP IM status error: %s", code.name())); + this.code = code; + } +} diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java index 4e469ab0e58245..477f133c81a9c4 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java @@ -18,6 +18,7 @@ package chip.devicecontroller; import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; /** An interface for receiving write response. */ @@ -40,8 +41,9 @@ public interface WriteAttributesCallback { * path. * * @param attributePath The attribute path field in write response. + * @param status The status field in write response. */ - void onResponse(ChipAttributePath attributePath); + void onResponse(ChipAttributePath attributePath, Status status); default void onDone() {} } diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java index fd7f8066c80a73..7b95b30759222f 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java @@ -18,6 +18,8 @@ package chip.devicecontroller; import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.Status; +import javax.annotation.Nullable; /** JNI wrapper callback class for {@link WriteAttributesCallback}. */ public final class WriteAttributesCallbackJni { @@ -45,9 +47,15 @@ private void onError( e); } - private void onResponse(int endpointId, long clusterId, long attributeId) { + private void onResponse( + int endpointId, + long clusterId, + long attributeId, + int status, + @Nullable Integer clusterStatus) { wrappedWriteAttributesCallback.onResponse( - ChipAttributePath.newInstance(endpointId, clusterId, attributeId)); + ChipAttributePath.newInstance(endpointId, clusterId, attributeId), + Status.newInstance(status, clusterStatus)); } private void onDone() { diff --git a/src/controller/java/src/chip/devicecontroller/model/Status.java b/src/controller/java/src/chip/devicecontroller/model/Status.java index c367535f5e8578..d859fae9f189e0 100644 --- a/src/controller/java/src/chip/devicecontroller/model/Status.java +++ b/src/controller/java/src/chip/devicecontroller/model/Status.java @@ -21,17 +21,87 @@ import java.util.Locale; import java.util.Optional; +/** Class for Interaction Model Status * */ public final class Status { - private Integer status; + public enum Code { + Success(0x0), + Failure(0x01), + InvalidSusbscription(0x7d), + UnsupportedAccess(0x7e), + UnsupportedEndPoint(0x7f), + InvalidAction(0x80), + UnsupportedCommand(0x81), + Deprecated82(0x82), + Deprecated83(0x83), + Deprecated84(0x84), + InvalidCommand(0x85), + UnsupportedAttribute(0x86), + ConstraintError(0x87), + UnsupportedWrite(0x88), + ResourceExhausted(0x89), + Deprecated8a(0x8a), + NotFound(0x8b), + UnreportableAttribute(0x8c), + InvalidDataType(0x8d), + Deprecated8e(0x8e), + UnsupportedRead(0x8f), + Deprecated90(0x90), + Deprecated91(0x91), + DataVersionMismatch(0x92), + Deprecated93(0x93), + Timeout(0x94), + Reserved95(0x95), + Reserved96(0x96), + Reserved97(0x97), + Reserved98(0x98), + Reserved99(0x99), + Reserved9a(0x9a), + Busy(0x9c), + Deprecatedc0(0xc0), + Deprecatedc1(0xc1), + Deprecatedc2(0xc2), + UnsupportedCluster(0xc3), + Deprecatedc4(0xc4), + NoUpstreamSubsricption(0xc5), + NeedTimedInteraction(0xc6), + UnsupportedEvent(0xc7), + PathExhausted(0xc8), + TimedRequestMismatch(0xc9), + FailsafeRequired(0xca), + InvalidInState(0xcb), + NoCommandResponse(0xcc), + WriteIgnored(0xf0); + + private int id = 0; + + Code(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static Code fromId(int id) { + for (Code type : values()) { + if (type.getId() == id) { + return type; + } + } + return null; + } + } + + private Code status = Code.Success; private Optional clusterStatus; private Status(int status, Optional clusterStatus) { - this.status = status; + this.status = Code.fromId(status); this.clusterStatus = clusterStatus; } // Getters - public Integer getStatus() { + public Code getStatus() { return status; } @@ -43,7 +113,7 @@ public String toString() { return String.format( Locale.ENGLISH, "status %s, clusterStatus %s", - String.valueOf(status), + status.name(), clusterStatus.isPresent() ? String.valueOf(clusterStatus.get()) : "None"); } @@ -51,7 +121,7 @@ public static Status newInstance(int status) { return new Status(status, Optional.empty()); } - static Status newInstance(int status, Integer clusterStatus) { + public static Status newInstance(int status, Integer clusterStatus) { return new Status(status, Optional.ofNullable(clusterStatus)); } } diff --git a/src/controller/java/src/matter/controller/MatterControllerImpl.kt b/src/controller/java/src/matter/controller/MatterControllerImpl.kt index 202d97a99e1ad0..6ae71f33a0faac 100644 --- a/src/controller/java/src/matter/controller/MatterControllerImpl.kt +++ b/src/controller/java/src/matter/controller/MatterControllerImpl.kt @@ -36,6 +36,7 @@ import matter.controller.model.AttributePath import matter.controller.model.EventPath import matter.controller.model.EventState import matter.controller.model.NodeState +import matter.controller.model.Status /** Controller to interact with the CHIP device. */ class MatterControllerImpl(params: ControllerParams) : MatterController { @@ -340,8 +341,11 @@ class MatterControllerImpl(params: ControllerParams) : MatterController { return suspendCancellableCoroutine { continuation -> val writeCallback = object : WriteAttributesCallback { - override fun onResponse(attributePath: AttributePath) { - logger.log(Level.INFO, "write success for attributePath:%s", attributePath.toString()) + override fun onResponse(attributePath: AttributePath, status: Status) { + logger.log( + Level.INFO, + "Receive write response for attributePath: ${attributePath} and status ${status}" + ) } override fun onError(attributePath: AttributePath?, ex: Exception) { diff --git a/src/controller/java/src/matter/controller/WriteAttributesCallback.kt b/src/controller/java/src/matter/controller/WriteAttributesCallback.kt index b4a3f112a02f83..6b1b3f7056f71e 100644 --- a/src/controller/java/src/matter/controller/WriteAttributesCallback.kt +++ b/src/controller/java/src/matter/controller/WriteAttributesCallback.kt @@ -18,6 +18,7 @@ package matter.controller import matter.controller.model.AttributePath +import matter.controller.model.Status /** An interface for receiving write response. */ interface WriteAttributesCallback { @@ -38,8 +39,9 @@ interface WriteAttributesCallback { * path. * * @param attributePath The attribute path field in write response. + * @param status The attribute status field in write response. */ - fun onResponse(attributePath: AttributePath) + fun onResponse(attributePath: AttributePath, status: Status) fun onDone() {} } diff --git a/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt b/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt index bd0bad3e228dda..fe52a329ff3078 100644 --- a/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt +++ b/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt @@ -18,6 +18,7 @@ package matter.controller import matter.controller.model.AttributePath +import matter.controller.model.Status /** JNI wrapper callback class for [WriteAttributesCallback]. */ class WriteAttributesCallbackJni( @@ -53,9 +54,16 @@ class WriteAttributesCallbackJni( ) } - private fun onResponse(endpointId: Int, clusterId: Long, attributeId: Long) { + private fun onResponse( + endpointId: Int, + clusterId: Long, + attributeId: Long, + status: Int, + clusterStatus: Int? + ) { wrappedWriteAttributesCallback.onResponse( - AttributePath(endpointId.toUShort(), clusterId.toUInt(), attributeId.toUInt()) + AttributePath(endpointId.toUShort(), clusterId.toUInt(), attributeId.toUInt()), + Status(status, clusterStatus) ) } diff --git a/src/controller/java/src/matter/controller/model/States.kt b/src/controller/java/src/matter/controller/model/States.kt index c913b37b9986f4..e7799f1f5a64e1 100644 --- a/src/controller/java/src/matter/controller/model/States.kt +++ b/src/controller/java/src/matter/controller/model/States.kt @@ -273,5 +273,3 @@ data class EventState( return null } } - -data class Status(val status: Int, val clusterStatus: Int?) diff --git a/src/controller/java/src/matter/controller/model/Status.kt b/src/controller/java/src/matter/controller/model/Status.kt new file mode 100644 index 00000000000000..fa12f0b1cb25a5 --- /dev/null +++ b/src/controller/java/src/matter/controller/model/Status.kt @@ -0,0 +1,86 @@ +/* + * 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 matter.controller.model + +/** + * Represents information about a node, including data on all available endpoints. + * + * @param endpoints A mapping of endpoint IDs with the associated cluster data. + */ +data class Status(val status: Int, val clusterStatus: Int?) { + enum class Code(val id: Int) { + SUCCESS(0X0), + FAILURE(0X01), + INVALID_SUSBSCRIPTION(0X7D), + UNSUPPORTED_ACCESS(0X7E), + UNSUPPORTED_ENDPOINT(0X7F), + INVALID_ACTION(0X80), + UNSUPPORTED_COMMAND(0X81), + DEPRECATED82(0X82), + DEPRECATED83(0X83), + DEPRECATED84(0X84), + INVALID_COMMAND(0X85), + UNSUPPORTED_ATTRIBUTE(0X86), + CONSTRAINT_ERROR(0X87), + UNSUPPORTED_WRITE(0X88), + RESOURCE_EXHAUSTED(0X89), + DEPRECATED8A(0X8A), + NOT_FOUND(0X8B), + UNREPORTABLE_ATTRIBUTE(0X8C), + INVALID_DATATYPE(0X8D), + DEPRECATED8E(0X8E), + UNSUPPORTED_READ(0X8F), + DEPRECATED90(0X90), + DEPRECATED91(0X91), + DATA_VERSION_MISMATCH(0X92), + DEPRECATED93(0X93), + TIMEOUT(0X94), + RESERVED95(0X95), + RESERVED96(0X96), + RESERVED97(0X97), + RESERVED98(0X98), + RESERVED99(0X99), + RESERVED9A(0X9A), + BUSY(0X9C), + DEPRECATEDC0(0XC0), + DEPRECATEDC1(0XC1), + DEPRECATEDC2(0XC2), + UNSUPPORTED_CLUSTER(0XC3), + DEPRECATEDC4(0XC4), + NO_UPSTREAM_SUBSRICPTION(0XC5), + NEEDS_TIMED_INTERACTION(0XC6), + UNSUPPORTED_EVENT(0XC7), + PATH_EXHAUSTED(0XC8), + TIMED_REQUEST_MISMATCH(0XC9), + FAILSAFE_REQUIRED(0XCA), + INVALID_IN_STATE(0XCB), + NO_COMMAND_RESPONSE(0XCC), + WRITE_IGNORED(0XF0) + } + + fun getCode(): Code? { + for (code in Code.values()) { + if (code.id == status) { + return code + } + } + return null + } + + override fun toString(): String = "$status/$clusterStatus/" +} diff --git a/src/controller/python/chip/interaction_model/__init__.py b/src/controller/python/chip/interaction_model/__init__.py index 61faa7f7d5d741..ec100846b085a5 100644 --- a/src/controller/python/chip/interaction_model/__init__.py +++ b/src/controller/python/chip/interaction_model/__init__.py @@ -86,6 +86,7 @@ class Status(enum.IntEnum): FailsafeRequired = 0xca InvalidInState = 0xcb NoCommandResponse = 0xcc + WriteIgnored = 0xf0 class InteractionModelError(ChipStackException): diff --git a/src/protocols/interaction_model/StatusCodeList.h b/src/protocols/interaction_model/StatusCodeList.h index 3b79e4a698b7b5..5538478d76ce52 100644 --- a/src/protocols/interaction_model/StatusCodeList.h +++ b/src/protocols/interaction_model/StatusCodeList.h @@ -22,7 +22,10 @@ * include this file, then undefine the macro. */ -/// WARNING: If you touch this list, please also update src/controller/python/chip/interaction_model/__init__.py +/// WARNING: If you touch this list, +/// please update src/controller/python/chip/interaction_model/__init__.py +/// please update src/controller/java/src/chip/devicecontroller/model/Status.java +/// please update src/controller/java/src/matter/controller/model/Status.kt // clang-format off CHIP_IM_STATUS_CODE(Success , SUCCESS , 0x0)