@@ -2223,17 +2223,16 @@ - (void)_removeCachedAttribute:(NSNumber *)attributeID fromCluster:(MTRClusterPa
2223
2223
[clusterData removeValueForAttribute:attributeID];
2224
2224
}
2225
2225
2226
- - (void)_createDataVersionFilterListFromDictionary:(NSDictionary<MTRClusterPath *, NSNumber *> *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count sizeReduction:(size_t)sizeReduction
2226
+ - (void)_createDataVersionFilterListFromDictionary:(NSDictionary<MTRClusterPath *, NSNumber *> *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count
2227
2227
{
2228
2228
size_t maxDataVersionFilterSize = dataVersions.count;
2229
2229
2230
2230
// Check if any filter list should be generated
2231
- if (!dataVersions.count || (maxDataVersionFilterSize <= sizeReduction) ) {
2231
+ if (!dataVersions.count) {
2232
2232
*count = 0;
2233
2233
*dataVersionFilterList = nullptr;
2234
2234
return;
2235
2235
}
2236
- maxDataVersionFilterSize -= sizeReduction;
2237
2236
2238
2237
DataVersionFilter * dataVersionFilterArray = new DataVersionFilter[maxDataVersionFilterSize];
2239
2238
size_t i = 0;
@@ -2242,13 +2241,13 @@ - (void)_createDataVersionFilterListFromDictionary:(NSDictionary<MTRClusterPath
2242
2241
if (dataVersionNumber) {
2243
2242
dataVersionFilterArray[i++] = DataVersionFilter(static_cast<chip::EndpointId>(path.endpoint.unsignedShortValue), static_cast<chip::ClusterId>(path.cluster.unsignedLongValue), static_cast<chip::DataVersion>(dataVersionNumber.unsignedLongValue));
2244
2243
}
2245
- if (i == maxDataVersionFilterSize) {
2246
- break;
2247
- }
2248
2244
}
2249
2245
2250
2246
*dataVersionFilterList = dataVersionFilterArray;
2251
- *count = maxDataVersionFilterSize;
2247
+ // Note that we might have i < maxDataVersionFilterSize here if some of the
2248
+ // dictionary entries had a null dataVersionNumber. The correct size of the
2249
+ // valid entried in our array is "i".
2250
+ *count = i;
2252
2251
}
2253
2252
2254
2253
- (void)_setupConnectivityMonitoring
@@ -2443,75 +2442,55 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason
2443
2442
auto readClient = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance(), exchangeManager,
2444
2443
clusterStateCache->GetBufferedCallback(), ReadClient::InteractionType::Subscribe);
2445
2444
2446
- // Subscribe with data version filter list and retry with smaller list if out of packet space
2447
- CHIP_ERROR err;
2448
- NSDictionary<MTRClusterPath *, NSNumber *> * dataVersions = [self _getCachedDataVersions];
2449
- size_t dataVersionFilterListSizeReduction = 0;
2450
- for (;;) {
2451
- // Wildcard endpoint, cluster, attribute, event.
2452
- auto attributePath = std::make_unique<AttributePathParams>();
2453
- auto eventPath = std::make_unique<EventPathParams>();
2454
- // We want to get event reports at the minInterval, not the maxInterval.
2455
- eventPath->mIsUrgentEvent = true;
2456
- ReadPrepareParams readParams(session.Value());
2457
-
2458
- readParams.mMinIntervalFloorSeconds = 0;
2459
- // Select a max interval based on the device's claimed idle sleep interval.
2460
- auto idleSleepInterval = std::chrono::duration_cast<System::Clock::Seconds32>(
2461
- session.Value()->GetRemoteMRPConfig().mIdleRetransTimeout);
2462
-
2463
- auto maxIntervalCeilingMin = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN);
2464
- if (idleSleepInterval < maxIntervalCeilingMin) {
2465
- idleSleepInterval = maxIntervalCeilingMin;
2466
- }
2467
-
2468
- auto maxIntervalCeilingMax = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX);
2469
- if (idleSleepInterval > maxIntervalCeilingMax) {
2470
- idleSleepInterval = maxIntervalCeilingMax;
2471
- }
2445
+ // Wildcard endpoint, cluster, attribute, event.
2446
+ auto attributePath = std::make_unique<AttributePathParams>();
2447
+ auto eventPath = std::make_unique<EventPathParams>();
2448
+ // We want to get event reports at the minInterval, not the maxInterval.
2449
+ eventPath->mIsUrgentEvent = true;
2450
+ ReadPrepareParams readParams(session.Value());
2451
+
2452
+ readParams.mMinIntervalFloorSeconds = 0;
2453
+ // Select a max interval based on the device's claimed idle sleep interval.
2454
+ auto idleSleepInterval = std::chrono::duration_cast<System::Clock::Seconds32>(
2455
+ session.Value()->GetRemoteMRPConfig().mIdleRetransTimeout);
2456
+
2457
+ auto maxIntervalCeilingMin = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN);
2458
+ if (idleSleepInterval < maxIntervalCeilingMin) {
2459
+ idleSleepInterval = maxIntervalCeilingMin;
2460
+ }
2461
+
2462
+ auto maxIntervalCeilingMax = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX);
2463
+ if (idleSleepInterval > maxIntervalCeilingMax) {
2464
+ idleSleepInterval = maxIntervalCeilingMax;
2465
+ }
2472
2466
#ifdef DEBUG
2473
- if (maxIntervalOverride.HasValue()) {
2474
- idleSleepInterval = maxIntervalOverride.Value();
2475
- }
2476
- #endif
2477
- readParams.mMaxIntervalCeilingSeconds = static_cast<uint16_t>(idleSleepInterval.count());
2478
-
2479
- readParams.mpAttributePathParamsList = attributePath.get();
2480
- readParams.mAttributePathParamsListSize = 1;
2481
- readParams.mpEventPathParamsList = eventPath.get();
2482
- readParams.mEventPathParamsListSize = 1;
2483
- readParams.mKeepSubscriptions = true;
2484
- readParams.mIsFabricFiltered = false;
2485
- size_t dataVersionFilterListSize = 0;
2486
- DataVersionFilter * dataVersionFilterList;
2487
- [self _createDataVersionFilterListFromDictionary:dataVersions dataVersionFilterList:&dataVersionFilterList count:&dataVersionFilterListSize sizeReduction:dataVersionFilterListSizeReduction];
2488
- readParams.mDataVersionFilterListSize = dataVersionFilterListSize;
2489
- readParams.mpDataVersionFilterList = dataVersionFilterList;
2490
- attributePath.release();
2491
- eventPath.release();
2492
-
2493
- // TODO: Change from local filter list generation to rehydrating ClusterStateCache ot take advantage of existing filter list sorting algorithm
2494
-
2495
- // SendAutoResubscribeRequest cleans up the params, even on failure.
2496
- err = readClient->SendAutoResubscribeRequest(std::move(readParams));
2497
- if (err == CHIP_NO_ERROR) {
2498
- break;
2499
- }
2500
-
2501
- // If error is not a "no memory" issue, then break and go through regular resubscribe logic
2502
- if (err != CHIP_ERROR_NO_MEMORY) {
2503
- break;
2504
- }
2505
-
2506
- // If "no memory" error is not caused by data version filter list, break as well
2507
- if (!dataVersionFilterListSize) {
2508
- break;
2509
- }
2510
-
2511
- // Now "no memory" could mean subscribe request packet space ran out. Reduce size and try again immediately
2512
- dataVersionFilterListSizeReduction++;
2467
+ if (maxIntervalOverride.HasValue()) {
2468
+ idleSleepInterval = maxIntervalOverride.Value();
2513
2469
}
2470
+ #endif
2471
+ readParams.mMaxIntervalCeilingSeconds = static_cast<uint16_t>(idleSleepInterval.count());
2514
2472
2473
+ readParams.mpAttributePathParamsList = attributePath.get();
2474
+ readParams.mAttributePathParamsListSize = 1;
2475
+ readParams.mpEventPathParamsList = eventPath.get();
2476
+ readParams.mEventPathParamsListSize = 1;
2477
+ readParams.mKeepSubscriptions = true;
2478
+ readParams.mIsFabricFiltered = false;
2479
+
2480
+ // Subscribe with data version filter list from our cache.
2481
+ size_t dataVersionFilterListSize = 0;
2482
+ DataVersionFilter * dataVersionFilterList;
2483
+ [self _createDataVersionFilterListFromDictionary:[self _getCachedDataVersions] dataVersionFilterList:&dataVersionFilterList count:&dataVersionFilterListSize];
2484
+
2485
+ readParams.mDataVersionFilterListSize = dataVersionFilterListSize;
2486
+ readParams.mpDataVersionFilterList = dataVersionFilterList;
2487
+ attributePath.release();
2488
+ eventPath.release();
2489
+
2490
+ // TODO: Change from local filter list generation to rehydrating ClusterStateCache to take advantage of existing filter list sorting algorithm
2491
+
2492
+ // SendAutoResubscribeRequest cleans up the params, even on failure.
2493
+ CHIP_ERROR err = readClient->SendAutoResubscribeRequest(std::move(readParams));
2515
2494
if (err != CHIP_NO_ERROR) {
2516
2495
NSError * error = [MTRError errorForCHIPErrorCode:err logContext:self];
2517
2496
MTR_LOG_ERROR("%@ SendAutoResubscribeRequest error %@", self, error);
@@ -2523,8 +2502,6 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason
2523
2502
return;
2524
2503
}
2525
2504
2526
- MTR_LOG("%@ Subscribe with data version list size %lu, reduced by %lu", self, static_cast<unsigned long>(dataVersions.count), static_cast<unsigned long>(dataVersionFilterListSizeReduction));
2527
-
2528
2505
// Callback and ClusterStateCache and ReadClient will be deleted
2529
2506
// when OnDone is called.
2530
2507
os_unfair_lock_lock(&self->_lock);
0 commit comments