@@ -251,11 +251,11 @@ - (void)invalidateCASESession
251
251
252
252
class SubscriptionCallback final : public MTRBaseSubscriptionCallback {
253
253
public:
254
- SubscriptionCallback (dispatch_queue_t queue, DataReportCallback attributeReportCallback, DataReportCallback eventReportCallback,
254
+ SubscriptionCallback (DataReportCallback attributeReportCallback, DataReportCallback eventReportCallback,
255
255
ErrorCallback errorCallback, MTRDeviceResubscriptionScheduledHandler _Nullable resubscriptionScheduledHandler,
256
256
MTRSubscriptionEstablishedHandler _Nullable subscriptionEstablishedHandler, OnDoneHandler _Nullable onDoneHandler)
257
- : MTRBaseSubscriptionCallback(queue, attributeReportCallback, eventReportCallback, errorCallback,
258
- resubscriptionScheduledHandler, subscriptionEstablishedHandler, onDoneHandler)
257
+ : MTRBaseSubscriptionCallback(attributeReportCallback, eventReportCallback, errorCallback, resubscriptionScheduledHandler ,
258
+ subscriptionEstablishedHandler, onDoneHandler)
259
259
{
260
260
}
261
261
@@ -286,80 +286,120 @@ - (void)subscribeWithQueue:(dispatch_queue_t)queue
286
286
// Copy params before going async.
287
287
params = [params copy ];
288
288
289
- [self .deviceController
290
- getSessionForNode: self .nodeID
291
- completion: ^(ExchangeManager * _Nullable exchangeManager, const Optional<SessionHandle> & session,
292
- NSError * _Nullable error) {
293
- if (error != nil ) {
294
- dispatch_async (queue, ^{
295
- errorHandler (error);
296
- });
297
- return ;
298
- }
299
-
300
- // Wildcard endpoint, cluster, attribute, event.
301
- auto attributePath = std::make_unique<AttributePathParams>();
302
- auto eventPath = std::make_unique<EventPathParams>();
303
- ReadPrepareParams readParams (session.Value ());
304
- readParams.mMinIntervalFloorSeconds = [params.minInterval unsignedShortValue ];
305
- readParams.mMaxIntervalCeilingSeconds = [params.maxInterval unsignedShortValue ];
306
- readParams.mpAttributePathParamsList = attributePath.get ();
307
- readParams.mAttributePathParamsListSize = 1 ;
308
- readParams.mpEventPathParamsList = eventPath.get ();
309
- readParams.mEventPathParamsListSize = 1 ;
310
- readParams.mIsFabricFiltered = params.fabricFiltered ;
311
- readParams.mKeepSubscriptions = params.keepPreviousSubscriptions ;
312
-
313
- std::unique_ptr<SubscriptionCallback> callback;
314
- std::unique_ptr<ReadClient> readClient;
315
- std::unique_ptr<ClusterStateCache> clusterStateCache;
316
- if (clusterStateCacheContainer) {
317
- __weak MTRClusterStateCacheContainer * weakPtr = clusterStateCacheContainer;
318
- callback = std::make_unique<SubscriptionCallback>(queue, attributeReportHandler, eventReportHandler,
319
- errorHandler, resubscriptionScheduled, subscriptionEstablished, ^{
320
- MTRClusterStateCacheContainer * container = weakPtr;
321
- if (container) {
322
- container.cppClusterStateCache = nullptr ;
323
- }
324
- });
325
- clusterStateCache = std::make_unique<ClusterStateCache>(*callback.get ());
326
- readClient = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance (), exchangeManager,
327
- clusterStateCache->GetBufferedCallback (), ReadClient::InteractionType::Subscribe);
328
- } else {
329
- callback = std::make_unique<SubscriptionCallback>(queue, attributeReportHandler, eventReportHandler,
330
- errorHandler, resubscriptionScheduled, subscriptionEstablished, nil );
331
- readClient = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance (), exchangeManager,
332
- callback->GetBufferedCallback (), ReadClient::InteractionType::Subscribe);
333
- }
334
-
335
- CHIP_ERROR err;
336
- if (!params.autoResubscribe ) {
337
- err = readClient->SendRequest (readParams);
338
- } else {
339
- // SendAutoResubscribeRequest cleans up the params, even on failure.
340
- attributePath.release ();
341
- eventPath.release ();
342
- err = readClient->SendAutoResubscribeRequest (std::move (readParams));
343
- }
344
-
345
- if (err != CHIP_NO_ERROR) {
346
- dispatch_async (queue, ^{
347
- errorHandler ([MTRError errorForCHIPErrorCode: err]);
348
- });
349
-
350
- return ;
351
- }
352
-
353
- if (clusterStateCacheContainer) {
354
- clusterStateCacheContainer.cppClusterStateCache = clusterStateCache.get ();
355
- // ClusterStateCache will be deleted when OnDone is called or an error is encountered as well.
356
- callback->AdoptClusterStateCache (std::move (clusterStateCache));
357
- }
358
- // Callback and ReadClient will be deleted when OnDone is called or an error is
359
- // encountered.
360
- callback->AdoptReadClient (std::move (readClient));
361
- callback.release ();
362
- }];
289
+ [self .deviceController getSessionForNode: self .nodeID
290
+ completion: ^(ExchangeManager * _Nullable exchangeManager, const Optional<SessionHandle> & session,
291
+ NSError * _Nullable error) {
292
+ if (error != nil ) {
293
+ dispatch_async (queue, ^{
294
+ errorHandler (error);
295
+ });
296
+ return ;
297
+ }
298
+
299
+ // Wildcard endpoint, cluster, attribute, event.
300
+ auto attributePath = std::make_unique<AttributePathParams>();
301
+ auto eventPath = std::make_unique<EventPathParams>();
302
+ ReadPrepareParams readParams (session.Value ());
303
+ readParams.mMinIntervalFloorSeconds = [params.minInterval unsignedShortValue ];
304
+ readParams.mMaxIntervalCeilingSeconds = [params.maxInterval unsignedShortValue ];
305
+ readParams.mpAttributePathParamsList = attributePath.get ();
306
+ readParams.mAttributePathParamsListSize = 1 ;
307
+ readParams.mpEventPathParamsList = eventPath.get ();
308
+ readParams.mEventPathParamsListSize = 1 ;
309
+ readParams.mIsFabricFiltered = params.fabricFiltered ;
310
+ readParams.mKeepSubscriptions = params.keepPreviousSubscriptions ;
311
+
312
+ std::unique_ptr<ClusterStateCache> clusterStateCache;
313
+ ReadClient::Callback * callbackForReadClient = nullptr ;
314
+ OnDoneHandler onDoneHandler = nil ;
315
+
316
+ if (clusterStateCacheContainer) {
317
+ __weak MTRClusterStateCacheContainer * weakPtr = clusterStateCacheContainer;
318
+ onDoneHandler = ^{
319
+ // This, like all manipulation of cppClusterStateCache, needs to run on the Matter
320
+ // queue.
321
+ MTRClusterStateCacheContainer * container = weakPtr;
322
+ if (container) {
323
+ container.cppClusterStateCache = nullptr ;
324
+ }
325
+ };
326
+ }
327
+
328
+ auto callback = std::make_unique<SubscriptionCallback>(
329
+ ^(NSArray * value) {
330
+ dispatch_async (queue, ^{
331
+ if (attributeReportHandler != nil ) {
332
+ attributeReportHandler (value);
333
+ }
334
+ });
335
+ },
336
+ ^(NSArray * value) {
337
+ dispatch_async (queue, ^{
338
+ if (eventReportHandler != nil ) {
339
+ eventReportHandler (value);
340
+ }
341
+ });
342
+ },
343
+ ^(NSError * error) {
344
+ dispatch_async (queue, ^{
345
+ errorHandler (error);
346
+ });
347
+ },
348
+ ^(NSError * error, NSNumber * resubscriptionDelay) {
349
+ dispatch_async (queue, ^{
350
+ if (resubscriptionScheduled != nil ) {
351
+ resubscriptionScheduled (error, resubscriptionDelay);
352
+ }
353
+ });
354
+ },
355
+ ^(void ) {
356
+ dispatch_async (queue, ^{
357
+ if (subscriptionEstablished != nil ) {
358
+ subscriptionEstablished ();
359
+ }
360
+ });
361
+ },
362
+ onDoneHandler);
363
+
364
+ if (clusterStateCacheContainer) {
365
+ clusterStateCache = std::make_unique<ClusterStateCache>(*callback.get ());
366
+ callbackForReadClient = &clusterStateCache->GetBufferedCallback ();
367
+ } else {
368
+ callbackForReadClient = &callback->GetBufferedCallback ();
369
+ }
370
+
371
+ auto readClient = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance (),
372
+ exchangeManager, *callbackForReadClient, ReadClient::InteractionType::Subscribe);
373
+
374
+ CHIP_ERROR err;
375
+ if (!params.autoResubscribe ) {
376
+ err = readClient->SendRequest (readParams);
377
+ } else {
378
+ // SendAutoResubscribeRequest cleans up the params, even on failure.
379
+ attributePath.release ();
380
+ eventPath.release ();
381
+ err = readClient->SendAutoResubscribeRequest (std::move (readParams));
382
+ }
383
+
384
+ if (err != CHIP_NO_ERROR) {
385
+ dispatch_async (queue, ^{
386
+ errorHandler ([MTRError errorForCHIPErrorCode: err]);
387
+ });
388
+
389
+ return ;
390
+ }
391
+
392
+ if (clusterStateCacheContainer) {
393
+ clusterStateCacheContainer.cppClusterStateCache = clusterStateCache.get ();
394
+ // ClusterStateCache will be deleted when OnDone is called or an error is encountered as
395
+ // well.
396
+ callback->AdoptClusterStateCache (std::move (clusterStateCache));
397
+ }
398
+ // Callback and ReadClient will be deleted when OnDone is called or an error is
399
+ // encountered.
400
+ callback->AdoptReadClient (std::move (readClient));
401
+ callback.release ();
402
+ }];
363
403
}
364
404
365
405
// Convert TLV data into data-value dictionary as described in MTRDeviceResponseHandler
0 commit comments