Skip to content

Commit

Permalink
Add List, Array TLV
Browse files Browse the repository at this point in the history
  • Loading branch information
joonhaengHeo committed Feb 26, 2024
1 parent 3f6e798 commit bdfb2aa
Showing 1 changed file with 57 additions and 26 deletions.
83 changes: 57 additions & 26 deletions src/controller/java/AndroidCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static const int MILLIS_SINCE_EPOCH = 1;
// Add the bytes for attribute tag(1:control + 8:tag + 8:length) and structure(1:struct + 1:close container)
static const int EXTRA_SPACE_FOR_ATTRIBUTE_TAG = 19;

jobject DecodeGeneralTLVValue(JNIEnv * env, TLV::TLVReader * apData);
jobject DecodeGeneralTLVValue(JNIEnv * env, TLV::TLVReader & readerForGeneralValueObject, CHIP_ERROR &err);

GetConnectedDeviceCallback::GetConnectedDeviceCallback(jobject wrapperCallback, jobject javaCallback,
const char * callbackClassSignature) :
Expand Down Expand Up @@ -316,23 +316,24 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat
readerForJavaTLV.Init(*apData);

jobject value = nullptr;
#ifdef USE_JAVA_TLV_ENCODE_DECODE
TLV::TLVReader readerForJavaObject;
readerForJavaObject.Init(*apData);

#ifdef USE_JAVA_TLV_ENCODE_DECODE
value = DecodeAttributeValue(aPath, readerForJavaObject, &err);
// If we don't know this attribute, suppress it.
if (err == CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB)
{
value = DecodeGeneralTLVValue(env, apData);
TLV::TLVReader readerForGeneralValueObject;
readerForGeneralValueObject.Init(*apData);
value = DecodeGeneralTLVValue(env, readerForGeneralValueObject, err);
err = CHIP_NO_ERROR;
}

VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to decode attribute with error %s", ErrorStr(err));
aPath.LogPath());
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
#else
value = DecodeGeneralTLVValue(env, apData);
value = DecodeGeneralTLVValue(env, readerForJavaObject, err);
#endif
// Create TLV byte array to pass to Java layer
size_t bufferLen = readerForJavaTLV.GetRemainingLength() + readerForJavaTLV.GetLengthRead();
Expand Down Expand Up @@ -473,21 +474,23 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV
}

jobject value = nullptr;
#ifdef USE_JAVA_TLV_ENCODE_DECODE
TLV::TLVReader readerForJavaObject;
readerForJavaObject.Init(*apData);
#ifdef USE_JAVA_TLV_ENCODE_DECODE
value = DecodeEventValue(aEventHeader.mPath, readerForJavaObject, &err);
// If we don't know this event, just skip it.
if (err == CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB)
{
value = DecodeGeneralTLVValue(env, apData);
TLV::TLVReader readerForGeneralValueObject;
readerForGeneralValueObject.Init(*apData);
value = DecodeGeneralTLVValue(env, readerForGeneralValueObject, err);
err = CHIP_NO_ERROR;
}
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to decode event with error %s", ErrorStr(err));
aEventHeader.LogPath());
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
#else
value = DecodeGeneralTLVValue(env, apData);
value = DecodeGeneralTLVValue(env, readerForJavaObject, err);
#endif

// Create TLV byte array to pass to Java layer
Expand Down Expand Up @@ -915,73 +918,101 @@ void InvokeCallback::ReportError(const char * message, ChipError::StorageType er
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
}

jobject DecodeGeneralTLVValue(JNIEnv * env, TLV::TLVReader * apData)
jobject DecodeGeneralTLVValue(JNIEnv * env, TLV::TLVReader & readerForGeneralValueObject, CHIP_ERROR &err)
{
CHIP_ERROR err = CHIP_NO_ERROR;
jobject retValue = nullptr;

TLV::TLVReader readerForJavaObject;
readerForJavaObject.Init(*apData);

switch (readerForJavaObject.GetType())
switch (readerForGeneralValueObject.GetType())
{
case TLV::kTLVType_SignedInteger: {
int64_t signedValue;
VerifyOrReturnValue(readerForJavaObject.Get(signedValue) == CHIP_NO_ERROR, nullptr,
int64_t signedValue = 0;
VerifyOrReturnValue(readerForGeneralValueObject.Get(signedValue) == CHIP_NO_ERROR, nullptr,
ChipLogProgress(Controller, "Get TLV Value fail!"));
err = JniReferences::GetInstance().CreateBoxedObject<jlong>("java/lang/Long", "(J)V", static_cast<jlong>(signedValue),
retValue);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Create Boxed Object fail!"));
return retValue;
}
case TLV::kTLVType_UnsignedInteger: {
uint64_t unsignedValue;
VerifyOrReturnValue(readerForJavaObject.Get(unsignedValue) == CHIP_NO_ERROR, nullptr,
uint64_t unsignedValue = 0;
VerifyOrReturnValue(readerForGeneralValueObject.Get(unsignedValue) == CHIP_NO_ERROR, nullptr,
ChipLogProgress(Controller, "Get TLV Value fail!"));
err = JniReferences::GetInstance().CreateBoxedObject<jlong>("java/lang/Long", "(J)V", static_cast<jlong>(unsignedValue),
retValue);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Create Boxed Object fail!"));
return retValue;
}
case TLV::kTLVType_Boolean: {
bool booleanValue;
VerifyOrReturnValue(readerForJavaObject.Get(booleanValue) == CHIP_NO_ERROR, nullptr,
bool booleanValue = false;
VerifyOrReturnValue(readerForGeneralValueObject.Get(booleanValue) == CHIP_NO_ERROR, nullptr,
ChipLogProgress(Controller, "Get TLV Value fail!"));
err = JniReferences::GetInstance().CreateBoxedObject<jboolean>("java/lang/Boolean", "(Z)V",
static_cast<jboolean>(booleanValue), retValue);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Create Boxed Object fail!"));
return retValue;
}
case TLV::kTLVType_FloatingPointNumber: {
double doubleValue;
VerifyOrReturnValue(readerForJavaObject.Get(doubleValue) == CHIP_NO_ERROR, nullptr,
double doubleValue = 0.0;
VerifyOrReturnValue(readerForGeneralValueObject.Get(doubleValue) == CHIP_NO_ERROR, nullptr,
ChipLogProgress(Controller, "Get TLV Value fail!"));
err = JniReferences::GetInstance().CreateBoxedObject<jdouble>("java/lang/Double", "(D)V", static_cast<jdouble>(doubleValue),
retValue);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Create Boxed Object fail!"));
return retValue;
}
case TLV::kTLVType_UTF8String: {
uint32_t bufferLen = readerForJavaObject.GetLength();
uint32_t bufferLen = readerForGeneralValueObject.GetLength();
std::unique_ptr<char[]> buffer = std::unique_ptr<char[]>(new char[bufferLen + 1]);
err = readerForJavaObject.GetString(buffer.get(), bufferLen + 1);
err = readerForGeneralValueObject.GetString(buffer.get(), bufferLen + 1);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Get TLV Value fail!"));
chip::CharSpan valueSpan(buffer.get(), bufferLen);
chip::JniReferences::GetInstance().CharToStringUTF(valueSpan, retValue);
return retValue;
}
case TLV::kTLVType_ByteString: {
uint32_t bufferLen = readerForJavaObject.GetLength();
uint32_t bufferLen = readerForGeneralValueObject.GetLength();
std::unique_ptr<uint8_t[]> buffer = std::unique_ptr<uint8_t[]>(new uint8_t[bufferLen + 1]);
err = readerForJavaObject.GetBytes(buffer.get(), bufferLen + 1);
err = readerForGeneralValueObject.GetBytes(buffer.get(), bufferLen + 1);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Get TLV Value fail!"));

jbyteArray valueByteArray = env->NewByteArray(static_cast<jsize>(bufferLen));
env->SetByteArrayRegion(valueByteArray, 0, static_cast<jsize>(bufferLen), reinterpret_cast<const jbyte *>(buffer.get()));

return static_cast<jobject>(valueByteArray);
}
case TLV::kTLVType_Array: {
TLV::TLVType containerType;
err = readerForGeneralValueObject.EnterContainer(containerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "EnterContainer fail! : %" CHIP_ERROR_FORMAT, err.Format()));
err = chip::JniReferences::GetInstance().CreateArrayList(retValue);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "CreateArrayList fail! : %" CHIP_ERROR_FORMAT, err.Format()));
while(readerForGeneralValueObject.Next() == CHIP_NO_ERROR)
{
jobject inValue = DecodeGeneralTLVValue(env, readerForGeneralValueObject, err);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Can't parse general value : %" CHIP_ERROR_FORMAT, err.Format()));
err = chip::JniReferences::GetInstance().AddToList(retValue, inValue);
}
return retValue;
}
case TLV::kTLVType_List: {
TLV::TLVType containerType;
err = readerForGeneralValueObject.EnterContainer(containerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "EnterContainer fail! : %" CHIP_ERROR_FORMAT, err.Format()));
err = chip::JniReferences::GetInstance().CreateArrayList(retValue);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "CreateArrayList fail! : %" CHIP_ERROR_FORMAT, err.Format()));
while(readerForGeneralValueObject.Next() == CHIP_NO_ERROR)
{
jobject inValue = DecodeGeneralTLVValue(env, readerForGeneralValueObject, err);
VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, ChipLogProgress(Controller, "Can't parse general value : %" CHIP_ERROR_FORMAT, err.Format()));
err = chip::JniReferences::GetInstance().AddToList(retValue, inValue);
}
return retValue;
}
case TLV::kTLVType_Null: {
return nullptr;
}
default:
err = CHIP_ERROR_WRONG_TLV_TYPE;
return nullptr;
}
}
Expand Down

0 comments on commit bdfb2aa

Please sign in to comment.