blob: 28678bdf2fb472607aaa21fe9a04a744c0fc9121 [file] [log] [blame]
Austin Hsiehfb469172022-02-15 19:11:22 -08001#include <jni.h>
joonhaengHeo155917e2023-11-08 10:29:50 +09002#include <lib/core/CHIPError.h>
3#include <lib/core/TLV.h>
Andrei Litvin377ac092022-09-14 16:16:41 -04004#include <lib/support/JniReferences.h>
joonhaengHeo155917e2023-11-08 10:29:50 +09005#include <lib/support/JniTypeWrappers.h>
Austin Hsiehfb469172022-02-15 19:11:22 -08006
7#define JNI_METHOD(RETURN, CLASS_NAME, METHOD_NAME) \
8 extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_ChipClusters_00024##CLASS_NAME##_##METHOD_NAME
9
joonhaengHeo155917e2023-11-08 10:29:50 +090010#define CHIP_TLV_WRITER_BUFFER_SIZE 1024
11
12jobject decodeValueFromTLV(JNIEnv * env, chip::TLV::TLVReader * data);
13static CHIP_ERROR encodeTLVFromValue(JNIEnv * env, jobject jObject, chip::TLV::TLVWriter & writer, chip::TLV::Tag tag);
14
15jobject decodeValueFromTLV(JNIEnv * env, chip::TLV::TLVReader * data)
Austin Hsiehfb469172022-02-15 19:11:22 -080016{
joonhaengHeo155917e2023-11-08 10:29:50 +090017 chip::TLV::TLVType dataTLVType = data->GetType();
18 switch (dataTLVType)
Austin Hsiehfb469172022-02-15 19:11:22 -080019 {
joonhaengHeo155917e2023-11-08 10:29:50 +090020 case chip::TLV::kTLVType_SignedInteger: {
21 int64_t val;
22 CHIP_ERROR err = data->Get(val);
23 VerifyOrReturnValue(
24 err == CHIP_NO_ERROR, nullptr,
25 ChipLogError(Controller, "Error: TLV signed integer decoding failed : %" CHIP_ERROR_FORMAT, err.Format()));
26 jclass intTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$IntType");
27 jmethodID constructor = env->GetMethodID(intTypeCls, "<init>", "(J)V");
28 return env->NewObject(intTypeCls, constructor, static_cast<jlong>(val));
29 }
30 case chip::TLV::kTLVType_UnsignedInteger: {
31 uint64_t val;
32 CHIP_ERROR err = data->Get(val);
33 VerifyOrReturnValue(
34 err == CHIP_NO_ERROR, nullptr,
35 ChipLogError(Controller, "Error: TLV unsigned integer decoding failed : %" CHIP_ERROR_FORMAT, err.Format()));
36 jclass uintTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$UIntType");
37 jmethodID constructor = env->GetMethodID(uintTypeCls, "<init>", "(J)V");
38 return env->NewObject(uintTypeCls, constructor, static_cast<jlong>(val));
39 }
40 case chip::TLV::kTLVType_Boolean: {
41 bool val;
42 CHIP_ERROR err = data->Get(val);
43 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
44 ChipLogError(Controller, "Error: TLV boolean decoding failed : %" CHIP_ERROR_FORMAT, err.Format()));
45 jclass booleanTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$BooleanType");
46 jmethodID constructor = env->GetMethodID(booleanTypeCls, "<init>", "(Z)V");
47 return env->NewObject(booleanTypeCls, constructor, static_cast<jboolean>(val));
48 }
49 case chip::TLV::kTLVType_FloatingPointNumber: {
50 // Try float first
51 float floatValue;
52 CHIP_ERROR err = data->Get(floatValue);
53 if (err == CHIP_NO_ERROR)
54 {
55 jclass floatTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$FloatType");
56 jmethodID constructor = env->GetMethodID(floatTypeCls, "<init>", "(F)V");
57 return env->NewObject(floatTypeCls, constructor, static_cast<jfloat>(floatValue));
58 }
59 double val;
60 err = data->Get(val);
61 VerifyOrReturnValue(
62 err == CHIP_NO_ERROR, nullptr,
63 ChipLogError(Controller, "Error: TLV floating point decoding failed : %" CHIP_ERROR_FORMAT, err.Format()));
64 jclass doubleTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$DoubleType");
65 jmethodID doubleConstructor = env->GetMethodID(doubleTypeCls, "<init>", "(D)V");
66 return env->NewObject(doubleTypeCls, doubleConstructor, static_cast<jdouble>(val));
67 }
68 case chip::TLV::kTLVType_UTF8String: {
69 chip::CharSpan stringValue;
70 CHIP_ERROR err = data->Get(stringValue);
71 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
72 ChipLogError(Controller, "Error: TLV UTF8String decoding failed : %" CHIP_ERROR_FORMAT, err.Format()));
73 chip::UtfString stringObj(env, stringValue);
74 jclass stringTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$StringType");
75 jmethodID constructor = env->GetMethodID(stringTypeCls, "<init>", "(Ljava/lang/String;)V");
76 return env->NewObject(stringTypeCls, constructor, stringObj.jniValue());
77 }
78 case chip::TLV::kTLVType_ByteString: {
79 chip::ByteSpan bytesValue;
80 CHIP_ERROR err = data->Get(bytesValue);
81 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
82 ChipLogError(Controller, "Error: TLV ByteString decoding failed : %" CHIP_ERROR_FORMAT, err.Format()));
83 chip::ByteArray byteArrayObj(env, bytesValue);
84 jclass stringTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$ByteArrayType");
85 jmethodID constructor = env->GetMethodID(stringTypeCls, "<init>", "([B)V");
86 return env->NewObject(stringTypeCls, constructor, byteArrayObj.jniValue());
87 }
88 case chip::TLV::kTLVType_Null: {
89 jclass nullTypeCls = env->FindClass("chip/devicecontroller/ChipTLVType$NullType");
90 jmethodID constructor = env->GetMethodID(nullTypeCls, "<init>", "()V");
91 return env->NewObject(nullTypeCls, constructor);
92 }
93 case chip::TLV::kTLVType_Structure:
94 case chip::TLV::kTLVType_Array: {
95 chip::TLV::TLVType tlvType;
96 CHIP_ERROR err = data->EnterContainer(tlvType);
97 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
98 ChipLogError(Controller, "Error: TLV container entering failed : %" CHIP_ERROR_FORMAT, err.Format()));
99
100 jobject arrayLists;
101 err = chip::JniReferences::GetInstance().CreateArrayList(arrayLists);
102 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
103 ChipLogError(Controller, "Error: Create ArrayList object failed : %" CHIP_ERROR_FORMAT, err.Format()));
104
105 while ((err = data->Next()) == CHIP_NO_ERROR)
106 {
107 chip::TLV::Tag tag = data->GetTag();
108 jobject value = decodeValueFromTLV(env, data);
109 VerifyOrReturnValue(
110 value != nullptr, nullptr,
111 ChipLogError(Controller, "Error when decoding TLV container of type : %" CHIP_ERROR_FORMAT, err.Format()));
112
113 jobject jValue = nullptr;
114 if (dataTLVType == chip::TLV::kTLVType_Structure)
115 {
116 uint64_t tagNum = TagNumFromTag(tag);
117
118 jclass structElementCls = env->FindClass("chip/devicecontroller/ChipTLVType$StructElement");
119 jmethodID constructor =
120 env->GetMethodID(structElementCls, "<init>", "(JLchip/devicecontroller/ChipTLVType$BaseTLVType;)V");
121
122 jValue = env->NewObject(structElementCls, constructor, static_cast<jlong>(tagNum), value);
123 }
124 else
125 {
126 jValue = value;
127 }
128 err = chip::JniReferences::GetInstance().AddToList(arrayLists, jValue);
129 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
130 ChipLogError(Controller, "Error: Add ArrayList object failed : %" CHIP_ERROR_FORMAT, err.Format()));
131 }
132 if (err != CHIP_END_OF_TLV)
133 {
134 ChipLogError(Controller, "Error: TLV container decoding failed: %" CHIP_ERROR_FORMAT, err.Format());
135 return nullptr;
136 }
137
138 err = data->ExitContainer(tlvType);
139 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr,
140 ChipLogError(Controller, "Error: TLV container exiting failed: %" CHIP_ERROR_FORMAT, err.Format()));
141
142 jclass typeCls = nullptr;
143 if (dataTLVType == chip::TLV::kTLVType_Structure)
144 {
145 typeCls = env->FindClass("chip/devicecontroller/ChipTLVType$StructType");
146 }
147 else
148 {
149 typeCls = env->FindClass("chip/devicecontroller/ChipTLVType$ArrayType");
150 }
151 jmethodID constructor = env->GetMethodID(typeCls, "<init>", "(Ljava/util/ArrayList;)V");
152 return env->NewObject(typeCls, constructor, arrayLists);
153 }
154 default:
155 ChipLogError(Controller, "Error: Unsupported TLV type for conversion : %u", data->GetType());
156 return nullptr;
Austin Hsiehfb469172022-02-15 19:11:22 -0800157 }
158}
Andrei Litvin377ac092022-09-14 16:16:41 -0400159
joonhaengHeo155917e2023-11-08 10:29:50 +0900160static bool isEqualTLVType(JNIEnv * env, const char * typeName, jobject tlvType)
Andrei Litvin377ac092022-09-14 16:16:41 -0400161{
joonhaengHeo155917e2023-11-08 10:29:50 +0900162 jclass tlvEnum = env->FindClass("chip/devicecontroller/ChipTLVType$TLVType");
Andrei Litvin377ac092022-09-14 16:16:41 -0400163
joonhaengHeo155917e2023-11-08 10:29:50 +0900164 jfieldID enumFieldID = env->GetStaticFieldID(tlvEnum, typeName, "Lchip/devicecontroller/ChipTLVType$TLVType;");
165 jobject enumObj = env->GetStaticObjectField(tlvEnum, enumFieldID);
Andrei Litvin377ac092022-09-14 16:16:41 -0400166
joonhaengHeo155917e2023-11-08 10:29:50 +0900167 jmethodID equalsMethodID = env->GetMethodID(tlvEnum, "equals", "(Ljava/lang/Object;)Z");
168
169 return (env->CallBooleanMethod(enumObj, equalsMethodID, tlvType) == JNI_TRUE);
Andrei Litvin377ac092022-09-14 16:16:41 -0400170}
171
joonhaengHeo155917e2023-11-08 10:29:50 +0900172static CHIP_ERROR encodeTLVFromValue(JNIEnv * env, jobject jValue, chip::TLV::TLVWriter & writer, chip::TLV::Tag tag)
Andrei Litvin377ac092022-09-14 16:16:41 -0400173{
joonhaengHeo155917e2023-11-08 10:29:50 +0900174 jmethodID getTypeMethod = nullptr;
175 jmethodID getValueMethod = nullptr;
176 ReturnLogErrorOnFailure(chip::JniReferences::GetInstance().FindMethod(
177 env, jValue, "type", "()Lchip/devicecontroller/ChipTLVType$TLVType;", &getTypeMethod));
Andrei Litvin377ac092022-09-14 16:16:41 -0400178
joonhaengHeo155917e2023-11-08 10:29:50 +0900179 jobject jType = env->CallObjectMethod(jValue, getTypeMethod);
180 if (jType == nullptr)
181 {
182 ChipLogError(Controller, "Error: Object to encode is corrupt");
183 return CHIP_ERROR_INVALID_ARGUMENT;
184 }
185 if (isEqualTLVType(env, "UInt", jType))
186 {
187 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$UIntType");
188 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
189 getValueMethod = env->GetMethodID(typeClass, "value", "()J");
190 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
Andrei Litvin377ac092022-09-14 16:16:41 -0400191
joonhaengHeo155917e2023-11-08 10:29:50 +0900192 jlong value = env->CallLongMethod(jValue, getValueMethod);
193 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
194
195 return writer.Put(tag, static_cast<uint64_t>(value));
Andrei Litvin377ac092022-09-14 16:16:41 -0400196 }
joonhaengHeo155917e2023-11-08 10:29:50 +0900197 if (isEqualTLVType(env, "Int", jType))
Andrei Litvin377ac092022-09-14 16:16:41 -0400198 {
joonhaengHeo155917e2023-11-08 10:29:50 +0900199 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$IntType");
200 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
201 getValueMethod = env->GetMethodID(typeClass, "value", "()J");
202 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
203
204 jlong value = env->CallLongMethod(jValue, getValueMethod);
205 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
206
207 return writer.Put(tag, static_cast<int64_t>(value));
Andrei Litvin377ac092022-09-14 16:16:41 -0400208 }
joonhaengHeo155917e2023-11-08 10:29:50 +0900209 if (isEqualTLVType(env, "Boolean", jType))
210 {
211 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$BooleanType");
212 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
213 getValueMethod = env->GetMethodID(typeClass, "value", "()Z");
214 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
215
216 jboolean value = env->CallBooleanMethod(jValue, getValueMethod);
217 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
218
219 return writer.Put(tag, static_cast<bool>(value));
220 }
221 if (isEqualTLVType(env, "Float", jType))
222 {
223 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$FloatType");
224 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
225 getValueMethod = env->GetMethodID(typeClass, "value", "()F");
226 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
227
228 jfloat value = env->CallFloatMethod(jValue, getValueMethod);
229 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
230
231 return writer.Put(tag, static_cast<float>(value));
232 }
233 if (isEqualTLVType(env, "Double", jType))
234 {
235 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$DoubleType");
236 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
237 getValueMethod = env->GetMethodID(typeClass, "value", "()D");
238 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
239
240 jdouble value = env->CallDoubleMethod(jValue, getValueMethod);
241 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
242
243 return writer.Put(tag, static_cast<double>(value));
244 }
245 if (isEqualTLVType(env, "Null", jType))
246 {
247 return writer.PutNull(tag);
248 }
249 if (isEqualTLVType(env, "String", jType))
250 {
251 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$StringType");
252 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
253 getValueMethod = env->GetMethodID(typeClass, "value", "()Ljava/lang/String;");
254 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
255
256 jstring value = (jstring) env->CallObjectMethod(jValue, getValueMethod);
257 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
258
259 chip::JniUtfString jniString(env, value);
260
261 return writer.PutString(tag, jniString.c_str());
262 }
263 if (isEqualTLVType(env, "ByteArray", jType))
264 {
265 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$ByteArrayType");
266 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
267 getValueMethod = env->GetMethodID(typeClass, "value", "()[B");
268 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
269
270 jbyteArray value = (jbyteArray) env->CallObjectMethod(jValue, getValueMethod);
271 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
272
273 chip::JniByteArray jniByteArray(env, value);
274
275 return writer.Put(tag, jniByteArray.byteSpan());
276 }
277 if (isEqualTLVType(env, "Struct", jType))
278 {
279 jmethodID getSizeMethod = nullptr;
280
281 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$StructType");
282 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
283 getSizeMethod = env->GetMethodID(typeClass, "size", "()I");
284 VerifyOrReturnError(getSizeMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
285 getValueMethod = env->GetMethodID(typeClass, "value", "(I)Lchip/devicecontroller/ChipTLVType$StructElement;");
286 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
287
288 jclass elementClass = env->FindClass("chip/devicecontroller/ChipTLVType$StructElement");
289 VerifyOrReturnError(elementClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
290 jmethodID getcontextTagNumMethod = env->GetMethodID(elementClass, "contextTagNum", "()J");
291 VerifyOrReturnError(getcontextTagNumMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
292 jmethodID getElementValueMethod =
293 env->GetMethodID(elementClass, "value", "()Lchip/devicecontroller/ChipTLVType$BaseTLVType;");
294 VerifyOrReturnError(getElementValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
295
296 jint size = env->CallIntMethod(jValue, getSizeMethod);
297 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
298
299 chip::TLV::TLVType outer;
300 ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
301 for (int i = 0; i < static_cast<int>(size); i++)
302 {
303 jobject eachElement = env->CallObjectMethod(jValue, getValueMethod, static_cast<jint>(i));
304 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
305
306 jlong jEachTag = env->CallLongMethod(eachElement, getcontextTagNumMethod);
307 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
308
309 jobject jEachValue = env->CallObjectMethod(eachElement, getElementValueMethod);
310 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
311
312 uint64_t tagValue = static_cast<uint64_t>(jEachTag);
313 chip::TLV::Tag innerTag = chip::TLV::ContextTag(static_cast<uint8_t>(tagValue));
314 ReturnErrorOnFailure(encodeTLVFromValue(env, jEachValue, writer, innerTag));
315 }
316 ReturnErrorOnFailure(writer.EndContainer(outer));
317 return CHIP_NO_ERROR;
318 }
319 if (isEqualTLVType(env, "Array", jType))
320 {
321 jmethodID getSizeMethod = nullptr;
322
323 jclass typeClass = env->FindClass("chip/devicecontroller/ChipTLVType$ArrayType");
324 VerifyOrReturnError(typeClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
325
326 getSizeMethod = env->GetMethodID(typeClass, "size", "()I");
327 VerifyOrReturnError(getSizeMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
328 getValueMethod = env->GetMethodID(typeClass, "value", "(I)Lchip/devicecontroller/ChipTLVType$BaseTLVType;");
329 VerifyOrReturnError(getValueMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
330
331 jint size = env->CallIntMethod(jValue, getSizeMethod);
332 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
333
334 chip::TLV::TLVType outer;
335 ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Array, outer));
336 for (int i = 0; i < static_cast<int>(size); i++)
337 {
338 jobject eachValue = env->CallObjectMethod(jValue, getValueMethod, static_cast<jint>(i));
339 VerifyOrReturnLogError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN);
340
341 ReturnErrorOnFailure(encodeTLVFromValue(env, eachValue, writer, chip::TLV::AnonymousTag()));
342 }
343 ReturnErrorOnFailure(writer.EndContainer(outer));
344 return CHIP_NO_ERROR;
345 }
346 if (isEqualTLVType(env, "Empty", jType))
347 {
348 // For optional Value
349 return CHIP_NO_ERROR;
350 }
351
352 ChipLogError(Controller, "Error: Unsupported type to encode");
353 return CHIP_ERROR_INVALID_ARGUMENT;
354}
355
356JNI_METHOD(jbyteArray, BaseChipCluster, encodeToTlv)(JNIEnv * env, jclass clazz, jobject value)
357{
358 VerifyOrReturnValue(value != nullptr, nullptr, ChipLogError(Controller, "invalid parameter: value is null"));
359 chip::TLV::TLVWriter writer;
360 uint8_t buffer[CHIP_TLV_WRITER_BUFFER_SIZE];
361 jbyteArray tlv = nullptr;
362 writer.Init(buffer, sizeof(buffer));
363
364 CHIP_ERROR err = encodeTLVFromValue(env, value, writer, chip::TLV::AnonymousTag());
365 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogError(Controller, "Encode Error: %" CHIP_ERROR_FORMAT, err.Format()));
366
joonhaengHeof3b78082024-01-05 00:02:18 +0900367 err = chip::JniReferences::GetInstance().N2J_ByteArray(env, buffer, static_cast<jint>(writer.GetLengthWritten()), tlv);
joonhaengHeo155917e2023-11-08 10:29:50 +0900368 VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogError(Controller, "JNI Error: %" CHIP_ERROR_FORMAT, err.Format()));
369
370 return tlv;
371}
372
373JNI_METHOD(jobject, BaseChipCluster, decodeFromTlv)(JNIEnv * env, jclass clazz, jbyteArray tlvBytesObj)
374{
375 VerifyOrReturnValue(tlvBytesObj != nullptr, nullptr, ChipLogError(Controller, "invalid parameter: tlvBytesObj is null"));
376 chip::JniByteArray tlvBytesObjBytes(env, tlvBytesObj);
377
378 chip::TLV::TLVReader reader;
379 reader.Init(tlvBytesObjBytes.byteSpan());
380 VerifyOrReturnValue(reader.Next() == CHIP_NO_ERROR, nullptr, ChipLogError(Controller, "TLV Parsing is wrong"));
381
382 return decodeValueFromTLV(env, &reader);
Andrei Litvin377ac092022-09-14 16:16:41 -0400383}