diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt index 734ce12c6810bb..b14f4a57062a57 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OpCredClientFragment.kt @@ -8,6 +8,8 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.ChipStructs +import chip.devicecontroller.ChipTLVValueDecoder import chip.devicecontroller.ClusterIDMapping.OperationalCredentials import chip.devicecontroller.InvokeCallback import chip.devicecontroller.ReportCallback @@ -120,8 +122,37 @@ class OpCredClientFragment : Fragment() { ?.getAttributeState(attributeId) ?.value ?: "null" - Log.i(TAG, "OpCred $attributeName value: $value") - showMessage("OpCred $attributeName value: $value") + val tlv = + nodeState + ?.getEndpointState(endpointId) + ?.getClusterState(clusterId) + ?.getAttributeState(attributeId) + ?.tlv + + if (tlv == null) { + Log.i(TAG, "OpCred $attributeName value: $value") + showMessage("OpCred $attributeName value: $value") + return + } + + val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId) + when (attribute) { + OperationalCredentials.Attribute.Fabrics -> { + val ret = + ChipTLVValueDecoder.decodeAttributeValue< + List + >( + attributePath, + tlv + ) + Log.i(TAG, "OpCred $attributeName value: $value") + showMessage(ret.toString()) + } + else -> { + Log.i(TAG, "OpCred $attributeName value: $value") + showMessage("OpCred $attributeName value: $value") + } + } } }, devicePtr, diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 22e3cc4fa79eb7..d6c78191e37fe0 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -56,6 +56,7 @@ shared_library("jni") { "CHIPDefaultCallbacks.cpp", "CHIPDefaultCallbacks.h", "CHIPDeviceController-JNI.cpp", + "CHIPTLVValueDecoder-JNI.cpp", "DeviceAttestationDelegateBridge.cpp", "DeviceAttestationDelegateBridge.h", "zap-generated/CHIPAttributeTLVValueDecoder.cpp", @@ -328,6 +329,7 @@ android_library("java") { "src/chip/devicecontroller/ChipDeviceController.java", "src/chip/devicecontroller/ChipDeviceControllerException.java", "src/chip/devicecontroller/ChipIdLookup.java", + "src/chip/devicecontroller/ChipTLVValueDecoder.java", "src/chip/devicecontroller/ControllerParams.java", "src/chip/devicecontroller/DeviceAttestationDelegate.java", "src/chip/devicecontroller/DiscoveredDevice.java", diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 1e6fedc01327d1..64c7dac4774785 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -81,11 +81,11 @@ static CHIP_ERROR N2J_NetworkLocation(JNIEnv * env, jstring ipAddress, jint port static CHIP_ERROR GetChipPathIdValue(jobject chipPathId, uint32_t wildcardValue, uint32_t & outValue); static CHIP_ERROR ParseAttributePathList(jobject attributePathList, std::vector & outAttributePathParamsList); -static CHIP_ERROR ParseAttributePath(jobject attributePath, EndpointId & outEndpointId, ClusterId & outClusterId, - AttributeId & outAttributeId); +CHIP_ERROR ParseAttributePath(jobject attributePath, EndpointId & outEndpointId, ClusterId & outClusterId, + AttributeId & outAttributeId); static CHIP_ERROR ParseEventPathList(jobject eventPathList, std::vector & outEventPathParamsList); -static CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId, - bool & outIsUrgent); +CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId, + bool & outIsUrgent); static CHIP_ERROR IsWildcardChipPathId(jobject chipPathId, bool & isWildcard); namespace { diff --git a/src/controller/java/CHIPTLVValueDecoder-JNI.cpp b/src/controller/java/CHIPTLVValueDecoder-JNI.cpp new file mode 100644 index 00000000000000..26604b2e272fc6 --- /dev/null +++ b/src/controller/java/CHIPTLVValueDecoder-JNI.cpp @@ -0,0 +1,83 @@ +#include "lib/core/CHIPError.h" +#include "lib/support/JniTypeWrappers.h" + +// #include +// #include +#include +#include + +#include "CHIPAttributeTLVValueDecoder.h" +#include "CHIPEventTLVValueDecoder.h" + +#include + +using namespace chip; + +#define JNI_METHOD(RETURN, METHOD_NAME) \ + extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_ChipTLVValueDecoder_##METHOD_NAME + +extern CHIP_ERROR ParseAttributePath(jobject attributePath, EndpointId & outEndpointId, ClusterId & outClusterId, + AttributeId & outAttributeId); +extern CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId, + bool & outIsUrgent); + +JNI_METHOD(jobject, decodeAttributeValue)(JNIEnv * env, jclass clazz, jobject attributePath, jbyteArray jTlv) +{ + EndpointId endpointId; + ClusterId clusterId; + AttributeId attributeId; + CHIP_ERROR err = ParseAttributePath(attributePath, endpointId, clusterId, attributeId); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(Controller, "decode error attributePath"); + return nullptr; + } + + JniByteArray tlv(env, jTlv); + + chip::app::ConcreteAttributePath path(endpointId, clusterId, attributeId); + + chip::TLV::TLVReader reader; + reader.Init(tlv.byteSpan()); + reader.Next(); + + jobject ret = DecodeAttributeValue(path, reader, &err); + + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(Controller, "decode error attributeValue"); + return nullptr; + } + + return ret; +} + +JNI_METHOD(jobject, decodeEventValue)(JNIEnv * env, jclass clazz, jobject eventPath, jbyteArray jTlv) +{ + EndpointId endpointId; + ClusterId clusterId; + EventId eventId; + bool isUrgent; + CHIP_ERROR err = ParseEventPath(eventPath, endpointId, clusterId, eventId, isUrgent); + if (err != CHIP_NO_ERROR) + { + return nullptr; + } + + JniByteArray tlv(env, jTlv); + + chip::app::ConcreteEventPath path(endpointId, clusterId, eventId); + chip::TLV::TLVReader reader; + + reader.Init(tlv.byteSpan()); + reader.Next(); + + jobject ret = DecodeEventValue(path, reader, &err); + + if (err != CHIP_NO_ERROR) + { + return nullptr; + } + + return ret; +} diff --git a/src/controller/java/src/chip/devicecontroller/ChipTLVValueDecoder.java b/src/controller/java/src/chip/devicecontroller/ChipTLVValueDecoder.java new file mode 100644 index 00000000000000..86c375bc93508c --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/ChipTLVValueDecoder.java @@ -0,0 +1,28 @@ +/* + * 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 chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.ChipEventPath; + +public class ChipTLVValueDecoder { + public static native T decodeAttributeValue(ChipAttributePath attributePath, byte[] tlv); + + public static native T decodeEventValue(ChipEventPath eventPath, byte[] tlv); +}