Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation of clamping timeout values according to header intenti…
Browse files Browse the repository at this point in the history
…on and spec
jtung-apple committed Oct 24, 2022
1 parent da55472 commit 4601a1b
Showing 5 changed files with 2,654 additions and 939 deletions.
11 changes: 7 additions & 4 deletions src/darwin/Framework/CHIP/MTRDevice.h
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@ typedef NS_ENUM(NSUInteger, MTRDeviceState) {
* MTRDeviceResponseHandler.
*
* @param expectedValueInterval maximum interval in milliseconds during which reads of the attribute will return the value being
* written. This value will be clamped to timeoutMs
* written. This value must be within [1, UINT32_MAX], and will be clamped to this range, or timeoutMs if it exists.
*
* TODO: document that -readAttribute... will return the expected value for the [endpoint,cluster,attribute] until one of the
* following:
@@ -96,7 +96,8 @@ typedef NS_ENUM(NSUInteger, MTRDeviceState) {
* 3. We succeed at writing the attribute.
* 4. We fail at writing the attribute and give up on the write
*
* @param timeout timeout in milliseconds for timed write, or nil.
* @param timeout timeout in milliseconds for timed write, or nil. This value must be within [1, UINT16_MAX], and will be clamped
* to this range.
* TODO: make timeout arguments uniform
*/
- (void)writeAttributeWithEndpointID:(NSNumber *)endpointID
@@ -123,9 +124,11 @@ typedef NS_ENUM(NSUInteger, MTRDeviceState) {
* readAttribute will get these values
*
* @param expectedValueInterval maximum interval in milliseconds during which reads of the attribute will return the value being
* written. This value will be clamped to timeout. This argument is ignored if expectedValues is nil.
* written. This value must be within [1, UINT32_MAX], and will be clamped to this range, or timeoutMs if it exists. This argument is
* ignored if expectedValues is nil.
*
* @param timeout timeout in milliseconds for timed invoke, or nil.
* @param timeout timeout in milliseconds for timed invoke, or nil. This value must be within [1, UINT16_MAX], and will be clamped
* to this range.
*
* @param completion response handler will receive either values or error.
*/
24 changes: 24 additions & 0 deletions src/darwin/Framework/CHIP/MTRDevice.mm
Original file line number Diff line number Diff line change
@@ -92,6 +92,16 @@ - (id)strongObject
}
@end

NSNumber * MTRClampedNumber(NSNumber * aNumber, NSNumber * min, NSNumber * max)
{
if ([aNumber compare:min] == NSOrderedAscending) {
return min;
} else if ([aNumber compare:max] == NSOrderedDescending) {
return max;
}
return aNumber;
}

#pragma mark - SubscriptionCallback class declaration
using namespace chip;
using namespace chip::app;
@@ -422,6 +432,10 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID
expectedValueInterval:(NSNumber *)expectedValueInterval
timedWriteTimeout:(NSNumber * _Nullable)timeout
{
if (timeout) {
timeout = MTRClampedNumber(timeout, @(1), @(UINT16_MAX));
}
expectedValueInterval = MTRClampedNumber(expectedValueInterval, @(1), timeout ?: @(UINT16_MAX));
MTRAsyncCallbackQueueWorkItem * workItem = [[MTRAsyncCallbackQueueWorkItem alloc] initWithQueue:_queue];
MTRAsyncCallbackReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) {
MTRBaseDevice * baseDevice = [self newBaseDevice];
@@ -461,6 +475,16 @@ - (void)invokeCommandWithEndpointID:(NSNumber *)endpointID
clientQueue:(dispatch_queue_t)clientQueue
completion:(MTRDeviceResponseHandler)completion
{
if (timeout) {
timeout = MTRClampedNumber(timeout, @(1), @(UINT16_MAX));
}
if (expectedValueInterval) {
if ([expectedValueInterval compare:@(0)] == NSOrderedAscending) {
expectedValues = nil;
} else {
expectedValueInterval = MTRClampedNumber(expectedValueInterval, @(1), timeout ?: @(UINT16_MAX));
}
}
MTRAsyncCallbackQueueWorkItem * workItem = [[MTRAsyncCallbackQueueWorkItem alloc] initWithQueue:_queue];
MTRAsyncCallbackReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) {
MTRBaseDevice * baseDevice = [self newBaseDevice];
5 changes: 5 additions & 0 deletions src/darwin/Framework/CHIP/MTRDevice_Internal.h
Original file line number Diff line number Diff line change
@@ -39,4 +39,9 @@ typedef void (^MTRDevicePerformAsyncBlock)(MTRBaseDevice * baseDevice);

@end

#pragma mark - Utility for clamping numbers
// Returns a NSNumber object that is aNumber if it falls within the range [min, max].
// Returns min or max, if it is below or above, respectively.
NSNumber * MTRClampedNumber(NSNumber * aNumber, NSNumber * min, NSNumber * max);

NS_ASSUME_NONNULL_END
19 changes: 14 additions & 5 deletions src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt
Original file line number Diff line number Diff line change
@@ -53,6 +53,10 @@ using chip::SessionHandle;
{
// Make a copy of params before we go async.
params = [params copy];
NSNumber *timedInvokeTimeoutMsParam = params.timedInvokeTimeoutMs;
if (timedInvokeTimeoutMsParam) {
timedInvokeTimeoutMsParam = MTRClampedNumber(timedInvokeTimeoutMsParam, @(1), @(UINT16_MAX));
}
MTRAsyncCallbackQueueWorkItem * workItem = [[MTRAsyncCallbackQueueWorkItem alloc] initWithQueue:self.callbackQueue];
MTRAsyncCallbackReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) {
MTRBaseDevice *baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController];
@@ -75,10 +79,8 @@ using chip::SessionHandle;
chip::Optional<uint16_t> timedInvokeTimeoutMs;
ListFreer listFreer;
{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Type request;
if (params != nil) {
if (params.timedInvokeTimeoutMs != nil) {
timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
}
if (timedInvokeTimeoutMsParam != nil) {
timedInvokeTimeoutMs.SetValue(timedInvokeTimeoutMsParam.unsignedShortValue);
}
{{#if mustUseTimedInvoke}}
if (!timedInvokeTimeoutMs.HasValue()) {
@@ -108,7 +110,14 @@ using chip::SessionHandle;
workItem.readyHandler = readyHandler;
[self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem];

[self.device setExpectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs];
if ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending) {
expectedValues = nil;
} else {
expectedValueIntervalMs = MTRClampedNumber(timedInvokeTimeoutMsParam, @(1), timedInvokeTimeoutMsParam ?: @(UINT16_MAX));
}
if (expectedValues) {
[self.device setExpectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs];
}
}
{{/chip_cluster_commands}}

3,534 changes: 2,604 additions & 930 deletions src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm

Large diffs are not rendered by default.

0 comments on commit 4601a1b

Please sign in to comment.