diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt index 80587a37fdf992..3e45d62323cfec 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt @@ -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 @@ -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(), @@ -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()) } @@ -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 } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt index 1c0957db981232..07c0321a99b5d6 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt @@ -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 @@ -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(), @@ -103,6 +114,7 @@ class PairOnNetworkLongImSubscribeCommand( devicePointer, attributePathList, Collections.emptyList(), + dataVersionFilterList, 0, 5, false, @@ -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 } } diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja index 00d09a51cbed85..45621c7e86469a 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja @@ -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( @@ -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( diff --git a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java index 62d0167f1d567c..94d8415d01ccee 100644 --- a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java +++ b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java @@ -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( @@ -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( diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 373d2051d3457f..d2a904ebbb5ccc 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -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); } diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index 93344a5e1bc7eb..fd6b043beacb34 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -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; } } diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 7fb098d4a1a88f..4d09f611bc4267 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -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", diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 7633b0a304d793..93a4e239a9b9ae 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -93,6 +94,10 @@ CHIP_ERROR ParseAttributePath(jobject attributePath, EndpointId & outEndpointId, static CHIP_ERROR ParseEventPathList(jobject eventPathList, std::vector & 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 & outDataVersionFilterList); static CHIP_ERROR IsWildcardChipPathId(jobject chipPathId, bool & isWildcard); namespace { @@ -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(callbackHandle); DeviceProxy * device = reinterpret_cast(devicePtr); if (device == nullptr) @@ -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 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(JniReferences::GetInstance().LongToPrimitive(eventMin))); @@ -2202,7 +2233,7 @@ 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; @@ -2210,6 +2241,7 @@ JNI_METHOD(void, read) auto callback = reinterpret_cast(callbackHandle); std::vector attributePathParamsList; std::vector eventPathParamsList; + std::vector versionList; app::ReadClient * readClient = nullptr; DeviceProxy * device = reinterpret_cast(devicePtr); if (device == nullptr) @@ -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; @@ -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 & 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); + 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); + + outDataVersion = static_cast(env->CallLongMethod(versionFilter, getDataVersionMethod)); + return CHIP_NO_ERROR; +} + CHIP_ERROR GetChipPathIdValue(jobject chipPathId, uint32_t wildcardValue, uint32_t & outValue) { JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index fc241abddf6087..19615feca714a5 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -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( @@ -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( diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 1173c6de35b43c..846ed32a84c6b1 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -23,6 +23,7 @@ import chip.devicecontroller.model.AttributeWriteRequest; import chip.devicecontroller.model.ChipAttributePath; import chip.devicecontroller.model.ChipEventPath; +import chip.devicecontroller.model.DataVersionFilter; import chip.devicecontroller.model.InvokeElement; import java.util.ArrayList; import java.util.Calendar; @@ -671,6 +672,7 @@ public void subscribeToAttributePath( devicePtr, attributePaths, null, + null, minInterval, maxInterval, false, @@ -708,6 +710,7 @@ public void subscribeToEventPath( devicePtr, null, eventPaths, + null, minInterval, maxInterval, false, @@ -733,6 +736,7 @@ public void subscribeToEventPath( devicePtr, null, eventPaths, + null, minInterval, maxInterval, false, @@ -744,6 +748,40 @@ public void subscribeToEventPath( /** * @brief Auto-Resubscribe to the given attribute/event path with keepSubscriptions and * isFabricFiltered + */ + public void subscribeToPath( + SubscriptionEstablishedCallback subscriptionEstablishedCallback, + ResubscriptionAttemptCallback resubscriptionAttemptCallback, + ReportCallback reportCallback, + long devicePtr, + List attributePaths, + List eventPaths, + int minInterval, + int maxInterval, + boolean keepSubscriptions, + boolean isFabricFiltered, + int imTimeoutMs) { + ReportCallbackJni jniCallback = + new ReportCallbackJni( + subscriptionEstablishedCallback, reportCallback, resubscriptionAttemptCallback); + subscribe( + deviceControllerPtr, + jniCallback.getCallbackHandle(), + devicePtr, + attributePaths, + eventPaths, + null, + minInterval, + maxInterval, + keepSubscriptions, + isFabricFiltered, + imTimeoutMs, + null); + } + + /** + * @brief Auto-Resubscribe to the given attribute/event/dataVersionFilter path with + * keepSubscriptions and isFabricFiltered * @param SubscriptionEstablishedCallback Callback when a subscribe response has been received and * processed * @param ResubscriptionAttemptCallback Callback when a resubscirption haoppens, the termination @@ -753,6 +791,7 @@ public void subscribeToEventPath( * @param devicePtr connected device pointer * @param attributePaths a list of attribute paths * @param eventPaths a list of event paths + * @param dataVersionFilters a list of data version filter * @param minInterval the requested minimum interval boundary floor in seconds * @param maxInterval the requested maximum interval boundary ceiling in seconds * @param keepSubscriptions If KeepSubscriptions is FALSE, all existing or pending subscriptions @@ -768,6 +807,7 @@ public void subscribeToPath( long devicePtr, List attributePaths, List eventPaths, + List dataVersionFilters, int minInterval, int maxInterval, boolean keepSubscriptions, @@ -782,6 +822,7 @@ public void subscribeToPath( devicePtr, attributePaths, eventPaths, + dataVersionFilters, minInterval, maxInterval, keepSubscriptions, @@ -812,6 +853,7 @@ public void subscribeToPath( devicePtr, attributePaths, eventPaths, + null, minInterval, maxInterval, keepSubscriptions, @@ -841,6 +883,7 @@ public void readAttributePath( devicePtr, attributePaths, null, + null, true, imTimeoutMs, null); @@ -864,6 +907,7 @@ public void readEventPath( devicePtr, null, eventPaths, + null, true, imTimeoutMs, null); @@ -883,18 +927,41 @@ public void readEventPath( devicePtr, null, eventPaths, + null, true, imTimeoutMs, eventMin); } + /** Read the given attribute/event path with isFabricFiltered flag. */ + public void readPath( + ReportCallback callback, + long devicePtr, + List attributePaths, + List eventPaths, + boolean isFabricFiltered, + int imTimeoutMs) { + ReportCallbackJni jniCallback = new ReportCallbackJni(null, callback, null); + read( + deviceControllerPtr, + jniCallback.getCallbackHandle(), + devicePtr, + attributePaths, + eventPaths, + null, + isFabricFiltered, + imTimeoutMs, + null); + } + /** - * @brief read the given attribute/event path with isFabricFiltered + * @brief read the given attribute/event/dataVersionFilter path * @param ReportCallback Callback when a report data has been received and processed for the given * paths. * @param devicePtr connected device pointer * @param attributePaths a list of attribute paths * @param eventPaths a list of event paths + * @param dataVersionFilters a list of data version filter * @param imTimeoutMs im interaction time out value, it would override the default value in c++ im * layer if this value is non-zero. */ @@ -903,6 +970,7 @@ public void readPath( long devicePtr, List attributePaths, List eventPaths, + List dataVersionFilters, boolean isFabricFiltered, int imTimeoutMs) { ReportCallbackJni jniCallback = new ReportCallbackJni(null, callback, null); @@ -912,6 +980,7 @@ public void readPath( devicePtr, attributePaths, eventPaths, + dataVersionFilters, isFabricFiltered, imTimeoutMs, null); @@ -933,6 +1002,7 @@ public void readPath( devicePtr, attributePaths, eventPaths, + null, isFabricFiltered, imTimeoutMs, eventMin); @@ -1125,6 +1195,7 @@ static native void subscribe( long devicePtr, List attributePaths, List eventPaths, + List dataVersionFilters, int minInterval, int maxInterval, boolean keepSubscriptions, @@ -1138,6 +1209,7 @@ static native void read( long devicePtr, List attributePaths, List eventPaths, + List dataVersionFilters, boolean isFabricFiltered, int imTimeoutMs, @Nullable Long eventMin); diff --git a/src/controller/java/src/chip/devicecontroller/model/DataVersionFilter.java b/src/controller/java/src/chip/devicecontroller/model/DataVersionFilter.java new file mode 100644 index 00000000000000..9eb9aa7b8e407a --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/model/DataVersionFilter.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller.model; + +import java.util.Locale; +import java.util.Objects; +import java.util.logging.Logger; + +/** A data version filter that should be used for interaction model write interaction. */ +public final class DataVersionFilter { + private static final Logger logger = Logger.getLogger(DataVersionFilter.class.getName()); + private final ChipPathId endpointId; + private final ChipPathId clusterId; + private final long dataVersion; + + private DataVersionFilter(ChipPathId endpointId, ChipPathId clusterId, long dataVersion) { + this.endpointId = endpointId; + this.clusterId = clusterId; + this.dataVersion = dataVersion; + } + + public ChipPathId getEndpointId() { + return endpointId; + } + + public ChipPathId getClusterId() { + return clusterId; + } + + public long getDataVersion() { + return dataVersion; + } + + // check whether the current DataVersionFilter has same path as others. + @Override + public boolean equals(Object object) { + if (object instanceof DataVersionFilter) { + DataVersionFilter that = (DataVersionFilter) object; + return Objects.equals(this.endpointId, that.endpointId) + && Objects.equals(this.clusterId, that.clusterId); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(endpointId, clusterId); + } + + @Override + public String toString() { + return String.format(Locale.ENGLISH, "Endpoint %s, cluster %s", endpointId, clusterId); + } + + public static DataVersionFilter newInstance( + ChipPathId endpointId, ChipPathId clusterId, long dataVersion) { + return new DataVersionFilter(endpointId, clusterId, dataVersion); + } +}