Fix auto resubcribe condition for in Darwin subscribeToAttributesWithEndpointID. (#23554)
A copy-paste error led to the wrong boolean being checked, so we would set up
auto-resubscription for any subscription which is not replacing existing
subscriptions, regardless of the value of resubscribeIfLost.
diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm
index 71e1cde..fdc5cdb 100644
--- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm
+++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm
@@ -1222,7 +1222,7 @@
auto readClient = Platform::New<app::ReadClient>(
engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe);
- if (params.replaceExistingSubscriptions) {
+ if (!params.resubscribeIfLost) {
err = readClient->SendRequest(readParams);
} else {
err = readClient->SendAutoResubscribeRequest(std::move(readParams));
diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
index a3a55d0..78659c7 100644
--- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
+++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
@@ -1234,6 +1234,8 @@
__auto_type clusterStateCacheContainer = [[MTRAttributeCacheContainer alloc] init];
__auto_type * params = [[MTRSubscribeParams alloc] init];
params.resubscribeIfLost = NO;
+ params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not
+ // affect this subscription erroring out correctly.
[device subscribeWithQueue:queue
minInterval:1
maxInterval:2
@@ -1272,6 +1274,7 @@
// Create second subscription which will cancel the first subscription. We
// can use a non-existent path here to cut down on the work that gets done.
+ params.replaceExistingSubscriptions = YES;
[device subscribeAttributeWithEndpointId:@10000
clusterId:@6
attributeId:@0
@@ -1330,6 +1333,7 @@
// Create second subscription which will cancel the first subscription. We
// can use a non-existent path here to cut down on the work that gets done.
+ params.replaceExistingSubscriptions = YES;
[device subscribeAttributeWithEndpointId:@10000
clusterId:@6
attributeId:@0
@@ -1366,6 +1370,67 @@
[self waitForExpectations:@[ subscriptionExpectation ] timeout:60];
}
+- (void)test018_SubscriptionErrorWhenNotResubscribing
+{
+#if MANUAL_INDIVIDUAL_TEST
+ [self initStack];
+ [self waitForCommissionee];
+#endif
+ MTRBaseDevice * device = GetConnectedDevice();
+ dispatch_queue_t queue = dispatch_get_main_queue();
+
+ XCTestExpectation * firstSubscribeExpectation = [self expectationWithDescription:@"First subscription complete"];
+ XCTestExpectation * errorExpectation = [self expectationWithDescription:@"First subscription errored out"];
+
+ // Subscribe
+ MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)];
+ params.resubscribeIfLost = NO;
+ params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not
+ // affect this subscription erroring out correctly.
+ __block BOOL subscriptionEstablished = NO;
+ [device subscribeToAttributesWithEndpointID:@1
+ clusterID:@6
+ attributeID:@0
+ params:params
+ queue:queue
+ reportHandler:^(id _Nullable values, NSError * _Nullable error) {
+ if (subscriptionEstablished) {
+ // We should only get an error here.
+ XCTAssertNil(values);
+ XCTAssertNotNil(error);
+ [errorExpectation fulfill];
+ } else {
+ XCTAssertNotNil(values);
+ XCTAssertNil(error);
+ }
+ }
+ subscriptionEstablished:^{
+ NSLog(@"subscribe attribute: OnOff established");
+ XCTAssertFalse(subscriptionEstablished);
+ subscriptionEstablished = YES;
+ [firstSubscribeExpectation fulfill];
+ }];
+
+ // Wait till establishment
+ [self waitForExpectations:@[ firstSubscribeExpectation ] timeout:kTimeoutInSeconds];
+
+ // Create second subscription which will cancel the first subscription. We
+ // can use a non-existent path here to cut down on the work that gets done.
+ params.replaceExistingSubscriptions = YES;
+ [device subscribeAttributeWithEndpointId:@10000
+ clusterId:@6
+ attributeId:@0
+ minInterval:@(1)
+ maxInterval:@(2)
+ params:params
+ clientQueue:queue
+ reportHandler:^(id _Nullable values, NSError * _Nullable error) {
+ }
+ subscriptionEstablished:^() {
+ }];
+ [self waitForExpectations:@[ errorExpectation ] timeout:60];
+}
+
- (void)test900_SubscribeAllAttributes
{
#if MANUAL_INDIVIDUAL_TEST