@@ -2277,17 +2277,16 @@ - (void)_removeCachedAttribute:(NSNumber *)attributeID fromCluster:(MTRClusterPa
2277
2277
[clusterData removeValueForAttribute:attributeID];
2278
2278
}
2279
2279
2280
- - (void)_createDataVersionFilterListFromDictionary:(NSDictionary<MTRClusterPath *, NSNumber *> *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count sizeReduction:(size_t)sizeReduction
2280
+ - (void)_createDataVersionFilterListFromDictionary:(NSDictionary<MTRClusterPath *, NSNumber *> *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count
2281
2281
{
2282
2282
size_t maxDataVersionFilterSize = dataVersions.count;
2283
2283
2284
2284
// Check if any filter list should be generated
2285
- if (!dataVersions.count || (maxDataVersionFilterSize <= sizeReduction) ) {
2285
+ if (!dataVersions.count) {
2286
2286
*count = 0;
2287
2287
*dataVersionFilterList = nullptr;
2288
2288
return;
2289
2289
}
2290
- maxDataVersionFilterSize -= sizeReduction;
2291
2290
2292
2291
DataVersionFilter * dataVersionFilterArray = new DataVersionFilter[maxDataVersionFilterSize];
2293
2292
size_t i = 0;
@@ -2296,13 +2295,13 @@ - (void)_createDataVersionFilterListFromDictionary:(NSDictionary<MTRClusterPath
2296
2295
if (dataVersionNumber) {
2297
2296
dataVersionFilterArray[i++] = DataVersionFilter(static_cast<chip::EndpointId>(path.endpoint.unsignedShortValue), static_cast<chip::ClusterId>(path.cluster.unsignedLongValue), static_cast<chip::DataVersion>(dataVersionNumber.unsignedLongValue));
2298
2297
}
2299
- if (i == maxDataVersionFilterSize) {
2300
- break;
2301
- }
2302
2298
}
2303
2299
2304
2300
*dataVersionFilterList = dataVersionFilterArray;
2305
- *count = maxDataVersionFilterSize;
2301
+ // Note that we might have i < maxDataVersionFilterSize here if some of the
2302
+ // dictionary entries had a null dataVersionNumber. The correct size of the
2303
+ // valid entried in our array is "i".
2304
+ *count = i;
2306
2305
}
2307
2306
2308
2307
- (void)_setupConnectivityMonitoring
@@ -2530,75 +2529,55 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason
2530
2529
auto readClient = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance(), exchangeManager,
2531
2530
clusterStateCache->GetBufferedCallback(), ReadClient::InteractionType::Subscribe);
2532
2531
2533
- // Subscribe with data version filter list and retry with smaller list if out of packet space
2534
- CHIP_ERROR err;
2535
- NSDictionary<MTRClusterPath *, NSNumber *> * dataVersions = [self _getCachedDataVersions];
2536
- size_t dataVersionFilterListSizeReduction = 0;
2537
- for (;;) {
2538
- // Wildcard endpoint, cluster, attribute, event.
2539
- auto attributePath = std::make_unique<AttributePathParams>();
2540
- auto eventPath = std::make_unique<EventPathParams>();
2541
- // We want to get event reports at the minInterval, not the maxInterval.
2542
- eventPath->mIsUrgentEvent = true;
2543
- ReadPrepareParams readParams(session.Value());
2544
-
2545
- readParams.mMinIntervalFloorSeconds = 0;
2546
- // Select a max interval based on the device's claimed idle sleep interval.
2547
- auto idleSleepInterval = std::chrono::duration_cast<System::Clock::Seconds32>(
2548
- session.Value()->GetRemoteMRPConfig().mIdleRetransTimeout);
2549
-
2550
- auto maxIntervalCeilingMin = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN);
2551
- if (idleSleepInterval < maxIntervalCeilingMin) {
2552
- idleSleepInterval = maxIntervalCeilingMin;
2553
- }
2554
-
2555
- auto maxIntervalCeilingMax = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX);
2556
- if (idleSleepInterval > maxIntervalCeilingMax) {
2557
- idleSleepInterval = maxIntervalCeilingMax;
2558
- }
2532
+ // Wildcard endpoint, cluster, attribute, event.
2533
+ auto attributePath = std::make_unique<AttributePathParams>();
2534
+ auto eventPath = std::make_unique<EventPathParams>();
2535
+ // We want to get event reports at the minInterval, not the maxInterval.
2536
+ eventPath->mIsUrgentEvent = true;
2537
+ ReadPrepareParams readParams(session.Value());
2538
+
2539
+ readParams.mMinIntervalFloorSeconds = 0;
2540
+ // Select a max interval based on the device's claimed idle sleep interval.
2541
+ auto idleSleepInterval = std::chrono::duration_cast<System::Clock::Seconds32>(
2542
+ session.Value()->GetRemoteMRPConfig().mIdleRetransTimeout);
2543
+
2544
+ auto maxIntervalCeilingMin = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN);
2545
+ if (idleSleepInterval < maxIntervalCeilingMin) {
2546
+ idleSleepInterval = maxIntervalCeilingMin;
2547
+ }
2548
+
2549
+ auto maxIntervalCeilingMax = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX);
2550
+ if (idleSleepInterval > maxIntervalCeilingMax) {
2551
+ idleSleepInterval = maxIntervalCeilingMax;
2552
+ }
2559
2553
#ifdef DEBUG
2560
- if (maxIntervalOverride.HasValue()) {
2561
- idleSleepInterval = maxIntervalOverride.Value();
2562
- }
2563
- #endif
2564
- readParams.mMaxIntervalCeilingSeconds = static_cast<uint16_t>(idleSleepInterval.count());
2565
-
2566
- readParams.mpAttributePathParamsList = attributePath.get();
2567
- readParams.mAttributePathParamsListSize = 1;
2568
- readParams.mpEventPathParamsList = eventPath.get();
2569
- readParams.mEventPathParamsListSize = 1;
2570
- readParams.mKeepSubscriptions = true;
2571
- readParams.mIsFabricFiltered = false;
2572
- size_t dataVersionFilterListSize = 0;
2573
- DataVersionFilter * dataVersionFilterList;
2574
- [self _createDataVersionFilterListFromDictionary:dataVersions dataVersionFilterList:&dataVersionFilterList count:&dataVersionFilterListSize sizeReduction:dataVersionFilterListSizeReduction];
2575
- readParams.mDataVersionFilterListSize = dataVersionFilterListSize;
2576
- readParams.mpDataVersionFilterList = dataVersionFilterList;
2577
- attributePath.release();
2578
- eventPath.release();
2579
-
2580
- // TODO: Change from local filter list generation to rehydrating ClusterStateCache ot take advantage of existing filter list sorting algorithm
2581
-
2582
- // SendAutoResubscribeRequest cleans up the params, even on failure.
2583
- err = readClient->SendAutoResubscribeRequest(std::move(readParams));
2584
- if (err == CHIP_NO_ERROR) {
2585
- break;
2586
- }
2587
-
2588
- // If error is not a "no memory" issue, then break and go through regular resubscribe logic
2589
- if (err != CHIP_ERROR_NO_MEMORY) {
2590
- break;
2591
- }
2592
-
2593
- // If "no memory" error is not caused by data version filter list, break as well
2594
- if (!dataVersionFilterListSize) {
2595
- break;
2596
- }
2597
-
2598
- // Now "no memory" could mean subscribe request packet space ran out. Reduce size and try again immediately
2599
- dataVersionFilterListSizeReduction++;
2554
+ if (maxIntervalOverride.HasValue()) {
2555
+ idleSleepInterval = maxIntervalOverride.Value();
2600
2556
}
2557
+ #endif
2558
+ readParams.mMaxIntervalCeilingSeconds = static_cast<uint16_t>(idleSleepInterval.count());
2601
2559
2560
+ readParams.mpAttributePathParamsList = attributePath.get();
2561
+ readParams.mAttributePathParamsListSize = 1;
2562
+ readParams.mpEventPathParamsList = eventPath.get();
2563
+ readParams.mEventPathParamsListSize = 1;
2564
+ readParams.mKeepSubscriptions = true;
2565
+ readParams.mIsFabricFiltered = false;
2566
+
2567
+ // Subscribe with data version filter list from our cache.
2568
+ size_t dataVersionFilterListSize = 0;
2569
+ DataVersionFilter * dataVersionFilterList;
2570
+ [self _createDataVersionFilterListFromDictionary:[self _getCachedDataVersions] dataVersionFilterList:&dataVersionFilterList count:&dataVersionFilterListSize];
2571
+
2572
+ readParams.mDataVersionFilterListSize = dataVersionFilterListSize;
2573
+ readParams.mpDataVersionFilterList = dataVersionFilterList;
2574
+ attributePath.release();
2575
+ eventPath.release();
2576
+
2577
+ // TODO: Change from local filter list generation to rehydrating ClusterStateCache to take advantage of existing filter list sorting algorithm
2578
+
2579
+ // SendAutoResubscribeRequest cleans up the params, even on failure.
2580
+ CHIP_ERROR err = readClient->SendAutoResubscribeRequest(std::move(readParams));
2602
2581
if (err != CHIP_NO_ERROR) {
2603
2582
NSError * error = [MTRError errorForCHIPErrorCode:err logContext:self];
2604
2583
MTR_LOG_ERROR("%@ SendAutoResubscribeRequest error %@", self, error);
@@ -2610,8 +2589,6 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason
2610
2589
return;
2611
2590
}
2612
2591
2613
- MTR_LOG("%@ Subscribe with data version list size %lu, reduced by %lu", self, static_cast<unsigned long>(dataVersions.count), static_cast<unsigned long>(dataVersionFilterListSizeReduction));
2614
-
2615
2592
// Callback and ClusterStateCache and ReadClient will be deleted
2616
2593
// when OnDone is called.
2617
2594
os_unfair_lock_lock(&self->_lock);
0 commit comments