Skip to content

Commit

Permalink
add data version filter support in android controller
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhanw-google committed Nov 12, 2023
1 parent 261b03f commit e1aba4b
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public class ChipClusters {
boolean isFabricFiltered) {
ReportCallbackJni jniCallback = new ReportCallbackJni(null, callback, null);
ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId);
ChipDeviceController.read(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, isFabricFiltered, timeoutMillis.orElse(0L).intValue(), null);
ChipDeviceController.read(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, isFabricFiltered, timeoutMillis.orElse(0L).intValue(), null);
}

protected void writeAttribute(
Expand All @@ -218,7 +218,7 @@ public class ChipClusters {
int maxInterval) {
ReportCallbackJni jniCallback = new ReportCallbackJni(callback, callback, null);
ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId);
ChipDeviceController.subscribe(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, minInterval, maxInterval, false, true, timeoutMillis.orElse(0L).intValue(), null);
ChipDeviceController.subscribe(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, minInterval, maxInterval, false, true, timeoutMillis.orElse(0L).intValue(), null);
}

protected void invoke(
Expand Down
2 changes: 1 addition & 1 deletion src/app/ReadClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ CHIP_ERROR ReadClient::ProcessAttributeReportIBs(TLV::TLVReader & aAttributeRepo
ReturnErrorOnFailure(data.GetDataVersion(&version));
attributePath.mDataVersion.SetValue(version);

if (mReadPrepareParams.mpDataVersionFilterList != nullptr)
if (mReadPrepareParams.mpDataVersionFilterList != nullptr && mReadPrepareParams.mDataVersionFilterListSize != 0)
{
UpdateDataVersionFilters(attributePath);
}
Expand Down
15 changes: 13 additions & 2 deletions src/controller/java/AndroidCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,25 @@ void ReportCallback::OnReportBegin()

void ReportCallback::OnDeallocatePaths(app::ReadPrepareParams && aReadPrepareParams)
{
if (aReadPrepareParams.mpAttributePathParamsList != nullptr)
if (aReadPrepareParams.mpAttributePathParamsList != nullptr && aReadPrepareParams.mAttributePathParamsListSize != 0)
{
delete[] aReadPrepareParams.mpAttributePathParamsList;
aReadPrepareParams.mpAttributePathParamsList = nullptr;
aReadPrepareParams.mAttributePathParamsListSize = 0;
}

if (aReadPrepareParams.mpEventPathParamsList != nullptr)
if (aReadPrepareParams.mpEventPathParamsList != nullptr && aReadPrepareParams.mEventPathParamsListSize != 0)
{
delete[] aReadPrepareParams.mpEventPathParamsList;
aReadPrepareParams.mpEventPathParamsList = nullptr;
aReadPrepareParams.mEventPathParamsListSize = 0;
}

if (aReadPrepareParams.mpDataVersionFilterList != nullptr && aReadPrepareParams.mDataVersionFilterListSize != 0)
{
delete[] aReadPrepareParams.mpDataVersionFilterList;
aReadPrepareParams.mpDataVersionFilterList = nullptr;
aReadPrepareParams.mDataVersionFilterListSize = 0;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ android_library("java") {
"src/chip/devicecontroller/model/ChipEventPath.java",
"src/chip/devicecontroller/model/ChipPathId.java",
"src/chip/devicecontroller/model/ClusterState.java",
"src/chip/devicecontroller/model/DataVersionFilter.java",
"src/chip/devicecontroller/model/EndpointState.java",
"src/chip/devicecontroller/model/EventState.java",
"src/chip/devicecontroller/model/InvokeElement.java",
Expand Down
102 changes: 100 additions & 2 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <lib/support/JniTypeWrappers.h>

#include <app/AttributePathParams.h>
#include <app/DataVersionFilter.h>
#include <app/InteractionModelEngine.h>
#include <app/ReadClient.h>
#include <app/WriteClient.h>
Expand Down Expand Up @@ -93,6 +94,10 @@ CHIP_ERROR ParseAttributePath(jobject attributePath, EndpointId & outEndpointId,
static CHIP_ERROR ParseEventPathList(jobject eventPathList, std::vector<app::EventPathParams> & outEventPathParamsList);
CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId,
bool & outIsUrgent);
CHIP_ERROR ParseDataVersionFilter(jobject dataVersionFilter, EndpointId & outEndpointId, ClusterId & outClusterId,
DataVersion & outDataVersion);
static CHIP_ERROR ParseDataVersionFilterList(jobject dataVersionFilterList,
std::vector<app::DataVersionFilter> & outDataVersionFilterList);
static CHIP_ERROR IsWildcardChipPathId(jobject chipPathId, bool & isWildcard);

namespace {
Expand Down Expand Up @@ -2093,13 +2098,15 @@ JNI_METHOD(jobject, computePaseVerifier)

JNI_METHOD(void, subscribe)
(JNIEnv * env, jclass clz, jlong handle, jlong callbackHandle, jlong devicePtr, jobject attributePathList, jobject eventPathList,
jint minInterval, jint maxInterval, jboolean keepSubscriptions, jboolean isFabricFiltered, jint imTimeoutMs, jobject eventMin)
jobject dataVersionFilterList, jint minInterval, jint maxInterval, jboolean keepSubscriptions, jboolean isFabricFiltered,
jint imTimeoutMs, jobject eventMin)
{
chip::DeviceLayer::StackLock lock;
CHIP_ERROR err = CHIP_NO_ERROR;
app::ReadClient * readClient = nullptr;
jint numAttributePaths = 0;
jint numEventPaths = 0;
jint numDataVersionFilters = 0;
auto callback = reinterpret_cast<ReportCallback *>(callbackHandle);
DeviceProxy * device = reinterpret_cast<DeviceProxy *>(devicePtr);
if (device == nullptr)
Expand Down Expand Up @@ -2141,6 +2148,30 @@ JNI_METHOD(void, subscribe)
attributePaths.release();
}

if (dataVersionFilterList != nullptr)
{
SuccessOrExit(err = JniReferences::GetInstance().GetListSize(dataVersionFilterList, numDataVersionFilters));
}

if (numDataVersionFilters > 0)
{
std::unique_ptr<chip::app::DataVersionFilter[]> dataVersionFilters(new chip::app::DataVersionFilter[numDataVersionFilters]);
for (uint8_t i = 0; i < numDataVersionFilters; i++)
{
jobject dataVersionFilterItem = nullptr;
SuccessOrExit(err = JniReferences::GetInstance().GetListItem(dataVersionFilterList, i, dataVersionFilterItem));

EndpointId endpointId;
ClusterId clusterId;
DataVersion dataVersion;
SuccessOrExit(err = ParseDataVersionFilter(dataVersionFilterItem, endpointId, clusterId, dataVersion));
dataVersionFilters[i] = chip::app::DataVersionFilter(endpointId, clusterId, dataVersion);
}
params.mpDataVersionFilterList = dataVersionFilters.get();
params.mDataVersionFilterListSize = numDataVersionFilters;
dataVersionFilters.release();
}

if (eventMin != nullptr)
{
params.mEventNumber.SetValue(static_cast<chip::EventNumber>(JniReferences::GetInstance().LongToPrimitive(eventMin)));
Expand Down Expand Up @@ -2202,14 +2233,15 @@ JNI_METHOD(void, subscribe)

JNI_METHOD(void, read)
(JNIEnv * env, jclass clz, jlong handle, jlong callbackHandle, jlong devicePtr, jobject attributePathList, jobject eventPathList,
jboolean isFabricFiltered, jint imTimeoutMs, jobject eventMin)
jobject dataVersionFilterList, jboolean isFabricFiltered, jint imTimeoutMs, jobject eventMin)
{
chip::DeviceLayer::StackLock lock;
CHIP_ERROR err = CHIP_NO_ERROR;

auto callback = reinterpret_cast<ReportCallback *>(callbackHandle);
std::vector<app::AttributePathParams> attributePathParamsList;
std::vector<app::EventPathParams> eventPathParamsList;
std::vector<app::DataVersionFilter> versionList;
app::ReadClient * readClient = nullptr;
DeviceProxy * device = reinterpret_cast<DeviceProxy *>(devicePtr);
if (device == nullptr)
Expand All @@ -2222,11 +2254,17 @@ JNI_METHOD(void, read)

SuccessOrExit(err = ParseAttributePathList(attributePathList, attributePathParamsList));
SuccessOrExit(err = ParseEventPathList(eventPathList, eventPathParamsList));
SuccessOrExit(err = ParseDataVersionFilterList(dataVersionFilterList, versionList));
VerifyOrExit(attributePathParamsList.size() != 0 || eventPathParamsList.size() != 0, err = CHIP_ERROR_INVALID_ARGUMENT);
params.mpAttributePathParamsList = attributePathParamsList.data();
params.mAttributePathParamsListSize = attributePathParamsList.size();
params.mpEventPathParamsList = eventPathParamsList.data();
params.mEventPathParamsListSize = eventPathParamsList.size();
if (versionList.size() != 0)
{
params.mpDataVersionFilterList = versionList.data();
params.mDataVersionFilterListSize = versionList.size();
}

params.mIsFabricFiltered = (isFabricFiltered != JNI_FALSE);
params.mTimeout = imTimeoutMs != 0 ? System::Clock::Milliseconds32(imTimeoutMs) : System::Clock::kZero;
Expand Down Expand Up @@ -2745,6 +2783,66 @@ CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, Cluster
return CHIP_NO_ERROR;
}

/**
* Takes objects in dataVersionFilterList, converts them to app:DataVersionFilter, and appends them to outDataVersionFilterList.
*/
CHIP_ERROR ParseDataVersionFilterList(jobject dataVersionFilterList, std::vector<app::DataVersionFilter> & outDataVersionFilterList)
{
jint listSize;

if (dataVersionFilterList == nullptr)
{
return CHIP_NO_ERROR;
}

ReturnErrorOnFailure(JniReferences::GetInstance().GetListSize(dataVersionFilterList, listSize));

for (uint8_t i = 0; i < listSize; i++)
{
jobject dataVersionFilterItem = nullptr;
ReturnErrorOnFailure(JniReferences::GetInstance().GetListItem(dataVersionFilterList, i, dataVersionFilterItem));

EndpointId endpointId;
ClusterId clusterId;
DataVersion dataVersion;
ReturnErrorOnFailure(ParseDataVersionFilter(dataVersionFilterItem, endpointId, clusterId, dataVersion));
outDataVersionFilterList.push_back(app::DataVersionFilter(endpointId, clusterId, dataVersion));
}

return CHIP_NO_ERROR;
}

CHIP_ERROR ParseDataVersionFilter(jobject versionFilter, EndpointId & outEndpointId, ClusterId & outClusterId,
DataVersion & outDataVersion)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

jmethodID getEndpointIdMethod = nullptr;
jmethodID getClusterIdMethod = nullptr;
jmethodID getDataVersionMethod = nullptr;

ReturnErrorOnFailure(JniReferences::GetInstance().FindMethod(
env, versionFilter, "getEndpointId", "()Lchip/devicecontroller/model/ChipPathId;", &getEndpointIdMethod));
ReturnErrorOnFailure(JniReferences::GetInstance().FindMethod(
env, versionFilter, "getClusterId", "()Lchip/devicecontroller/model/ChipPathId;", &getClusterIdMethod));
ReturnErrorOnFailure(
JniReferences::GetInstance().FindMethod(env, versionFilter, "getDataVersion", "()J;", &getDataVersionMethod));

jobject endpointIdObj = env->CallObjectMethod(versionFilter, getEndpointIdMethod);
VerifyOrReturnError(endpointIdObj != nullptr, CHIP_ERROR_INCORRECT_STATE);
uint32_t endpointId = 0;
ReturnErrorOnFailure(GetChipPathIdValue(endpointIdObj, kInvalidEndpointId, endpointId));
outEndpointId = static_cast<EndpointId>(endpointId);
jobject clusterIdObj = env->CallObjectMethod(versionFilter, getClusterIdMethod);
VerifyOrReturnError(clusterIdObj != nullptr, CHIP_ERROR_INCORRECT_STATE);
uint32_t clusterId = 0;
ReturnErrorOnFailure(GetChipPathIdValue(clusterIdObj, kInvalidClusterId, clusterId));
outClusterId = static_cast<ClusterId>(clusterId);

outDataVersion = static_cast<DataVersion>(env->CallLongMethod(versionFilter, getDataVersionMethod));
return CHIP_NO_ERROR;
}

CHIP_ERROR GetChipPathIdValue(jobject chipPathId, uint32_t wildcardValue, uint32_t & outValue)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ protected void readAttribute(
boolean isFabricFiltered) {
ReportCallbackJni jniCallback = new ReportCallbackJni(null, callback, null);
ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId);
ChipDeviceController.read(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, isFabricFiltered, timeoutMillis.orElse(0L).intValue(), null);
ChipDeviceController.read(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, isFabricFiltered, timeoutMillis.orElse(0L).intValue(), null);
}

protected void writeAttribute(
Expand All @@ -141,7 +141,7 @@ protected void subscribeAttribute(
int maxInterval) {
ReportCallbackJni jniCallback = new ReportCallbackJni(callback, callback, null);
ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId);
ChipDeviceController.subscribe(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, minInterval, maxInterval, false, true, timeoutMillis.orElse(0L).intValue(), null);
ChipDeviceController.subscribe(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, minInterval, maxInterval, false, true, timeoutMillis.orElse(0L).intValue(), null);
}

protected void invoke(
Expand Down

0 comments on commit e1aba4b

Please sign in to comment.