diff --git a/src/darwin/Framework/CHIP/MTRDefines_Internal.h b/src/darwin/Framework/CHIP/MTRDefines_Internal.h index 38de3a95f5d935..7894f31835a142 100644 --- a/src/darwin/Framework/CHIP/MTRDefines_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDefines_Internal.h @@ -111,56 +111,3 @@ typedef struct {} variable_hidden_by_mtr_hide; \ return outValue; \ } - -#ifndef MTR_OPTIONAL_ATTRIBUTE -#if __has_feature(objc_arc) -#define MTR_OPTIONAL_ATTRIBUTE(ATTRIBUTE, VALUE, DICTIONARY) \ - { \ - id valueToAdd = VALUE; \ - if (valueToAdd != nil) { \ - CFDictionarySetValue((CFMutableDictionaryRef) DICTIONARY, (CFStringRef) (__bridge const void *) ATTRIBUTE, (const void *) valueToAdd); \ - } \ - } -#else -#define MTR_OPTIONAL_ATTRIBUTE(ATTRIBUTE, VALUE, DICTIONARY) \ - { \ - id valueToAdd = VALUE; \ - if (valueToAdd != nil) { \ - CFDictionarySetValue((CFMutableDictionaryRef) DICTIONARY, (CFStringRef) (const void *) ATTRIBUTE, (const void *) valueToAdd); \ - } \ - } -#endif -#endif - -#ifndef MTR_OPTIONAL_COLLECTION_ATTRIBUTE -#define MTR_OPTIONAL_COLLECTION_ATTRIBUTE(ATTRIBUTE, COLLECTION, DICTIONARY) \ - if ([COLLECTION count] > 0) { \ - CFDictionarySetValue((CFMutableDictionaryRef) DICTIONARY, (CFStringRef) ATTRIBUTE, (const void *) COLLECTION); \ - } -#endif - -#ifndef MTR_OPTIONAL_NUMBER_ATTRIBUTE -#define MTR_OPTIONAL_NUMBER_ATTRIBUTE(ATTRIBUTE, NUMBER, DICTIONARY) \ - if ([NUMBER intValue] != 0) { \ - CFDictionarySetValue((CFMutableDictionaryRef) DICTIONARY, (CFStringRef) ATTRIBUTE, (const void *) NUMBER); \ - } -#endif - -#ifndef MTR_REMOVE_ATTRIBUTE -#define MTR_REMOVE_ATTRIBUTE(ATTRIBUTE, DICTIONARY) \ - if (ATTRIBUTE != nil && DICTIONARY) { \ - CFDictionaryRemoveValue((CFMutableDictionaryRef) DICTIONARY, (CFStringRef) ATTRIBUTE); \ - } -#endif - -#ifndef MTR_REQUIRED_ATTRIBUTE -#define MTR_REQUIRED_ATTRIBUTE(ATTRIBUTE, VALUE, DICTIONARY) \ - { \ - id valueToAdd = VALUE; \ - if (valueToAdd != nil) { \ - CFDictionarySetValue((CFMutableDictionaryRef) DICTIONARY, (CFStringRef) ATTRIBUTE, (const void *) valueToAdd); \ - } else { \ - MTR_LOG_ERROR("Warning, missing %@ to add to %s", ATTRIBUTE, #DICTIONARY); \ - } \ - } -#endif diff --git a/src/darwin/Framework/CHIP/MTRDeviceController+XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController+XPC.mm index 1cd02e24648867..87ce5560381cca 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController+XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController+XPC.mm @@ -34,13 +34,7 @@ static NSSet * GetXPCAllowedClasses() { static NSSet * const sXPCAllowedClasses = [NSSet setWithArray:@[ - [NSString class], - [NSNumber class], - [NSData class], - [NSArray class], - [NSDictionary class], - [NSError class], - [NSDate class], + [NSString class], [NSNumber class], [NSData class], [NSArray class], [NSDictionary class], [NSError class] ]]; return sXPCAllowedClasses; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.h b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.h index 87218b1f391a66..c891c10d726791 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.h @@ -27,7 +27,7 @@ MTR_TESTABLE - (id)initWithUniqueIdentifier:(NSUUID *)UUID machServiceName:(NSString *)machServiceName options:(NSXPCConnectionOptions)options #endif - @property(nullable, atomic, retain, readwrite)NSXPCConnection * xpcConnection; + @property(atomic, retain, readwrite)NSXPCConnection * xpcConnection; @end diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm index c58514ed2496ec..1bf0888ab3b2b4 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm @@ -19,7 +19,6 @@ #import "MTRDefines_Internal.h" #import "MTRDeviceController_Internal.h" #import "MTRDevice_XPC.h" -#import "MTRDevice_XPC_Internal.h" #import "MTRLogging_Internal.h" #import "MTRXPCClientProtocol.h" #import "MTRXPCServerProtocol.h" @@ -34,10 +33,7 @@ @interface MTRDeviceController_XPC () -@property (nonatomic, readwrite, retain) NSUUID * uniqueIdentifier; -@property (nonnull, atomic, readwrite, retain) MTRXPCDeviceControllerParameters * xpcParameters; -@property (atomic, readwrite, assign) NSTimeInterval xpcRetryTimeInterval; -@property (atomic, readwrite, assign) BOOL xpcConnectedOrConnecting; +@property (nonatomic, retain, readwrite) NSUUID * uniqueIdentifier; @end @@ -52,15 +48,7 @@ - (NSXPCInterface *)_interfaceForServerProtocol NSXPCInterface * interface = [NSXPCInterface interfaceWithProtocol:@protocol(MTRXPCServerProtocol)]; NSSet * allowedClasses = [NSSet setWithArray:@[ - [NSString class], - [NSNumber class], - [NSData class], - [NSArray class], - [NSDictionary class], - [NSError class], - [MTRCommandPath class], - [MTRAttributePath class], - [NSDate class], + [NSString class], [NSNumber class], [NSData class], [NSArray class], [NSDictionary class], [NSError class], [MTRCommandPath class], [MTRAttributePath class] ]]; [interface setClasses:allowedClasses @@ -74,14 +62,7 @@ - (NSXPCInterface *)_interfaceForClientProtocol { NSXPCInterface * interface = [NSXPCInterface interfaceWithProtocol:@protocol(MTRXPCClientProtocol)]; NSSet * allowedClasses = [NSSet setWithArray:@[ - [NSString class], - [NSNumber class], - [NSData class], - [NSArray class], - [NSDictionary class], - [NSError class], - [MTRAttributePath class], - [NSDate class], + [NSString class], [NSNumber class], [NSData class], [NSArray class], [NSDictionary class], [NSError class], [MTRAttributePath class] ]]; [interface setClasses:allowedClasses forSelector:@selector(device:receivedAttributeReport:) @@ -102,114 +83,6 @@ - (NSXPCInterface *)_interfaceForClientProtocol return [self.uniqueIdentifier UUIDString]; } -- (void)_startXPCConnectionRetry -{ - if (!self.xpcConnectedOrConnecting) { - MTR_LOG("%@: XPC Connection retry - Starting retry for XPC Connection", self); - self.xpcRetryTimeInterval = 0.5; - mtr_weakify(self); - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (self.xpcRetryTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - mtr_strongify(self); - [self _xpcConnectionRetry]; - }); - } else { - MTR_LOG("%@: XPC Connection retry - Not starting retry for XPC Connection, already trying", self); - } -} - -- (void)_xpcConnectionRetry -{ - MTR_LOG("%@: XPC Connection retry - timer hit", self); - if (!self.xpcConnectedOrConnecting) { - if (![self _setupXPCConnection]) { -#if 0 // FIXME: Not sure why this retry is not working, but I will fix this later - MTR_LOG("%@: XPC Connection retry - Scheduling another retry", self); - self.xpcRetryTimeInterval = self.xpcRetryTimeInterval >= 1 ? self.xpcRetryTimeInterval * 2 : 1; - self.xpcRetryTimeInterval = MIN(60.0, self.xpcRetryTimeInterval); - mtr_weakify(self); - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.xpcRetryTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - mtr_strongify(self); - [self _xpcConnectionRetry]; - }); -#else - MTR_LOG("%@: XPC Connection failed retry - bailing", self); -#endif - } else { - MTR_LOG("%@: XPC Connection retry - connection attempt successful", self); - } - } else { - MTR_LOG("%@: XPC Connection retry - Mid retry, or connected, stopping retry timer", self); - } -} - -- (BOOL)_setupXPCConnection -{ - self.xpcConnection = self.xpcParameters.xpcConnectionBlock(); - - MTR_LOG("%@ Set up XPC Connection: %@", self, self.xpcConnection); - if (self.xpcConnection) { - mtr_weakify(self); - self.xpcConnection.remoteObjectInterface = [self _interfaceForServerProtocol]; - - self.xpcConnection.exportedInterface = [self _interfaceForClientProtocol]; - self.xpcConnection.exportedObject = self; - - self.xpcConnection.interruptionHandler = ^{ - mtr_strongify(self); - MTR_LOG_ERROR("XPC Connection for device controller interrupted: %@", self.xpcParameters.uniqueIdentifier); - self.xpcConnectedOrConnecting = NO; - self.xpcConnection = nil; - [self _startXPCConnectionRetry]; - }; - - self.xpcConnection.invalidationHandler = ^{ - mtr_strongify(self); - MTR_LOG_ERROR("XPC Connection for device controller invalidated: %@", self.xpcParameters.uniqueIdentifier); - self.xpcConnectedOrConnecting = NO; - self.xpcConnection = nil; - [self _startXPCConnectionRetry]; - }; - - MTR_LOG("%@ Activating new XPC connection", self); - [self.xpcConnection activate]; - - [[self.xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - MTR_LOG_ERROR("Checkin error: %@", error); - }] deviceController:self.uniqueIdentifier checkInWithContext:[NSDictionary dictionary]]; - - // FIXME: Trying to kick all the MTRDevices attached to this controller to re-establish connections - // This state needs to be stored properly and re-established at connnection time - - MTR_LOG("%@ Starting existing NodeID Registration", self); - for (NSNumber * nodeID in [self.nodeIDToDeviceMap keyEnumerator]) { - MTR_LOG("%@ => Registering nodeID: %@", self, nodeID); - mtr_weakify(self); - - [[self.xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - mtr_strongify(self); - MTR_LOG_ERROR("%@ Registration error for device nodeID: %@ : %@", self, nodeID, error); - }] deviceController:self.uniqueIdentifier registerNodeID:nodeID]; - } - - __block BOOL barrierComplete = NO; - - [self.xpcConnection scheduleSendBarrierBlock:^{ - barrierComplete = YES; - MTR_LOG("%@: Barrier complete: %d", self, barrierComplete); - }]; - - MTR_LOG("%@ Done existing NodeID Registration, barrierComplete: %d", self, barrierComplete); - self.xpcConnectedOrConnecting = barrierComplete; - } else { - MTR_LOG_ERROR("%@ Failed to set up XPC Connection", self); - self.xpcConnectedOrConnecting = NO; - } - - return (self.xpcConnectedOrConnecting); -} - - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error { @@ -237,12 +110,30 @@ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParamete return nil; } - self.xpcParameters = xpcParameters; + self.xpcConnection = connectionBlock(); + self.uniqueIdentifier = UUID; self.chipWorkQueue = dispatch_queue_create("MTRDeviceController_XPC_queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); self.nodeIDToDeviceMap = [NSMapTable strongToWeakObjectsMapTable]; - self.uniqueIdentifier = UUID; - if (![self _setupXPCConnection]) { + MTR_LOG("Set up XPC Connection: %@", self.xpcConnection); + if (self.xpcConnection) { + self.xpcConnection.remoteObjectInterface = [self _interfaceForServerProtocol]; + + self.xpcConnection.exportedInterface = [self _interfaceForClientProtocol]; + self.xpcConnection.exportedObject = self; + + self.xpcConnection.interruptionHandler = ^{ + MTR_LOG_ERROR("XPC Connection for device controller interrupted: %@", UUID); + }; + + self.xpcConnection.invalidationHandler = ^{ + MTR_LOG_ERROR("XPC Connection for device controller invalidated: %@", UUID); + }; + + MTR_LOG("Activating new XPC connection"); + [self.xpcConnection activate]; + } else { + MTR_LOG_ERROR("Failed to set up XPC Connection"); return nil; } } @@ -268,7 +159,7 @@ - (id)initWithUniqueIdentifier:(NSUUID *)UUID machServiceName:(NSString *)machSe self.xpcConnection.exportedObject = self; MTR_LOG("%s: resuming new XPC connection"); - [self.xpcConnection activate]; + [self.xpcConnection resume]; } else { MTR_LOG_ERROR("Failed to set up XPC Connection"); return nil; @@ -286,7 +177,13 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N os_unfair_lock_assert_owner(self.deviceMapLock); MTRDevice * deviceToReturn = [[MTRDevice_XPC alloc] initWithNodeID:nodeID controller:self]; - [self.nodeIDToDeviceMap setObject:deviceToReturn forKey:nodeID]; + // If we're not running, don't add the device to our map. That would + // create a cycle that nothing would break. Just return the device, + // which will be in exactly the state it would be in if it were created + // while we were running and then we got shut down. + if ([self isRunning]) { + [self.nodeIDToDeviceMap setObject:deviceToReturn forKey:nodeID]; + } MTR_LOG("%s: returning XPC device for node id %@", __PRETTY_FUNCTION__, nodeID); return deviceToReturn; } @@ -358,14 +255,6 @@ - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID [device deviceConfigurationChanged:nodeID]; } -- (oneway void)device:(NSNumber *)nodeID internalStateUpdated:(NSDictionary *)dictionary -{ - MTRDevice_XPC * device = (MTRDevice_XPC *) [self deviceForNodeID:nodeID]; - MTR_LOG("Received internalStateUpdated: %@ found device: %@", nodeID, device); - - [device device:nodeID internalStateUpdated:dictionary]; -} - #pragma mark - MTRDeviceController Protocol Client // Not Supported via XPC diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index f554d14f9e7215..70824dd9bcd7d1 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -254,6 +254,8 @@ @interface MTRDevice_Concrete () @property (nonatomic) ReadClient * currentReadClient; @property (nonatomic) SubscriptionCallback * currentSubscriptionCallback; // valid when and only when currentReadClient is valid +@property (nonatomic, weak) id privateInternalStateDelegate; + @end // Declaring selector so compiler won't complain about testing and calling it in _handleReportEnd @@ -466,28 +468,31 @@ - (NSString *)description - (NSDictionary *)_internalProperties { - NSMutableDictionary * properties = [NSMutableDictionary dictionary]; - std::lock_guard lock(_descriptionLock); + id vidOrUnknown, pidOrUnknown; + + { + std::lock_guard lock(_descriptionLock); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyKeyVendorID, _vid, properties); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyKeyProductID, _pid, properties); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyNetworkFeatures, _allNetworkFeatures, properties); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyDeviceState, [NSNumber numberWithUnsignedInteger:_internalDeviceStateForDescription], properties); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyLastSubscriptionAttemptWait, [NSNumber numberWithUnsignedInt:_lastSubscriptionAttemptWaitForDescription], properties); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyMostRecentReportTime, _mostRecentReportTimeForDescription, properties); - MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyLastSubscriptionFailureTime, _lastSubscriptionFailureTimeForDescription, properties); + vidOrUnknown = _vid ?: @"Unknown"; + pidOrUnknown = _pid ?: @"Unknown"; + // id networkFeatures = _allNetworkFeatures; + // id internalDeviceState = _internalDeviceStateForDescription; + // id lastSubscriptionAttemptWait = _lastSubscriptionAttemptWaitForDescription; + // id mostRecentReportTime = _mostRecentReportTimeForDescription; + // id lastSubscriptionFailureTime = _lastSubscriptionFailureTimeForDescription; + } - return properties; + return @{ + kMTRDeviceInternalPropertyKeyVendorID : vidOrUnknown, + kMTRDeviceInternalPropertyKeyProductID : pidOrUnknown, + }; } -- (void)_notifyDelegateOfPrivateInternalPropertiesChanges +- (void)_notifyPrivateInternalPropertiesDelegateOfChanges { - os_unfair_lock_assert_owner(&self->_lock); - [self _callDelegatesWithBlock:^(id delegate) { - if ([delegate respondsToSelector:@selector(device:internalStateUpdated:)]) { - [delegate performSelector:@selector(device:internalStateUpdated:) withObject:self withObject:[self _internalProperties]]; - } - }]; + if ([self.privateInternalStateDelegate respondsToSelector:@selector(device:internalStateUpdated:)]) { + [self.privateInternalStateDelegate device:self.nodeID internalStateUpdated:[self _internalProperties]]; + } } #pragma mark - Time Synchronization @@ -755,8 +760,6 @@ - (void)_delegateAdded [self _setupSubscriptionWithReason:@"delegate is set and subscription is needed"]; } } - - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; } - (void)invalidate @@ -980,7 +983,7 @@ - (void)_changeInternalState:(MTRInternalDeviceState)state }]; /* END DRAGONS */ - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; } } @@ -1182,7 +1185,7 @@ - (void)_handleResubscriptionNeededWithDelay:(NSNumber *)resubscriptionDelayMs std::lock_guard lock(_descriptionLock); _lastSubscriptionFailureTimeForDescription = _lastSubscriptionFailureTime; } - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; deviceUsesThread = [self _deviceUsesThread]; // If a previous resubscription failed, remove the item from the subscription pool. @@ -1233,7 +1236,7 @@ - (void)_setLastSubscriptionAttemptWait:(uint32_t)lastSubscriptionAttemptWait _lastSubscriptionAttemptWaitForDescription = lastSubscriptionAttemptWait; } - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; } - (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay @@ -1249,7 +1252,7 @@ - (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay std::lock_guard lock(_descriptionLock); _lastSubscriptionFailureTimeForDescription = _lastSubscriptionFailureTime; } - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; // if there is no delegate then also do not retry if (![self _delegateExists]) { @@ -1307,7 +1310,6 @@ - (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay // For non-Thread-enabled devices, just call the resubscription block after the specified time dispatch_after(dispatch_time(DISPATCH_TIME_NOW, resubscriptionDelayNs), self.queue, resubscriptionBlock); } - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; } - (void)_reattemptSubscriptionNowIfNeededWithReason:(NSString *)reason @@ -1505,7 +1507,7 @@ - (void)unitTestSetMostRecentReportTimes:(NSMutableArray *)mostRecentR std::lock_guard lock(_descriptionLock); _mostRecentReportTimeForDescription = [mostRecentReportTimes lastObject]; } - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; } #endif @@ -1564,6 +1566,7 @@ - (void)_scheduleClusterDataPersistence std::lock_guard lock(_descriptionLock); _mostRecentReportTimeForDescription = [_mostRecentReportTimes lastObject]; } + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; // Calculate running average and update multiplier - need at least 2 items to calculate intervals if (_mostRecentReportTimes.count > 2) { @@ -1610,8 +1613,6 @@ - (void)_scheduleClusterDataPersistence } } - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; - // Do not schedule persistence if device is reporting excessively if ([self _deviceIsReportingExcessively]) { return; @@ -1636,6 +1637,7 @@ - (void)_resetStorageBehaviorState std::lock_guard lock(_descriptionLock); _mostRecentReportTimeForDescription = nil; } + [self _notifyPrivateInternalPropertiesDelegateOfChanges]; _deviceReportingExcessivelyStartTime = nil; _reportToPersistenceDelayCurrentMultiplier = 1; @@ -1644,8 +1646,6 @@ - (void)_resetStorageBehaviorState if ([self _dataStoreExists]) { [self _persistClusterData]; } - - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; } - (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration @@ -1699,8 +1699,6 @@ - (void)_handleReportEnd } }]; #endif - - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; } - (BOOL)_interestedPaths:(NSArray * _Nullable)interestedPaths includesAttributePath:(MTRAttributePath *)attributePath diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index baa34399bdb4d4..c3b6b60fa6314e 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -225,10 +225,6 @@ static NSString * const sLastInitialSubscribeLatencyKey = @"lastInitialSubscribe // Concrete to XPC internal state property dictionary keys static NSString * const kMTRDeviceInternalPropertyKeyVendorID = @"MTRDeviceInternalStateKeyVendorID"; static NSString * const kMTRDeviceInternalPropertyKeyProductID = @"MTRDeviceInternalStateKeyProductID"; -static NSString * const kMTRDeviceInternalPropertyNetworkFeatures = @"MTRDeviceInternalPropertyNetworkFeatures"; -static NSString * const kMTRDeviceInternalPropertyDeviceState = @"MTRDeviceInternalPropertyDeviceState"; -static NSString * const kMTRDeviceInternalPropertyLastSubscriptionAttemptWait = @"kMTRDeviceInternalPropertyLastSubscriptionAttemptWait"; -static NSString * const kMTRDeviceInternalPropertyMostRecentReportTime = @"MTRDeviceInternalPropertyMostRecentReportTime"; -static NSString * const kMTRDeviceInternalPropertyLastSubscriptionFailureTime = @"MTRDeviceInternalPropertyLastSubscriptionFailureTime"; +// TODO: more internal properties NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index 5279933104a11c..7267eb3a2b4f7e 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -103,35 +103,32 @@ - (void)dealloc - (NSString *)description { - NSString * wifi; - NSString * thread; - NSNumber * networkFeatures = [self._internalState objectForKey:kMTRDeviceInternalPropertyNetworkFeatures]; + // TODO: Figure out whether, and if so how, to log: VID, PID, WiFi, Thread, + // internalDeviceState (do we even have such a thing here?), last + // subscription attempt wait (does that apply to us?) queued work (do we + // have any?), last report, last subscription failure (does that apply to us?). + return [NSString + stringWithFormat:@"<%@: %p, node: %016llX-%016llX (%llu), VID: %@, PID: %@, controller: %@>", NSStringFromClass(self.class), self, _deviceController.compressedFabricID.unsignedLongLongValue, _nodeID.unsignedLongLongValue, _nodeID.unsignedLongLongValue, [self _vid], [self _pid], _deviceController.uniqueIdentifier]; +} - if (networkFeatures == nil) { - wifi = @"NO"; - thread = @"NO"; +- (nullable NSNumber *)_internalStateNumberOrNilForKey:(NSString *)key +{ + if ([_internalState[key] isKindOfClass:NSNumber.class]) { + NSNumber * number = _internalState[key]; + return number; } else { - wifi = YES_NO(networkFeatures.unsignedLongLongValue & MTRNetworkCommissioningFeatureWiFiNetworkInterface); - thread = YES_NO(networkFeatures.unsignedLongLongValue & MTRNetworkCommissioningFeatureThreadNetworkInterface); + return nil; } +} - // TODO: Add these to the description - // MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyDeviceState, _internalDeviceStateForDescription, properties); - // MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyLastSubscriptionAttemptWait, _lastSubscriptionAttemptWaitForDescription, properties); - // MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyMostRecentReportTime, _mostRecentReportTimeForDescription, properties); - // MTR_OPTIONAL_ATTRIBUTE(kMTRDeviceInternalPropertyLastSubscriptionFailureTime, _lastSubscriptionFailureTimeForDescription, properties); +- (nullable NSNumber *)_vid +{ + return [self _internalStateNumberOrNilForKey:kMTRDeviceInternalPropertyKeyVendorID]; +} - return [NSString - stringWithFormat:@"<%@: %p, node: %016llX-%016llX (%llu), VID: %@, PID: %@, WiFi: %@, Thread: %@, controller: %@>", - NSStringFromClass(self.class), self, - _deviceController.compressedFabricID.unsignedLongLongValue, - _nodeID.unsignedLongLongValue, - _nodeID.unsignedLongLongValue, - [self._internalState objectForKey:kMTRDeviceInternalPropertyKeyVendorID], - [self._internalState objectForKey:kMTRDeviceInternalPropertyKeyProductID], - wifi, - thread, - _deviceController.uniqueIdentifier]; +- (nullable NSNumber *)_pid +{ + return [self _internalStateNumberOrNilForKey:kMTRDeviceInternalPropertyKeyProductID]; } #pragma mark - Client Callbacks (MTRDeviceDelegate) @@ -190,12 +187,6 @@ - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID }]; } -- (oneway void)device:(NSNumber *)nodeID internalStateUpdated:(NSDictionary *)dictionary -{ - [self _setInternalState:dictionary]; - MTR_LOG("%@ internal state updated", self); -} - #pragma mark - Remote Commands MTR_DEVICE_SIMPLE_REMOTE_XPC_GETTER(state, MTRDeviceState, MTRDeviceStateUnknown, getStateWithReply) diff --git a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCClientProtocol.h b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCClientProtocol.h index cfa59db8a73303..b26b6d88849193 100644 --- a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCClientProtocol.h +++ b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCClientProtocol.h @@ -27,6 +27,9 @@ MTR_NEWLY_AVAILABLE - (oneway void)deviceBecameActive:(NSNumber *)nodeID; - (oneway void)deviceCachePrimed:(NSNumber *)nodeID; - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID; + +@optional +// temporarily optional to avoid lockstep needs - (oneway void)device:(NSNumber *)nodeID internalStateUpdated:(NSDictionary *)dictionary; @end diff --git a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h index 52a5d2228fa524..1ebdea5d3757ec 100644 --- a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h +++ b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h @@ -70,6 +70,9 @@ MTR_NEWLY_AVAILABLE //- (oneway void)deviceController:(NSUUID *)controller removeServerEndpoint:(MTRServerEndpoint *)endpoint; - (oneway void)deviceController:(NSUUID *)controller shutdownDeviceController:(NSUUID *)controller; + +@optional +// register / unregister temporarily optional to avoid lockstep needs - (oneway void)deviceController:(NSUUID *)controller registerNodeID:(NSNumber *)nodeID; - (oneway void)deviceController:(NSUUID *)controller unregisterNodeID:(NSNumber *)nodeID;