|
35 | 35 | #import "MTRError_Internal.h"
|
36 | 36 | #import "MTREventTLVValueDecoder_Internal.h"
|
37 | 37 | #import "MTRLogging_Internal.h"
|
| 38 | +#import "MTRMetricKeys.h" |
| 39 | +#import "MTRMetricsCollector.h" |
38 | 40 | #import "MTRTimeUtils.h"
|
39 | 41 | #import "MTRUnfairLock.h"
|
40 | 42 | #import "zap-generated/MTRCommandPayloads_Internal.h"
|
@@ -91,6 +93,39 @@ - (id)strongObject
|
91 | 93 | }
|
92 | 94 | @end
|
93 | 95 |
|
| 96 | +// Stores essential-for-logging attributes immutably for use in logs |
| 97 | +@interface MTRDeviceEssentialAttributes : NSObject |
| 98 | +@property (readonly) UInt16 vendorID; |
| 99 | +@property (readonly) UInt16 productID; |
| 100 | +@property (readonly) BOOL usesThread; |
| 101 | + |
| 102 | +- (void)addEssentialAttributesToCurrentMetricScope; |
| 103 | + |
| 104 | +@end |
| 105 | + |
| 106 | +@implementation MTRDeviceEssentialAttributes |
| 107 | + |
| 108 | +- (instancetype)initWithVendorID:(UInt16)vendorID productID:(UInt16)productID usesThread:(BOOL)usesThread { |
| 109 | + self = [super init]; |
| 110 | + |
| 111 | + if (self) { |
| 112 | + _vendorID = vendorID; |
| 113 | + _productID = productID; |
| 114 | + _usesThread = usesThread; |
| 115 | + } |
| 116 | + |
| 117 | + return self; |
| 118 | +} |
| 119 | + |
| 120 | +- (void)addEssentialAttributesToCurrentMetricScope { |
| 121 | + using namespace chip::Tracing::DarwinFramework; |
| 122 | + MATTER_LOG_METRIC(kMetricDeviceVendorID, _vendorID); |
| 123 | + MATTER_LOG_METRIC(kMetricDeviceProductID, _productID); |
| 124 | + MATTER_LOG_METRIC(kMetricDeviceUsesThread, _usesThread); |
| 125 | +} |
| 126 | + |
| 127 | +@end |
| 128 | + |
94 | 129 | NSNumber * MTRClampedNumber(NSNumber * aNumber, NSNumber * min, NSNumber * max)
|
95 | 130 | {
|
96 | 131 | if ([aNumber compare:min] == NSOrderedAscending) {
|
@@ -330,6 +365,10 @@ @interface MTRDevice ()
|
330 | 365 |
|
331 | 366 | @property (nonatomic) MTRInternalDeviceState internalDeviceState;
|
332 | 367 |
|
| 368 | +// TODO: cache this once I understand the point in the MTRDevice lifecycle that the relevant attributes will be present. |
| 369 | +// kmo 22 may 2024 14h55 |
| 370 | +// @property (nonatomic) MTRDeviceEssentialAttributes * essentialAttributes; |
| 371 | + |
333 | 372 | #define MTRDEVICE_SUBSCRIPTION_ATTEMPT_MIN_WAIT_SECONDS (1)
|
334 | 373 | #define MTRDEVICE_SUBSCRIPTION_ATTEMPT_MAX_WAIT_SECONDS (3600)
|
335 | 374 | @property (nonatomic) uint32_t lastSubscriptionAttemptWait;
|
@@ -1426,6 +1465,8 @@ - (void)_handleEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eventRepor
|
1426 | 1465 | BOOL isStartUpEvent = (eventPath.cluster.unsignedLongValue == MTRClusterIDTypeBasicInformationID)
|
1427 | 1466 | && (eventPath.event.unsignedLongValue == MTREventIDTypeClusterBasicInformationEventStartUpID);
|
1428 | 1467 | if (isStartUpEvent) {
|
| 1468 | + // REVIEWERS: this seems like a good place to set up / cache |
| 1469 | + // the essential device attributes - is it? |
1429 | 1470 | if (_estimatedStartTimeFromGeneralDiagnosticsUpTime) {
|
1430 | 1471 | // If UpTime was received, make use of it as mark of system start time
|
1431 | 1472 | MTR_LOG_INFO("%@ StartUp event: set estimated start time forward to %@", self,
|
@@ -1597,9 +1638,18 @@ - (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value f
|
1597 | 1638 | && isFromSubscription
|
1598 | 1639 | && !_receivingPrimingReport
|
1599 | 1640 | && AttributeHasChangesOmittedQuality(path)) {
|
1600 |
| - // Do not persist new values for Changes Omitted Quality attributes unless |
1601 |
| - // they're part of a Priming Report or from a read response. |
| 1641 | + // Do not persist new values for Changes Omitted Quality (aka C Quality) |
| 1642 | + // attributes unless they're part of a Priming Report or from a read response. |
1602 | 1643 | // (removals are OK)
|
| 1644 | + |
| 1645 | + // log when a device violates expectations for Changes Omitted Quality attributes. |
| 1646 | + MTRDeviceEssentialAttributes * attributes = [self _essentialAttributesForCurrentState]; |
| 1647 | + |
| 1648 | + using namespace chip::Tracing::DarwinFramework; |
| 1649 | + MATTER_LOG_METRIC_BEGIN(kMetricUnexpectedCQualityUpdate); |
| 1650 | + [attributes addEssentialAttributesToCurrentMetricScope]; |
| 1651 | + MATTER_LOG_METRIC_END(kMetricUnexpectedCQualityUpdate); |
| 1652 | + |
1603 | 1653 | return;
|
1604 | 1654 | }
|
1605 | 1655 |
|
@@ -3247,6 +3297,22 @@ - (void)removeClientDataForKey:(NSString *)key endpointID:(NSNumber *)endpointID
|
3247 | 3297 | [self.temporaryMetaDataCache removeObjectForKey:[NSString stringWithFormat:@"%@:%@", key, endpointID]];
|
3248 | 3298 | }
|
3249 | 3299 |
|
| 3300 | +#pragma mark Log Help |
| 3301 | + |
| 3302 | +- (MTRDeviceEssentialAttributes *)_essentialAttributesForCurrentState { |
| 3303 | + MTRClusterPath * basicInfoClusterPath = [MTRClusterPath clusterPathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeBasicInformationID)]; |
| 3304 | + MTRDeviceClusterData * basicInfoClusterData = [self _clusterDataForPath:basicInfoClusterPath]; |
| 3305 | + |
| 3306 | + NSNumber * vidObj = basicInfoClusterData.attributes[@(MTRAttributeIDTypeClusterBasicInformationAttributeVendorIDID)][MTRValueKey]; |
| 3307 | + UInt16 vendorID = vidObj.unsignedShortValue; |
| 3308 | + NSNumber * pidObj = basicInfoClusterData.attributes[@(MTRAttributeIDTypeClusterBasicInformationAttributeProductIDID)][MTRValueKey]; |
| 3309 | + UInt16 productID = pidObj.unsignedShortValue; |
| 3310 | + |
| 3311 | + BOOL usesThread = [self _deviceUsesThread]; |
| 3312 | + |
| 3313 | + return [[MTRDeviceEssentialAttributes alloc] initWithVendorID:vendorID productID:productID usesThread:usesThread]; |
| 3314 | +} |
| 3315 | + |
3250 | 3316 | @end
|
3251 | 3317 |
|
3252 | 3318 | @implementation MTRDevice (Deprecated)
|
|
0 commit comments