Skip to content

Commit

Permalink
add data version filter support in android controller (#30427)
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhanw-google authored and pull[bot] committed Jan 18, 2024
1 parent 1d07570 commit 1164415
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import chip.devicecontroller.model.AttributeState
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.ChipPathId
import chip.devicecontroller.model.DataVersionFilter
import chip.devicecontroller.model.EventState
import chip.devicecontroller.model.NodeState
import com.matter.controller.commands.common.CredentialsIssuer
Expand Down Expand Up @@ -169,6 +170,15 @@ class PairOnNetworkLongImReadCommand(
)
)

val dataVersionFilterList =
listOf(
DataVersionFilter.newInstance(
ChipPathId.forId(/* endpointId= */ 0),
ChipPathId.forId(CLUSTER_ID_BASIC),
CLUSTER_ID_BASIC_VERSION,
)
)

currentCommissioner()
.pairDeviceWithAddress(
getNodeId(),
Expand All @@ -184,7 +194,15 @@ class PairOnNetworkLongImReadCommand(
.getConnectedDevicePointer(getNodeId(), InternalGetConnectedDeviceCallback())
clear()
currentCommissioner()
.readPath(InternalReportCallback(), devicePointer, attributePathList, eventPathList, false, 0)
.readPath(
InternalReportCallback(),
devicePointer,
attributePathList,
eventPathList,
dataVersionFilterList,
false,
0
)
waitCompleteMs(getTimeoutMillis())
}

Expand All @@ -198,5 +216,6 @@ class PairOnNetworkLongImReadCommand(
private const val ATTR_ID_LOCAL_CONFIG_DISABLED = 16L
private const val EVENT_ID_START_UP = 0L
private const val GLOBAL_ATTRIBUTE_LIST = 65531L
private const val CLUSTER_ID_BASIC_VERSION = 0L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import chip.devicecontroller.ResubscriptionAttemptCallback
import chip.devicecontroller.SubscriptionEstablishedCallback
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.ChipPathId
import chip.devicecontroller.model.DataVersionFilter
import chip.devicecontroller.model.NodeState
import com.matter.controller.commands.common.CredentialsIssuer
import java.util.Collections
Expand Down Expand Up @@ -81,6 +83,15 @@ class PairOnNetworkLongImSubscribeCommand(
)
)

val dataVersionFilterList =
listOf(
DataVersionFilter.newInstance(
ChipPathId.forId(/* endpointId= */ 0),
ChipPathId.forId(CLUSTER_ID_BASIC),
CLUSTER_ID_BASIC_VERSION,
)
)

currentCommissioner()
.pairDeviceWithAddress(
getNodeId(),
Expand All @@ -103,6 +114,7 @@ class PairOnNetworkLongImSubscribeCommand(
devicePointer,
attributePathList,
Collections.emptyList(),
dataVersionFilterList,
0,
5,
false,
Expand All @@ -120,5 +132,6 @@ class PairOnNetworkLongImSubscribeCommand(
private const val MATTER_PORT = 5540
private const val CLUSTER_ID_BASIC = 0x0028L
private const val ATTR_ID_LOCAL_CONFIG_DISABLED = 16L
private const val CLUSTER_ID_BASIC_VERSION = 0L
}
}
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
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
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
Loading

0 comments on commit 1164415

Please sign in to comment.