Skip to content

Commit 3098808

Browse files
bzbarsky-applepull[bot]
authored andcommitted
Turn on auto-resubscribe for Darwin wildcard subscriptions. (#16201)
We weren't doing it before, but should do it.
1 parent 9d33bd4 commit 3098808

File tree

9 files changed

+6208
-10
lines changed

9 files changed

+6208
-10
lines changed

src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m

+1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ - (void)reportFromUserEnteredSettings
203203
[chipDevice subscribeWithQueue:dispatch_get_main_queue()
204204
minInterval:minIntervalSeconds
205205
maxInterval:maxIntervalSeconds
206+
params:nil
206207
reportHandler:^(NSArray<CHIPAttributeReport *> * _Nullable reports, NSError * _Nullable error) {
207208
if (error) {
208209
NSLog(@"Status: update reportAttributeMeasuredValue completed with error %@",

src/darwin/Framework/CHIP/CHIPCluster.h

+14
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ NS_ASSUME_NONNULL_BEGIN
7575
*/
7676
@property (strong, nonatomic, nullable) NSNumber * keepPreviousSubscriptions;
7777

78+
/**
79+
* Whether the subscription should automatically try to re-establish if it
80+
* drops. nil (the default value) is treated as YES.
81+
*
82+
* If NO, loss of subscription will simply lead to an error report. Some
83+
* subscription APIs do not support this value.
84+
*
85+
* If YES, loss of subscription will lead to an automatic resubscription
86+
* attempt. If this succeeds, the subscriptionEstablished callback will be
87+
* called again.
88+
*
89+
*/
90+
@property (strong, nonatomic, nullable) NSNumber * autoResubscribe;
91+
7892
- (instancetype)init;
7993
@end
8094

src/darwin/Framework/CHIP/CHIPCluster.mm

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ - (instancetype)init
7676
{
7777
if (self = [super init]) {
7878
_keepPreviousSubscriptions = nil;
79+
_autoResubscribe = nil;
7980
}
8081
return self;
8182
}

src/darwin/Framework/CHIP/CHIPDevice.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#import <Foundation/Foundation.h>
2222

23+
@class CHIPSubscribeParams;
24+
2325
NS_ASSUME_NONNULL_BEGIN
2426

2527
typedef void (^CHIPDeviceResponseHandler)(NSArray<NSDictionary<NSString *, id> *> * _Nullable values, NSError * _Nullable error);
@@ -65,13 +67,15 @@ extern NSString * const kCHIPStatusKey;
6567
*
6668
* subscriptionEstablished block, if not nil, will be called once the
6769
* subscription is established. This will be _after_ the first (priming) call
68-
* to reportHandler.
70+
* to reportHandler. Note that if the CHIPSubscribeParams are set to
71+
* automatically resubscribe this can end up being called more than once.
6972
*
7073
* TODO: The "all events" part does not work yet.
7174
*/
7275
- (void)subscribeWithQueue:(dispatch_queue_t)queue
7376
minInterval:(uint16_t)minInterval
7477
maxInterval:(uint16_t)maxInterval
78+
params:(nullable CHIPSubscribeParams *)params
7579
reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
7680
subscriptionEstablished:(nullable void (^)(void))subscriptionEstablishedHandler;
7781

src/darwin/Framework/CHIP/CHIPDevice.mm

+43-9
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ - (instancetype)initWithDevice:(chip::DeviceProxy *)device
238238

239239
void OnDone() override;
240240

241+
void OnDeallocatePaths(ReadPrepareParams && aReadPrepareParams) override;
242+
241243
void OnSubscriptionEstablished(uint64_t aSubscriptionId) override;
242244

243245
void ReportError(CHIP_ERROR err);
@@ -274,6 +276,7 @@ - (instancetype)initWithDevice:(chip::DeviceProxy *)device
274276
- (void)subscribeWithQueue:(dispatch_queue_t)queue
275277
minInterval:(uint16_t)minInterval
276278
maxInterval:(uint16_t)maxInterval
279+
params:(nullable CHIPSubscribeParams *)params
277280
reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
278281
subscriptionEstablished:(nullable void (^)(void))subscriptionEstablishedHandler
279282
{
@@ -284,18 +287,30 @@ - (void)subscribeWithQueue:(dispatch_queue_t)queue
284287
});
285288
return;
286289
}
287-
AttributePathParams attributePath; // Wildcard endpoint, cluster, attribute.
288-
ReadPrepareParams params(device->GetSecureSession().Value());
289-
params.mMinIntervalFloorSeconds = minInterval;
290-
params.mMaxIntervalCeilingSeconds = maxInterval;
291-
params.mpAttributePathParamsList = &attributePath;
292-
params.mAttributePathParamsListSize = 1;
290+
291+
// Wildcard endpoint, cluster, attribute.
292+
auto attributePath = std::make_unique<AttributePathParams>();
293+
ReadPrepareParams readParams(device->GetSecureSession().Value());
294+
readParams.mMinIntervalFloorSeconds = minInterval;
295+
readParams.mMaxIntervalCeilingSeconds = maxInterval;
296+
readParams.mpAttributePathParamsList = attributePath.get();
297+
readParams.mAttributePathParamsListSize = 1;
298+
readParams.mKeepSubscriptions
299+
= (params != nil) && (params.keepPreviousSubscriptions != nil) && [params.keepPreviousSubscriptions boolValue];
293300

294301
auto callback = std::make_unique<SubscriptionCallback>(queue, reportHandler, subscriptionEstablishedHandler);
295302
auto readClient = std::make_unique<ReadClient>(InteractionModelEngine::GetInstance(), device->GetExchangeManager(),
296303
callback->GetBufferedCallback(), ReadClient::InteractionType::Subscribe);
297304

298-
CHIP_ERROR err = readClient->SendRequest(params);
305+
CHIP_ERROR err;
306+
if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
307+
err = readClient->SendRequest(readParams);
308+
} else {
309+
// SendAutoResubscribeRequest cleans up the params, even on failure.
310+
attributePath.release();
311+
err = readClient->SendAutoResubscribeRequest(std::move(readParams));
312+
}
313+
299314
if (err != CHIP_NO_ERROR) {
300315
dispatch_async(queue, ^{
301316
reportHandler(nil, [CHIPError errorForCHIPErrorCode:err]);
@@ -1266,12 +1281,31 @@ - (instancetype)initWithPath:(const ConcreteDataAttributePath &)path value:(null
12661281
}
12671282
}
12681283

1284+
void SubscriptionCallback::OnDeallocatePaths(ReadPrepareParams && aReadPrepareParams)
1285+
{
1286+
VerifyOrDie((aReadPrepareParams.mAttributePathParamsListSize == 0 && aReadPrepareParams.mpAttributePathParamsList == nullptr)
1287+
|| (aReadPrepareParams.mAttributePathParamsListSize == 1 && aReadPrepareParams.mpAttributePathParamsList != nullptr));
1288+
if (aReadPrepareParams.mpAttributePathParamsList) {
1289+
delete aReadPrepareParams.mpAttributePathParamsList;
1290+
}
1291+
1292+
VerifyOrDie((aReadPrepareParams.mDataVersionFilterListSize == 0 && aReadPrepareParams.mpDataVersionFilterList == nullptr)
1293+
|| (aReadPrepareParams.mDataVersionFilterListSize == 1 && aReadPrepareParams.mpDataVersionFilterList != nullptr));
1294+
if (aReadPrepareParams.mpDataVersionFilterList != nullptr) {
1295+
delete aReadPrepareParams.mpDataVersionFilterList;
1296+
}
1297+
1298+
VerifyOrDie((aReadPrepareParams.mEventPathParamsListSize == 0 && aReadPrepareParams.mpEventPathParamsList == nullptr)
1299+
|| (aReadPrepareParams.mEventPathParamsListSize == 1 && aReadPrepareParams.mpEventPathParamsList != nullptr));
1300+
if (aReadPrepareParams.mpEventPathParamsList) {
1301+
delete aReadPrepareParams.mpEventPathParamsList;
1302+
}
1303+
}
1304+
12691305
void SubscriptionCallback::OnSubscriptionEstablished(uint64_t aSubscriptionId)
12701306
{
12711307
if (mSubscriptionEstablishedHandler) {
12721308
dispatch_async(mQueue, mSubscriptionEstablishedHandler);
1273-
// Don't need it anymore.
1274-
mSubscriptionEstablishedHandler = nil;
12751309
}
12761310
}
12771311

src/darwin/Framework/CHIP/templates/CHIPClustersObjc-src.zapt

+4
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEs
137137
not great from a type-safety perspective, of course. }}
138138
reportHandler,
139139
^(Cancelable * success, Cancelable * failure) {
140+
if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
141+
// We don't support disabling auto-resubscribe.
142+
return CHIP_ERROR_INVALID_ARGUMENT;
143+
}
140144
using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
141145
auto successFn = Callback<{{>attribute_data_callback_name}}Callback>::FromCancelable(success);
142146
auto failureFn = Callback<CHIPDefaultFailureCallbackType>::FromCancelable(failure);

src/darwin/Framework/CHIP/templates/CHIPClustersObjc.zapt

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ NS_ASSUME_NONNULL_BEGIN
4343
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completionHandler:(StatusCompletion)completionHandler;
4444
{{/if}}
4545
{{#if isReportableAttribute}}
46+
/**
47+
* This API does not support setting autoResubscribe to NO in the
48+
* CHIPSubscribeParams.
49+
*/
4650
- (void) subscribe{{>attribute}}WithMinInterval:(NSNumber * _Nonnull)minInterval maxInterval:(NSNumber * _Nonnull)maxInterval
4751
params:(CHIPSubscribeParams * _Nullable)params
4852
subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))reportHandler;

0 commit comments

Comments
 (0)