Skip to content

Commit

Permalink
onReport and onError needs to be mutual exclusive
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhanw-google committed Nov 30, 2023
1 parent 1c7accb commit 0c8c535
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 44 deletions.
7 changes: 7 additions & 0 deletions src/app/ConcreteAttributePath.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ struct ConcreteDataAttributePath : public ConcreteAttributePath
bool IsListOperation() const { return mListOp != ListOperation::NotList; }
bool IsListItemOperation() const { return ((mListOp != ListOperation::NotList) && (mListOp != ListOperation::ReplaceAll)); }

void LogPath() const
{
ChipLogProgress(DataManagement, "Concrete Attribute Path: (%d, " ChipLogFormatMEI ", " ChipLogFormatMEI ") ",
mEndpointId, ChipLogValueMEI(mClusterId),
ChipLogValueMEI(mAttributeId));
}

//
// This index is only valid if `mListOp` is set to a list item operation, i.e
// ReplaceItem, DeleteItem or AppendItem. Otherwise, it is to be ignored.
Expand Down
7 changes: 7 additions & 0 deletions src/app/EventHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ struct EventHeader
EventNumber mEventNumber = 0;
PriorityLevel mPriorityLevel = PriorityLevel::Invalid;
Timestamp mTimestamp;

void LogPath() const
{
ChipLogProgress(DataManagement, "Concrete Event Path: (%d, " ChipLogFormatMEI ", " ChipLogFormatMEI ") ",
mPath.mEndpointId, ChipLogValueMEI(mPath.mClusterId),
ChipLogValueMEI(mPath.mEventId));
}
};
} // namespace app
} // namespace chip
69 changes: 25 additions & 44 deletions src/controller/java/AndroidCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,23 +280,9 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat
err = CreateChipAttributePath(env, aPath, attributePathObj);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create Java ChipAttributePath: %s", ErrorStr(err)));

if (aPath.IsListItemOperation())
{
ReportError(attributePathObj, nullptr, CHIP_ERROR_INCORRECT_STATE);
return;
}

if (aStatus.mStatus != Protocols::InteractionModel::Status::Success)
{
ReportError(attributePathObj, nullptr, aStatus.mStatus);
return;
}

if (apData == nullptr)
{
ReportError(attributePathObj, nullptr, CHIP_ERROR_INVALID_ARGUMENT);
return;
}
VerifyOrReturn(!aPath.IsListItemOperation(), ChipLogError(Controller, "Expect non-list item operation"); aPath.LogPath());
VerifyOrReturn(aStatus.IsSuccess(), ChipLogError(Controller, "Receive bad status %s", ErrorStr(aStatus.ToChipError())); aPath.LogPath());
VerifyOrReturn(apData != nullptr, ChipLogError(Controller, "Receive empty apData"); aPath.LogPath());

TLV::TLVReader readerForJavaTLV;
readerForJavaTLV.Init(*apData);
Expand All @@ -313,9 +299,8 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat
err = CHIP_NO_ERROR;
}

VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(attributePathObj, nullptr, err));
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe(),
ReportError(attributePathObj, nullptr, CHIP_JNI_ERROR_EXCEPTION_THROWN));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to decode attribute with error %s", ErrorStr(err)); aPath.LogPath()));
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
#endif
// Create TLV byte array to pass to Java layer
size_t bufferLen = readerForJavaTLV.GetRemainingLength() + readerForJavaTLV.GetLengthRead();
Expand All @@ -328,33 +313,33 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat
TLV::TLVWriter writer;
writer.Init(buffer.get(), bufferLen);
err = writer.CopyElement(TLV::AnonymousTag(), readerForJavaTLV);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(attributePathObj, nullptr, err));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to copy tlv element with error %s", ErrorStr(err)); aPath.LogPath());
size = writer.GetLengthWritten();
chip::ByteArray jniByteArray(env, reinterpret_cast<jbyte *>(buffer.get()), size);

// Convert TLV to JSON
std::string json;
err = ConvertReportTlvToJson(static_cast<uint32_t>(aPath.mAttributeId), *apData, json);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(attributePathObj, nullptr, err));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to convert report tlv to json with error %s", ErrorStr(err)); aPath.LogPath());
UtfString jsonString(env, json.c_str());

// Create AttributeState object
jclass attributeStateCls;
err = JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/model/AttributeState", attributeStateCls);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find AttributeState class"));
VerifyOrReturn(attributeStateCls != nullptr, ChipLogError(Controller, "Could not find AttributeState class"));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find AttributeState class with error %s", ErrorStr(err)); aPath.LogPath());
VerifyOrReturn(attributeStateCls != nullptr, ChipLogError(Controller, "Could not find AttributeState class"); aPath.LogPath());
jmethodID attributeStateCtor = env->GetMethodID(attributeStateCls, "<init>", "(Ljava/lang/Object;[BLjava/lang/String;)V");
VerifyOrReturn(attributeStateCtor != nullptr, ChipLogError(Controller, "Could not find AttributeState constructor"));
VerifyOrReturn(attributeStateCtor != nullptr, ChipLogError(Controller, "Could not find AttributeState constructor"); aPath.LogPath());
jobject attributeStateObj =
env->NewObject(attributeStateCls, attributeStateCtor, value, jniByteArray.jniValue(), jsonString.jniValue());
VerifyOrReturn(attributeStateObj != nullptr, ChipLogError(Controller, "Could not create AttributeState object"));
VerifyOrReturn(attributeStateObj != nullptr, ChipLogError(Controller, "Could not create AttributeState object"); aPath.LogPath());

jobject nodeState = mNodeStateObj.ObjectRef();
// Add AttributeState to NodeState
jmethodID addAttributeMethod;
err = JniReferences::GetInstance().FindMethod(env, nodeState, "addAttribute",
"(IJJLchip/devicecontroller/model/AttributeState;)V", &addAttributeMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find addAttribute method"));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find addAttribute method with error %s", ErrorStr(err)));
env->CallVoidMethod(nodeState, addAttributeMethod, static_cast<jint>(aPath.mEndpointId), static_cast<jlong>(aPath.mClusterId),
static_cast<jlong>(aPath.mAttributeId), attributeStateObj);
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
Expand Down Expand Up @@ -408,11 +393,7 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV
err = CreateChipEventPath(env, aEventHeader.mPath, eventPathObj);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create Java ChipEventPath: %s", ErrorStr(err)));

if (apData == nullptr)
{
ReportError(nullptr, eventPathObj, CHIP_ERROR_INVALID_ARGUMENT);
return;
}
VerifyOrReturn(apData != nullptr, ChipLogError(Controller, "Receive empty apData"); aEventHeader.LogPath());

TLV::TLVReader readerForJavaTLV;
readerForJavaTLV.Init(*apData);
Expand All @@ -433,7 +414,7 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV
else
{
ChipLogError(Controller, "Unsupported event timestamp type");
ReportError(nullptr, eventPathObj, CHIP_ERROR_INVALID_ARGUMENT);
aEventHeader.LogPath();
return;
}

Expand All @@ -447,9 +428,8 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV
{
err = CHIP_NO_ERROR;
}
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(nullptr, eventPathObj, err));
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe(),
ReportError(nullptr, eventPathObj, CHIP_JNI_ERROR_EXCEPTION_THROWN));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to decode event with error %s", ErrorStr(err); aEventHeader.LogPath()));
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
#endif

// Create TLV byte array to pass to Java layer
Expand All @@ -462,37 +442,38 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV
TLV::TLVWriter writer;
writer.Init(buffer.get(), bufferLen);
err = writer.CopyElement(TLV::AnonymousTag(), readerForJavaTLV);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(nullptr, eventPathObj, err));

VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to copy element with error %s", ErrorStr(err)); aEventHeader.LogPath());
size = writer.GetLengthWritten();
chip::ByteArray jniByteArray(env, reinterpret_cast<jbyte *>(buffer.get()), size);

// Convert TLV to JSON
std::string json;
err = ConvertReportTlvToJson(static_cast<uint32_t>(aEventHeader.mPath.mEventId), *apData, json);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(eventPathObj, nullptr, err));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Fail to convert report tlv to Json with error %s", ErrorStr(err); aEventHeader.LogPath());
UtfString jsonString(env, json.c_str());

// Create EventState object
jclass eventStateCls;
err = JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/model/EventState", eventStateCls);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Failed to find EventState class"));
VerifyOrReturn(eventStateCls != nullptr, ChipLogError(Controller, "Could not find EventState class"));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Failed to find EventState class"); aEventHeader.LogPath());
VerifyOrReturn(eventStateCls != nullptr, ChipLogError(Controller, "Could not find EventState class"); aEventHeader.LogPath());
jmethodID eventStateCtor = env->GetMethodID(eventStateCls, "<init>", "(JIIJLjava/lang/Object;[BLjava/lang/String;)V");
VerifyOrReturn(eventStateCtor != nullptr, ChipLogError(Controller, "Could not find EventState constructor"));
VerifyOrReturn(eventStateCtor != nullptr, ChipLogError(Controller, "Could not find EventState constructor"); aEventHeader.LogPath());
jobject eventStateObj = env->NewObject(eventStateCls, eventStateCtor, eventNumber, priorityLevel, timestampType, timestampValue,
value, jniByteArray.jniValue(), jsonString.jniValue());
VerifyOrReturn(eventStateObj != nullptr, ChipLogError(Controller, "Could not create EventState object"));
VerifyOrReturn(eventStateObj != nullptr, ChipLogError(Controller, "Could not create EventState object"); aEventHeader.LogPath());

// Add EventState to NodeState
jmethodID addEventMethod;
jobject nodeState = mNodeStateObj.ObjectRef();
err = JniReferences::GetInstance().FindMethod(env, nodeState, "addEvent", "(IJJLchip/devicecontroller/model/EventState;)V",
&addEventMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find addEvent method"));
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find addEvent method with error %s", ErrorStr(err)); aEventHeader.LogPath());
env->CallVoidMethod(nodeState, addEventMethod, static_cast<jint>(aEventHeader.mPath.mEndpointId),
static_cast<jlong>(aEventHeader.mPath.mClusterId), static_cast<jlong>(aEventHeader.mPath.mEventId),
eventStateObj);
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe(); aEventHeader.LogPath());
}

CHIP_ERROR InvokeCallback::CreateInvokeElement(JNIEnv * env, const app::ConcreteCommandPath & aPath, TLV::TLVReader * apData,
Expand Down

0 comments on commit 0c8c535

Please sign in to comment.