Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Implement Java TLV Decoder API #27586

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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 com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
Expand Down Expand Up @@ -99,8 +101,26 @@ class OpCredClientFragment : Fragment() {

override fun onReport(nodeState: NodeState?) {
val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.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<ChipStructs.OperationalCredentialsClusterFabricDescriptorStruct>>(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, listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)), null, false, 0 /* imTimeoutMs */)
Expand Down
2 changes: 2 additions & 0 deletions src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -313,6 +314,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",
Expand Down
8 changes: 4 additions & 4 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<app::AttributePathParams> & 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<app::EventPathParams> & 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 {
Expand Down
83 changes: 83 additions & 0 deletions src/controller/java/CHIPTLVValueDecoder-JNI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "lib/core/CHIPError.h"
#include "lib/support/JniTypeWrappers.h"

// #include <lib/support/CHIPMem.h>
// #include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/logging/CHIPLogging.h>

#include "CHIPAttributeTLVValueDecoder.h"
#include "CHIPEventTLVValueDecoder.h"

#include <jni.h>

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;
}
Original file line number Diff line number Diff line change
@@ -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> T decodeAttributeValue(ChipAttributePath attributePath, byte[] tlv);

public static native <T> T decodeEventValue(ChipEventPath eventPath, byte[] tlv);
joonhaengHeo marked this conversation as resolved.
Show resolved Hide resolved
}