From 23dc3a6544cd932b1d1efed8e68e4ff30b22ce4b Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 17 Mar 2023 12:09:53 +0900 Subject: [PATCH 01/72] Implement darwin multiple attribute, event read / subscribe --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 118 +++--- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 465 +++++++++++++++++++++ 2 files changed, 530 insertions(+), 53 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 29ae7bded47e8a..2a18f5a0a4b459 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -130,6 +130,59 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { MTRTransportTypeTCP, } API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +/** + * A path indicating a specific cluster on a device (i.e. without any + * wildcards). + */ +API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) +@interface MTRClusterPath : NSObject +@property (nonatomic, readonly, copy) NSNumber * endpoint; +@property (nonatomic, readonly, copy) NSNumber * cluster; + ++ (MTRClusterPath *)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +@end + +/** + * A path indicating a specific attribute on a device (i.e. without any + * wildcards). + */ +@interface MTRAttributePath : MTRClusterPath +@property (nonatomic, readonly, copy) NSNumber * attribute; + ++ (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID + clusterID:(NSNumber *)clusterID + attributeID:(NSNumber *)attributeID + API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@end + +/** + * A path indicating a specific event that can be emitted on a device + * (i.e. without any wildcards). There can be multiple instances of actual + * events for a given event path. + */ +@interface MTREventPath : MTRClusterPath +@property (nonatomic, readonly, copy) NSNumber * event; + ++ (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID + clusterID:(NSNumber *)clusterID + eventID:(NSNumber *)eventID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@end + +/** + * A path indicating a specific command on a device (i.e. without any + * wildcards). + */ +@interface MTRCommandPath : MTRClusterPath +@property (nonatomic, readonly, copy) NSNumber * command; + ++ (MTRCommandPath *)commandPathWithEndpointID:(NSNumber *)endpointID + clusterID:(NSNumber *)clusterID + commandID:(NSNumber *)commandID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@end + @interface MTRBaseDevice : NSObject - (instancetype)init NS_UNAVAILABLE; @@ -229,6 +282,18 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { completion:(MTRDeviceResponseHandler)completion API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths + params:(MTRReadParams * _Nullable)params + queue:(dispatch_queue_t)queue + completion:(MTRDeviceResponseHandler)completion; + +- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths + params:(MTRSubscribeParams * _Nullable)params + queue:(dispatch_queue_t)queue + reportHandler:(MTRDeviceResponseHandler)reportHandler + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished; /** * Write to attribute in a designated attribute path * @@ -387,59 +452,6 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @end -/** - * A path indicating a specific cluster on a device (i.e. without any - * wildcards). - */ -API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) -@interface MTRClusterPath : NSObject -@property (nonatomic, readonly, copy) NSNumber * endpoint; -@property (nonatomic, readonly, copy) NSNumber * cluster; - -+ (MTRClusterPath *)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; - -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; -@end - -/** - * A path indicating a specific attribute on a device (i.e. without any - * wildcards). - */ -@interface MTRAttributePath : MTRClusterPath -@property (nonatomic, readonly, copy) NSNumber * attribute; - -+ (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID - clusterID:(NSNumber *)clusterID - attributeID:(NSNumber *)attributeID - API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -@end - -/** - * A path indicating a specific event that can be emitted on a device - * (i.e. without any wildcards). There can be multiple instances of actual - * events for a given event path. - */ -@interface MTREventPath : MTRClusterPath -@property (nonatomic, readonly, copy) NSNumber * event; - -+ (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID - clusterID:(NSNumber *)clusterID - eventID:(NSNumber *)eventID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -@end - -/** - * A path indicating a specific command on a device (i.e. without any - * wildcards). - */ -@interface MTRCommandPath : MTRClusterPath -@property (nonatomic, readonly, copy) NSNumber * command; - -+ (MTRCommandPath *)commandPathWithEndpointID:(NSNumber *)endpointID - clusterID:(NSNumber *)clusterID - commandID:(NSNumber *)commandID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -@end - @interface MTRAttributeReport : NSObject @property (nonatomic, readonly, copy) MTRAttributePath * path; // value is nullable because nullable attributes can have nil as value. diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index ea47734e3facf6..b02299edd5f212 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -80,7 +80,9 @@ @interface MTRReadClientContainer : NSObject @property (nonatomic, readwrite) app::ReadClient * readClientPtr; @property (nonatomic, readwrite) app::AttributePathParams * pathParams; +@property (nonatomic, readwrite) size_t pathParamsSize; @property (nonatomic, readwrite) app::EventPathParams * eventPathParams; +@property (nonatomic, readwrite) size_t eventPathParamsSize; @property (nonatomic, readwrite) uint64_t deviceID; - (void)onDone; @end @@ -225,6 +227,12 @@ - (void)onDone if (_pathParams) { Platform::Delete(_pathParams); _pathParams = nullptr; + _pathParamsSize = 0; + } + if (_eventPathParams) { + Platform::Delete(_eventPathParams); + _eventPathParams = nullptr; + _eventPathParamsSize = 0; } PurgeCompletedReadClientContainers(_deviceID); } @@ -238,6 +246,12 @@ - (void)dealloc if (_pathParams) { Platform::Delete(_pathParams); _pathParams = nullptr; + _pathParamsSize = 0; + } + if (_eventPathParams) { + Platform::Delete(_eventPathParams); + _eventPathParams = nullptr; + _eventPathParamsSize = 0; } } @end @@ -833,6 +847,105 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr Platform::UniquePtr mReadClient; }; +template class BufferedMultipleReadClientCallback final : public app::ReadClient::Callback { +public: + using OnSuccessAttributeCallbackType + = std::function; + using OnSuccessEventCallbackType + = std::function; + using OnErrorCallbackType + = std::function; + using OnDoneCallbackType = std::function; + using OnSubscriptionEstablishedCallbackType = std::function; + + BufferedMultipleReadClientCallback(OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, + OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, + OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) + : mOnAttributeSuccess(aOnAttributeSuccess) + , mOnEventSuccess(aOnEventSuccess) + , mOnError(aOnError) + , mOnDone(aOnDone) + , mOnSubscriptionEstablished(aOnSubscriptionEstablished) + , mBufferedReadAdapter(*this) + { + } + + ~BufferedMultipleReadClientCallback() + { + // Ensure we release the ReadClient before we tear down anything else, + // so it can call our OnDeallocatePaths properly. + mReadClient = nullptr; + } + + app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; } + + void AdoptReadClient(Platform::UniquePtr aReadClient) { mReadClient = std::move(aReadClient); } + +private: + void OnAttributeData( + const app::ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const app::StatusIB & aStatus) override + { + CHIP_ERROR err = CHIP_NO_ERROR; + DecodableValueType value; + + // + // We shouldn't be getting list item operations in the provided path since that should be handled by the buffered read + // callback. If we do, that's a bug. + // + VerifyOrDie(!aPath.IsListItemOperation()); + + VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); + VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + SuccessOrExit(err = app::DataModel::Decode(*apData, value)); + + mOnAttributeSuccess(aPath, aPath.mAttributeId, value); + + exit: + if (err != CHIP_NO_ERROR) { + mOnError(&aPath, aPath.mAttributeId, err); + } + } + + void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus) override + { + CHIP_ERROR err = CHIP_NO_ERROR; + DecodableValueType value; + + VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + SuccessOrExit(err = app::DataModel::Decode(*apData, value)); + + mOnEventSuccess(aEventHeader.mPath, aEventHeader.mPath.mEventId, value); + + exit: + if (err != CHIP_NO_ERROR) { + mOnError(&aEventHeader.mPath, aEventHeader.mPath.mEventId, err); + } + } + + void OnError(CHIP_ERROR aError) override { mOnError(nullptr, kInvalidAttributeId, aError); } + + void OnDone(ReadClient *) override { mOnDone(this); } + + void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override + { + if (mOnSubscriptionEstablished) { + mOnSubscriptionEstablished(); + } + } + + void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override {} + + OnSuccessAttributeCallbackType mOnAttributeSuccess; + OnSuccessEventCallbackType mOnEventSuccess; + OnErrorCallbackType mOnError; + OnDoneCallbackType mOnDone; + OnSubscriptionEstablishedCallbackType mOnSubscriptionEstablished; + app::BufferedReadCallback mBufferedReadAdapter; + Platform::UniquePtr mReadClient; +}; + - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID attributeID:(NSNumber * _Nullable)attributeID @@ -934,6 +1047,356 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID std::move(*bridge).DispatchAction(self); } +- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths + params:(MTRReadParams * _Nullable)params + queue:(dispatch_queue_t)queue + completion:(MTRDeviceResponseHandler)completion +{ + attributePaths = (attributePaths == nil) ? nil : [attributePaths copy]; + eventPaths = (eventPaths == nil) ? nil : [eventPaths copy]; + params = (params == nil) ? nil : [params copy]; + auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, + ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, + MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + // interactionStatus tracks whether the whole read interaction has failed. + // + // Make sure interactionStatus survives even if this block scope is destroyed. + auto interactionStatus = std::make_shared(CHIP_NO_ERROR); + + auto resultArray = [[NSMutableArray alloc] init]; + auto onAttributeSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, + const MTRDataValueDictionaryDecodableType & aData) { + app::ConcreteAttributePath attribPath(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); + [resultArray addObject:@ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], + MTRDataKey : aData.GetDecodedObject() + }]; + }; + + auto onEventSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const EventId aEventId, + const MTRDataValueDictionaryDecodableType & aData) { + app::ConcreteEventPath eventPath(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); + [resultArray addObject:@ { + MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], + MTRDataKey : aData.GetDecodedObject() + }]; + }; + + auto onFailureCb = [resultArray, interactionStatus]( + const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { + if (clusterPath) { + app::ConcreteAttributePath attribPath(clusterPath->mEndpointId, clusterPath->mClusterId, aValueId); + [resultArray addObject:@ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], + MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] + }]; + } else { + // This will only happen once per read interaction, and + // after that there will be no more calls to onFailureCb or + // onSuccessCb. + *interactionStatus = aError; + } + }; + + std::vector attributePathParamsList; + std::vector eventPathParamsList; + + if (attributePaths != nil) + { + for (uint8_t i = 0 ; i < [attributePaths count] ; i++) + { + chip::EndpointId endpointId = kInvalidEndpointId; + chip::ClusterId clusterId = kInvalidClusterId; + chip::AttributeId attributeId = kInvalidAttributeId; + + if ([attributePaths[i] endpoint]) + { + endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); + } + + if ([attributePaths[i] cluster]) + { + clusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + } + + if ([attributePaths[i] attribute]) + { + attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + } + attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); + } + } + + if (eventPaths != nil) + { + for (uint8_t i = 0 ; i < [eventPaths count] ; i++) + { + chip::EndpointId endpointId = kInvalidEndpointId; + chip::ClusterId clusterId = kInvalidClusterId; + chip::EventId eventId = kInvalidEventId; + + if ([eventPaths[i] endpoint]) + { + endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); + } + + if ([eventPaths[i] cluster]) + { + clusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); + } + + if ([eventPaths[i] event]) + { + eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); + } + eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); + } + } + + app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::app::ReadPrepareParams readParams(session); + [params toReadPrepareParams:readParams]; + readParams.mpAttributePathParamsList = attributePathParamsList.data(); + readParams.mAttributePathParamsListSize = attributePathParamsList.size(); + readParams.mpEventPathParamsList = eventPathParamsList.data(); + readParams.mEventPathParamsListSize = eventPathParamsList.size(); + + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( + BufferedMultipleReadClientCallback * callback) { + if (*interactionStatus != CHIP_NO_ERROR) { + // Failure + failureCb(bridge, *interactionStatus); + } else { + // Success + successCb(bridge, resultArray); + } + chip::Platform::Delete(callback); + }; + + auto callback = chip::Platform::MakeUnique>(onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); + VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); + + auto readClient = chip::Platform::MakeUnique( + engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); + VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); + + err = readClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) { + return err; + } + + // + // At this point, we'll get a callback through the OnDone callback above regardless of success or failure + // of the read operation to permit us to free up the callback object. So, release ownership of the callback + // object now to prevent it from being reclaimed at the end of this scoped block. + // + callback->AdoptReadClient(std::move(readClient)); + callback.release(); + return err; + }); + std::move(*bridge).DispatchAction(self); +} + +- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths + params:(MTRSubscribeParams * _Nullable)params + queue:(dispatch_queue_t)queue + reportHandler:(MTRDeviceResponseHandler)reportHandler + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished +{ + if (self.isPASEDevice) { + // We don't support subscriptions over PASE. + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); + }); + return; + } + + // Copy params before going async. + attributePaths = (attributePaths == nil) ? nil : [attributePaths copy]; + eventPaths = (eventPaths == nil) ? nil : [eventPaths copy]; + params = (params == nil) ? nil : [params copy]; + + [self.deviceController + getSessionForNode:self.nodeID + completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, + NSError * _Nullable error) { + if (error != nil) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, error); + }); + } + return; + } + + auto onAttributeReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, + const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + app::ConcreteAttributePath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); + dispatch_async(queue, ^{ + reportHandler(@[ @ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], + MTRDataKey : valueObject + } ], + nil); + }); + }; + + auto onEventReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const EventId aEventId, + const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + app::ConcreteEventPath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); + dispatch_async(queue, ^{ + reportHandler(@[ @ { + MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], + MTRDataKey : valueObject + } ], + nil); + }); + }; + + auto establishedOrFailed = chip::Platform::MakeShared(NO); + auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( + const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR error) { + if (!(*establishedOrFailed)) { + *establishedOrFailed = YES; + if (subscriptionEstablished) { + dispatch_async(queue, subscriptionEstablished); + } + } + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); + }); + } + }; + + auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { + if (*establishedOrFailed) { + return; + } + *establishedOrFailed = YES; + if (subscriptionEstablished) { + dispatch_async(queue, subscriptionEstablished); + } + }; + + MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; + container.deviceID = self.nodeID; + + if (attributePaths != nil) + { + container.pathParamsSize = [attributePaths count]; + container.pathParams = static_cast(Platform::MemoryCalloc(sizeof(app::AttributePathParams), container.pathParamsSize)); + for (uint8_t i = 0 ; i < container.pathParamsSize ; i++) + { + container.pathParams[i].mEndpointId = kInvalidEndpointId; + container.pathParams[i].mClusterId = kInvalidClusterId; + container.pathParams[i].mAttributeId = kInvalidAttributeId; + + if ([attributePaths[i] endpoint]) + { + container.pathParams[i].mEndpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); + } + + if ([attributePaths[i] cluster]) + { + container.pathParams[i].mClusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + } + + if ([attributePaths[i] attribute]) + { + container.pathParams[i].mAttributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + } + } + } + if (eventPaths != nil) + { + container.eventPathParamsSize = [eventPaths count]; + container.eventPathParams = static_cast(Platform::MemoryCalloc(sizeof(app::EventPathParams), container.eventPathParamsSize)); + for (uint8_t i = 0 ; i < container.eventPathParamsSize ; i++) + { + container.eventPathParams[i].mEndpointId = kInvalidEndpointId; + container.eventPathParams[i].mClusterId = kInvalidClusterId; + container.eventPathParams[i].mEventId = kInvalidEventId; + + if ([eventPaths[i] endpoint]) + { + container.eventPathParams[i].mEndpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); + } + + if ([eventPaths[i] cluster]) + { + container.eventPathParams[i].mClusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); + } + + if ([eventPaths[i] event]) + { + container.eventPathParams[i].mEventId = static_cast([[eventPaths[i] event] unsignedLongValue]); + } + } + } + + app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::app::ReadPrepareParams readParams(session.Value()); + [params toReadPrepareParams:readParams]; + readParams.mpAttributePathParamsList = container.pathParams; + readParams.mAttributePathParamsListSize = container.pathParamsSize; + readParams.mpEventPathParamsList = container.eventPathParams; + readParams.mEventPathParamsListSize = container.eventPathParamsSize; + + auto onDone = [container](BufferedMultipleReadClientCallback * callback) { + [container onDone]; + // Make sure we delete callback last, because doing that actually destroys our + // lambda, so we can't access captured values after that. + chip::Platform::Delete(callback); + }; + + auto callback = chip::Platform::MakeUnique>(onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); + + auto readClient = Platform::New( + engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); + + if (!params.resubscribeAutomatically) { + err = readClient->SendRequest(readParams); + } else { + err = readClient->SendAutoResubscribeRequest(std::move(readParams)); + } + + if (err != CHIP_NO_ERROR) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); + }); + } + Platform::Delete(readClient); + if (container.pathParams != nullptr) + { + Platform::Delete(container.pathParams); + } + + if (container.eventPathParams != nullptr) + { + Platform::Delete(container.eventPathParams); + } + container.pathParams = nullptr; + return; + } + + // Read clients will be purged when deregistered. + container.readClientPtr = readClient; + AddReadClientContainer(container.deviceID, container); + callback.release(); + }]; +} + - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID @@ -1210,6 +1673,7 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; container.pathParams = Platform::New(); + container.pathParamsSize = 1; if (endpointID) { container.pathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); } @@ -1637,6 +2101,7 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; container.eventPathParams = Platform::New(); + container.eventPathParamsSize = 1; if (endpointID) { container.eventPathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); } From fce7525ba969f53d83407517c3316fdd2a1a2ab7 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 17 Mar 2023 12:13:24 +0900 Subject: [PATCH 02/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 546 ++++++++++----------- 1 file changed, 267 insertions(+), 279 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index b02299edd5f212..7f36640b97240d 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -849,8 +849,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr template class BufferedMultipleReadClientCallback final : public app::ReadClient::Callback { public: - using OnSuccessAttributeCallbackType - = std::function; + using OnSuccessAttributeCallbackType = std::function; using OnSuccessEventCallbackType = std::function; using OnErrorCallbackType @@ -858,8 +858,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; - BufferedMultipleReadClientCallback(OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, - OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, + BufferedMultipleReadClientCallback(OnSuccessAttributeCallbackType aOnAttributeSuccess, + OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) : mOnAttributeSuccess(aOnAttributeSuccess) , mOnEventSuccess(aOnEventSuccess) @@ -1059,145 +1059,136 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - // interactionStatus tracks whether the whole read interaction has failed. - // - // Make sure interactionStatus survives even if this block scope is destroyed. - auto interactionStatus = std::make_shared(CHIP_NO_ERROR); - - auto resultArray = [[NSMutableArray alloc] init]; - auto onAttributeSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, - const MTRDataValueDictionaryDecodableType & aData) { - app::ConcreteAttributePath attribPath(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); - [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; - - auto onEventSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const EventId aEventId, - const MTRDataValueDictionaryDecodableType & aData) { - app::ConcreteEventPath eventPath(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); - [resultArray addObject:@ { - MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; - - auto onFailureCb = [resultArray, interactionStatus]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { - if (clusterPath) { - app::ConcreteAttributePath attribPath(clusterPath->mEndpointId, clusterPath->mClusterId, aValueId); + // interactionStatus tracks whether the whole read interaction has failed. + // + // Make sure interactionStatus survives even if this block scope is destroyed. + auto interactionStatus = std::make_shared(CHIP_NO_ERROR); + + auto resultArray = [[NSMutableArray alloc] init]; + auto onAttributeSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, + const MTRDataValueDictionaryDecodableType & aData) { + app::ConcreteAttributePath attribPath(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); [resultArray addObject:@ { MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], - MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] + MTRDataKey : aData.GetDecodedObject() }]; - } else { - // This will only happen once per read interaction, and - // after that there will be no more calls to onFailureCb or - // onSuccessCb. - *interactionStatus = aError; - } - }; - - std::vector attributePathParamsList; - std::vector eventPathParamsList; - - if (attributePaths != nil) - { - for (uint8_t i = 0 ; i < [attributePaths count] ; i++) - { - chip::EndpointId endpointId = kInvalidEndpointId; - chip::ClusterId clusterId = kInvalidClusterId; - chip::AttributeId attributeId = kInvalidAttributeId; - - if ([attributePaths[i] endpoint]) - { - endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); - } + }; + + auto onEventSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const EventId aEventId, + const MTRDataValueDictionaryDecodableType & aData) { + app::ConcreteEventPath eventPath(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); + [resultArray addObject:@ { + MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], + MTRDataKey : aData.GetDecodedObject() + }]; + }; - if ([attributePaths[i] cluster]) - { - clusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + auto onFailureCb = [resultArray, interactionStatus]( + const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { + if (clusterPath) { + app::ConcreteAttributePath attribPath(clusterPath->mEndpointId, clusterPath->mClusterId, aValueId); + [resultArray addObject:@ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], + MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] + }]; + } else { + // This will only happen once per read interaction, and + // after that there will be no more calls to onFailureCb or + // onSuccessCb. + *interactionStatus = aError; } + }; + + std::vector attributePathParamsList; + std::vector eventPathParamsList; - if ([attributePaths[i] attribute]) - { - attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + if (attributePaths != nil) { + for (uint8_t i = 0; i < [attributePaths count]; i++) { + chip::EndpointId endpointId = kInvalidEndpointId; + chip::ClusterId clusterId = kInvalidClusterId; + chip::AttributeId attributeId = kInvalidAttributeId; + + if ([attributePaths[i] endpoint]) { + endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); + } + + if ([attributePaths[i] cluster]) { + clusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + } + + if ([attributePaths[i] attribute]) { + attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + } + attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); } - attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); } - } - if (eventPaths != nil) - { - for (uint8_t i = 0 ; i < [eventPaths count] ; i++) - { - chip::EndpointId endpointId = kInvalidEndpointId; - chip::ClusterId clusterId = kInvalidClusterId; - chip::EventId eventId = kInvalidEventId; - - if ([eventPaths[i] endpoint]) - { - endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); - } + if (eventPaths != nil) { + for (uint8_t i = 0; i < [eventPaths count]; i++) { + chip::EndpointId endpointId = kInvalidEndpointId; + chip::ClusterId clusterId = kInvalidClusterId; + chip::EventId eventId = kInvalidEventId; - if ([eventPaths[i] cluster]) - { - clusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); - } + if ([eventPaths[i] endpoint]) { + endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); + } - if ([eventPaths[i] event]) - { - eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); + if ([eventPaths[i] cluster]) { + clusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); + } + + if ([eventPaths[i] event]) { + eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); + } + eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); } - eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); } - } - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; + app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); + CHIP_ERROR err = CHIP_NO_ERROR; - chip::app::ReadPrepareParams readParams(session); - [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = attributePathParamsList.data(); - readParams.mAttributePathParamsListSize = attributePathParamsList.size(); - readParams.mpEventPathParamsList = eventPathParamsList.data(); - readParams.mEventPathParamsListSize = eventPathParamsList.size(); - - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( - BufferedMultipleReadClientCallback * callback) { - if (*interactionStatus != CHIP_NO_ERROR) { - // Failure - failureCb(bridge, *interactionStatus); - } else { - // Success - successCb(bridge, resultArray); - } - chip::Platform::Delete(callback); - }; + chip::app::ReadPrepareParams readParams(session); + [params toReadPrepareParams:readParams]; + readParams.mpAttributePathParamsList = attributePathParamsList.data(); + readParams.mAttributePathParamsListSize = attributePathParamsList.size(); + readParams.mpEventPathParamsList = eventPathParamsList.data(); + readParams.mEventPathParamsListSize = eventPathParamsList.size(); - auto callback = chip::Platform::MakeUnique>(onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); - VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( + BufferedMultipleReadClientCallback * callback) { + if (*interactionStatus != CHIP_NO_ERROR) { + // Failure + failureCb(bridge, *interactionStatus); + } else { + // Success + successCb(bridge, resultArray); + } + chip::Platform::Delete(callback); + }; - auto readClient = chip::Platform::MakeUnique( - engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); - VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); + auto callback = chip::Platform::MakeUnique>( + onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); + VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); - err = readClient->SendRequest(readParams); + auto readClient = chip::Platform::MakeUnique( + engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); + VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); - if (err != CHIP_NO_ERROR) { - return err; - } + err = readClient->SendRequest(readParams); - // - // At this point, we'll get a callback through the OnDone callback above regardless of success or failure - // of the read operation to permit us to free up the callback object. So, release ownership of the callback - // object now to prevent it from being reclaimed at the end of this scoped block. - // - callback->AdoptReadClient(std::move(readClient)); - callback.release(); - return err; - }); + if (err != CHIP_NO_ERROR) { + return err; + } + + // + // At this point, we'll get a callback through the OnDone callback above regardless of success or failure + // of the read operation to permit us to free up the callback object. So, release ownership of the callback + // object now to prevent it from being reclaimed at the end of this scoped block. + // + callback->AdoptReadClient(std::move(readClient)); + callback.release(); + return err; + }); std::move(*bridge).DispatchAction(self); } @@ -1224,177 +1215,174 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att [self.deviceController getSessionForNode:self.nodeID completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, - NSError * _Nullable error) { - if (error != nil) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, error); - }); - } - return; - } + NSError * _Nullable error) { + if (error != nil) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, error); + }); + } + return; + } - auto onAttributeReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - app::ConcreteAttributePath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); - dispatch_async(queue, ^{ - reportHandler(@[ @ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], - MTRDataKey : valueObject - } ], - nil); - }); - }; + auto onAttributeReportCb + = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, + const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + app::ConcreteAttributePath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); + dispatch_async(queue, ^{ + reportHandler(@[ @ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], + MTRDataKey : valueObject + } ], + nil); + }); + }; + + auto onEventReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, + const EventId aEventId, const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + app::ConcreteEventPath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); + dispatch_async(queue, ^{ + reportHandler( + @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], MTRDataKey : valueObject } ], + nil); + }); + }; - auto onEventReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const EventId aEventId, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - app::ConcreteEventPath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); - dispatch_async(queue, ^{ - reportHandler(@[ @ { - MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], - MTRDataKey : valueObject - } ], - nil); - }); - }; - - auto establishedOrFailed = chip::Platform::MakeShared(NO); - auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR error) { - if (!(*establishedOrFailed)) { - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - } - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); - }); - } - }; - - auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { - if (*establishedOrFailed) { - return; - } - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - }; - - MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; - container.deviceID = self.nodeID; - - if (attributePaths != nil) - { - container.pathParamsSize = [attributePaths count]; - container.pathParams = static_cast(Platform::MemoryCalloc(sizeof(app::AttributePathParams), container.pathParamsSize)); - for (uint8_t i = 0 ; i < container.pathParamsSize ; i++) - { - container.pathParams[i].mEndpointId = kInvalidEndpointId; - container.pathParams[i].mClusterId = kInvalidClusterId; - container.pathParams[i].mAttributeId = kInvalidAttributeId; - - if ([attributePaths[i] endpoint]) - { - container.pathParams[i].mEndpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); - } + auto establishedOrFailed = chip::Platform::MakeShared(NO); + auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( + const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR error) { + if (!(*establishedOrFailed)) { + *establishedOrFailed = YES; + if (subscriptionEstablished) { + dispatch_async(queue, subscriptionEstablished); + } + } + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); + }); + } + }; - if ([attributePaths[i] cluster]) - { - container.pathParams[i].mClusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); - } + auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { + if (*establishedOrFailed) { + return; + } + *establishedOrFailed = YES; + if (subscriptionEstablished) { + dispatch_async(queue, subscriptionEstablished); + } + }; - if ([attributePaths[i] attribute]) - { - container.pathParams[i].mAttributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); - } - } - } - if (eventPaths != nil) - { - container.eventPathParamsSize = [eventPaths count]; - container.eventPathParams = static_cast(Platform::MemoryCalloc(sizeof(app::EventPathParams), container.eventPathParamsSize)); - for (uint8_t i = 0 ; i < container.eventPathParamsSize ; i++) - { - container.eventPathParams[i].mEndpointId = kInvalidEndpointId; - container.eventPathParams[i].mClusterId = kInvalidClusterId; - container.eventPathParams[i].mEventId = kInvalidEventId; - - if ([eventPaths[i] endpoint]) - { - container.eventPathParams[i].mEndpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); - } + MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; + container.deviceID = self.nodeID; - if ([eventPaths[i] cluster]) - { - container.eventPathParams[i].mClusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); - } + if (attributePaths != nil) { + container.pathParamsSize = [attributePaths count]; + container.pathParams = static_cast( + Platform::MemoryCalloc(sizeof(app::AttributePathParams), container.pathParamsSize)); + for (uint8_t i = 0; i < container.pathParamsSize; i++) { + container.pathParams[i].mEndpointId = kInvalidEndpointId; + container.pathParams[i].mClusterId = kInvalidClusterId; + container.pathParams[i].mAttributeId = kInvalidAttributeId; + + if ([attributePaths[i] endpoint]) { + container.pathParams[i].mEndpointId + = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); + } - if ([eventPaths[i] event]) - { - container.eventPathParams[i].mEventId = static_cast([[eventPaths[i] event] unsignedLongValue]); - } - } - } + if ([attributePaths[i] cluster]) { + container.pathParams[i].mClusterId + = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + } - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; + if ([attributePaths[i] attribute]) { + container.pathParams[i].mAttributeId + = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + } + } + } + if (eventPaths != nil) { + container.eventPathParamsSize = [eventPaths count]; + container.eventPathParams = static_cast( + Platform::MemoryCalloc(sizeof(app::EventPathParams), container.eventPathParamsSize)); + for (uint8_t i = 0; i < container.eventPathParamsSize; i++) { + container.eventPathParams[i].mEndpointId = kInvalidEndpointId; + container.eventPathParams[i].mClusterId = kInvalidClusterId; + container.eventPathParams[i].mEventId = kInvalidEventId; + + if ([eventPaths[i] endpoint]) { + container.eventPathParams[i].mEndpointId + = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); + } - chip::app::ReadPrepareParams readParams(session.Value()); - [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = container.pathParams; - readParams.mAttributePathParamsListSize = container.pathParamsSize; - readParams.mpEventPathParamsList = container.eventPathParams; - readParams.mEventPathParamsListSize = container.eventPathParamsSize; + if ([eventPaths[i] cluster]) { + container.eventPathParams[i].mClusterId + = static_cast([[eventPaths[i] cluster] unsignedLongValue]); + } - auto onDone = [container](BufferedMultipleReadClientCallback * callback) { - [container onDone]; - // Make sure we delete callback last, because doing that actually destroys our - // lambda, so we can't access captured values after that. - chip::Platform::Delete(callback); - }; + if ([eventPaths[i] event]) { + container.eventPathParams[i].mEventId + = static_cast([[eventPaths[i] event] unsignedLongValue]); + } + } + } - auto callback = chip::Platform::MakeUnique>(onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); + app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); + CHIP_ERROR err = CHIP_NO_ERROR; - auto readClient = Platform::New( - engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); + chip::app::ReadPrepareParams readParams(session.Value()); + [params toReadPrepareParams:readParams]; + readParams.mpAttributePathParamsList = container.pathParams; + readParams.mAttributePathParamsListSize = container.pathParamsSize; + readParams.mpEventPathParamsList = container.eventPathParams; + readParams.mEventPathParamsListSize = container.eventPathParamsSize; - if (!params.resubscribeAutomatically) { - err = readClient->SendRequest(readParams); - } else { - err = readClient->SendAutoResubscribeRequest(std::move(readParams)); - } + auto onDone = [container](BufferedMultipleReadClientCallback * callback) { + [container onDone]; + // Make sure we delete callback last, because doing that actually destroys our + // lambda, so we can't access captured values after that. + chip::Platform::Delete(callback); + }; - if (err != CHIP_NO_ERROR) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); - }); - } - Platform::Delete(readClient); - if (container.pathParams != nullptr) - { - Platform::Delete(container.pathParams); - } + auto callback + = chip::Platform::MakeUnique>( + onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); - if (container.eventPathParams != nullptr) - { - Platform::Delete(container.eventPathParams); - } - container.pathParams = nullptr; - return; - } + auto readClient = Platform::New( + engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); - // Read clients will be purged when deregistered. - container.readClientPtr = readClient; - AddReadClientContainer(container.deviceID, container); - callback.release(); - }]; + if (!params.resubscribeAutomatically) { + err = readClient->SendRequest(readParams); + } else { + err = readClient->SendAutoResubscribeRequest(std::move(readParams)); + } + + if (err != CHIP_NO_ERROR) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); + }); + } + Platform::Delete(readClient); + if (container.pathParams != nullptr) { + Platform::Delete(container.pathParams); + } + + if (container.eventPathParams != nullptr) { + Platform::Delete(container.eventPathParams); + } + container.pathParams = nullptr; + return; + } + + // Read clients will be purged when deregistered. + container.readClientPtr = readClient; + AddReadClientContainer(container.deviceID, container); + callback.release(); + }]; } - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID From a36a2e93ac1814ff8c8d2a0190cd17a537526928 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Mon, 27 Mar 2023 14:58:46 +0900 Subject: [PATCH 03/72] Add Exception check --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 30 ++++++ src/darwin/Framework/CHIP/MTRBaseDevice.mm | 115 +++++++++++++++------ 2 files changed, 113 insertions(+), 32 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 22554280223770..b0a5864879fc9a 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -282,12 +282,42 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) completion:(MTRDeviceResponseHandler)completion API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +/** + * Reads multiple attributes or events from the device. + * + * Nil values for endpointID, clusterID, attributeID, eventID indicate wildcards + * (e.g. nil attributeID means "read all the attributes from the endpoint(s) and + * cluster(s) that match endpointID/clusterID"). + * + * If the list of MTRAttributePath class as input parameters, device will be read multiple attributes. + * Similarly,If the list of MTRAttributePath class as input parameters, device will be read multiple events. + * (Device can be read both of them.) + * + * The completion will be called with an error if the entire read interaction fails. + * Otherwise it will be called with values, which may be empty (e.g. if no paths + * matched the wildcard) or may include per-path errors if particular paths + * failed. + */ - (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths params:(MTRReadParams * _Nullable)params queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion; +/** + * Subscribes to the specified attributes on the device. + * + * Nil values for endpointID, clusterID, attributeID, eventID indicate wildcards + * (e.g. nil attributeID means "subscribe to all the attributes from the + * endpoint(s) and cluster(s) that match endpointID/clusterID"). + * + * If the list of MTRAttributePath class as input parameters, device will be subscribed multiple attributes. + * Similarly,If the list of MTRAttributePath class as input parameters, device will be subscribed multiple events. + * (Device can be subscribed both of them.) + * + * A non-nil attributeID along with a nil clusterID will only succeed if the + * attribute ID is for a global attribute that applies to all clusters. + */ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths params:(MTRSubscribeParams * _Nullable)params diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 7f36640b97240d..dcf46562f3e9e3 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -858,10 +858,12 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; - BufferedMultipleReadClientCallback(OnSuccessAttributeCallbackType aOnAttributeSuccess, + BufferedMultipleReadClientCallback(std::vector aAttributePathParamsList, std::vector aEventPathParamsList, OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) - : mOnAttributeSuccess(aOnAttributeSuccess) + : mAttributePathParamsList(aAttributePathParamsList) + , mEventPathParamsList(aEventPathParamsList) + , mOnAttributeSuccess(aOnAttributeSuccess) , mOnEventSuccess(aOnEventSuccess) , mOnError(aOnError) , mOnDone(aOnDone) @@ -895,6 +897,7 @@ void OnAttributeData( VerifyOrDie(!aPath.IsListItemOperation()); VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); + VerifyOrExit(std::find_if(mAttributePathParamsList.begin(), mAttributePathParamsList.end(), [aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); }) != mAttributePathParamsList.end(), err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); SuccessOrExit(err = app::DataModel::Decode(*apData, value)); @@ -912,6 +915,7 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons CHIP_ERROR err = CHIP_NO_ERROR; DecodableValueType value; + VerifyOrExit(std::find_if(mEventPathParamsList.begin(), mEventPathParamsList.end(), [aEventHeader](app::EventPathParams & pathParam) -> bool { return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); }) != mEventPathParamsList.end(), err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); SuccessOrExit(err = app::DataModel::Decode(*apData, value)); @@ -944,6 +948,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr OnSubscriptionEstablishedCallbackType mOnSubscriptionEstablished; app::BufferedReadCallback mBufferedReadAdapter; Platform::UniquePtr mReadClient; + std::vector mAttributePathParamsList; + std::vector mEventPathParamsList; }; - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID @@ -1167,7 +1173,7 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut }; auto callback = chip::Platform::MakeUnique>( - onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); + attributePathParamsList, eventPathParamsList, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -1278,56 +1284,101 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; + + std::vector attributePathParamsList; + std::vector eventPathParamsList; if (attributePaths != nil) { - container.pathParamsSize = [attributePaths count]; - container.pathParams = static_cast( - Platform::MemoryCalloc(sizeof(app::AttributePathParams), container.pathParamsSize)); - for (uint8_t i = 0; i < container.pathParamsSize; i++) { - container.pathParams[i].mEndpointId = kInvalidEndpointId; - container.pathParams[i].mClusterId = kInvalidClusterId; - container.pathParams[i].mAttributeId = kInvalidAttributeId; - + for (uint8_t i = 0 ; i < [attributePaths count] ; i++) { + chip::EndpointId endpointId = kInvalidEndpointId; + chip::ClusterId clusterId = kInvalidClusterId; + chip::AttributeId attributeId = kInvalidAttributeId; + if ([attributePaths[i] endpoint]) { - container.pathParams[i].mEndpointId - = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); + endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); } if ([attributePaths[i] cluster]) { - container.pathParams[i].mClusterId - = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + clusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); } if ([attributePaths[i] attribute]) { - container.pathParams[i].mAttributeId - = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); } + + attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); } + container.pathParamsSize = attributePathParamsList.size(); + container.pathParams = attributePathParamsList.data(); +// container.pathParamsSize = [attributePaths count]; +// container.pathParams = static_cast( +// Platform::MemoryCalloc(sizeof(app::AttributePathParams), container.pathParamsSize)); +// for (uint8_t i = 0; i < container.pathParamsSize; i++) { +// container.pathParams[i].mEndpointId = kInvalidEndpointId; +// container.pathParams[i].mClusterId = kInvalidClusterId; +// container.pathParams[i].mAttributeId = kInvalidAttributeId; +// +// if ([attributePaths[i] endpoint]) { +// container.pathParams[i].mEndpointId +// = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); +// } +// +// if ([attributePaths[i] cluster]) { +// container.pathParams[i].mClusterId +// = static_cast([[attributePaths[i] cluster] unsignedLongValue]); +// } +// +// if ([attributePaths[i] attribute]) { +// container.pathParams[i].mAttributeId +// = static_cast([[attributePaths[i] attribute] unsignedLongValue]); +// } +// } } if (eventPaths != nil) { - container.eventPathParamsSize = [eventPaths count]; - container.eventPathParams = static_cast( - Platform::MemoryCalloc(sizeof(app::EventPathParams), container.eventPathParamsSize)); - for (uint8_t i = 0; i < container.eventPathParamsSize; i++) { - container.eventPathParams[i].mEndpointId = kInvalidEndpointId; - container.eventPathParams[i].mClusterId = kInvalidClusterId; - container.eventPathParams[i].mEventId = kInvalidEventId; - + for (uint8_t i = 0 ; i < [eventPaths count] ; i++) { + chip::EndpointId endpointId = kInvalidEndpointId; + chip::ClusterId clusterId = kInvalidClusterId; + chip::EventId eventId = kInvalidEventId; + if ([eventPaths[i] endpoint]) { - container.eventPathParams[i].mEndpointId - = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); + endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); } if ([eventPaths[i] cluster]) { - container.eventPathParams[i].mClusterId - = static_cast([[eventPaths[i] cluster] unsignedLongValue]); + clusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); } if ([eventPaths[i] event]) { - container.eventPathParams[i].mEventId - = static_cast([[eventPaths[i] event] unsignedLongValue]); + eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); } + + eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); } + container.eventPathParamsSize = eventPathParamsList.size(); + container.eventPathParams = eventPathParamsList.data(); +// container.eventPathParamsSize = [eventPaths count]; +// container.eventPathParams = static_cast( +// Platform::MemoryCalloc(sizeof(app::EventPathParams), container.eventPathParamsSize)); +// for (uint8_t i = 0; i < container.eventPathParamsSize; i++) { +// container.eventPathParams[i].mEndpointId = kInvalidEndpointId; +// container.eventPathParams[i].mClusterId = kInvalidClusterId; +// container.eventPathParams[i].mEventId = kInvalidEventId; +// +// if ([eventPaths[i] endpoint]) { +// container.eventPathParams[i].mEndpointId +// = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); +// } +// +// if ([eventPaths[i] cluster]) { +// container.eventPathParams[i].mClusterId +// = static_cast([[eventPaths[i] cluster] unsignedLongValue]); +// } +// +// if ([eventPaths[i] event]) { +// container.eventPathParams[i].mEventId +// = static_cast([[eventPaths[i] event] unsignedLongValue]); +// } +// } } app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); @@ -1349,7 +1400,7 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att auto callback = chip::Platform::MakeUnique>( - onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); + attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); From 5be341461f9b8c677adc782552e025747f2f0ab3 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Mon, 27 Mar 2023 15:02:06 +0900 Subject: [PATCH 04/72] Remove unused code --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 46 ---------------------- 1 file changed, 46 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index dcf46562f3e9e3..f48f0958162a61 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1310,29 +1310,6 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att } container.pathParamsSize = attributePathParamsList.size(); container.pathParams = attributePathParamsList.data(); -// container.pathParamsSize = [attributePaths count]; -// container.pathParams = static_cast( -// Platform::MemoryCalloc(sizeof(app::AttributePathParams), container.pathParamsSize)); -// for (uint8_t i = 0; i < container.pathParamsSize; i++) { -// container.pathParams[i].mEndpointId = kInvalidEndpointId; -// container.pathParams[i].mClusterId = kInvalidClusterId; -// container.pathParams[i].mAttributeId = kInvalidAttributeId; -// -// if ([attributePaths[i] endpoint]) { -// container.pathParams[i].mEndpointId -// = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); -// } -// -// if ([attributePaths[i] cluster]) { -// container.pathParams[i].mClusterId -// = static_cast([[attributePaths[i] cluster] unsignedLongValue]); -// } -// -// if ([attributePaths[i] attribute]) { -// container.pathParams[i].mAttributeId -// = static_cast([[attributePaths[i] attribute] unsignedLongValue]); -// } -// } } if (eventPaths != nil) { for (uint8_t i = 0 ; i < [eventPaths count] ; i++) { @@ -1356,29 +1333,6 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att } container.eventPathParamsSize = eventPathParamsList.size(); container.eventPathParams = eventPathParamsList.data(); -// container.eventPathParamsSize = [eventPaths count]; -// container.eventPathParams = static_cast( -// Platform::MemoryCalloc(sizeof(app::EventPathParams), container.eventPathParamsSize)); -// for (uint8_t i = 0; i < container.eventPathParamsSize; i++) { -// container.eventPathParams[i].mEndpointId = kInvalidEndpointId; -// container.eventPathParams[i].mClusterId = kInvalidClusterId; -// container.eventPathParams[i].mEventId = kInvalidEventId; -// -// if ([eventPaths[i] endpoint]) { -// container.eventPathParams[i].mEndpointId -// = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); -// } -// -// if ([eventPaths[i] cluster]) { -// container.eventPathParams[i].mClusterId -// = static_cast([[eventPaths[i] cluster] unsignedLongValue]); -// } -// -// if ([eventPaths[i] event]) { -// container.eventPathParams[i].mEventId -// = static_cast([[eventPaths[i] event] unsignedLongValue]); -// } -// } } app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); From 2e7495e2e1487f4a00236617eb6cdb94b507e17a Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Mon, 27 Mar 2023 15:06:49 +0900 Subject: [PATCH 05/72] Restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 33 ++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index f48f0958162a61..511f32083535fc 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -858,7 +858,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; - BufferedMultipleReadClientCallback(std::vector aAttributePathParamsList, std::vector aEventPathParamsList, OnSuccessAttributeCallbackType aOnAttributeSuccess, + BufferedMultipleReadClientCallback(std::vector aAttributePathParamsList, + std::vector aEventPathParamsList, OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) : mAttributePathParamsList(aAttributePathParamsList) @@ -897,7 +898,11 @@ void OnAttributeData( VerifyOrDie(!aPath.IsListItemOperation()); VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); - VerifyOrExit(std::find_if(mAttributePathParamsList.begin(), mAttributePathParamsList.end(), [aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); }) != mAttributePathParamsList.end(), err = CHIP_ERROR_SCHEMA_MISMATCH); + VerifyOrExit( + std::find_if(mAttributePathParamsList.begin(), mAttributePathParamsList.end(), + [aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); }) + != mAttributePathParamsList.end(), + err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); SuccessOrExit(err = app::DataModel::Decode(*apData, value)); @@ -915,7 +920,12 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons CHIP_ERROR err = CHIP_NO_ERROR; DecodableValueType value; - VerifyOrExit(std::find_if(mEventPathParamsList.begin(), mEventPathParamsList.end(), [aEventHeader](app::EventPathParams & pathParam) -> bool { return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); }) != mEventPathParamsList.end(), err = CHIP_ERROR_SCHEMA_MISMATCH); + VerifyOrExit(std::find_if(mEventPathParamsList.begin(), mEventPathParamsList.end(), + [aEventHeader](app::EventPathParams & pathParam) -> bool { + return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); + }) + != mEventPathParamsList.end(), + err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); SuccessOrExit(err = app::DataModel::Decode(*apData, value)); @@ -1284,16 +1294,16 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - + std::vector attributePathParamsList; std::vector eventPathParamsList; if (attributePaths != nil) { - for (uint8_t i = 0 ; i < [attributePaths count] ; i++) { + for (uint8_t i = 0; i < [attributePaths count]; i++) { chip::EndpointId endpointId = kInvalidEndpointId; chip::ClusterId clusterId = kInvalidClusterId; chip::AttributeId attributeId = kInvalidAttributeId; - + if ([attributePaths[i] endpoint]) { endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); } @@ -1305,18 +1315,18 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att if ([attributePaths[i] attribute]) { attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); } - + attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); } container.pathParamsSize = attributePathParamsList.size(); container.pathParams = attributePathParamsList.data(); } if (eventPaths != nil) { - for (uint8_t i = 0 ; i < [eventPaths count] ; i++) { + for (uint8_t i = 0; i < [eventPaths count]; i++) { chip::EndpointId endpointId = kInvalidEndpointId; chip::ClusterId clusterId = kInvalidClusterId; chip::EventId eventId = kInvalidEventId; - + if ([eventPaths[i] endpoint]) { endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); } @@ -1328,7 +1338,7 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att if ([eventPaths[i] event]) { eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); } - + eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); } container.eventPathParamsSize = eventPathParamsList.size(); @@ -1354,7 +1364,8 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); + attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, + onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); From 69548b28aa1a191b5b67b7c34392a2bccac3aaf7 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 28 Mar 2023 12:33:11 +0900 Subject: [PATCH 06/72] Modify from comment --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 27 +-- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 201 +++++++----------- .../Framework/CHIP/MTRBaseDevice_Internal.h | 9 + 3 files changed, 89 insertions(+), 148 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index b0a5864879fc9a..01c087652a929e 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -285,18 +285,12 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) /** * Reads multiple attributes or events from the device. * - * Nil values for endpointID, clusterID, attributeID, eventID indicate wildcards - * (e.g. nil attributeID means "read all the attributes from the endpoint(s) and - * cluster(s) that match endpointID/clusterID"). + * Nil value is treated as empty array for attributePaths and eventPaths. * - * If the list of MTRAttributePath class as input parameters, device will be read multiple attributes. - * Similarly,If the list of MTRAttributePath class as input parameters, device will be read multiple events. - * (Device can be read both of them.) + * Lists of attribute and event paths to read can be provided via attributePaths and eventPaths. * - * The completion will be called with an error if the entire read interaction fails. - * Otherwise it will be called with values, which may be empty (e.g. if no paths - * matched the wildcard) or may include per-path errors if particular paths - * failed. + * The completion will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are empty.) or the entire read interaction fails. + * Otherwise it will be called with values, which may be empty (e.g. if no paths matched the wildcard) or may include per-path errors if particular paths failed. */ - (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths @@ -305,18 +299,13 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) completion:(MTRDeviceResponseHandler)completion; /** - * Subscribes to the specified attributes on the device. + * Subscribes multiple attributes or events from the device. * - * Nil values for endpointID, clusterID, attributeID, eventID indicate wildcards - * (e.g. nil attributeID means "subscribe to all the attributes from the - * endpoint(s) and cluster(s) that match endpointID/clusterID"). + * Nil value is treated as empty array for attributePaths and eventPaths. * - * If the list of MTRAttributePath class as input parameters, device will be subscribed multiple attributes. - * Similarly,If the list of MTRAttributePath class as input parameters, device will be subscribed multiple events. - * (Device can be subscribed both of them.) + * Lists of attribute and event paths to subscribe can be provided via attributePaths and eventPaths. * - * A non-nil attributeID along with a nil clusterID will only succeed if the - * attribute ID is for a global attribute that applies to all clusters. + * The reportHandler will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are empty.). */ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 511f32083535fc..0a770bfaeb0184 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -743,111 +743,6 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const }; template class BufferedReadClientCallback final : public app::ReadClient::Callback { -public: - using OnSuccessCallbackType - = std::function; - using OnErrorCallbackType - = std::function; - using OnDoneCallbackType = std::function; - using OnSubscriptionEstablishedCallbackType = std::function; - - BufferedReadClientCallback(ClusterId aClusterId, uint32_t aValueId, OnSuccessCallbackType aOnSuccess, - OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, - OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) - : mClusterId(aClusterId) - , mValueId(aValueId) - , mOnSuccess(aOnSuccess) - , mOnError(aOnError) - , mOnDone(aOnDone) - , mOnSubscriptionEstablished(aOnSubscriptionEstablished) - , mBufferedReadAdapter(*this) - { - } - - ~BufferedReadClientCallback() - { - // Ensure we release the ReadClient before we tear down anything else, - // so it can call our OnDeallocatePaths properly. - mReadClient = nullptr; - } - - app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; } - - void AdoptReadClient(Platform::UniquePtr aReadClient) { mReadClient = std::move(aReadClient); } - -private: - void OnAttributeData( - const app::ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const app::StatusIB & aStatus) override - { - CHIP_ERROR err = CHIP_NO_ERROR; - DecodableValueType value; - - // - // We shouldn't be getting list item operations in the provided path since that should be handled by the buffered read - // callback. If we do, that's a bug. - // - VerifyOrDie(!aPath.IsListItemOperation()); - - VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); - VerifyOrExit((aPath.mClusterId == mClusterId || mClusterId == kInvalidClusterId) - && (aPath.mAttributeId == mValueId || mValueId == kInvalidAttributeId), - err = CHIP_ERROR_SCHEMA_MISMATCH); - VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - - SuccessOrExit(err = app::DataModel::Decode(*apData, value)); - - mOnSuccess(aPath, aPath.mAttributeId, value); - - exit: - if (err != CHIP_NO_ERROR) { - mOnError(&aPath, aPath.mAttributeId, err); - } - } - - void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus) override - { - CHIP_ERROR err = CHIP_NO_ERROR; - DecodableValueType value; - - VerifyOrExit((aEventHeader.mPath.mClusterId == mClusterId || mClusterId == kInvalidClusterId) - && (aEventHeader.mPath.mEventId == mValueId || mValueId == kInvalidEventId), - err = CHIP_ERROR_SCHEMA_MISMATCH); - VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - - SuccessOrExit(err = app::DataModel::Decode(*apData, value)); - - mOnSuccess(aEventHeader.mPath, aEventHeader.mPath.mEventId, value); - - exit: - if (err != CHIP_NO_ERROR) { - mOnError(&aEventHeader.mPath, aEventHeader.mPath.mEventId, err); - } - } - - void OnError(CHIP_ERROR aError) override { mOnError(nullptr, kInvalidAttributeId, aError); } - - void OnDone(ReadClient *) override { mOnDone(this); } - - void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override - { - if (mOnSubscriptionEstablished) { - mOnSubscriptionEstablished(); - } - } - - void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override {} - - ClusterId mClusterId; - uint32_t mValueId; - OnSuccessCallbackType mOnSuccess; - OnErrorCallbackType mOnError; - OnDoneCallbackType mOnDone; - OnSubscriptionEstablishedCallbackType mOnSubscriptionEstablished; - app::BufferedReadCallback mBufferedReadAdapter; - Platform::UniquePtr mReadClient; -}; - -template class BufferedMultipleReadClientCallback final : public app::ReadClient::Callback { public: using OnSuccessAttributeCallbackType = std::function; @@ -855,10 +750,10 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr = std::function; using OnErrorCallbackType = std::function; - using OnDoneCallbackType = std::function; + using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; - BufferedMultipleReadClientCallback(std::vector aAttributePathParamsList, + BufferedReadClientCallback(std::vector aAttributePathParamsList, std::vector aEventPathParamsList, OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) @@ -873,7 +768,7 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr { } - ~BufferedMultipleReadClientCallback() + ~BufferedReadClientCallback() { // Ensure we release the ReadClient before we tear down anything else, // so it can call our OnDeallocatePaths properly. @@ -891,6 +786,8 @@ void OnAttributeData( CHIP_ERROR err = CHIP_NO_ERROR; DecodableValueType value; + VerifyOrExit(mOnAttributeSuccess != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + // // We shouldn't be getting list item operations in the provided path since that should be handled by the buffered read // callback. If we do, that's a bug. @@ -920,6 +817,8 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons CHIP_ERROR err = CHIP_NO_ERROR; DecodableValueType value; + VerifyOrExit(mOnEventSuccess != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(std::find_if(mEventPathParamsList.begin(), mEventPathParamsList.end(), [aEventHeader](app::EventPathParams & pathParam) -> bool { return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); @@ -1037,8 +936,10 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; + std::vector attributePathParamsList { attributePath }; + std::vector eventPathParamsList; auto callback = chip::Platform::MakeUnique>( - attributePath.mClusterId, attributePath.mAttributeId, onSuccessCb, onFailureCb, onDone, nullptr); + attributePathParamsList, eventPathParamsList, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -1069,6 +970,14 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { + if ((attributePaths == nil || [attributePaths count] == 0) + && (eventPaths == nil || [eventPaths count] == 0)) { + dispatch_async(queue, ^{ + completion(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); + }); + return; + } + attributePaths = (attributePaths == nil) ? nil : [attributePaths copy]; eventPaths = (eventPaths == nil) ? nil : [eventPaths copy]; params = (params == nil) ? nil : [params copy]; @@ -1171,7 +1080,7 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut readParams.mEventPathParamsListSize = eventPathParamsList.size(); auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( - BufferedMultipleReadClientCallback * callback) { + BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); @@ -1182,7 +1091,7 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut chip::Platform::Delete(callback); }; - auto callback = chip::Platform::MakeUnique>( + auto callback = chip::Platform::MakeUnique>( attributePathParamsList, eventPathParamsList, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); @@ -1215,6 +1124,14 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished { + if ((attributePaths == nil || [attributePaths count] == 0) + && (eventPaths == nil || [eventPaths count] == 0)) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); + }); + return; + } + if (self.isPASEDevice) { // We don't support subscriptions over PASE. dispatch_async(queue, ^{ @@ -1355,7 +1272,7 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att readParams.mpEventPathParamsList = container.eventPathParams; readParams.mEventPathParamsListSize = container.eventPathParamsSize; - auto onDone = [container](BufferedMultipleReadClientCallback * callback) { + auto onDone = [container](BufferedReadClientCallback * callback) { [container onDone]; // Make sure we delete callback last, because doing that actually destroys our // lambda, so we can't access captured values after that. @@ -1363,7 +1280,7 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att }; auto callback - = chip::Platform::MakeUnique>( + = chip::Platform::MakeUnique>( attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); @@ -1703,8 +1620,10 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; + std::vector attributePathParamsList { *container.pathParams }; + std::vector eventPathParamsList; auto callback = chip::Platform::MakeUnique>( - container.pathParams->mClusterId, container.pathParams->mAttributeId, onReportCb, onFailureCb, onDone, + attributePathParamsList, eventPathParamsList, onReportCb, nullptr, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( @@ -2004,8 +1923,10 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; + std::vector attributePathParamsList; + std::vector eventPathParamsList { eventPath }; auto callback = chip::Platform::MakeUnique>( - eventPath.mClusterId, eventPath.mEventId, onSuccessCb, onFailureCb, onDone, nullptr); + attributePathParamsList, eventPathParamsList, nullptr, onSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -2132,8 +2053,10 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; + std::vector attributePathParamsList; + std::vector eventPathParamsList { *container.eventPathParams }; auto callback = chip::Platform::MakeUnique>( - container.eventPathParams->mClusterId, container.eventPathParams->mEventId, onReportCb, onFailureCb, onDone, + attributePathParamsList, eventPathParamsList, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( @@ -2287,6 +2210,16 @@ - (instancetype)initWithPath:(const ConcreteClusterPath &)path return self; } +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID +{ + if (self = [super init]) { + _endpoint = endpointID; + _cluster = clusterID; + } + return self; +} + - (NSString *)description { return [NSString stringWithFormat:@" endpoint %u cluster %u", (uint16_t) _endpoint.unsignedShortValue, @@ -2295,10 +2228,7 @@ - (NSString *)description + (MTRClusterPath *)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID { - ConcreteClusterPath path(static_cast([endpointID unsignedShortValue]), - static_cast([clusterID unsignedLongValue])); - - return [[MTRClusterPath alloc] initWithPath:path]; + return [[MTRClusterPath alloc] initWithEndpointID:endpointID clusterID:clusterID]; } - (BOOL)isEqualToClusterPath:(MTRClusterPath *)clusterPath @@ -2335,6 +2265,16 @@ - (instancetype)initWithPath:(const ConcreteDataAttributePath &)path return self; } +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + attributeID:(NSNumber * _Nullable)attributeID +{ + if (self = [super initWithEndpointID:endpointID clusterID:clusterID]) { + _attribute = attributeID; + } + return self; +} + - (NSString *)description { return [NSString stringWithFormat:@" endpoint %u cluster %u attribute %u", @@ -2346,11 +2286,7 @@ + (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID { - ConcreteDataAttributePath path(static_cast([endpointID unsignedShortValue]), - static_cast([clusterID unsignedLongValue]), - static_cast([attributeID unsignedLongValue])); - - return [[MTRAttributePath alloc] initWithPath:path]; + return [[MTRAttributePath alloc] initWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]; } - (BOOL)isEqualToAttributePath:(MTRAttributePath *)attributePath @@ -2395,6 +2331,16 @@ - (instancetype)initWithPath:(const ConcreteEventPath &)path return self; } +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + eventID:(NSNumber * _Nullable)eventID +{ + if (self = [super initWithEndpointID:endpointID clusterID:clusterID]) { + _event = endpointID; + } + return self; +} + - (NSString *)description { return @@ -2404,10 +2350,7 @@ - (NSString *)description + (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID eventID:(NSNumber *)eventID { - ConcreteEventPath path(static_cast([endpointID unsignedShortValue]), - static_cast([clusterID unsignedLongValue]), static_cast([eventID unsignedLongValue])); - - return [[MTREventPath alloc] initWithPath:path]; + return [[MTREventPath alloc] initWithEndpointID:endpointID clusterID:clusterID eventID:eventID]; } - (id)copyWithZone:(NSZone *)zone diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index 9fb062a90cceb2..c1c9669eab1386 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -77,14 +77,23 @@ static inline MTRTransportType MTRMakeTransportType(chip::Transport::Type type) @interface MTRClusterPath () - (instancetype)initWithPath:(const chip::app::ConcreteClusterPath &)path; +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID; + @end @interface MTRAttributePath () - (instancetype)initWithPath:(const chip::app::ConcreteDataAttributePath &)path; +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + attributeID:(NSNumber * _Nullable)attributeID; @end @interface MTREventPath () - (instancetype)initWithPath:(const chip::app::ConcreteEventPath &)path; +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + eventID:(NSNumber * _Nullable)eventID; @end @interface MTRCommandPath () From 51c867062efd98861f83fc6f11ebed6d55d6c3c2 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 28 Mar 2023 13:04:26 +0900 Subject: [PATCH 07/72] Restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 8 ++++--- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 24 +++++++------------ .../Framework/CHIP/MTRBaseDevice_Internal.h | 3 +-- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 01c087652a929e..ec8d296ed9fa27 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -289,8 +289,9 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * * Lists of attribute and event paths to read can be provided via attributePaths and eventPaths. * - * The completion will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are empty.) or the entire read interaction fails. - * Otherwise it will be called with values, which may be empty (e.g. if no paths matched the wildcard) or may include per-path errors if particular paths failed. + * The completion will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are + * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths + * matched the wildcard) or may include per-path errors if particular paths failed. */ - (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths @@ -305,7 +306,8 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * * Lists of attribute and event paths to subscribe can be provided via attributePaths and eventPaths. * - * The reportHandler will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are empty.). + * The reportHandler will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are + * empty.). */ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0a770bfaeb0184..7dca79829e59a5 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -939,7 +939,7 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID std::vector attributePathParamsList { attributePath }; std::vector eventPathParamsList; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); + attributePathParamsList, eventPathParamsList, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -970,8 +970,7 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { - if ((attributePaths == nil || [attributePaths count] == 0) - && (eventPaths == nil || [eventPaths count] == 0)) { + if ((attributePaths == nil || [attributePaths count] == 0) && (eventPaths == nil || [eventPaths count] == 0)) { dispatch_async(queue, ^{ completion(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); }); @@ -1124,8 +1123,7 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished { - if ((attributePaths == nil || [attributePaths count] == 0) - && (eventPaths == nil || [eventPaths count] == 0)) { + if ((attributePaths == nil || [attributePaths count] == 0) && (eventPaths == nil || [eventPaths count] == 0)) { dispatch_async(queue, ^{ reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); }); @@ -1279,10 +1277,9 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)att chip::Platform::Delete(callback); }; - auto callback - = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, - onEstablishedCb); + auto callback = chip::Platform::MakeUnique>( + attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, + onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -1623,8 +1620,7 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID std::vector attributePathParamsList { *container.pathParams }; std::vector eventPathParamsList; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onReportCb, nullptr, onFailureCb, onDone, - onEstablishedCb); + attributePathParamsList, eventPathParamsList, onReportCb, nullptr, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -2056,8 +2052,7 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID std::vector attributePathParamsList; std::vector eventPathParamsList { *container.eventPathParams }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, nullptr, onReportCb, onFailureCb, onDone, - onEstablishedCb); + attributePathParamsList, eventPathParamsList, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -2210,8 +2205,7 @@ - (instancetype)initWithPath:(const ConcreteClusterPath &)path return self; } -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - clusterID:(NSNumber * _Nullable)clusterID +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID { if (self = [super init]) { _endpoint = endpointID; diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index c1c9669eab1386..b80a48ba7e67d7 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -77,8 +77,7 @@ static inline MTRTransportType MTRMakeTransportType(chip::Transport::Type type) @interface MTRClusterPath () - (instancetype)initWithPath:(const chip::app::ConcreteClusterPath &)path; -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - clusterID:(NSNumber * _Nullable)clusterID; +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID; @end From f8d8c69e1a0e34660411c837cd393a08c0aa30cf Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 7 Apr 2023 17:37:34 +0900 Subject: [PATCH 08/72] Add MTRAttributeRequestPath, EventRequestPath --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 135 ++++++++++------ src/darwin/Framework/CHIP/MTRBaseDevice.mm | 153 ++++++++++++++---- .../Framework/CHIP/MTRBaseDevice_Internal.h | 8 - 3 files changed, 201 insertions(+), 95 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index ec8d296ed9fa27..2c4c2245d6d61c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -131,56 +131,35 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { } API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** - * A path indicating a specific cluster on a device (i.e. without any - * wildcards). - */ -API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) -@interface MTRClusterPath : NSObject -@property (nonatomic, readonly, copy) NSNumber * endpoint; -@property (nonatomic, readonly, copy) NSNumber * cluster; - -+ (MTRClusterPath *)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; - -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; -@end - -/** - * A path indicating a specific attribute on a device (i.e. without any - * wildcards). - */ -@interface MTRAttributePath : MTRClusterPath -@property (nonatomic, readonly, copy) NSNumber * attribute; - -+ (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID - clusterID:(NSNumber *)clusterID - attributeID:(NSNumber *)attributeID - API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -@end - -/** - * A path indicating a specific event that can be emitted on a device - * (i.e. without any wildcards). There can be multiple instances of actual - * events for a given event path. + * A path indicating a attribute on a device. + * If value is a wildcard, set it to nil. */ -@interface MTREventPath : MTRClusterPath -@property (nonatomic, readonly, copy) NSNumber * event; - -+ (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID - clusterID:(NSNumber *)clusterID - eventID:(NSNumber *)eventID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +MTR_NEWLY_AVAILABLE; +@interface MTRAttributeRequestPath : NSObject +@property (nonatomic, readonly, copy) NSNumber * _Nullable endpoint; +@property (nonatomic, readonly, copy) NSNumber * _Nullable cluster; +@property (nonatomic, readonly, copy) NSNumber * _Nullable attribute; + ++ (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + attributeID:(NSNumber * _Nullable)attributeID +MTR_NEWLY_AVAILABLE; @end /** - * A path indicating a specific command on a device (i.e. without any - * wildcards). + * A path indicating a event on a device. + * If value is a wildcard, set it to nil. */ -@interface MTRCommandPath : MTRClusterPath -@property (nonatomic, readonly, copy) NSNumber * command; - -+ (MTRCommandPath *)commandPathWithEndpointID:(NSNumber *)endpointID - clusterID:(NSNumber *)clusterID - commandID:(NSNumber *)commandID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +MTR_NEWLY_AVAILABLE; +@interface MTREventRequestPath : NSObject +@property (nonatomic, readonly, copy) NSNumber * _Nullable endpoint; +@property (nonatomic, readonly, copy) NSNumber * _Nullable cluster; +@property (nonatomic, readonly, copy) NSNumber * _Nullable event; + ++ (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + eventID:(NSNumber * _Nullable)eventID; +MTR_NEWLY_AVAILABLE; @end @interface MTRBaseDevice : NSObject @@ -293,12 +272,11 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard) or may include per-path errors if particular paths failed. */ -- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths +- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths params:(MTRReadParams * _Nullable)params queue:(dispatch_queue_t)queue - completion:(MTRDeviceResponseHandler)completion; - + completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; /** * Subscribes multiple attributes or events from the device. * @@ -309,12 +287,12 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * The reportHandler will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are * empty.). */ -- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths +- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths params:(MTRSubscribeParams * _Nullable)params queue:(dispatch_queue_t)queue reportHandler:(MTRDeviceResponseHandler)reportHandler - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished; + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished MTR_NEWLY_AVAILABLE; /** * Write to attribute in a designated attribute path * @@ -473,6 +451,59 @@ API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @end +/** + * A path indicating a specific cluster on a device (i.e. without any + * wildcards). + */ +API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) +@interface MTRClusterPath : NSObject +@property (nonatomic, readonly, copy) NSNumber * endpoint; +@property (nonatomic, readonly, copy) NSNumber * cluster; + ++ (MTRClusterPath *)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +@end + +/** + * A path indicating a specific attribute on a device (i.e. without any + * wildcards). + */ +@interface MTRAttributePath : MTRClusterPath +@property (nonatomic, readonly, copy) NSNumber * attribute; + ++ (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID + clusterID:(NSNumber *)clusterID + attributeID:(NSNumber *)attributeID + API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@end + +/** + * A path indicating a specific event that can be emitted on a device + * (i.e. without any wildcards). There can be multiple instances of actual + * events for a given event path. + */ +@interface MTREventPath : MTRClusterPath +@property (nonatomic, readonly, copy) NSNumber * event; + ++ (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID + clusterID:(NSNumber *)clusterID + eventID:(NSNumber *)eventID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@end + +/** + * A path indicating a specific command on a device (i.e. without any + * wildcards). + */ +@interface MTRCommandPath : MTRClusterPath +@property (nonatomic, readonly, copy) NSNumber * command; + ++ (MTRCommandPath *)commandPathWithEndpointID:(NSNumber *)endpointID + clusterID:(NSNumber *)clusterID + commandID:(NSNumber *)commandID API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@end + @interface MTRAttributeReport : NSObject @property (nonatomic, readonly, copy) MTRAttributePath * path; // value is nullable because nullable attributes can have nil as value. diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 7dca79829e59a5..44b8a5497b0038 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -964,8 +964,8 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID std::move(*bridge).DispatchAction(self); } -- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths +- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths params:(MTRReadParams * _Nullable)params queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion @@ -1116,8 +1116,8 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)attribut std::move(*bridge).DispatchAction(self); } -- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths +- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths + EventPaths:(NSArray * _Nullable)eventPaths params:(MTRSubscribeParams * _Nullable)params queue:(dispatch_queue_t)queue reportHandler:(MTRDeviceResponseHandler)reportHandler @@ -2195,21 +2195,114 @@ - (void)deregisterReportHandlersWithClientQueue:(dispatch_queue_t)queue completi @end -@implementation MTRClusterPath -- (instancetype)initWithPath:(const ConcreteClusterPath &)path +@implementation MTRAttributeRequestPath +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + attributeID:(NSNumber * _Nullable)attributeID { - if (self = [super init]) { - _endpoint = @(path.mEndpointId); - _cluster = @(path.mClusterId); + _endpoint = endpointID; + _cluster = clusterID; + _attribute = attributeID; + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@" endpoint %u cluster %u attribute %u", (uint16_t) _endpoint.unsignedShortValue, + (uint32_t) _cluster.unsignedLongValue, + (uint32_t) _attribute.unsignedLongValue + ]; +} + ++ (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + attributeID:(NSNumber * _Nullable)attributeID +{ + + return [[MTRAttributeRequestPath alloc] initWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]; +} + +- (BOOL)isEqualToAttributeRequestPath:(MTRAttributeRequestPath *)path +{ + return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_attribute isEqualToNumber:path.attribute]; +} + +- (BOOL)isEqual:(id)object +{ + if (![object isKindOfClass:[self class]]) { + return NO; } + return [self isEqualToAttributeRequestPath:object]; +} + +- (NSUInteger)hash +{ + return _endpoint.unsignedShortValue ^ _cluster.unsignedLongValue ^ _attribute.unsignedLongValue; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [MTRAttributeRequestPath requestPathWithEndpointID:_endpoint clusterID:_cluster attributeID:_attribute]; +} +@end + +@implementation MTREventRequestPath +- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + eventID:(NSNumber * _Nullable)eventID +{ + _endpoint = endpointID; + _cluster = clusterID; + _event = eventID; return self; } -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID +- (NSString *)description +{ + return [NSString stringWithFormat:@" endpoint %u cluster %u event %u", (uint16_t) _endpoint.unsignedShortValue, + (uint32_t) _cluster.unsignedLongValue, + (uint32_t) _event.unsignedLongValue + ]; +} + ++ (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID + clusterID:(NSNumber * _Nullable)clusterID + eventID:(NSNumber * _Nullable)eventID +{ + + return [[MTREventRequestPath alloc] initWithEndpointID:endpointID clusterID:clusterID eventID:eventID]; +} + +- (BOOL)isEqualToEventRequestPath:(MTREventRequestPath *)path +{ + return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_event isEqualToNumber:path.event]; +} + +- (BOOL)isEqual:(id)object +{ + if (![object isKindOfClass:[self class]]) { + return NO; + } + return [self isEqualToEventRequestPath:object]; +} + +- (NSUInteger)hash +{ + return _endpoint.unsignedShortValue ^ _cluster.unsignedLongValue ^ _event.unsignedLongValue; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [MTREventRequestPath requestPathWithEndpointID:_endpoint clusterID:_cluster eventID:_event]; +} +@end + +@implementation MTRClusterPath +- (instancetype)initWithPath:(const ConcreteClusterPath &)path { if (self = [super init]) { - _endpoint = endpointID; - _cluster = clusterID; + _endpoint = @(path.mEndpointId); + _cluster = @(path.mClusterId); } return self; } @@ -2222,7 +2315,10 @@ - (NSString *)description + (MTRClusterPath *)clusterPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID { - return [[MTRClusterPath alloc] initWithEndpointID:endpointID clusterID:clusterID]; + ConcreteClusterPath path(static_cast([endpointID unsignedShortValue]), + static_cast([clusterID unsignedLongValue])); + + return [[MTRClusterPath alloc] initWithPath:path]; } - (BOOL)isEqualToClusterPath:(MTRClusterPath *)clusterPath @@ -2259,16 +2355,6 @@ - (instancetype)initWithPath:(const ConcreteDataAttributePath &)path return self; } -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - clusterID:(NSNumber * _Nullable)clusterID - attributeID:(NSNumber * _Nullable)attributeID -{ - if (self = [super initWithEndpointID:endpointID clusterID:clusterID]) { - _attribute = attributeID; - } - return self; -} - - (NSString *)description { return [NSString stringWithFormat:@" endpoint %u cluster %u attribute %u", @@ -2280,7 +2366,11 @@ + (MTRAttributePath *)attributePathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID { - return [[MTRAttributePath alloc] initWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]; + ConcreteDataAttributePath path(static_cast([endpointID unsignedShortValue]), + static_cast([clusterID unsignedLongValue]), + static_cast([attributeID unsignedLongValue])); + + return [[MTRAttributePath alloc] initWithPath:path]; } - (BOOL)isEqualToAttributePath:(MTRAttributePath *)attributePath @@ -2325,16 +2415,6 @@ - (instancetype)initWithPath:(const ConcreteEventPath &)path return self; } -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - clusterID:(NSNumber * _Nullable)clusterID - eventID:(NSNumber * _Nullable)eventID -{ - if (self = [super initWithEndpointID:endpointID clusterID:clusterID]) { - _event = endpointID; - } - return self; -} - - (NSString *)description { return @@ -2344,7 +2424,10 @@ - (NSString *)description + (MTREventPath *)eventPathWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID eventID:(NSNumber *)eventID { - return [[MTREventPath alloc] initWithEndpointID:endpointID clusterID:clusterID eventID:eventID]; + ConcreteEventPath path(static_cast([endpointID unsignedShortValue]), + static_cast([clusterID unsignedLongValue]), static_cast([eventID unsignedLongValue])); + + return [[MTREventPath alloc] initWithPath:path]; } - (id)copyWithZone:(NSZone *)zone diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index b80a48ba7e67d7..9fb062a90cceb2 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -77,22 +77,14 @@ static inline MTRTransportType MTRMakeTransportType(chip::Transport::Type type) @interface MTRClusterPath () - (instancetype)initWithPath:(const chip::app::ConcreteClusterPath &)path; -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID; - @end @interface MTRAttributePath () - (instancetype)initWithPath:(const chip::app::ConcreteDataAttributePath &)path; -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - clusterID:(NSNumber * _Nullable)clusterID - attributeID:(NSNumber * _Nullable)attributeID; @end @interface MTREventPath () - (instancetype)initWithPath:(const chip::app::ConcreteEventPath &)path; -- (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - clusterID:(NSNumber * _Nullable)clusterID - eventID:(NSNumber * _Nullable)eventID; @end @interface MTRCommandPath () From 09d9521f4159ec98670caf2c890307241931e736 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 7 Apr 2023 17:41:21 +0900 Subject: [PATCH 09/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 3 +-- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 2c4c2245d6d61c..e8e8f7096082c1 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -142,8 +142,7 @@ MTR_NEWLY_AVAILABLE; + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID - attributeID:(NSNumber * _Nullable)attributeID -MTR_NEWLY_AVAILABLE; + attributeID:(NSNumber * _Nullable)attributeID MTR_NEWLY_AVAILABLE; @end /** diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 44b8a5497b0038..19d3e2a2329b3e 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -2208,10 +2208,9 @@ - (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - (NSString *)description { - return [NSString stringWithFormat:@" endpoint %u cluster %u attribute %u", (uint16_t) _endpoint.unsignedShortValue, - (uint32_t) _cluster.unsignedLongValue, - (uint32_t) _attribute.unsignedLongValue - ]; + return [NSString stringWithFormat:@" endpoint %u cluster %u attribute %u", + (uint16_t) _endpoint.unsignedShortValue, (uint32_t) _cluster.unsignedLongValue, + (uint32_t) _attribute.unsignedLongValue]; } + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID @@ -2224,7 +2223,8 @@ + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)end - (BOOL)isEqualToAttributeRequestPath:(MTRAttributeRequestPath *)path { - return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_attribute isEqualToNumber:path.attribute]; + return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && + [_attribute isEqualToNumber:path.attribute]; } - (BOOL)isEqual:(id)object @@ -2259,10 +2259,9 @@ - (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID - (NSString *)description { - return [NSString stringWithFormat:@" endpoint %u cluster %u event %u", (uint16_t) _endpoint.unsignedShortValue, - (uint32_t) _cluster.unsignedLongValue, - (uint32_t) _event.unsignedLongValue - ]; + return [NSString stringWithFormat:@" endpoint %u cluster %u event %u", + (uint16_t) _endpoint.unsignedShortValue, (uint32_t) _cluster.unsignedLongValue, + (uint32_t) _event.unsignedLongValue]; } + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID @@ -2275,7 +2274,8 @@ + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpoin - (BOOL)isEqualToEventRequestPath:(MTREventRequestPath *)path { - return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_event isEqualToNumber:path.event]; + return + [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_event isEqualToNumber:path.event]; } - (BOOL)isEqual:(id)object From d9c09b0c1e430524387f4a0a9055a4785e84f936 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 16:59:44 +0900 Subject: [PATCH 10/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index e8e8f7096082c1..aac9a5527c3180 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -131,8 +131,9 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { } API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** - * A path indicating a attribute on a device. - * If value is a wildcard, set it to nil. + * A path indicating an attribute being requested (for read or subscribe). + * + * nil is used to represent wildcards. */ MTR_NEWLY_AVAILABLE; @interface MTRAttributeRequestPath : NSObject From 4b65716b67a779d25634b64f767c22a68a2212f9 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:00:22 +0900 Subject: [PATCH 11/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index aac9a5527c3180..d50b4e35b0e8c9 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -137,9 +137,9 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { */ MTR_NEWLY_AVAILABLE; @interface MTRAttributeRequestPath : NSObject -@property (nonatomic, readonly, copy) NSNumber * _Nullable endpoint; -@property (nonatomic, readonly, copy) NSNumber * _Nullable cluster; -@property (nonatomic, readonly, copy) NSNumber * _Nullable attribute; +@property (nonatomic, readonly, copy, nullable) NSNumber * endpoint; +@property (nonatomic, readonly, copy, nullable) NSNumber * cluster; +@property (nonatomic, readonly, copy, nullable) NSNumber * attribute; + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID From 5c4302f93295f3fdd426d9a3f97d54d5a2eeb9e1 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:00:38 +0900 Subject: [PATCH 12/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index d50b4e35b0e8c9..a274435a648a1d 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -152,9 +152,9 @@ MTR_NEWLY_AVAILABLE; */ MTR_NEWLY_AVAILABLE; @interface MTREventRequestPath : NSObject -@property (nonatomic, readonly, copy) NSNumber * _Nullable endpoint; -@property (nonatomic, readonly, copy) NSNumber * _Nullable cluster; -@property (nonatomic, readonly, copy) NSNumber * _Nullable event; +@property (nonatomic, readonly, copy, nullable) NSNumber * endpoint; +@property (nonatomic, readonly, copy, nullable) NSNumber * cluster; +@property (nonatomic, readonly, copy, nullable) NSNumber * event; + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID From bfc594a3f347046dd1189678f9f7e8175dc97dca Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:01:02 +0900 Subject: [PATCH 13/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index a274435a648a1d..b2da8596a90c76 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -264,7 +264,7 @@ MTR_NEWLY_AVAILABLE; /** * Reads multiple attributes or events from the device. * - * Nil value is treated as empty array for attributePaths and eventPaths. + * Nil is treated as an empty array for attributePaths and eventPaths. * * Lists of attribute and event paths to read can be provided via attributePaths and eventPaths. * From 23bdf38a0952042c8a89ac0a404fac241b819d23 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:02:51 +0900 Subject: [PATCH 14/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index b2da8596a90c76..58b543c491d47b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -135,7 +135,7 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { * * nil is used to represent wildcards. */ -MTR_NEWLY_AVAILABLE; +MTR_NEWLY_AVAILABLE @interface MTRAttributeRequestPath : NSObject @property (nonatomic, readonly, copy, nullable) NSNumber * endpoint; @property (nonatomic, readonly, copy, nullable) NSNumber * cluster; From e5d6acb4ccc7f63326a1c89c709f314e0c1d6a1e Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:03:11 +0900 Subject: [PATCH 15/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 58b543c491d47b..a4458defd3df6b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -150,7 +150,7 @@ MTR_NEWLY_AVAILABLE * A path indicating a event on a device. * If value is a wildcard, set it to nil. */ -MTR_NEWLY_AVAILABLE; +MTR_NEWLY_AVAILABLE @interface MTREventRequestPath : NSObject @property (nonatomic, readonly, copy, nullable) NSNumber * endpoint; @property (nonatomic, readonly, copy, nullable) NSNumber * cluster; From b084dc91d4f94d87d1cf76e1913b30ce58bc86a8 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:03:23 +0900 Subject: [PATCH 16/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index a4458defd3df6b..d146a6d1278a76 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -262,7 +262,7 @@ MTR_NEWLY_AVAILABLE; API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** - * Reads multiple attributes or events from the device. + * Reads multiple attribute or event paths from the device. * * Nil is treated as an empty array for attributePaths and eventPaths. * From 392e27665a25b1ff91dfd9f46836d522bb786788 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:03:34 +0900 Subject: [PATCH 17/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index d146a6d1278a76..3f51c7e6be3d5d 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -268,7 +268,7 @@ MTR_NEWLY_AVAILABLE; * * Lists of attribute and event paths to read can be provided via attributePaths and eventPaths. * - * The completion will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are + * The completion will be called with an error if the input parameters are invalid (e.g., both attributePaths and eventPaths are * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard) or may include per-path errors if particular paths failed. */ From 3d0139254d107ca37025cbbcedb6c3cfbd0723ea Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:03:44 +0900 Subject: [PATCH 18/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 3f51c7e6be3d5d..579ddca2d5499b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -270,7 +270,7 @@ MTR_NEWLY_AVAILABLE; * * The completion will be called with an error if the input parameters are invalid (e.g., both attributePaths and eventPaths are * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths - * matched the wildcard) or may include per-path errors if particular paths failed. + * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. */ - (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths From 00831cabdb971748616fdd5a53efda30f590ee1c Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:04:17 +0900 Subject: [PATCH 19/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 579ddca2d5499b..1116229f180a41 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -272,7 +272,7 @@ MTR_NEWLY_AVAILABLE; * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. */ -- (void)readWithAttributePaths:(NSArray * _Nullable)attributePaths +- (void)readAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths params:(MTRReadParams * _Nullable)params queue:(dispatch_queue_t)queue From d4a25dc834fb0a84f6cfbbfea1018f6fe4e3fe6f Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:04:28 +0900 Subject: [PATCH 20/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 1116229f180a41..21118c51a4795c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -278,7 +278,7 @@ MTR_NEWLY_AVAILABLE; queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; /** - * Subscribes multiple attributes or events from the device. + * Subscribes to multiple attribute or event paths. * * Nil value is treated as empty array for attributePaths and eventPaths. * From 9a11f72e765fadd4e179ecf9c2e9fe24ee9e07c2 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:04:40 +0900 Subject: [PATCH 21/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 21118c51a4795c..0cf6728b237afe 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -273,7 +273,7 @@ MTR_NEWLY_AVAILABLE; * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. */ - (void)readAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths + eventPaths:(NSArray * _Nullable)eventPaths params:(MTRReadParams * _Nullable)params queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; From 4131e359b7e40cc7f299d24301a0f454b64d3ef7 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:04:51 +0900 Subject: [PATCH 22/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 0cf6728b237afe..b1127161fcb7f3 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -280,7 +280,7 @@ MTR_NEWLY_AVAILABLE; /** * Subscribes to multiple attribute or event paths. * - * Nil value is treated as empty array for attributePaths and eventPaths. + * Nil is treated as an empty array for attributePaths and eventPaths. * * Lists of attribute and event paths to subscribe can be provided via attributePaths and eventPaths. * From fc27a7c6dd09ea51891b084e044f5290b17272da Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:05:00 +0900 Subject: [PATCH 23/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index b1127161fcb7f3..da49abbbc46e21 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -282,7 +282,7 @@ MTR_NEWLY_AVAILABLE; * * Nil is treated as an empty array for attributePaths and eventPaths. * - * Lists of attribute and event paths to subscribe can be provided via attributePaths and eventPaths. + * Lists of attribute and event paths to subscribe to can be provided via attributePaths and eventPaths. * * The reportHandler will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are * empty.). From d6ff44c9fedc72ed18e75610aea3f0db47cc86ca Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:05:09 +0900 Subject: [PATCH 24/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index da49abbbc46e21..f938e8b0275239 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -284,7 +284,7 @@ MTR_NEWLY_AVAILABLE; * * Lists of attribute and event paths to subscribe to can be provided via attributePaths and eventPaths. * - * The reportHandler will be called with an error if the input parameter has a problem(e.g., both attributePaths and eventPaths are + * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are * empty.). */ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths From dd9dfdad4a91587bae49c0e6fcb1642b70388689 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:05:22 +0900 Subject: [PATCH 25/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 19d3e2a2329b3e..21ca9e663977d5 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -745,7 +745,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const template class BufferedReadClientCallback final : public app::ReadClient::Callback { public: using OnSuccessAttributeCallbackType = std::function; + const ConcreteAttributePath & aPath, const DecodableValueType & aData)>; using OnSuccessEventCallbackType = std::function; using OnErrorCallbackType From b05f10ee9697cdd935944560ee7acef517666001 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:05:33 +0900 Subject: [PATCH 26/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index f938e8b0275239..0e41243cd237e0 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -285,7 +285,7 @@ MTR_NEWLY_AVAILABLE; * Lists of attribute and event paths to subscribe to can be provided via attributePaths and eventPaths. * * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are - * empty.). + * empty), or if the subscription fails entirely. */ - (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths From 465963a28c01a501a3fd91e8a4776951784d4c1e Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:05:43 +0900 Subject: [PATCH 27/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 0e41243cd237e0..6663eafe61cf52 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -287,7 +287,7 @@ MTR_NEWLY_AVAILABLE; * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are * empty), or if the subscription fails entirely. */ -- (void)subscribeWithAttributePaths:(NSArray * _Nullable)attributePaths +- (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths EventPaths:(NSArray * _Nullable)eventPaths params:(MTRSubscribeParams * _Nullable)params queue:(dispatch_queue_t)queue From 287d75dbf40c52580dbf9fa841edcac50ebe502e Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:05:54 +0900 Subject: [PATCH 28/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 6663eafe61cf52..eb432a1f6b511a 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -288,7 +288,7 @@ MTR_NEWLY_AVAILABLE; * empty), or if the subscription fails entirely. */ - (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths + eventPaths:(NSArray * _Nullable)eventPaths params:(MTRSubscribeParams * _Nullable)params queue:(dispatch_queue_t)queue reportHandler:(MTRDeviceResponseHandler)reportHandler From 574120f8471c816bf9ea69bc136e890c464b8be2 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:06:19 +0900 Subject: [PATCH 29/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 21ca9e663977d5..e05f64c55ff770 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -747,7 +747,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const using OnSuccessAttributeCallbackType = std::function; using OnSuccessEventCallbackType - = std::function; + = std::function; using OnErrorCallbackType = std::function; using OnDoneCallbackType = std::function; From b8cb57def75334b3b61ebc7e511125268425eeb4 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:06:32 +0900 Subject: [PATCH 30/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index e05f64c55ff770..d3aa29bcbdb032 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -804,7 +804,7 @@ void OnAttributeData( SuccessOrExit(err = app::DataModel::Decode(*apData, value)); - mOnAttributeSuccess(aPath, aPath.mAttributeId, value); + mOnAttributeSuccess(aPath, value); exit: if (err != CHIP_NO_ERROR) { From 39978a513752aab8504429e2aa956078fdbbe259 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:06:48 +0900 Subject: [PATCH 31/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index d3aa29bcbdb032..84c8a221710283 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -829,7 +829,7 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons SuccessOrExit(err = app::DataModel::Decode(*apData, value)); - mOnEventSuccess(aEventHeader.mPath, aEventHeader.mPath.mEventId, value); + mOnEventSuccess(aEventHeader.mPath, value); exit: if (err != CHIP_NO_ERROR) { From 95ec85b170f0039ad23ce32b69d40a10084cea88 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:07:11 +0900 Subject: [PATCH 32/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 84c8a221710283..0ae8c60a85b3ec 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -989,11 +989,10 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)a auto interactionStatus = std::make_shared(CHIP_NO_ERROR); auto resultArray = [[NSMutableArray alloc] init]; - auto onAttributeSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, + auto onAttributeSuccessCb = [resultArray](const ConcreteAttributePath & attributePath, const MTRDataValueDictionaryDecodableType & aData) { - app::ConcreteAttributePath attribPath(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], MTRDataKey : aData.GetDecodedObject() }]; }; From cae5d81d7fbca07fd4ed8ce02e9458371d5abf1c Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:07:32 +0900 Subject: [PATCH 33/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0ae8c60a85b3ec..e85d6738e19a24 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1156,10 +1156,10 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nulla } auto onAttributeReportCb - = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const AttributeId aAttributeId, + = [queue, reportHandler](const ConcreteAttributePath & attributePath, const MTRDataValueDictionaryDecodableType & data) { id valueObject = data.GetDecodedObject(); - app::ConcreteAttributePath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aAttributeId); + ConcreteAttributePath pathCopy(attributePath); dispatch_async(queue, ^{ reportHandler(@[ @ { MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], From 1160cf8872fda2ad924d636ba26e82a11fe4d955 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:08:06 +0900 Subject: [PATCH 34/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index e85d6738e19a24..f9ccccd6970c64 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1209,8 +1209,8 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nulla MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - std::vector attributePathParamsList; - std::vector eventPathParamsList; + std::vector attributePathParamsList; + std::vector eventPathParamsList; if (attributePaths != nil) { for (uint8_t i = 0; i < [attributePaths count]; i++) { From 374845b12a7d44234971d73708a20686211c9c1b Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:08:23 +0900 Subject: [PATCH 35/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index f9ccccd6970c64..b3ac056ee2a3b2 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -997,9 +997,8 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)a }]; }; - auto onEventSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const EventId aEventId, + auto onEventSuccessCb = [resultArray](const ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { - app::ConcreteEventPath eventPath(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); [resultArray addObject:@ { MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], MTRDataKey : aData.GetDecodedObject() From ec0434a96eaddfd5c83d81206657b5f5eedd59f4 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:08:42 +0900 Subject: [PATCH 36/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index b3ac056ee2a3b2..71ed6d51559832 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1025,7 +1025,7 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)a std::vector eventPathParamsList; if (attributePaths != nil) { - for (uint8_t i = 0; i < [attributePaths count]; i++) { + for (MTRAttributeRequestPath * attributePath in attributePaths) { chip::EndpointId endpointId = kInvalidEndpointId; chip::ClusterId clusterId = kInvalidClusterId; chip::AttributeId attributeId = kInvalidAttributeId; From 5981cbda4c7a324c75ff6fa295ea310b6635d42c Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 8 Apr 2023 17:09:29 +0900 Subject: [PATCH 37/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 71ed6d51559832..2f58bbcdd93c55 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1168,10 +1168,10 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nulla }); }; - auto onEventReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, - const EventId aEventId, const MTRDataValueDictionaryDecodableType & data) { + auto onEventReportCb = [queue, reportHandler](const ConcreteEventPath & eventPath, + const MTRDataValueDictionaryDecodableType & data) { id valueObject = data.GetDecodedObject(); - app::ConcreteEventPath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aEventId); + ConcreteEventPath pathCopy(eventPath); dispatch_async(queue, ^{ reportHandler( @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], MTRDataKey : valueObject } ], From ebfbfcecd44e11c3660d81dc3808b40868f9c2c3 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Sun, 9 Apr 2023 17:46:46 +0900 Subject: [PATCH 38/72] fix build error --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 5 ++- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 44 ++++++++++------------ 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index eb432a1f6b511a..210116c25efe60 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -147,8 +147,9 @@ MTR_NEWLY_AVAILABLE @end /** - * A path indicating a event on a device. - * If value is a wildcard, set it to nil. + * A path indicating an event being requested (for read or subscribe). + * + * nil is used to represent wildcards. */ MTR_NEWLY_AVAILABLE @interface MTREventRequestPath : NSObject diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 2f58bbcdd93c55..ae452a67984877 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -881,11 +881,10 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID auto interactionStatus = std::make_shared(CHIP_NO_ERROR); auto resultArray = [[NSMutableArray alloc] init]; - auto onSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const uint32_t aValueId, + auto onSuccessCb = [resultArray](const app::ConcreteAttributePath & attributePath, const MTRDataValueDictionaryDecodableType & aData) { - app::ConcreteAttributePath attribPath(clusterPath.mEndpointId, clusterPath.mClusterId, aValueId); [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], MTRDataKey : aData.GetDecodedObject() }]; }; @@ -1030,37 +1029,37 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)a chip::ClusterId clusterId = kInvalidClusterId; chip::AttributeId attributeId = kInvalidAttributeId; - if ([attributePaths[i] endpoint]) { - endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); + if ([attributePath endpoint]) { + endpointId = static_cast([[attributePath endpoint] unsignedShortValue]); } - if ([attributePaths[i] cluster]) { - clusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); + if ([attributePath cluster]) { + clusterId = static_cast([[attributePath cluster] unsignedLongValue]); } - if ([attributePaths[i] attribute]) { - attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); + if ([attributePath attribute]) { + attributeId = static_cast([[attributePath attribute] unsignedLongValue]); } attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); } } if (eventPaths != nil) { - for (uint8_t i = 0; i < [eventPaths count]; i++) { + for (MTREventRequestPath * eventPath in eventPaths) { chip::EndpointId endpointId = kInvalidEndpointId; chip::ClusterId clusterId = kInvalidClusterId; chip::EventId eventId = kInvalidEventId; - if ([eventPaths[i] endpoint]) { - endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); + if ([eventPath endpoint]) { + endpointId = static_cast([[eventPath endpoint] unsignedShortValue]); } - if ([eventPaths[i] cluster]) { - clusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); + if ([eventPath cluster]) { + clusterId = static_cast([[eventPath cluster] unsignedLongValue]); } - if ([eventPaths[i] event]) { - eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); + if ([eventPath event]) { + eventId = static_cast([[eventPath event] unsignedLongValue]); } eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); } @@ -1547,13 +1546,12 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID return; } - auto onReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const uint32_t aValueId, + auto onReportCb = [queue, reportHandler](const app::ConcreteAttributePath & attributePath, const MTRDataValueDictionaryDecodableType & data) { id valueObject = data.GetDecodedObject(); - app::ConcreteAttributePath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aValueId); dispatch_async(queue, ^{ reportHandler(@[ @ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], MTRDataKey : valueObject } ], nil); @@ -1863,9 +1861,8 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID auto interactionStatus = std::make_shared(CHIP_NO_ERROR); auto resultArray = [[NSMutableArray alloc] init]; - auto onSuccessCb = [resultArray](const app::ConcreteClusterPath & clusterPath, const uint32_t aValueId, + auto onSuccessCb = [resultArray](const app::ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { - app::ConcreteEventPath eventPath(clusterPath.mEndpointId, clusterPath.mClusterId, aValueId); [resultArray addObject:@ { MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], MTRDataKey : aData.GetDecodedObject() @@ -1980,13 +1977,12 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID return; } - auto onReportCb = [queue, reportHandler](const app::ConcreteClusterPath & clusterPath, const uint32_t aValueId, + auto onReportCb = [queue, reportHandler](const app::ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & data) { id valueObject = data.GetDecodedObject(); - app::ConcreteEventPath pathCopy(clusterPath.mEndpointId, clusterPath.mClusterId, aValueId); dispatch_async(queue, ^{ reportHandler( - @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], MTRDataKey : valueObject } ], + @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], MTRDataKey : valueObject } ], nil); }); }; From a26987a2b48313d821104df7946659f779926206 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Sun, 9 Apr 2023 17:52:25 +0900 Subject: [PATCH 39/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 20 +++--- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 78 +++++++++++----------- 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 210116c25efe60..1e9f466e8c07e6 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -131,7 +131,7 @@ typedef NS_ENUM(uint8_t, MTRTransportType) { } API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** - * A path indicating an attribute being requested (for read or subscribe). + * A path indicating an attribute being requested (for read or subscribe). * * nil is used to represent wildcards. */ @@ -274,10 +274,10 @@ MTR_NEWLY_AVAILABLE; * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. */ - (void)readAttributePaths:(NSArray * _Nullable)attributePaths - eventPaths:(NSArray * _Nullable)eventPaths - params:(MTRReadParams * _Nullable)params - queue:(dispatch_queue_t)queue - completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; + eventPaths:(NSArray * _Nullable)eventPaths + params:(MTRReadParams * _Nullable)params + queue:(dispatch_queue_t)queue + completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; /** * Subscribes to multiple attribute or event paths. * @@ -289,11 +289,11 @@ MTR_NEWLY_AVAILABLE; * empty), or if the subscription fails entirely. */ - (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths - eventPaths:(NSArray * _Nullable)eventPaths - params:(MTRSubscribeParams * _Nullable)params - queue:(dispatch_queue_t)queue - reportHandler:(MTRDeviceResponseHandler)reportHandler - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished MTR_NEWLY_AVAILABLE; + eventPaths:(NSArray * _Nullable)eventPaths + params:(MTRSubscribeParams * _Nullable)params + queue:(dispatch_queue_t)queue + reportHandler:(MTRDeviceResponseHandler)reportHandler + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished MTR_NEWLY_AVAILABLE; /** * Write to attribute in a designated attribute path * diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index ae452a67984877..3ca9b19fc1a70b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -744,10 +744,9 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const template class BufferedReadClientCallback final : public app::ReadClient::Callback { public: - using OnSuccessAttributeCallbackType = std::function; - using OnSuccessEventCallbackType - = std::function; + using OnSuccessAttributeCallbackType + = std::function; + using OnSuccessEventCallbackType = std::function; using OnErrorCallbackType = std::function; using OnDoneCallbackType = std::function; @@ -988,21 +987,21 @@ - (void)readWithAttributePaths:(NSArray * _Nullable)a auto interactionStatus = std::make_shared(CHIP_NO_ERROR); auto resultArray = [[NSMutableArray alloc] init]; - auto onAttributeSuccessCb = [resultArray](const ConcreteAttributePath & attributePath, - const MTRDataValueDictionaryDecodableType & aData) { - [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; - - auto onEventSuccessCb = [resultArray](const ConcreteEventPath & eventPath, - const MTRDataValueDictionaryDecodableType & aData) { - [resultArray addObject:@ { - MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; + auto onAttributeSuccessCb + = [resultArray](const ConcreteAttributePath & attributePath, const MTRDataValueDictionaryDecodableType & aData) { + [resultArray addObject:@ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], + MTRDataKey : aData.GetDecodedObject() + }]; + }; + + auto onEventSuccessCb + = [resultArray](const ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { + [resultArray addObject:@ { + MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], + MTRDataKey : aData.GetDecodedObject() + }]; + }; auto onFailureCb = [resultArray, interactionStatus]( const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { @@ -1153,22 +1152,21 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nulla return; } - auto onAttributeReportCb - = [queue, reportHandler](const ConcreteAttributePath & attributePath, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - ConcreteAttributePath pathCopy(attributePath); - dispatch_async(queue, ^{ - reportHandler(@[ @ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], - MTRDataKey : valueObject - } ], - nil); - }); - }; + auto onAttributeReportCb = [queue, reportHandler](const ConcreteAttributePath & attributePath, + const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + ConcreteAttributePath pathCopy(attributePath); + dispatch_async(queue, ^{ + reportHandler(@[ @ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], + MTRDataKey : valueObject + } ], + nil); + }); + }; auto onEventReportCb = [queue, reportHandler](const ConcreteEventPath & eventPath, - const MTRDataValueDictionaryDecodableType & data) { + const MTRDataValueDictionaryDecodableType & data) { id valueObject = data.GetDecodedObject(); ConcreteEventPath pathCopy(eventPath); dispatch_async(queue, ^{ @@ -1861,13 +1859,13 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID auto interactionStatus = std::make_shared(CHIP_NO_ERROR); auto resultArray = [[NSMutableArray alloc] init]; - auto onSuccessCb = [resultArray](const app::ConcreteEventPath & eventPath, - const MTRDataValueDictionaryDecodableType & aData) { - [resultArray addObject:@ { - MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; + auto onSuccessCb + = [resultArray](const app::ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { + [resultArray addObject:@ { + MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], + MTRDataKey : aData.GetDecodedObject() + }]; + }; auto onFailureCb = [resultArray, interactionStatus]( const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { From dca26f6de94824bf43b835af338081fd47c3c5c4 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Sun, 9 Apr 2023 17:59:29 +0900 Subject: [PATCH 40/72] Add set null eventPath --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index ae452a67984877..7cab78de496c90 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1302,6 +1302,7 @@ - (void)subscribeWithAttributePaths:(NSArray * _Nulla Platform::Delete(container.eventPathParams); } container.pathParams = nullptr; + container.eventPathParams = nullptr; return; } From 6267b376ed7ad36fba6d16d6e790a25621cc4341 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 11 Apr 2023 15:51:36 +0900 Subject: [PATCH 41/72] Modify memort allocation --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 234 +++++++++--------- .../Framework/CHIP/MTRBaseDevice_Internal.h | 10 + 2 files changed, 121 insertions(+), 123 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0a226d9f5b57e6..e70f1aec7fe78f 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -225,12 +225,12 @@ - (void)onDone _readClientPtr = nullptr; } if (_pathParams) { - Platform::Delete(_pathParams); + Platform::MemoryFree(_pathParams); _pathParams = nullptr; _pathParamsSize = 0; } if (_eventPathParams) { - Platform::Delete(_eventPathParams); + Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; _eventPathParamsSize = 0; } @@ -244,12 +244,12 @@ - (void)dealloc _readClientPtr = nullptr; } if (_pathParams) { - Platform::Delete(_pathParams); + Platform::MemoryFree(_pathParams); _pathParams = nullptr; _pathParamsSize = 0; } if (_eventPathParams) { - Platform::Delete(_eventPathParams); + Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; _eventPathParamsSize = 0; } @@ -752,12 +752,14 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; - BufferedReadClientCallback(std::vector aAttributePathParamsList, - std::vector aEventPathParamsList, OnSuccessAttributeCallbackType aOnAttributeSuccess, + BufferedReadClientCallback(app::AttributePathParams *aAttributePathParamsList, size_t aAttributePathParamsSize, + app::EventPathParams *aEventPathParamsList, size_t aEventPathParamsSize, OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) : mAttributePathParamsList(aAttributePathParamsList) + , mAttributePathParamsSize(aAttributePathParamsSize) , mEventPathParamsList(aEventPathParamsList) + , mEventPathParamsSize(aEventPathParamsSize) , mOnAttributeSuccess(aOnAttributeSuccess) , mOnEventSuccess(aOnEventSuccess) , mOnError(aOnError) @@ -786,6 +788,8 @@ void OnAttributeData( DecodableValueType value; VerifyOrExit(mOnAttributeSuccess != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + VerifyOrExit(mAttributePathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); // // We shouldn't be getting list item operations in the provided path since that should be handled by the buffered read @@ -795,9 +799,9 @@ void OnAttributeData( VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); VerifyOrExit( - std::find_if(mAttributePathParamsList.begin(), mAttributePathParamsList.end(), + std::find_if(mAttributePathParamsList, mAttributePathParamsList + mAttributePathParamsSize, [aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); }) - != mAttributePathParamsList.end(), + != mAttributePathParamsList + mAttributePathParamsSize, err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -817,12 +821,14 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons DecodableValueType value; VerifyOrExit(mOnEventSuccess != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + VerifyOrExit(mEventPathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(std::find_if(mEventPathParamsList.begin(), mEventPathParamsList.end(), + VerifyOrExit(std::find_if(mEventPathParamsList, mEventPathParamsList + mEventPathParamsSize, [aEventHeader](app::EventPathParams & pathParam) -> bool { return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); }) - != mEventPathParamsList.end(), + != mEventPathParamsList + mEventPathParamsSize, err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -856,8 +862,10 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr OnSubscriptionEstablishedCallbackType mOnSubscriptionEstablished; app::BufferedReadCallback mBufferedReadAdapter; Platform::UniquePtr mReadClient; - std::vector mAttributePathParamsList; - std::vector mEventPathParamsList; + app::AttributePathParams * mAttributePathParamsList; + app::EventPathParams * mEventPathParamsList; + size_t mAttributePathParamsSize; + size_t mEventPathParamsSize; }; - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID @@ -904,25 +912,25 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID } }; - app::AttributePathParams attributePath; + app::AttributePathParams *attributePath = static_cast(Platform::MemoryCalloc(1, sizeof(AttributePathParams))); if (endpointID) { - attributePath.mEndpointId = static_cast([endpointID unsignedShortValue]); + attributePath->mEndpointId = static_cast([endpointID unsignedShortValue]); } if (clusterID) { - attributePath.mClusterId = static_cast([clusterID unsignedLongValue]); + attributePath->mClusterId = static_cast([clusterID unsignedLongValue]); } if (attributeID) { - attributePath.mAttributeId = static_cast([attributeID unsignedLongValue]); + attributePath->mAttributeId = static_cast([attributeID unsignedLongValue]); } app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); CHIP_ERROR err = CHIP_NO_ERROR; chip::app::ReadPrepareParams readParams(session); [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = &attributePath; + readParams.mpAttributePathParamsList = attributePath; readParams.mAttributePathParamsListSize = 1; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePath]( BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure @@ -931,13 +939,12 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID // Success successCb(bridge, resultArray); } + chip::Platform::MemoryFree(attributePath); chip::Platform::Delete(callback); }; - std::vector attributePathParamsList { attributePath }; - std::vector eventPathParamsList; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); + attributePath, 1, nullptr, 0, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -1019,48 +1026,24 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } }; - std::vector attributePathParamsList; - std::vector eventPathParamsList; + AttributePathParams * attributePathParamsList = nullptr; + EventPathParams * eventPathParamsList = nullptr; if (attributePaths != nil) { + size_t count = 0; + attributePathParamsList = static_cast(Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); + VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attributePath in attributePaths) { - chip::EndpointId endpointId = kInvalidEndpointId; - chip::ClusterId clusterId = kInvalidClusterId; - chip::AttributeId attributeId = kInvalidAttributeId; - - if ([attributePath endpoint]) { - endpointId = static_cast([[attributePath endpoint] unsignedShortValue]); - } - - if ([attributePath cluster]) { - clusterId = static_cast([[attributePath cluster] unsignedLongValue]); - } - - if ([attributePath attribute]) { - attributeId = static_cast([[attributePath attribute] unsignedLongValue]); - } - attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); + [attributePath convertToAttributePathParams:attributePathParamsList[count++]]; } } if (eventPaths != nil) { + size_t count = 0; + eventPathParamsList = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); + VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTREventRequestPath * eventPath in eventPaths) { - chip::EndpointId endpointId = kInvalidEndpointId; - chip::ClusterId clusterId = kInvalidClusterId; - chip::EventId eventId = kInvalidEventId; - - if ([eventPath endpoint]) { - endpointId = static_cast([[eventPath endpoint] unsignedShortValue]); - } - - if ([eventPath cluster]) { - clusterId = static_cast([[eventPath cluster] unsignedLongValue]); - } - - if ([eventPath event]) { - eventId = static_cast([[eventPath event] unsignedLongValue]); - } - eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); + [eventPath convertToEventPathParams:eventPathParamsList[count++]]; } } @@ -1069,12 +1052,12 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri chip::app::ReadPrepareParams readParams(session); [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = attributePathParamsList.data(); - readParams.mAttributePathParamsListSize = attributePathParamsList.size(); - readParams.mpEventPathParamsList = eventPathParamsList.data(); - readParams.mEventPathParamsListSize = eventPathParamsList.size(); + readParams.mpAttributePathParamsList = attributePathParamsList; + readParams.mAttributePathParamsListSize = [attributePaths count]; + readParams.mpEventPathParamsList = eventPathParamsList; + readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList, eventPathParamsList]( BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure @@ -1083,11 +1066,17 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // Success successCb(bridge, resultArray); } + if (attributePathParamsList != nullptr) { + chip::Platform::MemoryFree(attributePathParamsList); + } + if (eventPathParamsList != nullptr) { + chip::Platform::MemoryFree(eventPathParamsList); + } chip::Platform::Delete(callback); }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); + attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList, readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -1205,54 +1194,21 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - std::vector attributePathParamsList; - std::vector eventPathParamsList; - if (attributePaths != nil) { - for (uint8_t i = 0; i < [attributePaths count]; i++) { - chip::EndpointId endpointId = kInvalidEndpointId; - chip::ClusterId clusterId = kInvalidClusterId; - chip::AttributeId attributeId = kInvalidAttributeId; - - if ([attributePaths[i] endpoint]) { - endpointId = static_cast([[attributePaths[i] endpoint] unsignedShortValue]); - } - - if ([attributePaths[i] cluster]) { - clusterId = static_cast([[attributePaths[i] cluster] unsignedLongValue]); - } - - if ([attributePaths[i] attribute]) { - attributeId = static_cast([[attributePaths[i] attribute] unsignedLongValue]); - } - - attributePathParamsList.push_back(app::AttributePathParams(endpointId, clusterId, attributeId)); + container.pathParamsSize = 0; + container.pathParams = static_cast(Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); + for (MTRAttributeRequestPath * attributePath in attributePaths) { + [attributePath convertToAttributePathParams:container.pathParams[container.pathParamsSize++]]; } - container.pathParamsSize = attributePathParamsList.size(); - container.pathParams = attributePathParamsList.data(); + + } if (eventPaths != nil) { - for (uint8_t i = 0; i < [eventPaths count]; i++) { - chip::EndpointId endpointId = kInvalidEndpointId; - chip::ClusterId clusterId = kInvalidClusterId; - chip::EventId eventId = kInvalidEventId; - - if ([eventPaths[i] endpoint]) { - endpointId = static_cast([[eventPaths[i] endpoint] unsignedShortValue]); - } - - if ([eventPaths[i] cluster]) { - clusterId = static_cast([[eventPaths[i] cluster] unsignedLongValue]); - } - - if ([eventPaths[i] event]) { - eventId = static_cast([[eventPaths[i] event] unsignedLongValue]); - } - - eventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId)); + container.eventPathParamsSize = 0; + container.eventPathParams = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); + for (MTREventRequestPath * eventPath in eventPaths) { + [eventPath convertToEventPathParams:container.eventPathParams[container.eventPathParamsSize++]]; } - container.eventPathParamsSize = eventPathParamsList.size(); - container.eventPathParams = eventPathParamsList.data(); } app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); @@ -1273,7 +1229,7 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, + container.pathParams, container.pathParamsSize, container.eventPathParams, container.eventPathParamsSize, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( @@ -1585,7 +1541,7 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - container.pathParams = Platform::New(); + container.pathParams = static_cast(Platform::MemoryCalloc(1, sizeof(app::AttributePathParams))); container.pathParamsSize = 1; if (endpointID) { container.pathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); @@ -1612,10 +1568,8 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; - std::vector attributePathParamsList { *container.pathParams }; - std::vector eventPathParamsList; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, onReportCb, nullptr, onFailureCb, onDone, onEstablishedCb); + container.pathParams, container.pathParamsSize, nullptr, 0, onReportCb, nullptr, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -1633,7 +1587,7 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID }); } Platform::Delete(readClient); - Platform::Delete(container.pathParams); + Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; return; } @@ -1884,22 +1838,22 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID } }; - app::EventPathParams eventPath; + app::EventPathParams *eventPath = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); if (endpointID) { - eventPath.mEndpointId = static_cast([endpointID unsignedShortValue]); + eventPath->mEndpointId = static_cast([endpointID unsignedShortValue]); } if (clusterID) { - eventPath.mClusterId = static_cast([clusterID unsignedLongValue]); + eventPath->mClusterId = static_cast([clusterID unsignedLongValue]); } if (eventID) { - eventPath.mEventId = static_cast([eventID unsignedLongValue]); + eventPath->mEventId = static_cast([eventID unsignedLongValue]); } app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); CHIP_ERROR err = CHIP_NO_ERROR; chip::app::ReadPrepareParams readParams(session); [params toReadPrepareParams:readParams]; - readParams.mpEventPathParamsList = &eventPath; + readParams.mpEventPathParamsList = eventPath; readParams.mEventPathParamsListSize = 1; auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( @@ -1913,10 +1867,8 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; - std::vector attributePathParamsList; - std::vector eventPathParamsList { eventPath }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, nullptr, onSuccessCb, onFailureCb, onDone, nullptr); + nullptr, 0, eventPath, 1, nullptr, onSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -2014,7 +1966,7 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - container.eventPathParams = Platform::New(); + container.eventPathParams = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); container.eventPathParamsSize = 1; if (endpointID) { container.eventPathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); @@ -2042,10 +1994,8 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID chip::Platform::Delete(callback); }; - std::vector attributePathParamsList; - std::vector eventPathParamsList { *container.eventPathParams }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, eventPathParamsList, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); + nullptr, 0, container.eventPathParams, 1, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -2063,7 +2013,7 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID }); } Platform::Delete(readClient); - Platform::Delete(container.eventPathParams); + Platform::MemoryFree(container.eventPathParams); container.eventPathParams = nullptr; return; } @@ -2237,6 +2187,25 @@ - (id)copyWithZone:(NSZone *)zone { return [MTRAttributeRequestPath requestPathWithEndpointID:_endpoint clusterID:_cluster attributeID:_attribute]; } + +- (void)convertToAttributePathParams:(chip::app::AttributePathParams &)params +{ + params.mEndpointId = kInvalidEndpointId; + params.mClusterId = kInvalidClusterId; + params.mAttributeId = kInvalidAttributeId; + + if (_endpoint) { + params.mEndpointId = static_cast([_endpoint unsignedShortValue]); + } + + if (_cluster) { + params.mClusterId = static_cast([_cluster unsignedLongValue]); + } + + if (_attribute) { + params.mAttributeId = static_cast([_attribute unsignedLongValue]); + } +} @end @implementation MTREventRequestPath @@ -2288,6 +2257,25 @@ - (id)copyWithZone:(NSZone *)zone { return [MTREventRequestPath requestPathWithEndpointID:_endpoint clusterID:_cluster eventID:_event]; } + +- (void)convertToEventPathParams:(chip::app::EventPathParams &)params +{ + params.mEndpointId = kInvalidEndpointId; + params.mClusterId = kInvalidClusterId; + params.mEventId = kInvalidEventId; + + if (_endpoint) { + params.mEndpointId = static_cast([_endpoint unsignedShortValue]); + } + + if (_cluster) { + params.mClusterId = static_cast([_cluster unsignedLongValue]); + } + + if (_event) { + params.mEventId = static_cast([_event unsignedLongValue]); + } +} @end @implementation MTRClusterPath diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index 9fb062a90cceb2..f82f7d634bcdad 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -18,11 +18,13 @@ #import "MTRBaseDevice.h" #import +#include #include #include #include #include #include +#include @class MTRDeviceController; @@ -106,6 +108,14 @@ static inline MTRTransportType MTRMakeTransportType(chip::Transport::Type type) error:(NSError * _Nullable)error; @end +@interface MTRAttributeRequestPath () +- (void)convertToAttributePathParams:(const chip::app::AttributePathParams &)params; +@end + +@interface MTREventRequestPath () +- (void)convertToEventPathParams:(const chip::app::EventPathParams &)params; +@end + // Exported utility function // Convert TLV data into data-value dictionary as described in MTRDeviceResponseHandler id _Nullable MTRDecodeDataValueDictionaryFromCHIPTLV(chip::TLV::TLVReader * data); From e77bd17fa4a17db182d4bb11281cb7c7458c2b2e Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 11 Apr 2023 15:53:12 +0900 Subject: [PATCH 42/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 55 +++++++++++++--------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index e70f1aec7fe78f..870fceffcf94e4 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -752,9 +752,10 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; - BufferedReadClientCallback(app::AttributePathParams *aAttributePathParamsList, size_t aAttributePathParamsSize, - app::EventPathParams *aEventPathParamsList, size_t aEventPathParamsSize, OnSuccessAttributeCallbackType aOnAttributeSuccess, - OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, + BufferedReadClientCallback(app::AttributePathParams * aAttributePathParamsList, size_t aAttributePathParamsSize, + app::EventPathParams * aEventPathParamsList, size_t aEventPathParamsSize, + OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, + OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) : mAttributePathParamsList(aAttributePathParamsList) , mAttributePathParamsSize(aAttributePathParamsSize) @@ -788,7 +789,7 @@ void OnAttributeData( DecodableValueType value; VerifyOrExit(mOnAttributeSuccess != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - + VerifyOrExit(mAttributePathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); // @@ -821,7 +822,7 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons DecodableValueType value; VerifyOrExit(mOnEventSuccess != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - + VerifyOrExit(mEventPathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(std::find_if(mEventPathParamsList, mEventPathParamsList + mEventPathParamsSize, @@ -912,7 +913,8 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID } }; - app::AttributePathParams *attributePath = static_cast(Platform::MemoryCalloc(1, sizeof(AttributePathParams))); + app::AttributePathParams * attributePath + = static_cast(Platform::MemoryCalloc(1, sizeof(AttributePathParams))); if (endpointID) { attributePath->mEndpointId = static_cast([endpointID unsignedShortValue]); } @@ -1031,7 +1033,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri if (attributePaths != nil) { size_t count = 0; - attributePathParamsList = static_cast(Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); + attributePathParamsList = static_cast( + Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attributePath in attributePaths) { [attributePath convertToAttributePathParams:attributePathParamsList[count++]]; @@ -1040,7 +1043,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri if (eventPaths != nil) { size_t count = 0; - eventPathParamsList = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); + eventPathParamsList + = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTREventRequestPath * eventPath in eventPaths) { [eventPath convertToEventPathParams:eventPathParamsList[count++]]; @@ -1057,8 +1061,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri readParams.mpEventPathParamsList = eventPathParamsList; readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList, eventPathParamsList]( - BufferedReadClientCallback * callback) { + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList, + eventPathParamsList](BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); @@ -1076,7 +1080,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList, readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); + attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList, + readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); auto readClient = chip::Platform::MakeUnique( @@ -1196,16 +1201,16 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl if (attributePaths != nil) { container.pathParamsSize = 0; - container.pathParams = static_cast(Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); + container.pathParams = static_cast( + Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); for (MTRAttributeRequestPath * attributePath in attributePaths) { [attributePath convertToAttributePathParams:container.pathParams[container.pathParamsSize++]]; } - - } if (eventPaths != nil) { container.eventPathParamsSize = 0; - container.eventPathParams = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); + container.eventPathParams + = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); for (MTREventRequestPath * eventPath in eventPaths) { [eventPath convertToEventPathParams:container.eventPathParams[container.eventPathParamsSize++]]; } @@ -1229,8 +1234,8 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl }; auto callback = chip::Platform::MakeUnique>( - container.pathParams, container.pathParamsSize, container.eventPathParams, container.eventPathParamsSize, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, - onEstablishedCb); + container.pathParams, container.pathParamsSize, container.eventPathParams, container.eventPathParamsSize, + onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -1541,7 +1546,8 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - container.pathParams = static_cast(Platform::MemoryCalloc(1, sizeof(app::AttributePathParams))); + container.pathParams + = static_cast(Platform::MemoryCalloc(1, sizeof(app::AttributePathParams))); container.pathParamsSize = 1; if (endpointID) { container.pathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); @@ -1569,7 +1575,8 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID }; auto callback = chip::Platform::MakeUnique>( - container.pathParams, container.pathParamsSize, nullptr, 0, onReportCb, nullptr, onFailureCb, onDone, onEstablishedCb); + container.pathParams, container.pathParamsSize, nullptr, 0, onReportCb, nullptr, onFailureCb, onDone, + onEstablishedCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -1838,7 +1845,8 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID } }; - app::EventPathParams *eventPath = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); + app::EventPathParams * eventPath + = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); if (endpointID) { eventPath->mEndpointId = static_cast([endpointID unsignedShortValue]); } @@ -1966,7 +1974,8 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - container.eventPathParams = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); + container.eventPathParams + = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); container.eventPathParamsSize = 1; if (endpointID) { container.eventPathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); @@ -2193,7 +2202,7 @@ - (void)convertToAttributePathParams:(chip::app::AttributePathParams &)params params.mEndpointId = kInvalidEndpointId; params.mClusterId = kInvalidClusterId; params.mAttributeId = kInvalidAttributeId; - + if (_endpoint) { params.mEndpointId = static_cast([_endpoint unsignedShortValue]); } @@ -2263,7 +2272,7 @@ - (void)convertToEventPathParams:(chip::app::EventPathParams &)params params.mEndpointId = kInvalidEndpointId; params.mClusterId = kInvalidClusterId; params.mEventId = kInvalidEventId; - + if (_endpoint) { params.mEndpointId = static_cast([_endpoint unsignedShortValue]); } From cc4f374acd2105e7a1fd2a0af2d0ea9ea3ce2784 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 11 Apr 2023 16:07:25 +0900 Subject: [PATCH 43/72] Modify delete -> memoryfree --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 870fceffcf94e4..9a39a98c31bab4 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -145,11 +145,11 @@ static void PurgeReadClientContainers( asyncDispatchToMatterQueue:^() { for (MTRReadClientContainer * container in listToDelete) { if (container.readClientPtr) { - Platform::Delete(container.readClientPtr); + Platform::MemoryFree(container.readClientPtr); container.readClientPtr = nullptr; } if (container.pathParams) { - Platform::Delete(container.pathParams); + Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; } } @@ -1254,11 +1254,11 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl } Platform::Delete(readClient); if (container.pathParams != nullptr) { - Platform::Delete(container.pathParams); + Platform::MemoryFree(container.pathParams); } if (container.eventPathParams != nullptr) { - Platform::Delete(container.eventPathParams); + Platform::MemoryFree(container.eventPathParams); } container.pathParams = nullptr; container.eventPathParams = nullptr; From 7144454e244f803c901b40be67c9506a10e1646e Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 10:21:04 +0900 Subject: [PATCH 44/72] Update code --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 3 +- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 1038 +++++++++-------- .../Framework/CHIP/MTRBaseDevice_Internal.h | 4 +- 3 files changed, 552 insertions(+), 493 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 1e9f466e8c07e6..2bef6574c2a46b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -293,7 +293,8 @@ MTR_NEWLY_AVAILABLE; params:(MTRSubscribeParams * _Nullable)params queue:(dispatch_queue_t)queue reportHandler:(MTRDeviceResponseHandler)reportHandler - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished MTR_NEWLY_AVAILABLE; + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + resubscriptionScheduled:(MTRDeviceResubscriptionScheduledHandler _Nullable)resubscriptionScheduled MTR_NEWLY_AVAILABLE; /** * Write to attribute in a designated attribute path * diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 9a39a98c31bab4..6407d585a984f0 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -748,15 +748,17 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const = std::function; using OnSuccessEventCallbackType = std::function; using OnErrorCallbackType - = std::function; + = std::function; using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; + using OnDeviceResubscriptionScheduledCallbackType = std::function; BufferedReadClientCallback(app::AttributePathParams * aAttributePathParamsList, size_t aAttributePathParamsSize, app::EventPathParams * aEventPathParamsList, size_t aEventPathParamsSize, OnSuccessAttributeCallbackType aOnAttributeSuccess, OnSuccessEventCallbackType aOnEventSuccess, OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, - OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr) + OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr, + OnDeviceResubscriptionScheduledCallbackType aOnDeviceResubscriptionScheduled = nullptr) : mAttributePathParamsList(aAttributePathParamsList) , mAttributePathParamsSize(aAttributePathParamsSize) , mEventPathParamsList(aEventPathParamsList) @@ -766,6 +768,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const , mOnError(aOnError) , mOnDone(aOnDone) , mOnSubscriptionEstablished(aOnSubscriptionEstablished) + , mOnDeviceResubscriptionScheduled(aOnDeviceResubscriptionScheduled) , mBufferedReadAdapter(*this) { } @@ -812,7 +815,7 @@ void OnAttributeData( exit: if (err != CHIP_NO_ERROR) { - mOnError(&aPath, aPath.mAttributeId, err); + mOnError(&aPath, nullptr, err); } } @@ -839,11 +842,11 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons exit: if (err != CHIP_NO_ERROR) { - mOnError(&aEventHeader.mPath, aEventHeader.mPath.mEventId, err); + mOnError(nullptr, &aEventHeader.mPath, err); } } - void OnError(CHIP_ERROR aError) override { mOnError(nullptr, kInvalidAttributeId, aError); } + void OnError(CHIP_ERROR aError) override { mOnError(nullptr, nullptr, aError); } void OnDone(ReadClient *) override { mOnDone(this); } @@ -854,6 +857,20 @@ void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override } } + CHIP_ERROR OnResubscriptionNeeded(ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override + { + CHIP_ERROR err = ReadClient::Callback::OnResubscriptionNeeded(apReadClient, aTerminationCause); + ReturnErrorOnFailure(err); + + if (mOnDeviceResubscriptionScheduled != nullptr) { + auto callback = mOnDeviceResubscriptionScheduled; + auto error = [MTRError errorForCHIPErrorCode:aTerminationCause]; + auto delayMs = @(apReadClient->ComputeTimeTillNextSubscription()); + callback(error, delayMs); + } + return CHIP_NO_ERROR; + } + void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override {} OnSuccessAttributeCallbackType mOnAttributeSuccess; @@ -861,6 +878,7 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr OnErrorCallbackType mOnError; OnDoneCallbackType mOnDone; OnSubscriptionEstablishedCallbackType mOnSubscriptionEstablished; + OnDeviceResubscriptionScheduledCallbackType mOnDeviceResubscriptionScheduled; app::BufferedReadCallback mBufferedReadAdapter; Platform::UniquePtr mReadClient; app::AttributePathParams * mAttributePathParamsList; @@ -876,99 +894,101 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { - endpointID = (endpointID == nil) ? nil : [endpointID copy]; - clusterID = (clusterID == nil) ? nil : [clusterID copy]; - attributeID = (attributeID == nil) ? nil : [attributeID copy]; - params = (params == nil) ? nil : [params copy]; - auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, - ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, - MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - // interactionStatus tracks whether the whole read interaction has failed. - // - // Make sure interactionStatus survives even if this block scope is destroyed. - auto interactionStatus = std::make_shared(CHIP_NO_ERROR); - - auto resultArray = [[NSMutableArray alloc] init]; - auto onSuccessCb = [resultArray](const app::ConcreteAttributePath & attributePath, - const MTRDataValueDictionaryDecodableType & aData) { - [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; - - auto onFailureCb = [resultArray, interactionStatus]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { - if (clusterPath) { - app::ConcreteAttributePath attribPath(clusterPath->mEndpointId, clusterPath->mClusterId, aValueId); - [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], - MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] - }]; - } else { - // This will only happen once per read interaction, and - // after that there will be no more calls to onFailureCb or - // onSuccessCb. - *interactionStatus = aError; - } - }; - - app::AttributePathParams * attributePath - = static_cast(Platform::MemoryCalloc(1, sizeof(AttributePathParams))); - if (endpointID) { - attributePath->mEndpointId = static_cast([endpointID unsignedShortValue]); - } - if (clusterID) { - attributePath->mClusterId = static_cast([clusterID unsignedLongValue]); - } - if (attributeID) { - attributePath->mAttributeId = static_cast([attributeID unsignedLongValue]); - } - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; - - chip::app::ReadPrepareParams readParams(session); - [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = attributePath; - readParams.mAttributePathParamsListSize = 1; - - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePath]( - BufferedReadClientCallback * callback) { - if (*interactionStatus != CHIP_NO_ERROR) { - // Failure - failureCb(bridge, *interactionStatus); - } else { - // Success - successCb(bridge, resultArray); - } - chip::Platform::MemoryFree(attributePath); - chip::Platform::Delete(callback); - }; - - auto callback = chip::Platform::MakeUnique>( - attributePath, 1, nullptr, 0, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); - VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); - - auto readClient = chip::Platform::MakeUnique( - engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); - VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); - - err = readClient->SendRequest(readParams); - - if (err != CHIP_NO_ERROR) { - return err; - } - - // - // At this point, we'll get a callback through the OnDone callback above regardless of success or failure - // of the read operation to permit us to free up the callback object. So, release ownership of the callback - // object now to prevent it from being reclaimed at the end of this scoped block. - // - callback->AdoptReadClient(std::move(readClient)); - callback.release(); - return err; - }); - std::move(*bridge).DispatchAction(self); + NSArray * attributePaths = [NSArray arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; + [self readAttributePaths:attributePaths eventPaths:nil params:params queue:queue completion:completion]; +// endpointID = (endpointID == nil) ? nil : [endpointID copy]; +// clusterID = (clusterID == nil) ? nil : [clusterID copy]; +// attributeID = (attributeID == nil) ? nil : [attributeID copy]; +// params = (params == nil) ? nil : [params copy]; +// auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, +// ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, +// MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { +// // interactionStatus tracks whether the whole read interaction has failed. +// // +// // Make sure interactionStatus survives even if this block scope is destroyed. +// auto interactionStatus = std::make_shared(CHIP_NO_ERROR); +// +// auto resultArray = [[NSMutableArray alloc] init]; +// auto onSuccessCb = [resultArray](const app::ConcreteAttributePath & attributePath, +// const MTRDataValueDictionaryDecodableType & aData) { +// [resultArray addObject:@ { +// MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], +// MTRDataKey : aData.GetDecodedObject() +// }]; +// }; +// +// auto onFailureCb = [resultArray, interactionStatus]( +// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { +// if (attributePath) { +// app::ConcreteAttributePath attriPath(attributePath->mEndpointId, attributePath->mClusterId, attributePath->mAttributeId); +// [resultArray addObject:@ { +// MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attriPath], +// MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] +// }]; +// } else { +// // This will only happen once per read interaction, and +// // after that there will be no more calls to onFailureCb or +// // onSuccessCb. +// *interactionStatus = aError; +// } +// }; +// +// app::AttributePathParams * attributePath +// = static_cast(Platform::MemoryCalloc(1, sizeof(AttributePathParams))); +// if (endpointID) { +// attributePath->mEndpointId = static_cast([endpointID unsignedShortValue]); +// } +// if (clusterID) { +// attributePath->mClusterId = static_cast([clusterID unsignedLongValue]); +// } +// if (attributeID) { +// attributePath->mAttributeId = static_cast([attributeID unsignedLongValue]); +// } +// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); +// CHIP_ERROR err = CHIP_NO_ERROR; +// +// chip::app::ReadPrepareParams readParams(session); +// [params toReadPrepareParams:readParams]; +// readParams.mpAttributePathParamsList = attributePath; +// readParams.mAttributePathParamsListSize = 1; +// +// auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePath]( +// BufferedReadClientCallback * callback) { +// if (*interactionStatus != CHIP_NO_ERROR) { +// // Failure +// failureCb(bridge, *interactionStatus); +// } else { +// // Success +// successCb(bridge, resultArray); +// } +// chip::Platform::MemoryFree(attributePath); +// chip::Platform::Delete(callback); +// }; +// +// auto callback = chip::Platform::MakeUnique>( +// attributePath, 1, nullptr, 0, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); +// VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); +// +// auto readClient = chip::Platform::MakeUnique( +// engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); +// VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); +// +// err = readClient->SendRequest(readParams); +// +// if (err != CHIP_NO_ERROR) { +// return err; +// } +// +// // +// // At this point, we'll get a callback through the OnDone callback above regardless of success or failure +// // of the read operation to permit us to free up the callback object. So, release ownership of the callback +// // object now to prevent it from being reclaimed at the end of this scoped block. +// // +// callback->AdoptReadClient(std::move(readClient)); +// callback.release(); +// return err; +// }); +// std::move(*bridge).DispatchAction(self); } - (void)readAttributePaths:(NSArray * _Nullable)attributePaths @@ -984,8 +1004,21 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri return; } - attributePaths = (attributePaths == nil) ? nil : [attributePaths copy]; - eventPaths = (eventPaths == nil) ? nil : [eventPaths copy]; + NSMutableArray * attributes = nil; + if (attributePaths != nil) { + attributes = [[NSMutableArray alloc] init]; + for (MTRAttributeRequestPath * attributePath in attributePaths) { + [attributes addObject:[attributePath copy]]; + } + } + + NSMutableArray * events = nil; + if (eventPaths != nil) { + events = [[NSMutableArray alloc] init]; + for (MTRAttributeRequestPath * eventPath in eventPaths) { + [events addObject:[eventPath copy]]; + } + } params = (params == nil) ? nil : [params copy]; auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, @@ -1013,11 +1046,17 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri }; auto onFailureCb = [resultArray, interactionStatus]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { - if (clusterPath) { - app::ConcreteAttributePath attribPath(clusterPath->mEndpointId, clusterPath->mClusterId, aValueId); + const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { + if (attributePath != nullptr) { +// ConcreteAttributePath path(attributePath->mEndpointId, attributePath->mClusterId, attributePath->mAttributeId); + [resultArray addObject:@ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:*attributePath], + MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] + }]; + } else if (eventPath != nullptr) { +// ConcreteEventPath path(eventPath->mEndpointId, eventPath->mClusterId, eventPath->mEventId); [resultArray addObject:@ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attribPath], + MTREventPathKey : [[MTREventPath alloc] initWithPath:*eventPath], MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] }]; } else { @@ -1031,23 +1070,23 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri AttributePathParams * attributePathParamsList = nullptr; EventPathParams * eventPathParamsList = nullptr; - if (attributePaths != nil) { + if (attributes != nil) { size_t count = 0; attributePathParamsList = static_cast( - Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); + Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); - for (MTRAttributeRequestPath * attributePath in attributePaths) { - [attributePath convertToAttributePathParams:attributePathParamsList[count++]]; + for (MTRAttributeRequestPath * attribute in attributes) { + [attribute convertToAttributePathParams:attributePathParamsList[count++]]; } } - if (eventPaths != nil) { + if (events != nil) { size_t count = 0; eventPathParamsList - = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); + = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); - for (MTREventRequestPath * eventPath in eventPaths) { - [eventPath convertToEventPathParams:eventPathParamsList[count++]]; + for (MTREventRequestPath * event in events) { + [event convertToEventPathParams:eventPathParamsList[count++]]; } } @@ -1107,11 +1146,12 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } - (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths - EventPaths:(NSArray * _Nullable)eventPaths + eventPaths:(NSArray * _Nullable)eventPaths params:(MTRSubscribeParams * _Nullable)params queue:(dispatch_queue_t)queue reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + resubscriptionScheduled:(MTRDeviceResubscriptionScheduledHandler _Nullable)resubscriptionScheduled { if ((attributePaths == nil || [attributePaths count] == 0) && (eventPaths == nil || [eventPaths count] == 0)) { dispatch_async(queue, ^{ @@ -1129,8 +1169,22 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl } // Copy params before going async. - attributePaths = (attributePaths == nil) ? nil : [attributePaths copy]; - eventPaths = (eventPaths == nil) ? nil : [eventPaths copy]; + NSMutableArray * attributes = nil; + if (attributePaths != nil) { + attributes = [[NSMutableArray alloc] init]; + for (MTRAttributeRequestPath * attributePath in attributePaths) { + [attributes addObject:[attributePath copy]]; + } + } + + NSMutableArray * events = nil; + if (eventPaths != nil) { + events = [[NSMutableArray alloc] init]; + for (MTRAttributeRequestPath * eventPath in eventPaths) { + [events addObject:[eventPath copy]]; + } + } + params = (params == nil) ? nil : [params copy]; [self.deviceController @@ -1172,7 +1226,8 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl auto establishedOrFailed = chip::Platform::MakeShared(NO); auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR error) { + const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR error) { + // TODO, Requires additional logic if attributePath or eventPath is not null if (!(*establishedOrFailed)) { *establishedOrFailed = YES; if (subscriptionEstablished) { @@ -1195,24 +1250,30 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl dispatch_async(queue, subscriptionEstablished); } }; + + auto onResubscriptionScheduledCb = [resubscriptionScheduled](NSError * error, NSNumber * resubscriptionDelay) { + if (resubscriptionScheduled) { + resubscriptionScheduled(error, resubscriptionDelay); + } + }; MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; - if (attributePaths != nil) { + if (attributes != nil) { container.pathParamsSize = 0; container.pathParams = static_cast( - Platform::MemoryCalloc([attributePaths count], sizeof(AttributePathParams))); - for (MTRAttributeRequestPath * attributePath in attributePaths) { - [attributePath convertToAttributePathParams:container.pathParams[container.pathParamsSize++]]; + Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); + for (MTRAttributeRequestPath * attribute in attributes) { + [attribute convertToAttributePathParams:container.pathParams[container.pathParamsSize++]]; } } - if (eventPaths != nil) { + if (events != nil) { container.eventPathParamsSize = 0; container.eventPathParams - = static_cast(Platform::MemoryCalloc([eventPaths count], sizeof(EventPathParams))); - for (MTREventRequestPath * eventPath in eventPaths) { - [eventPath convertToEventPathParams:container.eventPathParams[container.eventPathParamsSize++]]; + = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); + for (MTREventRequestPath * event in events) { + [event convertToEventPathParams:container.eventPathParams[container.eventPathParamsSize++]]; } } @@ -1235,7 +1296,7 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl auto callback = chip::Platform::MakeUnique>( container.pathParams, container.pathParamsSize, container.eventPathParams, container.eventPathParamsSize, - onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb); + onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb, onResubscriptionScheduledCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); @@ -1479,131 +1540,133 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler)subscriptionEstablished { - if (self.isPASEDevice) { - // We don't support subscriptions over PASE. - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); - }); - return; - } - - // Copy params before going async. - endpointID = (endpointID == nil) ? nil : [endpointID copy]; - clusterID = (clusterID == nil) ? nil : [clusterID copy]; - attributeID = (attributeID == nil) ? nil : [attributeID copy]; - params = (params == nil) ? nil : [params copy]; - - [self.deviceController - getSessionForNode:self.nodeID - completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, - NSError * _Nullable error) { - if (error != nil) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, error); - }); - } - return; - } - - auto onReportCb = [queue, reportHandler](const app::ConcreteAttributePath & attributePath, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - dispatch_async(queue, ^{ - reportHandler(@[ @ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], - MTRDataKey : valueObject - } ], - nil); - }); - }; - - auto establishedOrFailed = chip::Platform::MakeShared(NO); - auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR error) { - if (!(*establishedOrFailed)) { - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - } - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); - }); - } - }; - - auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { - if (*establishedOrFailed) { - return; - } - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - }; - - MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; - container.deviceID = self.nodeID; - container.pathParams - = static_cast(Platform::MemoryCalloc(1, sizeof(app::AttributePathParams))); - container.pathParamsSize = 1; - if (endpointID) { - container.pathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); - } - if (clusterID) { - container.pathParams->mClusterId = static_cast([clusterID unsignedLongValue]); - } - if (attributeID) { - container.pathParams->mAttributeId = static_cast([attributeID unsignedLongValue]); - } - - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; - - chip::app::ReadPrepareParams readParams(session.Value()); - [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = container.pathParams; - readParams.mAttributePathParamsListSize = 1; - - auto onDone = [container](BufferedReadClientCallback * callback) { - [container onDone]; - // Make sure we delete callback last, because doing that actually destroys our - // lambda, so we can't access captured values after that. - chip::Platform::Delete(callback); - }; - - auto callback = chip::Platform::MakeUnique>( - container.pathParams, container.pathParamsSize, nullptr, 0, onReportCb, nullptr, onFailureCb, onDone, - onEstablishedCb); - - auto readClient = Platform::New( - engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); - - if (!params.resubscribeAutomatically) { - err = readClient->SendRequest(readParams); - } else { - err = readClient->SendAutoResubscribeRequest(std::move(readParams)); - } - - if (err != CHIP_NO_ERROR) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); - }); - } - Platform::Delete(readClient); - Platform::MemoryFree(container.pathParams); - container.pathParams = nullptr; - return; - } - - // Read clients will be purged when deregistered. - container.readClientPtr = readClient; - AddReadClientContainer(container.deviceID, container); - callback.release(); - }]; + NSArray * attributePaths = [NSArray arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; + [self subscribeToAttributePaths:attributePaths eventPaths:nil params:params queue:queue reportHandler:reportHandler subscriptionEstablished:subscriptionEstablished resubscriptionScheduled:nil]; +// if (self.isPASEDevice) { +// // We don't support subscriptions over PASE. +// dispatch_async(queue, ^{ +// reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); +// }); +// return; +// } +// +// // Copy params before going async. +// endpointID = (endpointID == nil) ? nil : [endpointID copy]; +// clusterID = (clusterID == nil) ? nil : [clusterID copy]; +// attributeID = (attributeID == nil) ? nil : [attributeID copy]; +// params = (params == nil) ? nil : [params copy]; +// +// [self.deviceController +// getSessionForNode:self.nodeID +// completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, +// NSError * _Nullable error) { +// if (error != nil) { +// if (reportHandler) { +// dispatch_async(queue, ^{ +// reportHandler(nil, error); +// }); +// } +// return; +// } +// +// auto onReportCb = [queue, reportHandler](const app::ConcreteAttributePath & attributePath, +// const MTRDataValueDictionaryDecodableType & data) { +// id valueObject = data.GetDecodedObject(); +// dispatch_async(queue, ^{ +// reportHandler(@[ @ { +// MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], +// MTRDataKey : valueObject +// } ], +// nil); +// }); +// }; +// +// auto establishedOrFailed = chip::Platform::MakeShared(NO); +// auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( +// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { +// if (!(*establishedOrFailed)) { +// *establishedOrFailed = YES; +// if (subscriptionEstablished) { +// dispatch_async(queue, subscriptionEstablished); +// } +// } +// if (reportHandler) { +// dispatch_async(queue, ^{ +// reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); +// }); +// } +// }; +// +// auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { +// if (*establishedOrFailed) { +// return; +// } +// *establishedOrFailed = YES; +// if (subscriptionEstablished) { +// dispatch_async(queue, subscriptionEstablished); +// } +// }; +// +// MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; +// container.deviceID = self.nodeID; +// container.pathParams +// = static_cast(Platform::MemoryCalloc(1, sizeof(app::AttributePathParams))); +// container.pathParamsSize = 1; +// if (endpointID) { +// container.pathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); +// } +// if (clusterID) { +// container.pathParams->mClusterId = static_cast([clusterID unsignedLongValue]); +// } +// if (attributeID) { +// container.pathParams->mAttributeId = static_cast([attributeID unsignedLongValue]); +// } +// +// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); +// CHIP_ERROR err = CHIP_NO_ERROR; +// +// chip::app::ReadPrepareParams readParams(session.Value()); +// [params toReadPrepareParams:readParams]; +// readParams.mpAttributePathParamsList = container.pathParams; +// readParams.mAttributePathParamsListSize = 1; +// +// auto onDone = [container](BufferedReadClientCallback * callback) { +// [container onDone]; +// // Make sure we delete callback last, because doing that actually destroys our +// // lambda, so we can't access captured values after that. +// chip::Platform::Delete(callback); +// }; +// +// auto callback = chip::Platform::MakeUnique>( +// container.pathParams, container.pathParamsSize, nullptr, 0, onReportCb, nullptr, onFailureCb, onDone, +// onEstablishedCb); +// +// auto readClient = Platform::New( +// engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); +// +// if (!params.resubscribeAutomatically) { +// err = readClient->SendRequest(readParams); +// } else { +// err = readClient->SendAutoResubscribeRequest(std::move(readParams)); +// } +// +// if (err != CHIP_NO_ERROR) { +// if (reportHandler) { +// dispatch_async(queue, ^{ +// reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); +// }); +// } +// Platform::Delete(readClient); +// Platform::MemoryFree(container.pathParams); +// container.pathParams = nullptr; +// return; +// } +// +// // Read clients will be purged when deregistered. +// container.readClientPtr = readClient; +// AddReadClientContainer(container.deviceID, container); +// callback.release(); +// }]; } - (void)deregisterReportHandlersWithQueue:(dispatch_queue_t)queue completion:(dispatch_block_t)completion @@ -1808,97 +1871,98 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { - endpointID = (endpointID == nil) ? nil : [endpointID copy]; - clusterID = (clusterID == nil) ? nil : [clusterID copy]; - eventID = (eventID == nil) ? nil : [eventID copy]; - params = (params == nil) ? nil : [params copy]; - auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, - ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, - MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - // interactionStatus tracks whether the whole read interaction has failed. - // - // Make sure interactionStatus survives even if this block scope is destroyed. - auto interactionStatus = std::make_shared(CHIP_NO_ERROR); - - auto resultArray = [[NSMutableArray alloc] init]; - auto onSuccessCb - = [resultArray](const app::ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { - [resultArray addObject:@ { - MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], - MTRDataKey : aData.GetDecodedObject() - }]; - }; - - auto onFailureCb = [resultArray, interactionStatus]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR aError) { - if (clusterPath) { - app::ConcreteEventPath eventPath(clusterPath->mEndpointId, clusterPath->mClusterId, aValueId); - [resultArray addObject:@ { - MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], - MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] - }]; - } else { - // This will only happen once per read interaction, and - // after that there will be no more calls to onFailureCb or - // onSuccessCb. - *interactionStatus = aError; - } - }; - - app::EventPathParams * eventPath - = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); - if (endpointID) { - eventPath->mEndpointId = static_cast([endpointID unsignedShortValue]); - } - if (clusterID) { - eventPath->mClusterId = static_cast([clusterID unsignedLongValue]); - } - if (eventID) { - eventPath->mEventId = static_cast([eventID unsignedLongValue]); - } - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; - - chip::app::ReadPrepareParams readParams(session); - [params toReadPrepareParams:readParams]; - readParams.mpEventPathParamsList = eventPath; - readParams.mEventPathParamsListSize = 1; - - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( - BufferedReadClientCallback * callback) { - if (*interactionStatus != CHIP_NO_ERROR) { - // Failure - failureCb(bridge, *interactionStatus); - } else { - successCb(bridge, resultArray); - } - chip::Platform::Delete(callback); - }; - - auto callback = chip::Platform::MakeUnique>( - nullptr, 0, eventPath, 1, nullptr, onSuccessCb, onFailureCb, onDone, nullptr); - VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); - - auto readClient = chip::Platform::MakeUnique( - engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); - VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); - - err = readClient->SendRequest(readParams); - - if (err != CHIP_NO_ERROR) { - return err; - } - - // - // At this point, we'll get a callback through the OnDone callback above regardless of success or failure - // of the read operation to permit us to free up the callback object. So, release ownership of the callback - // object now to prevent it from being reclaimed at the end of this scoped block. - // - callback->AdoptReadClient(std::move(readClient)); - callback.release(); - return err; - }); - std::move(*bridge).DispatchAction(self); + NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID]]; + [self readAttributePaths:nil eventPaths:eventPaths params:params queue:queue completion:completion]; +// endpointID = (endpointID == nil) ? nil : [endpointID copy]; +// clusterID = (clusterID == nil) ? nil : [clusterID copy]; +// eventID = (eventID == nil) ? nil : [eventID copy]; +// params = (params == nil) ? nil : [params copy]; +// auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, +// ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, +// MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { +// // interactionStatus tracks whether the whole read interaction has failed. +// // +// // Make sure interactionStatus survives even if this block scope is destroyed. +// auto interactionStatus = std::make_shared(CHIP_NO_ERROR); +// +// auto resultArray = [[NSMutableArray alloc] init]; +// auto onSuccessCb +// = [resultArray](const app::ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { +// [resultArray addObject:@ { +// MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], +// MTRDataKey : aData.GetDecodedObject() +// }]; +// }; +// +// auto onFailureCb = [resultArray, interactionStatus]( +// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { +// if (eventPath) { +// [resultArray addObject:@ { +// MTREventPathKey : [[MTREventPath alloc] initWithPath:*eventPath], +// MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] +// }]; +// } else { +// // This will only happen once per read interaction, and +// // after that there will be no more calls to onFailureCb or +// // onSuccessCb. +// *interactionStatus = aError; +// } +// }; +// +// app::EventPathParams * eventPath +// = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); +// if (endpointID) { +// eventPath->mEndpointId = static_cast([endpointID unsignedShortValue]); +// } +// if (clusterID) { +// eventPath->mClusterId = static_cast([clusterID unsignedLongValue]); +// } +// if (eventID) { +// eventPath->mEventId = static_cast([eventID unsignedLongValue]); +// } +// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); +// CHIP_ERROR err = CHIP_NO_ERROR; +// +// chip::app::ReadPrepareParams readParams(session); +// [params toReadPrepareParams:readParams]; +// readParams.mpEventPathParamsList = eventPath; +// readParams.mEventPathParamsListSize = 1; +// +// auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( +// BufferedReadClientCallback * callback) { +// if (*interactionStatus != CHIP_NO_ERROR) { +// // Failure +// failureCb(bridge, *interactionStatus); +// } else { +// successCb(bridge, resultArray); +// } +// chip::Platform::Delete(callback); +// }; +// +// auto callback = chip::Platform::MakeUnique>( +// nullptr, 0, eventPath, 1, nullptr, onSuccessCb, onFailureCb, onDone, nullptr); +// VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); +// +// auto readClient = chip::Platform::MakeUnique( +// engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); +// VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); +// +// err = readClient->SendRequest(readParams); +// +// if (err != CHIP_NO_ERROR) { +// return err; +// } +// +// // +// // At this point, we'll get a callback through the OnDone callback above regardless of success or failure +// // of the read operation to permit us to free up the callback object. So, release ownership of the callback +// // object now to prevent it from being reclaimed at the end of this scoped block. +// // +// callback->AdoptReadClient(std::move(readClient)); +// callback.release(); +// return err; +// }); +// std::move(*bridge).DispatchAction(self); } - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID @@ -1909,129 +1973,131 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler)subscriptionEstablished { - if (self.isPASEDevice) { - // We don't support subscriptions over PASE. - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); - }); - return; - } - - // Copy params before going async. - endpointID = (endpointID == nil) ? nil : [endpointID copy]; - clusterID = (clusterID == nil) ? nil : [clusterID copy]; - eventID = (eventID == nil) ? nil : [eventID copy]; - params = (params == nil) ? nil : [params copy]; - - [self.deviceController - getSessionForNode:self.nodeID - completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, - NSError * _Nullable error) { - if (error != nil) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, error); - }); - } - return; - } - - auto onReportCb = [queue, reportHandler](const app::ConcreteEventPath & eventPath, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - dispatch_async(queue, ^{ - reportHandler( - @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], MTRDataKey : valueObject } ], - nil); - }); - }; - - auto establishedOrFailed = chip::Platform::MakeShared(NO); - auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( - const app::ConcreteClusterPath * clusterPath, const uint32_t aValueId, CHIP_ERROR error) { - if (!(*establishedOrFailed)) { - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - } - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); - }); - } - }; - - auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { - if (*establishedOrFailed) { - return; - } - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - }; - - MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; - container.deviceID = self.nodeID; - container.eventPathParams - = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); - container.eventPathParamsSize = 1; - if (endpointID) { - container.eventPathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); - } - if (clusterID) { - container.eventPathParams->mClusterId = static_cast([clusterID unsignedLongValue]); - } - if (eventID) { - container.eventPathParams->mEventId = static_cast([eventID unsignedLongValue]); - } - container.eventPathParams->mIsUrgentEvent = params.reportEventsUrgently; - - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; - - chip::app::ReadPrepareParams readParams(session.Value()); - [params toReadPrepareParams:readParams]; - readParams.mpEventPathParamsList = container.eventPathParams; - readParams.mEventPathParamsListSize = 1; - - auto onDone = [container](BufferedReadClientCallback * callback) { - [container onDone]; - // Make sure we delete callback last, because doing that actually destroys our - // lambda, so we can't access captured values after that. - chip::Platform::Delete(callback); - }; - - auto callback = chip::Platform::MakeUnique>( - nullptr, 0, container.eventPathParams, 1, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); - - auto readClient = Platform::New( - engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); - - if (!params.resubscribeAutomatically) { - err = readClient->SendRequest(readParams); - } else { - err = readClient->SendAutoResubscribeRequest(std::move(readParams)); - } - - if (err != CHIP_NO_ERROR) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); - }); - } - Platform::Delete(readClient); - Platform::MemoryFree(container.eventPathParams); - container.eventPathParams = nullptr; - return; - } - - // Read clients will be purged when deregistered. - container.readClientPtr = readClient; - AddReadClientContainer(container.deviceID, container); - callback.release(); - }]; + NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID]]; + [self subscribeToAttributePaths:nil eventPaths:eventPaths params:params queue:queue reportHandler:reportHandler subscriptionEstablished:subscriptionEstablished resubscriptionScheduled:nil]; +// if (self.isPASEDevice) { +// // We don't support subscriptions over PASE. +// dispatch_async(queue, ^{ +// reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); +// }); +// return; +// } +// +// // Copy params before going async. +// endpointID = (endpointID == nil) ? nil : [endpointID copy]; +// clusterID = (clusterID == nil) ? nil : [clusterID copy]; +// eventID = (eventID == nil) ? nil : [eventID copy]; +// params = (params == nil) ? nil : [params copy]; +// +// [self.deviceController +// getSessionForNode:self.nodeID +// completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, +// NSError * _Nullable error) { +// if (error != nil) { +// if (reportHandler) { +// dispatch_async(queue, ^{ +// reportHandler(nil, error); +// }); +// } +// return; +// } +// +// auto onReportCb = [queue, reportHandler](const app::ConcreteEventPath & eventPath, +// const MTRDataValueDictionaryDecodableType & data) { +// id valueObject = data.GetDecodedObject(); +// dispatch_async(queue, ^{ +// reportHandler( +// @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], MTRDataKey : valueObject } ], +// nil); +// }); +// }; +// +// auto establishedOrFailed = chip::Platform::MakeShared(NO); +// auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( +// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aErrorOh) { +// if (!(*establishedOrFailed)) { +// *establishedOrFailed = YES; +// if (subscriptionEstablished) { +// dispatch_async(queue, subscriptionEstablished); +// } +// } +// if (reportHandler) { +// dispatch_async(queue, ^{ +// reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); +// }); +// } +// }; +// +// auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { +// if (*establishedOrFailed) { +// return; +// } +// *establishedOrFailed = YES; +// if (subscriptionEstablished) { +// dispatch_async(queue, subscriptionEstablished); +// } +// }; +// +// MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; +// container.deviceID = self.nodeID; +// container.eventPathParams +// = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); +// container.eventPathParamsSize = 1; +// if (endpointID) { +// container.eventPathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); +// } +// if (clusterID) { +// container.eventPathParams->mClusterId = static_cast([clusterID unsignedLongValue]); +// } +// if (eventID) { +// container.eventPathParams->mEventId = static_cast([eventID unsignedLongValue]); +// } +// container.eventPathParams->mIsUrgentEvent = params.reportEventsUrgently; +// +// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); +// CHIP_ERROR err = CHIP_NO_ERROR; +// +// chip::app::ReadPrepareParams readParams(session.Value()); +// [params toReadPrepareParams:readParams]; +// readParams.mpEventPathParamsList = container.eventPathParams; +// readParams.mEventPathParamsListSize = 1; +// +// auto onDone = [container](BufferedReadClientCallback * callback) { +// [container onDone]; +// // Make sure we delete callback last, because doing that actually destroys our +// // lambda, so we can't access captured values after that. +// chip::Platform::Delete(callback); +// }; +// +// auto callback = chip::Platform::MakeUnique>( +// nullptr, 0, container.eventPathParams, 1, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); +// +// auto readClient = Platform::New( +// engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); +// +// if (!params.resubscribeAutomatically) { +// err = readClient->SendRequest(readParams); +// } else { +// err = readClient->SendAutoResubscribeRequest(std::move(readParams)); +// } +// +// if (err != CHIP_NO_ERROR) { +// if (reportHandler) { +// dispatch_async(queue, ^{ +// reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); +// }); +// } +// Platform::Delete(readClient); +// Platform::MemoryFree(container.eventPathParams); +// container.eventPathParams = nullptr; +// return; +// } +// +// // Read clients will be purged when deregistered. +// container.readClientPtr = readClient; +// AddReadClientContainer(container.deviceID, container); +// callback.release(); +// }]; } @end @@ -2152,9 +2218,9 @@ - (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID attributeID:(NSNumber * _Nullable)attributeID { - _endpoint = endpointID; - _cluster = clusterID; - _attribute = attributeID; + _endpoint = [endpointID copy]; + _cluster = [clusterID copy]; + _attribute = [attributeID copy]; return self; } @@ -2199,20 +2265,16 @@ - (id)copyWithZone:(NSZone *)zone - (void)convertToAttributePathParams:(chip::app::AttributePathParams &)params { - params.mEndpointId = kInvalidEndpointId; - params.mClusterId = kInvalidClusterId; - params.mAttributeId = kInvalidAttributeId; - - if (_endpoint) { - params.mEndpointId = static_cast([_endpoint unsignedShortValue]); + if (_endpoint != nil) { + params.mEndpointId = static_cast(_endpoint.unsignedShortValue); } - if (_cluster) { - params.mClusterId = static_cast([_cluster unsignedLongValue]); + if (_cluster != nil) { + params.mClusterId = static_cast(_cluster.unsignedLongValue); } - if (_attribute) { - params.mAttributeId = static_cast([_attribute unsignedLongValue]); + if (_attribute != nil) { + params.mAttributeId = static_cast(_attribute.unsignedLongValue); } } @end @@ -2222,9 +2284,9 @@ - (instancetype)initWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID eventID:(NSNumber * _Nullable)eventID { - _endpoint = endpointID; - _cluster = clusterID; - _event = eventID; + _endpoint = [endpointID copy]; + _cluster = [clusterID copy]; + _event = [eventID copy]; return self; } @@ -2269,20 +2331,16 @@ - (id)copyWithZone:(NSZone *)zone - (void)convertToEventPathParams:(chip::app::EventPathParams &)params { - params.mEndpointId = kInvalidEndpointId; - params.mClusterId = kInvalidClusterId; - params.mEventId = kInvalidEventId; - - if (_endpoint) { - params.mEndpointId = static_cast([_endpoint unsignedShortValue]); + if (_endpoint != nil) { + params.mEndpointId = static_cast(_endpoint.unsignedShortValue); } - if (_cluster) { - params.mClusterId = static_cast([_cluster unsignedLongValue]); + if (_cluster != nil) { + params.mClusterId = static_cast(_cluster.unsignedLongValue); } - if (_event) { - params.mEventId = static_cast([_event unsignedLongValue]); + if (_event != nil) { + params.mEventId = static_cast(_event.unsignedLongValue); } } @end diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index f82f7d634bcdad..cf5944a0a66a5d 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -109,11 +109,11 @@ static inline MTRTransportType MTRMakeTransportType(chip::Transport::Type type) @end @interface MTRAttributeRequestPath () -- (void)convertToAttributePathParams:(const chip::app::AttributePathParams &)params; +- (void)convertToAttributePathParams:(chip::app::AttributePathParams &)params; @end @interface MTREventRequestPath () -- (void)convertToEventPathParams:(const chip::app::EventPathParams &)params; +- (void)convertToEventPathParams:(chip::app::EventPathParams &)params; @end // Exported utility function From 32cc8cef66b9484f24ed07a6b8f27c298dd55dd4 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 10:24:53 +0900 Subject: [PATCH 45/72] remove unused code --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 433 --------------------- 1 file changed, 433 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 6407d585a984f0..650b18b35f331c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -896,99 +896,6 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID { NSArray * attributePaths = [NSArray arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; [self readAttributePaths:attributePaths eventPaths:nil params:params queue:queue completion:completion]; -// endpointID = (endpointID == nil) ? nil : [endpointID copy]; -// clusterID = (clusterID == nil) ? nil : [clusterID copy]; -// attributeID = (attributeID == nil) ? nil : [attributeID copy]; -// params = (params == nil) ? nil : [params copy]; -// auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, -// ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, -// MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { -// // interactionStatus tracks whether the whole read interaction has failed. -// // -// // Make sure interactionStatus survives even if this block scope is destroyed. -// auto interactionStatus = std::make_shared(CHIP_NO_ERROR); -// -// auto resultArray = [[NSMutableArray alloc] init]; -// auto onSuccessCb = [resultArray](const app::ConcreteAttributePath & attributePath, -// const MTRDataValueDictionaryDecodableType & aData) { -// [resultArray addObject:@ { -// MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], -// MTRDataKey : aData.GetDecodedObject() -// }]; -// }; -// -// auto onFailureCb = [resultArray, interactionStatus]( -// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { -// if (attributePath) { -// app::ConcreteAttributePath attriPath(attributePath->mEndpointId, attributePath->mClusterId, attributePath->mAttributeId); -// [resultArray addObject:@ { -// MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attriPath], -// MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] -// }]; -// } else { -// // This will only happen once per read interaction, and -// // after that there will be no more calls to onFailureCb or -// // onSuccessCb. -// *interactionStatus = aError; -// } -// }; -// -// app::AttributePathParams * attributePath -// = static_cast(Platform::MemoryCalloc(1, sizeof(AttributePathParams))); -// if (endpointID) { -// attributePath->mEndpointId = static_cast([endpointID unsignedShortValue]); -// } -// if (clusterID) { -// attributePath->mClusterId = static_cast([clusterID unsignedLongValue]); -// } -// if (attributeID) { -// attributePath->mAttributeId = static_cast([attributeID unsignedLongValue]); -// } -// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); -// CHIP_ERROR err = CHIP_NO_ERROR; -// -// chip::app::ReadPrepareParams readParams(session); -// [params toReadPrepareParams:readParams]; -// readParams.mpAttributePathParamsList = attributePath; -// readParams.mAttributePathParamsListSize = 1; -// -// auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePath]( -// BufferedReadClientCallback * callback) { -// if (*interactionStatus != CHIP_NO_ERROR) { -// // Failure -// failureCb(bridge, *interactionStatus); -// } else { -// // Success -// successCb(bridge, resultArray); -// } -// chip::Platform::MemoryFree(attributePath); -// chip::Platform::Delete(callback); -// }; -// -// auto callback = chip::Platform::MakeUnique>( -// attributePath, 1, nullptr, 0, onSuccessCb, nullptr, onFailureCb, onDone, nullptr); -// VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); -// -// auto readClient = chip::Platform::MakeUnique( -// engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); -// VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); -// -// err = readClient->SendRequest(readParams); -// -// if (err != CHIP_NO_ERROR) { -// return err; -// } -// -// // -// // At this point, we'll get a callback through the OnDone callback above regardless of success or failure -// // of the read operation to permit us to free up the callback object. So, release ownership of the callback -// // object now to prevent it from being reclaimed at the end of this scoped block. -// // -// callback->AdoptReadClient(std::move(readClient)); -// callback.release(); -// return err; -// }); -// std::move(*bridge).DispatchAction(self); } - (void)readAttributePaths:(NSArray * _Nullable)attributePaths @@ -1048,13 +955,11 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri auto onFailureCb = [resultArray, interactionStatus]( const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { if (attributePath != nullptr) { -// ConcreteAttributePath path(attributePath->mEndpointId, attributePath->mClusterId, attributePath->mAttributeId); [resultArray addObject:@ { MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:*attributePath], MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] }]; } else if (eventPath != nullptr) { -// ConcreteEventPath path(eventPath->mEndpointId, eventPath->mClusterId, eventPath->mEventId); [resultArray addObject:@ { MTREventPathKey : [[MTREventPath alloc] initWithPath:*eventPath], MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] @@ -1542,131 +1447,6 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID { NSArray * attributePaths = [NSArray arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; [self subscribeToAttributePaths:attributePaths eventPaths:nil params:params queue:queue reportHandler:reportHandler subscriptionEstablished:subscriptionEstablished resubscriptionScheduled:nil]; -// if (self.isPASEDevice) { -// // We don't support subscriptions over PASE. -// dispatch_async(queue, ^{ -// reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); -// }); -// return; -// } -// -// // Copy params before going async. -// endpointID = (endpointID == nil) ? nil : [endpointID copy]; -// clusterID = (clusterID == nil) ? nil : [clusterID copy]; -// attributeID = (attributeID == nil) ? nil : [attributeID copy]; -// params = (params == nil) ? nil : [params copy]; -// -// [self.deviceController -// getSessionForNode:self.nodeID -// completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, -// NSError * _Nullable error) { -// if (error != nil) { -// if (reportHandler) { -// dispatch_async(queue, ^{ -// reportHandler(nil, error); -// }); -// } -// return; -// } -// -// auto onReportCb = [queue, reportHandler](const app::ConcreteAttributePath & attributePath, -// const MTRDataValueDictionaryDecodableType & data) { -// id valueObject = data.GetDecodedObject(); -// dispatch_async(queue, ^{ -// reportHandler(@[ @ { -// MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:attributePath], -// MTRDataKey : valueObject -// } ], -// nil); -// }); -// }; -// -// auto establishedOrFailed = chip::Platform::MakeShared(NO); -// auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( -// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { -// if (!(*establishedOrFailed)) { -// *establishedOrFailed = YES; -// if (subscriptionEstablished) { -// dispatch_async(queue, subscriptionEstablished); -// } -// } -// if (reportHandler) { -// dispatch_async(queue, ^{ -// reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); -// }); -// } -// }; -// -// auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { -// if (*establishedOrFailed) { -// return; -// } -// *establishedOrFailed = YES; -// if (subscriptionEstablished) { -// dispatch_async(queue, subscriptionEstablished); -// } -// }; -// -// MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; -// container.deviceID = self.nodeID; -// container.pathParams -// = static_cast(Platform::MemoryCalloc(1, sizeof(app::AttributePathParams))); -// container.pathParamsSize = 1; -// if (endpointID) { -// container.pathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); -// } -// if (clusterID) { -// container.pathParams->mClusterId = static_cast([clusterID unsignedLongValue]); -// } -// if (attributeID) { -// container.pathParams->mAttributeId = static_cast([attributeID unsignedLongValue]); -// } -// -// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); -// CHIP_ERROR err = CHIP_NO_ERROR; -// -// chip::app::ReadPrepareParams readParams(session.Value()); -// [params toReadPrepareParams:readParams]; -// readParams.mpAttributePathParamsList = container.pathParams; -// readParams.mAttributePathParamsListSize = 1; -// -// auto onDone = [container](BufferedReadClientCallback * callback) { -// [container onDone]; -// // Make sure we delete callback last, because doing that actually destroys our -// // lambda, so we can't access captured values after that. -// chip::Platform::Delete(callback); -// }; -// -// auto callback = chip::Platform::MakeUnique>( -// container.pathParams, container.pathParamsSize, nullptr, 0, onReportCb, nullptr, onFailureCb, onDone, -// onEstablishedCb); -// -// auto readClient = Platform::New( -// engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); -// -// if (!params.resubscribeAutomatically) { -// err = readClient->SendRequest(readParams); -// } else { -// err = readClient->SendAutoResubscribeRequest(std::move(readParams)); -// } -// -// if (err != CHIP_NO_ERROR) { -// if (reportHandler) { -// dispatch_async(queue, ^{ -// reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); -// }); -// } -// Platform::Delete(readClient); -// Platform::MemoryFree(container.pathParams); -// container.pathParams = nullptr; -// return; -// } -// -// // Read clients will be purged when deregistered. -// container.readClientPtr = readClient; -// AddReadClientContainer(container.deviceID, container); -// callback.release(); -// }]; } - (void)deregisterReportHandlersWithQueue:(dispatch_queue_t)queue completion:(dispatch_block_t)completion @@ -1873,96 +1653,6 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID { NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID]]; [self readAttributePaths:nil eventPaths:eventPaths params:params queue:queue completion:completion]; -// endpointID = (endpointID == nil) ? nil : [endpointID copy]; -// clusterID = (clusterID == nil) ? nil : [clusterID copy]; -// eventID = (eventID == nil) ? nil : [eventID copy]; -// params = (params == nil) ? nil : [params copy]; -// auto * bridge = new MTRDataValueDictionaryCallbackBridge(queue, completion, -// ^(ExchangeManager & exchangeManager, const SessionHandle & session, MTRDataValueDictionaryCallback successCb, -// MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { -// // interactionStatus tracks whether the whole read interaction has failed. -// // -// // Make sure interactionStatus survives even if this block scope is destroyed. -// auto interactionStatus = std::make_shared(CHIP_NO_ERROR); -// -// auto resultArray = [[NSMutableArray alloc] init]; -// auto onSuccessCb -// = [resultArray](const app::ConcreteEventPath & eventPath, const MTRDataValueDictionaryDecodableType & aData) { -// [resultArray addObject:@ { -// MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], -// MTRDataKey : aData.GetDecodedObject() -// }]; -// }; -// -// auto onFailureCb = [resultArray, interactionStatus]( -// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { -// if (eventPath) { -// [resultArray addObject:@ { -// MTREventPathKey : [[MTREventPath alloc] initWithPath:*eventPath], -// MTRErrorKey : [MTRError errorForCHIPErrorCode:aError] -// }]; -// } else { -// // This will only happen once per read interaction, and -// // after that there will be no more calls to onFailureCb or -// // onSuccessCb. -// *interactionStatus = aError; -// } -// }; -// -// app::EventPathParams * eventPath -// = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); -// if (endpointID) { -// eventPath->mEndpointId = static_cast([endpointID unsignedShortValue]); -// } -// if (clusterID) { -// eventPath->mClusterId = static_cast([clusterID unsignedLongValue]); -// } -// if (eventID) { -// eventPath->mEventId = static_cast([eventID unsignedLongValue]); -// } -// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); -// CHIP_ERROR err = CHIP_NO_ERROR; -// -// chip::app::ReadPrepareParams readParams(session); -// [params toReadPrepareParams:readParams]; -// readParams.mpEventPathParamsList = eventPath; -// readParams.mEventPathParamsListSize = 1; -// -// auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( -// BufferedReadClientCallback * callback) { -// if (*interactionStatus != CHIP_NO_ERROR) { -// // Failure -// failureCb(bridge, *interactionStatus); -// } else { -// successCb(bridge, resultArray); -// } -// chip::Platform::Delete(callback); -// }; -// -// auto callback = chip::Platform::MakeUnique>( -// nullptr, 0, eventPath, 1, nullptr, onSuccessCb, onFailureCb, onDone, nullptr); -// VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); -// -// auto readClient = chip::Platform::MakeUnique( -// engine, &exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Read); -// VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); -// -// err = readClient->SendRequest(readParams); -// -// if (err != CHIP_NO_ERROR) { -// return err; -// } -// -// // -// // At this point, we'll get a callback through the OnDone callback above regardless of success or failure -// // of the read operation to permit us to free up the callback object. So, release ownership of the callback -// // object now to prevent it from being reclaimed at the end of this scoped block. -// // -// callback->AdoptReadClient(std::move(readClient)); -// callback.release(); -// return err; -// }); -// std::move(*bridge).DispatchAction(self); } - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID @@ -1975,129 +1665,6 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID { NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID]]; [self subscribeToAttributePaths:nil eventPaths:eventPaths params:params queue:queue reportHandler:reportHandler subscriptionEstablished:subscriptionEstablished resubscriptionScheduled:nil]; -// if (self.isPASEDevice) { -// // We don't support subscriptions over PASE. -// dispatch_async(queue, ^{ -// reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); -// }); -// return; -// } -// -// // Copy params before going async. -// endpointID = (endpointID == nil) ? nil : [endpointID copy]; -// clusterID = (clusterID == nil) ? nil : [clusterID copy]; -// eventID = (eventID == nil) ? nil : [eventID copy]; -// params = (params == nil) ? nil : [params copy]; -// -// [self.deviceController -// getSessionForNode:self.nodeID -// completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, -// NSError * _Nullable error) { -// if (error != nil) { -// if (reportHandler) { -// dispatch_async(queue, ^{ -// reportHandler(nil, error); -// }); -// } -// return; -// } -// -// auto onReportCb = [queue, reportHandler](const app::ConcreteEventPath & eventPath, -// const MTRDataValueDictionaryDecodableType & data) { -// id valueObject = data.GetDecodedObject(); -// dispatch_async(queue, ^{ -// reportHandler( -// @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:eventPath], MTRDataKey : valueObject } ], -// nil); -// }); -// }; -// -// auto establishedOrFailed = chip::Platform::MakeShared(NO); -// auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( -// const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aErrorOh) { -// if (!(*establishedOrFailed)) { -// *establishedOrFailed = YES; -// if (subscriptionEstablished) { -// dispatch_async(queue, subscriptionEstablished); -// } -// } -// if (reportHandler) { -// dispatch_async(queue, ^{ -// reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); -// }); -// } -// }; -// -// auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { -// if (*establishedOrFailed) { -// return; -// } -// *establishedOrFailed = YES; -// if (subscriptionEstablished) { -// dispatch_async(queue, subscriptionEstablished); -// } -// }; -// -// MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; -// container.deviceID = self.nodeID; -// container.eventPathParams -// = static_cast(Platform::MemoryCalloc(1, sizeof(app::EventPathParams))); -// container.eventPathParamsSize = 1; -// if (endpointID) { -// container.eventPathParams->mEndpointId = static_cast([endpointID unsignedShortValue]); -// } -// if (clusterID) { -// container.eventPathParams->mClusterId = static_cast([clusterID unsignedLongValue]); -// } -// if (eventID) { -// container.eventPathParams->mEventId = static_cast([eventID unsignedLongValue]); -// } -// container.eventPathParams->mIsUrgentEvent = params.reportEventsUrgently; -// -// app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); -// CHIP_ERROR err = CHIP_NO_ERROR; -// -// chip::app::ReadPrepareParams readParams(session.Value()); -// [params toReadPrepareParams:readParams]; -// readParams.mpEventPathParamsList = container.eventPathParams; -// readParams.mEventPathParamsListSize = 1; -// -// auto onDone = [container](BufferedReadClientCallback * callback) { -// [container onDone]; -// // Make sure we delete callback last, because doing that actually destroys our -// // lambda, so we can't access captured values after that. -// chip::Platform::Delete(callback); -// }; -// -// auto callback = chip::Platform::MakeUnique>( -// nullptr, 0, container.eventPathParams, 1, nullptr, onReportCb, onFailureCb, onDone, onEstablishedCb); -// -// auto readClient = Platform::New( -// engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); -// -// if (!params.resubscribeAutomatically) { -// err = readClient->SendRequest(readParams); -// } else { -// err = readClient->SendAutoResubscribeRequest(std::move(readParams)); -// } -// -// if (err != CHIP_NO_ERROR) { -// if (reportHandler) { -// dispatch_async(queue, ^{ -// reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); -// }); -// } -// Platform::Delete(readClient); -// Platform::MemoryFree(container.eventPathParams); -// container.eventPathParams = nullptr; -// return; -// } -// -// // Read clients will be purged when deregistered. -// container.readClientPtr = readClient; -// AddReadClientContainer(container.deviceID, container); -// callback.release(); -// }]; } @end From 7eb0bbb78cd1eaf56c19272b7a9a58b3bd799c95 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 10:26:29 +0900 Subject: [PATCH 46/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 47 +++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 650b18b35f331c..529c49a4ca1cce 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -747,8 +747,8 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const using OnSuccessAttributeCallbackType = std::function; using OnSuccessEventCallbackType = std::function; - using OnErrorCallbackType - = std::function; + using OnErrorCallbackType = std::function; using OnDoneCallbackType = std::function; using OnSubscriptionEstablishedCallbackType = std::function; using OnDeviceResubscriptionScheduledCallbackType = std::function; @@ -894,7 +894,8 @@ - (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { - NSArray * attributePaths = [NSArray arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; + NSArray * attributePaths = [NSArray + arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; [self readAttributePaths:attributePaths eventPaths:nil params:params queue:queue completion:completion]; } @@ -952,8 +953,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri }]; }; - auto onFailureCb = [resultArray, interactionStatus]( - const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { + auto onFailureCb = [resultArray, interactionStatus](const app::ConcreteAttributePath * attributePath, + const app::ConcreteEventPath * eventPath, CHIP_ERROR aError) { if (attributePath != nullptr) { [resultArray addObject:@ { MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:*attributePath], @@ -977,8 +978,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri if (attributes != nil) { size_t count = 0; - attributePathParamsList = static_cast( - Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); + attributePathParamsList + = static_cast(Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attribute in attributes) { [attribute convertToAttributePathParams:attributePathParamsList[count++]]; @@ -1131,7 +1132,8 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl auto establishedOrFailed = chip::Platform::MakeShared(NO); auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( - const app::ConcreteAttributePath * attributePath, const app::ConcreteEventPath * eventPath, CHIP_ERROR error) { + const app::ConcreteAttributePath * attributePath, + const app::ConcreteEventPath * eventPath, CHIP_ERROR error) { // TODO, Requires additional logic if attributePath or eventPath is not null if (!(*establishedOrFailed)) { *establishedOrFailed = YES; @@ -1155,7 +1157,7 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl dispatch_async(queue, subscriptionEstablished); } }; - + auto onResubscriptionScheduledCb = [resubscriptionScheduled](NSError * error, NSNumber * resubscriptionDelay) { if (resubscriptionScheduled) { resubscriptionScheduled(error, resubscriptionDelay); @@ -1445,8 +1447,15 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler)subscriptionEstablished { - NSArray * attributePaths = [NSArray arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; - [self subscribeToAttributePaths:attributePaths eventPaths:nil params:params queue:queue reportHandler:reportHandler subscriptionEstablished:subscriptionEstablished resubscriptionScheduled:nil]; + NSArray * attributePaths = [NSArray + arrayWithObject:[MTRAttributeRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID attributeID:attributeID]]; + [self subscribeToAttributePaths:attributePaths + eventPaths:nil + params:params + queue:queue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished + resubscriptionScheduled:nil]; } - (void)deregisterReportHandlersWithQueue:(dispatch_queue_t)queue completion:(dispatch_block_t)completion @@ -1651,7 +1660,9 @@ - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { - NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID]]; + NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID + clusterID:clusterID + eventID:eventID]]; [self readAttributePaths:nil eventPaths:eventPaths params:params queue:queue completion:completion]; } @@ -1663,8 +1674,16 @@ - (void)subscribeToEventsWithEndpointID:(NSNumber * _Nullable)endpointID reportHandler:(MTRDeviceResponseHandler)reportHandler subscriptionEstablished:(MTRSubscriptionEstablishedHandler)subscriptionEstablished { - NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID]]; - [self subscribeToAttributePaths:nil eventPaths:eventPaths params:params queue:queue reportHandler:reportHandler subscriptionEstablished:subscriptionEstablished resubscriptionScheduled:nil]; + NSArray * eventPaths = [NSArray arrayWithObject:[MTREventRequestPath requestPathWithEndpointID:endpointID + clusterID:clusterID + eventID:eventID]]; + [self subscribeToAttributePaths:nil + eventPaths:eventPaths + params:params + queue:queue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished + resubscriptionScheduled:nil]; } @end From 12373e9c5d1061a02c915994d814daa2dcae2034 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 14:25:09 +0900 Subject: [PATCH 47/72] Fix crash in Test --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 2efadc339dbded..5df6c5095a21e0 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -145,12 +145,18 @@ static void PurgeReadClientContainers( asyncDispatchToMatterQueue:^() { for (MTRReadClientContainer * container in listToDelete) { if (container.readClientPtr) { - Platform::MemoryFree(container.readClientPtr); + Platform::Delete(container.readClientPtr); container.readClientPtr = nullptr; } if (container.pathParams) { Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; + container.pathParamsSize = 0; + } + if (container.eventPathParams) { + Platform::MemoryFree(container.eventPathParams); + container.eventPathParams = nullptr; + container.eventPathParamsSize = 0; } } [listToDelete removeAllObjects]; @@ -1230,6 +1236,8 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl } container.pathParams = nullptr; container.eventPathParams = nullptr; + container.pathParamsSize = 0; + container.eventPathParamsSize = 0; return; } From 0d0de78ad75fd51ef2f48f41023f76c77bf0e53b Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 17:42:09 +0900 Subject: [PATCH 48/72] Add TestCases, modify some issues --- src/app/EventPathParams.h | 3 + src/darwin/Framework/CHIP/MTRBaseDevice.mm | 36 +-- .../Framework/CHIPTests/MTRDeviceTests.m | 280 +++++++++++++++++- 3 files changed, 301 insertions(+), 18 deletions(-) diff --git a/src/app/EventPathParams.h b/src/app/EventPathParams.h index 0a8cea3ee1acaa..29af405c60b515 100644 --- a/src/app/EventPathParams.h +++ b/src/app/EventPathParams.h @@ -43,6 +43,9 @@ struct EventPathParams inline bool HasWildcardEndpointId() const { return mEndpointId == kInvalidEndpointId; } inline bool HasWildcardClusterId() const { return mClusterId == kInvalidClusterId; } inline bool HasWildcardEventId() const { return mEventId == kInvalidEventId; } + inline void SetWildcardEndpointId() { mEndpointId = kInvalidEndpointId; } + inline void SetWildcardClusterId() { mClusterId = kInvalidClusterId; } + inline void SetWildcardEventId() { mEventId = kInvalidEventId; } bool IsEventPathSupersetOf(const ConcreteEventPath & other) const { diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 5df6c5095a21e0..5d820c370db49b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -80,9 +80,7 @@ @interface MTRReadClientContainer : NSObject @property (nonatomic, readwrite) app::ReadClient * readClientPtr; @property (nonatomic, readwrite) app::AttributePathParams * pathParams; -@property (nonatomic, readwrite) size_t pathParamsSize; @property (nonatomic, readwrite) app::EventPathParams * eventPathParams; -@property (nonatomic, readwrite) size_t eventPathParamsSize; @property (nonatomic, readwrite) uint64_t deviceID; - (void)onDone; @end @@ -151,12 +149,10 @@ static void PurgeReadClientContainers( if (container.pathParams) { Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; - container.pathParamsSize = 0; } if (container.eventPathParams) { Platform::MemoryFree(container.eventPathParams); container.eventPathParams = nullptr; - container.eventPathParamsSize = 0; } } [listToDelete removeAllObjects]; @@ -233,12 +229,10 @@ - (void)onDone if (_pathParams) { Platform::MemoryFree(_pathParams); _pathParams = nullptr; - _pathParamsSize = 0; } if (_eventPathParams) { Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; - _eventPathParamsSize = 0; } PurgeCompletedReadClientContainers(_deviceID); } @@ -252,12 +246,10 @@ - (void)dealloc if (_pathParams) { Platform::MemoryFree(_pathParams); _pathParams = nullptr; - _pathParamsSize = 0; } if (_eventPathParams) { Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; - _eventPathParamsSize = 0; } } @end @@ -1173,20 +1165,20 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID; + size_t attributePathSize = 0; if (attributes != nil) { - container.pathParamsSize = 0; container.pathParams = static_cast( Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); for (MTRAttributeRequestPath * attribute in attributes) { - [attribute convertToAttributePathParams:container.pathParams[container.pathParamsSize++]]; + [attribute convertToAttributePathParams:container.pathParams[attributePathSize++]]; } } + size_t eventPathSize = 0; if (events != nil) { - container.eventPathParamsSize = 0; container.eventPathParams = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); for (MTREventRequestPath * event in events) { - [event convertToEventPathParams:container.eventPathParams[container.eventPathParamsSize++]]; + [event convertToEventPathParams:container.eventPathParams[eventPathSize++]]; } } @@ -1196,9 +1188,9 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl chip::app::ReadPrepareParams readParams(session.Value()); [params toReadPrepareParams:readParams]; readParams.mpAttributePathParamsList = container.pathParams; - readParams.mAttributePathParamsListSize = container.pathParamsSize; + readParams.mAttributePathParamsListSize = attributePathSize; readParams.mpEventPathParamsList = container.eventPathParams; - readParams.mEventPathParamsListSize = container.eventPathParamsSize; + readParams.mEventPathParamsListSize = eventPathSize; auto onDone = [container](BufferedReadClientCallback * callback) { [container onDone]; @@ -1208,7 +1200,7 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl }; auto callback = chip::Platform::MakeUnique>( - container.pathParams, container.pathParamsSize, container.eventPathParams, container.eventPathParamsSize, + container.pathParams, attributePathSize, container.eventPathParams, eventPathSize, onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb, onResubscriptionScheduledCb); auto readClient = Platform::New( @@ -1236,8 +1228,6 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl } container.pathParams = nullptr; container.eventPathParams = nullptr; - container.pathParamsSize = 0; - container.eventPathParamsSize = 0; return; } @@ -1890,14 +1880,20 @@ - (void)convertToAttributePathParams:(chip::app::AttributePathParams &)params { if (_endpoint != nil) { params.mEndpointId = static_cast(_endpoint.unsignedShortValue); + } else { + params.SetWildcardEndpointId(); } if (_cluster != nil) { params.mClusterId = static_cast(_cluster.unsignedLongValue); + } else { + params.SetWildcardClusterId(); } if (_attribute != nil) { params.mAttributeId = static_cast(_attribute.unsignedLongValue); + } else { + params.SetWildcardAttributeId(); } } @end @@ -1956,14 +1952,20 @@ - (void)convertToEventPathParams:(chip::app::EventPathParams &)params { if (_endpoint != nil) { params.mEndpointId = static_cast(_endpoint.unsignedShortValue); + } else { + params.SetWildcardEndpointId(); } if (_cluster != nil) { params.mClusterId = static_cast(_cluster.unsignedLongValue); + } else { + params.SetWildcardClusterId(); } if (_event != nil) { params.mEventId = static_cast(_event.unsignedLongValue); + } else { + params.SetWildcardEventId(); } } @end diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index b5edbaa69dfbea..aa74cae77000d1 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1577,6 +1577,284 @@ - (void)test019_MTRDeviceMultipleCommands enforceOrder:YES]; } +- (void)test020_ReadMultipleAttributes +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"read Multiple Attributes (Descriptor, Basic Information Cluster) for all endpoints"]; + + MTRBaseDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + + NSArray * attributePaths = [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@0] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@1] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@2] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@3] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@4] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@9] + , nil]; + + NSArray * eventPaths = [NSArray arrayWithObjects:[MTREventRequestPath requestPathWithEndpointID:nil clusterID:@40 eventID:@0] + , nil]; + + [device readAttributePaths:attributePaths + eventPaths:eventPaths + params:nil + queue:queue + completion:^(id _Nullable values, NSError * _Nullable error) { + NSLog(@"read attribute: DeviceType values: %@, error: %@", values, error); + + XCTAssertNil(error); + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + + { + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSArray * resultArray = values; + BOOL includeEventPath = NO; + for (NSDictionary * result in resultArray) { + if ([result objectForKey:@"eventPath"]) { + MTREventPath * path = result[@"eventPath"]; + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + XCTAssertEqual([path.event unsignedIntegerValue], 0); + XCTAssertNotNil(result[@"data"]); + XCTAssertNil(result[@"error"]); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + includeEventPath = YES; + } else if ([result objectForKey:@"attributePath"]) { + MTRAttributePath * path = result[@"attributePath"]; + if ([path.attribute unsignedIntegerValue] < 5) { + XCTAssertEqual([path.cluster unsignedIntegerValue], 29); + } else { + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + } + XCTAssertNotNil(result[@"data"]); + XCTAssertNil(result[@"error"]); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + } + } + XCTAssertTrue(includeEventPath); + XCTAssertTrue([resultArray count] > 0); + } + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)test021_ReadMultipleAttributesIncludeUnsupportedAttribute +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"read Basic Information Cluster's attributes and include 1 unsupported attribute"]; + + MTRBaseDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + + NSNumber * failAttributeID = @10000; + + NSArray * attributePaths = [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@0] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@1] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@2] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@3] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@4] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:failAttributeID] // Fail Case + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7] + , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8] + , nil]; + + [device readAttributePaths:attributePaths + eventPaths:nil + params:nil + queue:queue + completion:^(id _Nullable values, NSError * _Nullable error) { + NSLog(@"read attribute: DeviceType values: %@, error: %@", values, error); + + XCTAssertNil(error); + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + + { + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSArray * resultArray = values; + for (NSDictionary * result in resultArray) { + MTRAttributePath * path = result[@"attributePath"]; + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + if (path.attribute.unsignedIntegerValue != failAttributeID.unsignedIntegerValue) { + XCTAssertNotNil(result[@"data"]); + XCTAssertNil(result[@"error"]); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + } else { + XCTAssertNil(result[@"data"]); + XCTAssertNotNil(result[@"error"]); + } + } + XCTAssertTrue([resultArray count] > 0); + } + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)test022_SubscribeMultipleAttributes +{ + MTRBaseDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + + // Subscribe + XCTestExpectation * expectation = [self expectationWithDescription:@"subscribe OnOff attribute"]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)]; + + NSArray * attributePaths = [NSArray arrayWithObjects: + [MTRAttributeRequestPath requestPathWithEndpointID:@1 clusterID:@6 attributeID:@0] + , [MTRAttributeRequestPath requestPathWithEndpointID:@0 clusterID:@40 attributeID:@5] + , nil]; + + [device subscribeToAttributePaths:attributePaths + eventPaths:nil + params:params + queue:queue + reportHandler:^(id _Nullable values, NSError * _Nullable error) { + NSLog(@"report attributes: values: %@, error: %@", values, error); + + if (globalReportHandler) { + __auto_type callback = globalReportHandler; + callback(values, error); + } + } + subscriptionEstablished:^{ + NSLog(@"subscribe attribute"); + [expectation fulfill]; + } + resubscriptionScheduled:nil + ]; + + // Wait till establishment + [self waitForExpectations:[NSArray arrayWithObject:expectation] timeout:kTimeoutInSeconds]; + + // Set up expectation for report + XCTestExpectation * reportExpectation = [self expectationWithDescription:@"report received"]; + globalReportHandler = ^(id _Nullable values, NSError * _Nullable error) { + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSDictionary * result = values[0]; + MTRAttributePath * path = result[@"attributePath"]; + if (path.endpoint.unsignedShortValue == 1) { + XCTAssertEqual([path.cluster unsignedIntegerValue], 6); + XCTAssertEqual([path.attribute unsignedIntegerValue], 0); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + XCTAssertTrue([result[@"data"][@"type"] isEqualToString:@"Boolean"]); + if ([result[@"data"][@"value"] boolValue] == YES) { + [reportExpectation fulfill]; + globalReportHandler = nil; + } + } else if (path.endpoint.unsignedShortValue == 0) { + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + XCTAssertEqual([path.attribute unsignedIntegerValue], 5); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + XCTAssertTrue([result[@"data"][@"type"] isEqualToString:@"UTF8String"]); + } else { + XCTAssertTrue(NO); + } + }; + + // Send commands to trigger attribute change + XCTestExpectation * commandExpectation = [self expectationWithDescription:@"command responded"]; + NSDictionary * fields = @{ @"type" : @"Structure", @"value" : [NSArray array] }; + [device invokeCommandWithEndpointID:@1 + clusterID:@6 + commandID:@1 + commandFields:fields + timedInvokeTimeout:nil + queue:queue + completion:^(id _Nullable values, NSError * _Nullable error) { + NSLog(@"invoke command: On values: %@, error: %@", values, error); + + XCTAssertNil(error); + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + + { + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSArray * resultArray = values; + for (NSDictionary * result in resultArray) { + MTRCommandPath * path = result[@"commandPath"]; + XCTAssertEqual([path.endpoint unsignedIntegerValue], 1); + XCTAssertEqual([path.cluster unsignedIntegerValue], 6); + XCTAssertEqual([path.command unsignedIntegerValue], 1); + XCTAssertNil(result[@"error"]); + } + XCTAssertEqual([resultArray count], 1); + } + [commandExpectation fulfill]; + }]; + + [self waitForExpectations:[NSArray arrayWithObject:commandExpectation] timeout:kTimeoutInSeconds]; + + // Wait for report + [self waitForExpectations:[NSArray arrayWithObject:reportExpectation] timeout:kTimeoutInSeconds]; + + // Set up expectation for 2nd report + reportExpectation = [self expectationWithDescription:@"receive OnOff attribute report"]; + globalReportHandler = ^(id _Nullable values, NSError * _Nullable error) { + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSDictionary * result = values[0]; + MTRAttributePath * path = result[@"attributePath"]; + XCTAssertEqual([path.endpoint unsignedIntegerValue], 1); + XCTAssertEqual([path.cluster unsignedIntegerValue], 6); + XCTAssertEqual([path.attribute unsignedIntegerValue], 0); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + XCTAssertTrue([result[@"data"][@"type"] isEqualToString:@"Boolean"]); + if ([result[@"data"][@"value"] boolValue] == NO) { + [reportExpectation fulfill]; + globalReportHandler = nil; + } + }; + + // Send command to trigger attribute change + fields = [NSDictionary dictionaryWithObjectsAndKeys:@"Structure", @"type", [NSArray array], @"value", nil]; + [device invokeCommandWithEndpointID:@1 + clusterID:@6 + commandID:@0 + commandFields:fields + timedInvokeTimeout:nil + queue:queue + completion:^(id _Nullable values, NSError * _Nullable error) { + NSLog(@"invoke command: On values: %@, error: %@", values, error); + + XCTAssertNil(error); + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + + { + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSArray * resultArray = values; + for (NSDictionary * result in resultArray) { + MTRCommandPath * path = result[@"commandPath"]; + XCTAssertEqual([path.endpoint unsignedIntegerValue], 1); + XCTAssertEqual([path.cluster unsignedIntegerValue], 6); + XCTAssertEqual([path.command unsignedIntegerValue], 0); + XCTAssertNil(result[@"error"]); + } + XCTAssertEqual([resultArray count], 1); + } + }]; + + // Wait for report + [self waitForExpectations:[NSArray arrayWithObject:reportExpectation] timeout:kTimeoutInSeconds]; + + expectation = [self expectationWithDescription:@"Report handler deregistered"]; + [device deregisterReportHandlersWithQueue:queue + completion:^{ + [expectation fulfill]; + }]; + [self waitForExpectations:@[ expectation ] timeout:kTimeoutInSeconds]; +} + - (void)test900_SubscribeAllAttributes { MTRBaseDevice * device = GetConnectedDevice(); @@ -1597,7 +1875,7 @@ - (void)test900_SubscribeAllAttributes params.resubscribeAutomatically = NO; [device subscribeToAttributesWithEndpointID:@1 clusterID:@6 - attributeID:@0xffffffff + attributeID:nil params:params queue:queue reportHandler:^(id _Nullable values, NSError * _Nullable error) { From 3adafc0683d29378b7074d1d3b8ee02db88e50a7 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 17:44:35 +0900 Subject: [PATCH 49/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 +- .../Framework/CHIPTests/MTRDeviceTests.m | 219 +++++++++--------- 2 files changed, 111 insertions(+), 112 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 5d820c370db49b..7e4cfdcc3993a0 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1200,8 +1200,8 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl }; auto callback = chip::Platform::MakeUnique>( - container.pathParams, attributePathSize, container.eventPathParams, eventPathSize, - onAttributeReportCb, onEventReportCb, onFailureCb, onDone, onEstablishedCb, onResubscriptionScheduledCb); + container.pathParams, attributePathSize, container.eventPathParams, eventPathSize, onAttributeReportCb, + onEventReportCb, onFailureCb, onDone, onEstablishedCb, onResubscriptionScheduledCb); auto readClient = Platform::New( engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index aa74cae77000d1..6a0bcb7845617c 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1584,63 +1584,63 @@ - (void)test020_ReadMultipleAttributes MTRBaseDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); - - NSArray * attributePaths = [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@0] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@1] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@2] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@3] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@4] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@9] - , nil]; - - NSArray * eventPaths = [NSArray arrayWithObjects:[MTREventRequestPath requestPathWithEndpointID:nil clusterID:@40 eventID:@0] - , nil]; - + + NSArray * attributePaths = + [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@0], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@1], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@2], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@3], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@4], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@9], nil]; + + NSArray * eventPaths = + [NSArray arrayWithObjects:[MTREventRequestPath requestPathWithEndpointID:nil clusterID:@40 eventID:@0], nil]; + [device readAttributePaths:attributePaths eventPaths:eventPaths params:nil queue:queue completion:^(id _Nullable values, NSError * _Nullable error) { - NSLog(@"read attribute: DeviceType values: %@, error: %@", values, error); - - XCTAssertNil(error); - XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + NSLog(@"read attribute: DeviceType values: %@, error: %@", values, error); - { - XCTAssertTrue([values isKindOfClass:[NSArray class]]); - NSArray * resultArray = values; - BOOL includeEventPath = NO; - for (NSDictionary * result in resultArray) { - if ([result objectForKey:@"eventPath"]) { - MTREventPath * path = result[@"eventPath"]; - XCTAssertEqual([path.cluster unsignedIntegerValue], 40); - XCTAssertEqual([path.event unsignedIntegerValue], 0); - XCTAssertNotNil(result[@"data"]); - XCTAssertNil(result[@"error"]); - XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); - includeEventPath = YES; - } else if ([result objectForKey:@"attributePath"]) { - MTRAttributePath * path = result[@"attributePath"]; - if ([path.attribute unsignedIntegerValue] < 5) { - XCTAssertEqual([path.cluster unsignedIntegerValue], 29); - } else { - XCTAssertEqual([path.cluster unsignedIntegerValue], 40); - } - XCTAssertNotNil(result[@"data"]); - XCTAssertNil(result[@"error"]); - XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); - } - } - XCTAssertTrue(includeEventPath); - XCTAssertTrue([resultArray count] > 0); - } + XCTAssertNil(error); + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + + { + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSArray * resultArray = values; + BOOL includeEventPath = NO; + for (NSDictionary * result in resultArray) { + if ([result objectForKey:@"eventPath"]) { + MTREventPath * path = result[@"eventPath"]; + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + XCTAssertEqual([path.event unsignedIntegerValue], 0); + XCTAssertNotNil(result[@"data"]); + XCTAssertNil(result[@"error"]); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + includeEventPath = YES; + } else if ([result objectForKey:@"attributePath"]) { + MTRAttributePath * path = result[@"attributePath"]; + if ([path.attribute unsignedIntegerValue] < 5) { + XCTAssertEqual([path.cluster unsignedIntegerValue], 29); + } else { + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + } + XCTAssertNotNil(result[@"data"]); + XCTAssertNil(result[@"error"]); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + } + } + XCTAssertTrue(includeEventPath); + XCTAssertTrue([resultArray count] > 0); + } - [expectation fulfill]; - }]; + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } @@ -1652,51 +1652,52 @@ - (void)test021_ReadMultipleAttributesIncludeUnsupportedAttribute MTRBaseDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); - + NSNumber * failAttributeID = @10000; - - NSArray * attributePaths = [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@0] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@1] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@2] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@3] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@4] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:failAttributeID] // Fail Case - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7] - , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8] - , nil]; + + NSArray * attributePaths = + [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@0], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@1], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@2], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@3], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@4], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:failAttributeID] // Fail Case + , + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7], + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8], nil]; [device readAttributePaths:attributePaths eventPaths:nil params:nil queue:queue completion:^(id _Nullable values, NSError * _Nullable error) { - NSLog(@"read attribute: DeviceType values: %@, error: %@", values, error); + NSLog(@"read attribute: DeviceType values: %@, error: %@", values, error); - XCTAssertNil(error); - XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); - - { - XCTAssertTrue([values isKindOfClass:[NSArray class]]); - NSArray * resultArray = values; - for (NSDictionary * result in resultArray) { - MTRAttributePath * path = result[@"attributePath"]; - XCTAssertEqual([path.cluster unsignedIntegerValue], 40); - if (path.attribute.unsignedIntegerValue != failAttributeID.unsignedIntegerValue) { - XCTAssertNotNil(result[@"data"]); - XCTAssertNil(result[@"error"]); - XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); - } else { - XCTAssertNil(result[@"data"]); - XCTAssertNotNil(result[@"error"]); - } - } - XCTAssertTrue([resultArray count] > 0); - } + XCTAssertNil(error); + XCTAssertEqual([MTRErrorTestUtils errorToZCLErrorCode:error], 0); + + { + XCTAssertTrue([values isKindOfClass:[NSArray class]]); + NSArray * resultArray = values; + for (NSDictionary * result in resultArray) { + MTRAttributePath * path = result[@"attributePath"]; + XCTAssertEqual([path.cluster unsignedIntegerValue], 40); + if (path.attribute.unsignedIntegerValue != failAttributeID.unsignedIntegerValue) { + XCTAssertNotNil(result[@"data"]); + XCTAssertNil(result[@"error"]); + XCTAssertTrue([result[@"data"] isKindOfClass:[NSDictionary class]]); + } else { + XCTAssertNil(result[@"data"]); + XCTAssertNotNil(result[@"error"]); + } + } + XCTAssertTrue([resultArray count] > 0); + } - [expectation fulfill]; - }]; + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } @@ -1709,30 +1710,28 @@ - (void)test022_SubscribeMultipleAttributes // Subscribe XCTestExpectation * expectation = [self expectationWithDescription:@"subscribe OnOff attribute"]; __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)]; - - NSArray * attributePaths = [NSArray arrayWithObjects: - [MTRAttributeRequestPath requestPathWithEndpointID:@1 clusterID:@6 attributeID:@0] - , [MTRAttributeRequestPath requestPathWithEndpointID:@0 clusterID:@40 attributeID:@5] - , nil]; - + + NSArray * attributePaths = + [NSArray arrayWithObjects:[MTRAttributeRequestPath requestPathWithEndpointID:@1 clusterID:@6 attributeID:@0], + [MTRAttributeRequestPath requestPathWithEndpointID:@0 clusterID:@40 attributeID:@5], nil]; + [device subscribeToAttributePaths:attributePaths - eventPaths:nil - params:params - queue:queue - reportHandler:^(id _Nullable values, NSError * _Nullable error) { - NSLog(@"report attributes: values: %@, error: %@", values, error); - - if (globalReportHandler) { - __auto_type callback = globalReportHandler; - callback(values, error); - } - } - subscriptionEstablished:^{ - NSLog(@"subscribe attribute"); - [expectation fulfill]; - } - resubscriptionScheduled:nil - ]; + eventPaths:nil + params:params + queue:queue + reportHandler:^(id _Nullable values, NSError * _Nullable error) { + NSLog(@"report attributes: values: %@, error: %@", values, error); + + if (globalReportHandler) { + __auto_type callback = globalReportHandler; + callback(values, error); + } + } + subscriptionEstablished:^{ + NSLog(@"subscribe attribute"); + [expectation fulfill]; + } + resubscriptionScheduled:nil]; // Wait till establishment [self waitForExpectations:[NSArray arrayWithObject:expectation] timeout:kTimeoutInSeconds]; @@ -1762,7 +1761,7 @@ - (void)test022_SubscribeMultipleAttributes XCTAssertTrue(NO); } }; - + // Send commands to trigger attribute change XCTestExpectation * commandExpectation = [self expectationWithDescription:@"command responded"]; NSDictionary * fields = @{ @"type" : @"Structure", @"value" : [NSArray array] }; From 069c9eefcfda3d8e66a6bc05066ac6fb0364e508 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 12 Apr 2023 17:52:24 +0900 Subject: [PATCH 50/72] Add comment, modify testcase --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 4 ++++ src/darwin/Framework/CHIPTests/MTRDeviceTests.m | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 196e75705a3999..69af45d6e044e1 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -272,6 +272,8 @@ MTR_NEWLY_AVAILABLE; * The completion will be called with an error if the input parameters are invalid (e.g., both attributePaths and eventPaths are * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. + * + * The length of the path is guaranteed up to 9. */ - (void)readAttributePaths:(NSArray * _Nullable)attributePaths eventPaths:(NSArray * _Nullable)eventPaths @@ -287,6 +289,8 @@ MTR_NEWLY_AVAILABLE; * * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are * empty), or if the subscription fails entirely. + * + * The length of the Path is guaranteed up to 9. */ - (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths eventPaths:(NSArray * _Nullable)eventPaths diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 6a0bcb7845617c..65db3208d17edc 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1593,9 +1593,7 @@ - (void)test020_ReadMultipleAttributes [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@4], [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5], [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6], - [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7], - [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8], - [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@9], nil]; + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7], nil]; NSArray * eventPaths = [NSArray arrayWithObjects:[MTREventRequestPath requestPathWithEndpointID:nil clusterID:@40 eventID:@0], nil]; @@ -1665,8 +1663,7 @@ - (void)test021_ReadMultipleAttributesIncludeUnsupportedAttribute , [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@5], [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@6], - [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7], - [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@8], nil]; + [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@40 attributeID:@7], nil]; [device readAttributePaths:attributePaths eventPaths:nil From a1cd0cc6e1fde281970bd53928cec112e18f0031 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:25:37 +0900 Subject: [PATCH 51/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 69af45d6e044e1..47e13fcae4b59a 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -290,7 +290,7 @@ MTR_NEWLY_AVAILABLE; * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are * empty), or if the subscription fails entirely. * - * The length of the Path is guaranteed up to 9. + * If the sum of the lengths of attributePaths and eventPaths exceeds 3, the subscribe may fail due to the device not supporting that many paths for a subscription. */ - (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths eventPaths:(NSArray * _Nullable)eventPaths From debd9aa9f5338500e77f5cd0b5ed07817657a94b Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:26:08 +0900 Subject: [PATCH 52/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 7e4cfdcc3993a0..31a7f14e790b37 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -151,6 +151,7 @@ static void PurgeReadClientContainers( container.pathParams = nullptr; } if (container.eventPathParams) { + static_assert(std::is_trivially_destructible::value, "EventPathParams destructors won't get run"); Platform::MemoryFree(container.eventPathParams); container.eventPathParams = nullptr; } From ac6a7ab08b8256efabd5b3a37d03a904caf28fc9 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:26:24 +0900 Subject: [PATCH 53/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 31a7f14e790b37..94dbc9bd21a16d 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -147,6 +147,7 @@ static void PurgeReadClientContainers( container.readClientPtr = nullptr; } if (container.pathParams) { + static_assert(std::is_trivially_destructible::value, "AttributePathPArams destructors won't get run"); Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; } From 580746ff11fc00dcac40ccbd7817232dcf46da06 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:26:32 +0900 Subject: [PATCH 54/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 47e13fcae4b59a..7869b955d86c54 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -280,6 +280,7 @@ MTR_NEWLY_AVAILABLE; params:(MTRReadParams * _Nullable)params queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; + /** * Subscribes to multiple attribute or event paths. * From bd0ff2ab79780802caf9b14bd73b9c9b7a242583 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:26:39 +0900 Subject: [PATCH 55/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 7869b955d86c54..fe8c6b1d1d2091 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -269,7 +269,7 @@ MTR_NEWLY_AVAILABLE; * * Lists of attribute and event paths to read can be provided via attributePaths and eventPaths. * - * The completion will be called with an error if the input parameters are invalid (e.g., both attributePaths and eventPaths are + * The completion will be called with an error if the input parameters are invalid (e.g., both attributePaths and eventPaths are * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. * From 3212054354bc2029417b7bff1d2a6d7522b96d23 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:26:46 +0900 Subject: [PATCH 56/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index fe8c6b1d1d2091..567598c4a3cff7 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -273,7 +273,7 @@ MTR_NEWLY_AVAILABLE; * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. * - * The length of the path is guaranteed up to 9. + * If the sum of the lengths of attributePaths and eventPaths exceeds 9, the read may fail due to the device not supporting that many read paths. */ - (void)readAttributePaths:(NSArray * _Nullable)attributePaths eventPaths:(NSArray * _Nullable)eventPaths From 48e88fd43e479802d0d06ed285255ea0dec48dd6 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 08:27:01 +0900 Subject: [PATCH 57/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.h Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index 567598c4a3cff7..f0d365a097ee6c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -159,7 +159,7 @@ MTR_NEWLY_AVAILABLE + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID - eventID:(NSNumber * _Nullable)eventID; + eventID:(NSNumber * _Nullable)eventID MTR_NEWLY_AVAILABLE; @end From 85aac30663695f30b662a469ec8ee1e2423326b7 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Thu, 13 Apr 2023 08:39:20 +0900 Subject: [PATCH 58/72] modify code location, add some patch --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 39 +-- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 380 +++++++++++---------- 2 files changed, 211 insertions(+), 208 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index f0d365a097ee6c..f8cdc9db24b912 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -281,25 +281,6 @@ MTR_NEWLY_AVAILABLE; queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion MTR_NEWLY_AVAILABLE; -/** - * Subscribes to multiple attribute or event paths. - * - * Nil is treated as an empty array for attributePaths and eventPaths. - * - * Lists of attribute and event paths to subscribe to can be provided via attributePaths and eventPaths. - * - * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are - * empty), or if the subscription fails entirely. - * - * If the sum of the lengths of attributePaths and eventPaths exceeds 3, the subscribe may fail due to the device not supporting that many paths for a subscription. - */ -- (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths - eventPaths:(NSArray * _Nullable)eventPaths - params:(MTRSubscribeParams * _Nullable)params - queue:(dispatch_queue_t)queue - reportHandler:(MTRDeviceResponseHandler)reportHandler - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - resubscriptionScheduled:(MTRDeviceResubscriptionScheduledHandler _Nullable)resubscriptionScheduled MTR_NEWLY_AVAILABLE; /** * Write to attribute in a designated attribute path * @@ -376,6 +357,26 @@ MTR_NEWLY_AVAILABLE; subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished API_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +/** + * Subscribes to multiple attribute or event paths. + * + * Nil is treated as an empty array for attributePaths and eventPaths. + * + * Lists of attribute and event paths to subscribe to can be provided via attributePaths and eventPaths. + * + * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are + * empty), or if the subscription fails entirely. + * + * If the sum of the lengths of attributePaths and eventPaths exceeds 3, the subscribe may fail due to the device not supporting that many paths for a subscription. + */ +- (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths + eventPaths:(NSArray * _Nullable)eventPaths + params:(MTRSubscribeParams * _Nullable)params + queue:(dispatch_queue_t)queue + reportHandler:(MTRDeviceResponseHandler)reportHandler + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + resubscriptionScheduled:(MTRDeviceResubscriptionScheduledHandler _Nullable)resubscriptionScheduled MTR_NEWLY_AVAILABLE; + /** * Deregister all local report handlers for a remote device * diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 94dbc9bd21a16d..18cd0c9f52bdc1 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -246,10 +246,12 @@ - (void)dealloc _readClientPtr = nullptr; } if (_pathParams) { + static_assert(std::is_trivially_destructible::value, "AttributePathPArams destructors won't get run"); Platform::MemoryFree(_pathParams); _pathParams = nullptr; } if (_eventPathParams) { + static_assert(std::is_trivially_destructible::value, "EventPathParams destructors won't get run"); Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; } @@ -1051,195 +1053,6 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri std::move(*bridge).DispatchAction(self); } -- (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths - eventPaths:(NSArray * _Nullable)eventPaths - params:(MTRSubscribeParams * _Nullable)params - queue:(dispatch_queue_t)queue - reportHandler:(MTRDeviceResponseHandler)reportHandler - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - resubscriptionScheduled:(MTRDeviceResubscriptionScheduledHandler _Nullable)resubscriptionScheduled -{ - if ((attributePaths == nil || [attributePaths count] == 0) && (eventPaths == nil || [eventPaths count] == 0)) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); - }); - return; - } - - if (self.isPASEDevice) { - // We don't support subscriptions over PASE. - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); - }); - return; - } - - // Copy params before going async. - NSMutableArray * attributes = nil; - if (attributePaths != nil) { - attributes = [[NSMutableArray alloc] init]; - for (MTRAttributeRequestPath * attributePath in attributePaths) { - [attributes addObject:[attributePath copy]]; - } - } - - NSMutableArray * events = nil; - if (eventPaths != nil) { - events = [[NSMutableArray alloc] init]; - for (MTRAttributeRequestPath * eventPath in eventPaths) { - [events addObject:[eventPath copy]]; - } - } - - params = (params == nil) ? nil : [params copy]; - - [self.deviceController - getSessionForNode:self.nodeID - completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, - NSError * _Nullable error) { - if (error != nil) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, error); - }); - } - return; - } - - auto onAttributeReportCb = [queue, reportHandler](const ConcreteAttributePath & attributePath, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - ConcreteAttributePath pathCopy(attributePath); - dispatch_async(queue, ^{ - reportHandler(@[ @ { - MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], - MTRDataKey : valueObject - } ], - nil); - }); - }; - - auto onEventReportCb = [queue, reportHandler](const ConcreteEventPath & eventPath, - const MTRDataValueDictionaryDecodableType & data) { - id valueObject = data.GetDecodedObject(); - ConcreteEventPath pathCopy(eventPath); - dispatch_async(queue, ^{ - reportHandler( - @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], MTRDataKey : valueObject } ], - nil); - }); - }; - - auto establishedOrFailed = chip::Platform::MakeShared(NO); - auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( - const app::ConcreteAttributePath * attributePath, - const app::ConcreteEventPath * eventPath, CHIP_ERROR error) { - // TODO, Requires additional logic if attributePath or eventPath is not null - if (!(*establishedOrFailed)) { - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - } - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); - }); - } - }; - - auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { - if (*establishedOrFailed) { - return; - } - *establishedOrFailed = YES; - if (subscriptionEstablished) { - dispatch_async(queue, subscriptionEstablished); - } - }; - - auto onResubscriptionScheduledCb = [resubscriptionScheduled](NSError * error, NSNumber * resubscriptionDelay) { - if (resubscriptionScheduled) { - resubscriptionScheduled(error, resubscriptionDelay); - } - }; - - MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; - container.deviceID = self.nodeID; - - size_t attributePathSize = 0; - if (attributes != nil) { - container.pathParams = static_cast( - Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); - for (MTRAttributeRequestPath * attribute in attributes) { - [attribute convertToAttributePathParams:container.pathParams[attributePathSize++]]; - } - } - size_t eventPathSize = 0; - if (events != nil) { - container.eventPathParams - = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); - for (MTREventRequestPath * event in events) { - [event convertToEventPathParams:container.eventPathParams[eventPathSize++]]; - } - } - - app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - CHIP_ERROR err = CHIP_NO_ERROR; - - chip::app::ReadPrepareParams readParams(session.Value()); - [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = container.pathParams; - readParams.mAttributePathParamsListSize = attributePathSize; - readParams.mpEventPathParamsList = container.eventPathParams; - readParams.mEventPathParamsListSize = eventPathSize; - - auto onDone = [container](BufferedReadClientCallback * callback) { - [container onDone]; - // Make sure we delete callback last, because doing that actually destroys our - // lambda, so we can't access captured values after that. - chip::Platform::Delete(callback); - }; - - auto callback = chip::Platform::MakeUnique>( - container.pathParams, attributePathSize, container.eventPathParams, eventPathSize, onAttributeReportCb, - onEventReportCb, onFailureCb, onDone, onEstablishedCb, onResubscriptionScheduledCb); - - auto readClient = Platform::New( - engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); - - if (!params.resubscribeAutomatically) { - err = readClient->SendRequest(readParams); - } else { - err = readClient->SendAutoResubscribeRequest(std::move(readParams)); - } - - if (err != CHIP_NO_ERROR) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); - }); - } - Platform::Delete(readClient); - if (container.pathParams != nullptr) { - Platform::MemoryFree(container.pathParams); - } - - if (container.eventPathParams != nullptr) { - Platform::MemoryFree(container.eventPathParams); - } - container.pathParams = nullptr; - container.eventPathParams = nullptr; - return; - } - - // Read clients will be purged when deregistered. - container.readClientPtr = readClient; - AddReadClientContainer(container.deviceID, container); - callback.release(); - }]; -} - - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID clusterID:(NSNumber *)clusterID attributeID:(NSNumber *)attributeID @@ -1458,6 +1271,195 @@ - (void)subscribeToAttributesWithEndpointID:(NSNumber * _Nullable)endpointID resubscriptionScheduled:nil]; } +- (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths + eventPaths:(NSArray * _Nullable)eventPaths + params:(MTRSubscribeParams * _Nullable)params + queue:(dispatch_queue_t)queue + reportHandler:(MTRDeviceResponseHandler)reportHandler + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + resubscriptionScheduled:(MTRDeviceResubscriptionScheduledHandler _Nullable)resubscriptionScheduled +{ + if ((attributePaths == nil || [attributePaths count] == 0) && (eventPaths == nil || [eventPaths count] == 0)) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); + }); + return; + } + + if (self.isPASEDevice) { + // We don't support subscriptions over PASE. + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]); + }); + return; + } + + // Copy params before going async. + NSMutableArray * attributes = nil; + if (attributePaths != nil) { + attributes = [[NSMutableArray alloc] init]; + for (MTRAttributeRequestPath * attributePath in attributePaths) { + [attributes addObject:[attributePath copy]]; + } + } + + NSMutableArray * events = nil; + if (eventPaths != nil) { + events = [[NSMutableArray alloc] init]; + for (MTRAttributeRequestPath * eventPath in eventPaths) { + [events addObject:[eventPath copy]]; + } + } + + params = (params == nil) ? nil : [params copy]; + + [self.deviceController + getSessionForNode:self.nodeID + completion:^(ExchangeManager * _Nullable exchangeManager, const Optional & session, + NSError * _Nullable error) { + if (error != nil) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, error); + }); + } + return; + } + + auto onAttributeReportCb = [queue, reportHandler](const ConcreteAttributePath & attributePath, + const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + ConcreteAttributePath pathCopy(attributePath); + dispatch_async(queue, ^{ + reportHandler(@[ @ { + MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:pathCopy], + MTRDataKey : valueObject + } ], + nil); + }); + }; + + auto onEventReportCb = [queue, reportHandler](const ConcreteEventPath & eventPath, + const MTRDataValueDictionaryDecodableType & data) { + id valueObject = data.GetDecodedObject(); + ConcreteEventPath pathCopy(eventPath); + dispatch_async(queue, ^{ + reportHandler( + @[ @ { MTREventPathKey : [[MTREventPath alloc] initWithPath:pathCopy], MTRDataKey : valueObject } ], + nil); + }); + }; + + auto establishedOrFailed = chip::Platform::MakeShared(NO); + auto onFailureCb = [establishedOrFailed, queue, subscriptionEstablished, reportHandler]( + const app::ConcreteAttributePath * attributePath, + const app::ConcreteEventPath * eventPath, CHIP_ERROR error) { + // TODO, Requires additional logic if attributePath or eventPath is not null + if (!(*establishedOrFailed)) { + *establishedOrFailed = YES; + if (subscriptionEstablished) { + dispatch_async(queue, subscriptionEstablished); + } + } + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:error]); + }); + } + }; + + auto onEstablishedCb = [establishedOrFailed, queue, subscriptionEstablished]() { + if (*establishedOrFailed) { + return; + } + *establishedOrFailed = YES; + if (subscriptionEstablished) { + dispatch_async(queue, subscriptionEstablished); + } + }; + + auto onResubscriptionScheduledCb = [resubscriptionScheduled](NSError * error, NSNumber * resubscriptionDelay) { + if (resubscriptionScheduled) { + resubscriptionScheduled(error, resubscriptionDelay); + } + }; + + MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; + container.deviceID = self.nodeID; + + size_t attributePathSize = 0; + if (attributes != nil) { + container.pathParams = static_cast( + Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); + for (MTRAttributeRequestPath * attribute in attributes) { + [attribute convertToAttributePathParams:container.pathParams[attributePathSize++]]; + } + } + size_t eventPathSize = 0; + if (events != nil) { + container.eventPathParams + = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); + for (MTREventRequestPath * event in events) { + [event convertToEventPathParams:container.eventPathParams[eventPathSize++]]; + } + } + + app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); + CHIP_ERROR err = CHIP_NO_ERROR; + + chip::app::ReadPrepareParams readParams(session.Value()); + [params toReadPrepareParams:readParams]; + readParams.mpAttributePathParamsList = container.pathParams; + readParams.mAttributePathParamsListSize = attributePathSize; + readParams.mpEventPathParamsList = container.eventPathParams; + readParams.mEventPathParamsListSize = eventPathSize; + + auto onDone = [container](BufferedReadClientCallback * callback) { + [container onDone]; + // Make sure we delete callback last, because doing that actually destroys our + // lambda, so we can't access captured values after that. + chip::Platform::Delete(callback); + }; + + auto callback = chip::Platform::MakeUnique>( + container.pathParams, attributePathSize, container.eventPathParams, eventPathSize, onAttributeReportCb, + onEventReportCb, onFailureCb, onDone, onEstablishedCb, onResubscriptionScheduledCb); + + auto readClient = Platform::New( + engine, exchangeManager, callback->GetBufferedCallback(), chip::app::ReadClient::InteractionType::Subscribe); + + if (!params.resubscribeAutomatically) { + err = readClient->SendRequest(readParams); + } else { + err = readClient->SendAutoResubscribeRequest(std::move(readParams)); + } + + if (err != CHIP_NO_ERROR) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:err]); + }); + } + Platform::Delete(readClient); + if (container.pathParams != nullptr) { + Platform::MemoryFree(container.pathParams); + } + + if (container.eventPathParams != nullptr) { + Platform::MemoryFree(container.eventPathParams); + } + container.pathParams = nullptr; + container.eventPathParams = nullptr; + return; + } + + // Read clients will be purged when deregistered. + container.readClientPtr = readClient; + AddReadClientContainer(container.deviceID, container); + callback.release(); + }]; +} + - (void)deregisterReportHandlersWithQueue:(dispatch_queue_t)queue completion:(dispatch_block_t)completion { // This method must only be used for MTRDeviceOverXPC. However, for unit testing purpose, the method purges all read clients. From 3c7b624aa1a1ba301b980a1febc8b18a2c561b75 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Thu, 13 Apr 2023 08:41:25 +0900 Subject: [PATCH 59/72] modify typo --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 18cd0c9f52bdc1..8c73aaa83d4ddd 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -147,7 +147,7 @@ static void PurgeReadClientContainers( container.readClientPtr = nullptr; } if (container.pathParams) { - static_assert(std::is_trivially_destructible::value, "AttributePathPArams destructors won't get run"); + static_assert(std::is_trivially_destructible::value, "AttributePathParams destructors won't get run"); Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; } @@ -246,7 +246,7 @@ - (void)dealloc _readClientPtr = nullptr; } if (_pathParams) { - static_assert(std::is_trivially_destructible::value, "AttributePathPArams destructors won't get run"); + static_assert(std::is_trivially_destructible::value, "AttributePathParams destructors won't get run"); Platform::MemoryFree(_pathParams); _pathParams = nullptr; } From 477a88efdcda95de29f8d29c01ce4e0ced21a422 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Thu, 13 Apr 2023 08:44:30 +0900 Subject: [PATCH 60/72] Add assert code --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 8c73aaa83d4ddd..8e73a87cfc6aec 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -229,10 +229,12 @@ - (void)onDone _readClientPtr = nullptr; } if (_pathParams) { + static_assert(std::is_trivially_destructible::value, "AttributePathParams destructors won't get run"); Platform::MemoryFree(_pathParams); _pathParams = nullptr; } if (_eventPathParams) { + static_assert(std::is_trivially_destructible::value, "EventPathParams destructors won't get run"); Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; } From c83dfd5af2e98969d8e34ec27a4efa643c215872 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Thu, 13 Apr 2023 08:50:50 +0900 Subject: [PATCH 61/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.h | 9 +++++---- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 6 ++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.h b/src/darwin/Framework/CHIP/MTRBaseDevice.h index f8cdc9db24b912..fecf8757befdc3 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.h @@ -159,8 +159,7 @@ MTR_NEWLY_AVAILABLE + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID - eventID:(NSNumber * _Nullable)eventID -MTR_NEWLY_AVAILABLE; + eventID:(NSNumber * _Nullable)eventID MTR_NEWLY_AVAILABLE; @end @interface MTRBaseDevice : NSObject @@ -273,7 +272,8 @@ MTR_NEWLY_AVAILABLE; * empty.) or the entire read interaction fails. Otherwise it will be called with values, which may be empty (e.g. if no paths * matched the wildcard paths passed in) or may include per-path errors if particular paths failed. * - * If the sum of the lengths of attributePaths and eventPaths exceeds 9, the read may fail due to the device not supporting that many read paths. + * If the sum of the lengths of attributePaths and eventPaths exceeds 9, the read may fail due to the device not supporting that + * many read paths. */ - (void)readAttributePaths:(NSArray * _Nullable)attributePaths eventPaths:(NSArray * _Nullable)eventPaths @@ -367,7 +367,8 @@ MTR_NEWLY_AVAILABLE; * The reportHandler will be called with an error if the inputs are invalid (e.g., both attributePaths and eventPaths are * empty), or if the subscription fails entirely. * - * If the sum of the lengths of attributePaths and eventPaths exceeds 3, the subscribe may fail due to the device not supporting that many paths for a subscription. + * If the sum of the lengths of attributePaths and eventPaths exceeds 3, the subscribe may fail due to the device not supporting + * that many paths for a subscription. */ - (void)subscribeToAttributePaths:(NSArray * _Nullable)attributePaths eventPaths:(NSArray * _Nullable)eventPaths diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 8e73a87cfc6aec..7aa9a7078b65a2 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -147,12 +147,14 @@ static void PurgeReadClientContainers( container.readClientPtr = nullptr; } if (container.pathParams) { - static_assert(std::is_trivially_destructible::value, "AttributePathParams destructors won't get run"); + static_assert(std::is_trivially_destructible::value, + "AttributePathParams destructors won't get run"); Platform::MemoryFree(container.pathParams); container.pathParams = nullptr; } if (container.eventPathParams) { - static_assert(std::is_trivially_destructible::value, "EventPathParams destructors won't get run"); + static_assert( + std::is_trivially_destructible::value, "EventPathParams destructors won't get run"); Platform::MemoryFree(container.eventPathParams); container.eventPathParams = nullptr; } From e442c8ce05f4c0209840fec01ed25577ebf26997 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 10:18:41 +0900 Subject: [PATCH 62/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 7aa9a7078b65a2..05829d6a3787da 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1025,7 +1025,7 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri chip::Platform::MemoryFree(attributePathParamsList); } if (eventPathParamsList != nullptr) { - chip::Platform::MemoryFree(eventPathParamsList); + Platform::MemoryFree(eventPathParamsList); } chip::Platform::Delete(callback); }; From dd40779bc9ed4fcbeb9ba0a201649bae61e82808 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 13 Apr 2023 10:18:52 +0900 Subject: [PATCH 63/72] Update src/darwin/Framework/CHIP/MTRBaseDevice.mm Co-authored-by: Boris Zbarsky --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 05829d6a3787da..2c5ca6c715aba3 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1022,7 +1022,7 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri successCb(bridge, resultArray); } if (attributePathParamsList != nullptr) { - chip::Platform::MemoryFree(attributePathParamsList); + Platform::MemoryFree(attributePathParamsList); } if (eventPathParamsList != nullptr) { Platform::MemoryFree(eventPathParamsList); From 994c73e3f0701aeea436eb3b39cabae0490f4cde Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Thu, 13 Apr 2023 15:09:24 +0900 Subject: [PATCH 64/72] Add subscribe null check --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 2c5ca6c715aba3..bf88e6e333d676 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1395,6 +1395,14 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl if (attributes != nil) { container.pathParams = static_cast( Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); + if (container.pathParams == nullptr) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]); + }); + } + return; + } for (MTRAttributeRequestPath * attribute in attributes) { [attribute convertToAttributePathParams:container.pathParams[attributePathSize++]]; } @@ -1403,6 +1411,14 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl if (events != nil) { container.eventPathParams = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); + if (container.eventPathParams == nullptr) { + if (reportHandler) { + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]); + }); + } + return; + } for (MTREventRequestPath * event in events) { [event convertToEventPathParams:container.eventPathParams[eventPathSize++]]; } From c97da797c5d579d9bd0806ba00f27a61aa6d05b7 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 14 Apr 2023 11:47:20 +0900 Subject: [PATCH 65/72] modify --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index bf88e6e333d676..6f1d8ec301bc75 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -996,7 +996,13 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri size_t count = 0; eventPathParamsList = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); - VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); + if (eventPathParamsList == nullptr) { + if (attributePathParamsList != nullptr) { + Platform::MemoryFree(attributePathParamsList); + attributePathParamsList = nullptr; + } + return CHIP_ERROR_NO_MEMORY; + } for (MTREventRequestPath * event in events) { [event convertToEventPathParams:eventPathParamsList[count++]]; } @@ -1396,11 +1402,9 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl container.pathParams = static_cast( Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); if (container.pathParams == nullptr) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]); - }); - } + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]); + }); return; } for (MTRAttributeRequestPath * attribute in attributes) { @@ -1412,11 +1416,9 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl container.eventPathParams = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); if (container.eventPathParams == nullptr) { - if (reportHandler) { - dispatch_async(queue, ^{ - reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]); - }); - } + dispatch_async(queue, ^{ + reportHandler(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_NO_MEMORY]); + }); return; } for (MTREventRequestPath * event in events) { From 40eca604e7d71c71580aa67c89902f6abab21e1d Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Mon, 17 Apr 2023 10:47:59 +0900 Subject: [PATCH 66/72] Modify using uniqur_ptr --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 85 +++++++++++++--------- src/lib/support/CHIPMem.h | 15 ++++ 2 files changed, 64 insertions(+), 36 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 6f1d8ec301bc75..0e8cc503a5113c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -76,12 +76,15 @@ NSString * const MTRArrayValueType = @"Array"; class MTRDataValueDictionaryCallbackBridge; +template class BufferedReadClientCallback; +class MTRDataValueDictionaryDecodableType; @interface MTRReadClientContainer : NSObject @property (nonatomic, readwrite) app::ReadClient * readClientPtr; @property (nonatomic, readwrite) app::AttributePathParams * pathParams; @property (nonatomic, readwrite) app::EventPathParams * eventPathParams; @property (nonatomic, readwrite) uint64_t deviceID; +@property (nonatomic, readwrite) BufferedReadClientCallback * callbackPtr; - (void)onDone; @end @@ -158,6 +161,10 @@ static void PurgeReadClientContainers( Platform::MemoryFree(container.eventPathParams); container.eventPathParams = nullptr; } + if (container.callbackPtr != nullptr) { + Platform::Delete(container.callbackPtr); + container.callbackPtr = nullptr; + } } [listToDelete removeAllObjects]; if (completion) { @@ -240,6 +247,10 @@ - (void)onDone Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; } + if (_callbackPtr) { + Platform::Delete(_callbackPtr); + _callbackPtr = nullptr; + } PurgeCompletedReadClientContainers(_deviceID); } @@ -259,6 +270,10 @@ - (void)dealloc Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; } + if (_callbackPtr) { + Platform::Delete(_callbackPtr); + _callbackPtr = nullptr; + } } @end @@ -748,7 +763,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const static void OnSuccessFn(void * context, id value) { DispatchSuccess(context, value); } }; -template class BufferedReadClientCallback final : public app::ReadClient::Callback { +template class BufferedReadClientCallback : public app::ReadClient::Callback { public: using OnSuccessAttributeCallbackType = std::function; @@ -765,11 +780,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr, OnDeviceResubscriptionScheduledCallbackType aOnDeviceResubscriptionScheduled = nullptr) - : mAttributePathParamsList(aAttributePathParamsList) - , mAttributePathParamsSize(aAttributePathParamsSize) - , mEventPathParamsList(aEventPathParamsList) - , mEventPathParamsSize(aEventPathParamsSize) - , mOnAttributeSuccess(aOnAttributeSuccess) + : mOnAttributeSuccess(aOnAttributeSuccess) , mOnEventSuccess(aOnEventSuccess) , mOnError(aOnError) , mOnDone(aOnDone) @@ -777,6 +788,17 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const , mOnDeviceResubscriptionScheduled(aOnDeviceResubscriptionScheduled) , mBufferedReadAdapter(*this) { + if (aAttributePathParamsList != nullptr) { + mAttributePathParamsList = Platform::MakeMemoryUnique(aAttributePathParamsSize, sizeof(AttributePathParams)); + memcpy(mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams)); + mAttributePathParamsSize = aAttributePathParamsSize; + } + + if (aEventPathParamsList != nullptr) { + mEventPathParamsList = Platform::MakeMemoryUnique(aEventPathParamsSize, sizeof(EventPathParams)); + memcpy(mEventPathParamsList.get(), aEventPathParamsList, aEventPathParamsSize * sizeof(EventPathParams)); + mEventPathParamsSize = aEventPathParamsSize; + } } ~BufferedReadClientCallback() @@ -784,6 +806,8 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const // Ensure we release the ReadClient before we tear down anything else, // so it can call our OnDeallocatePaths properly. mReadClient = nullptr; + mAttributePathParamsList = nullptr; + mEventPathParamsList = nullptr; } app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; } @@ -809,9 +833,9 @@ void OnAttributeData( VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); VerifyOrExit( - std::find_if(mAttributePathParamsList, mAttributePathParamsList + mAttributePathParamsSize, + std::find_if(mAttributePathParamsList.get(), mAttributePathParamsList.get() + mAttributePathParamsSize, [aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); }) - != mAttributePathParamsList + mAttributePathParamsSize, + != mAttributePathParamsList.get() + mAttributePathParamsSize, err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -834,11 +858,11 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons VerifyOrExit(mEventPathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(std::find_if(mEventPathParamsList, mEventPathParamsList + mEventPathParamsSize, + VerifyOrExit(std::find_if(mEventPathParamsList.get(), mEventPathParamsList.get() + mEventPathParamsSize, [aEventHeader](app::EventPathParams & pathParam) -> bool { return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); }) - != mEventPathParamsList + mEventPathParamsSize, + != mEventPathParamsList.get() + mEventPathParamsSize, err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -887,8 +911,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr OnDeviceResubscriptionScheduledCallbackType mOnDeviceResubscriptionScheduled; app::BufferedReadCallback mBufferedReadAdapter; Platform::UniquePtr mReadClient; - app::AttributePathParams * mAttributePathParamsList; - app::EventPathParams * mEventPathParamsList; + Platform::MemoryUniquePtr mAttributePathParamsList; + Platform::MemoryUniquePtr mEventPathParamsList; size_t mAttributePathParamsSize; size_t mEventPathParamsSize; }; @@ -979,32 +1003,26 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } }; - AttributePathParams * attributePathParamsList = nullptr; - EventPathParams * eventPathParamsList = nullptr; + Platform::MemoryUniquePtr attributePathParamsList = nullptr; + Platform::MemoryUniquePtr eventPathParamsList = nullptr; if (attributes != nil) { size_t count = 0; attributePathParamsList - = static_cast(Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); + = Platform::MakeMemoryUnique([attributes count], sizeof(AttributePathParams)); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attribute in attributes) { - [attribute convertToAttributePathParams:attributePathParamsList[count++]]; + [attribute convertToAttributePathParams:attributePathParamsList.get()[count++]]; } } if (events != nil) { size_t count = 0; eventPathParamsList - = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); - if (eventPathParamsList == nullptr) { - if (attributePathParamsList != nullptr) { - Platform::MemoryFree(attributePathParamsList); - attributePathParamsList = nullptr; - } - return CHIP_ERROR_NO_MEMORY; - } + = Platform::MakeMemoryUnique([events count], sizeof(EventPathParams)); + VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTREventRequestPath * event in events) { - [event convertToEventPathParams:eventPathParamsList[count++]]; + [event convertToEventPathParams:eventPathParamsList.get()[count++]]; } } @@ -1013,13 +1031,12 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri chip::app::ReadPrepareParams readParams(session); [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = attributePathParamsList; + readParams.mpAttributePathParamsList = attributePathParamsList.get(); readParams.mAttributePathParamsListSize = [attributePaths count]; - readParams.mpEventPathParamsList = eventPathParamsList; + readParams.mpEventPathParamsList = eventPathParamsList.get(); readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList, - eventPathParamsList](BufferedReadClientCallback * callback) { + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb](BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); @@ -1027,17 +1044,11 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // Success successCb(bridge, resultArray); } - if (attributePathParamsList != nullptr) { - Platform::MemoryFree(attributePathParamsList); - } - if (eventPathParamsList != nullptr) { - Platform::MemoryFree(eventPathParamsList); - } chip::Platform::Delete(callback); }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList, + attributePathParamsList.get(), readParams.mAttributePathParamsListSize, eventPathParamsList.get(), readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); @@ -1437,6 +1448,7 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl readParams.mEventPathParamsListSize = eventPathSize; auto onDone = [container](BufferedReadClientCallback * callback) { + container.callbackPtr = nullptr; [container onDone]; // Make sure we delete callback last, because doing that actually destroys our // lambda, so we can't access captured values after that. @@ -1477,6 +1489,7 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl // Read clients will be purged when deregistered. container.readClientPtr = readClient; + container.callbackPtr = callback.get(); AddReadClientContainer(container.deviceID, container); callback.release(); }]; diff --git a/src/lib/support/CHIPMem.h b/src/lib/support/CHIPMem.h index a1e27c20b73ce3..463366de3c92c3 100644 --- a/src/lib/support/CHIPMem.h +++ b/src/lib/support/CHIPMem.h @@ -175,15 +175,30 @@ struct Deleter void operator()(T * p) { Delete(p); } }; +template +struct MemoryFreer +{ + void operator()(T * p) { MemoryFree(p); } +}; + template using UniquePtr = std::unique_ptr>; +template +using MemoryUniquePtr = std::unique_ptr>; + template inline UniquePtr MakeUnique(Args &&... args) { return UniquePtr(New(std::forward(args)...)); } +template +inline MemoryUniquePtr MakeMemoryUnique(size_t num, size_t size) +{ + return MemoryUniquePtr(static_cast(MemoryCalloc(num, size))); +} + template using SharedPtr = std::shared_ptr; From f855ea573ccbfa8b136b6fc349ee235ab00cc91c Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Mon, 17 Apr 2023 10:49:33 +0900 Subject: [PATCH 67/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0e8cc503a5113c..5d2458d62bf3eb 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -789,11 +789,13 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const , mBufferedReadAdapter(*this) { if (aAttributePathParamsList != nullptr) { - mAttributePathParamsList = Platform::MakeMemoryUnique(aAttributePathParamsSize, sizeof(AttributePathParams)); - memcpy(mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams)); + mAttributePathParamsList + = Platform::MakeMemoryUnique(aAttributePathParamsSize, sizeof(AttributePathParams)); + memcpy( + mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams)); mAttributePathParamsSize = aAttributePathParamsSize; } - + if (aEventPathParamsList != nullptr) { mEventPathParamsList = Platform::MakeMemoryUnique(aEventPathParamsSize, sizeof(EventPathParams)); memcpy(mEventPathParamsList.get(), aEventPathParamsList, aEventPathParamsSize * sizeof(EventPathParams)); @@ -1003,13 +1005,13 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } }; - Platform::MemoryUniquePtr attributePathParamsList = nullptr; - Platform::MemoryUniquePtr eventPathParamsList = nullptr; + Platform::MemoryUniquePtr attributePathParamsList = nullptr; + Platform::MemoryUniquePtr eventPathParamsList = nullptr; if (attributes != nil) { size_t count = 0; attributePathParamsList - = Platform::MakeMemoryUnique([attributes count], sizeof(AttributePathParams)); + = Platform::MakeMemoryUnique([attributes count], sizeof(AttributePathParams)); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attribute in attributes) { [attribute convertToAttributePathParams:attributePathParamsList.get()[count++]]; @@ -1018,8 +1020,7 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri if (events != nil) { size_t count = 0; - eventPathParamsList - = Platform::MakeMemoryUnique([events count], sizeof(EventPathParams)); + eventPathParamsList = Platform::MakeMemoryUnique([events count], sizeof(EventPathParams)); VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTREventRequestPath * event in events) { [event convertToEventPathParams:eventPathParamsList.get()[count++]]; @@ -1036,7 +1037,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri readParams.mpEventPathParamsList = eventPathParamsList.get(); readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb](BufferedReadClientCallback * callback) { + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( + BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); From fb12a69fb26e91543bf20ce7f0ff1947ae938649 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 18 Apr 2023 09:05:37 +0900 Subject: [PATCH 68/72] Revert "restyle" This reverts commit f855ea573ccbfa8b136b6fc349ee235ab00cc91c. --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 5d2458d62bf3eb..0e8cc503a5113c 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -789,13 +789,11 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const , mBufferedReadAdapter(*this) { if (aAttributePathParamsList != nullptr) { - mAttributePathParamsList - = Platform::MakeMemoryUnique(aAttributePathParamsSize, sizeof(AttributePathParams)); - memcpy( - mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams)); + mAttributePathParamsList = Platform::MakeMemoryUnique(aAttributePathParamsSize, sizeof(AttributePathParams)); + memcpy(mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams)); mAttributePathParamsSize = aAttributePathParamsSize; } - + if (aEventPathParamsList != nullptr) { mEventPathParamsList = Platform::MakeMemoryUnique(aEventPathParamsSize, sizeof(EventPathParams)); memcpy(mEventPathParamsList.get(), aEventPathParamsList, aEventPathParamsSize * sizeof(EventPathParams)); @@ -1005,13 +1003,13 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } }; - Platform::MemoryUniquePtr attributePathParamsList = nullptr; - Platform::MemoryUniquePtr eventPathParamsList = nullptr; + Platform::MemoryUniquePtr attributePathParamsList = nullptr; + Platform::MemoryUniquePtr eventPathParamsList = nullptr; if (attributes != nil) { size_t count = 0; attributePathParamsList - = Platform::MakeMemoryUnique([attributes count], sizeof(AttributePathParams)); + = Platform::MakeMemoryUnique([attributes count], sizeof(AttributePathParams)); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attribute in attributes) { [attribute convertToAttributePathParams:attributePathParamsList.get()[count++]]; @@ -1020,7 +1018,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri if (events != nil) { size_t count = 0; - eventPathParamsList = Platform::MakeMemoryUnique([events count], sizeof(EventPathParams)); + eventPathParamsList + = Platform::MakeMemoryUnique([events count], sizeof(EventPathParams)); VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTREventRequestPath * event in events) { [event convertToEventPathParams:eventPathParamsList.get()[count++]]; @@ -1037,8 +1036,7 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri readParams.mpEventPathParamsList = eventPathParamsList.get(); readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb]( - BufferedReadClientCallback * callback) { + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb](BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); From 5428b0a34a4d0297b16eaabb31b5ae5c98ab341f Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 18 Apr 2023 09:06:06 +0900 Subject: [PATCH 69/72] Revert "Modify using uniqur_ptr" This reverts commit 40eca604e7d71c71580aa67c89902f6abab21e1d. --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 85 +++++++++------------- src/lib/support/CHIPMem.h | 15 ---- 2 files changed, 36 insertions(+), 64 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 0e8cc503a5113c..6f1d8ec301bc75 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -76,15 +76,12 @@ NSString * const MTRArrayValueType = @"Array"; class MTRDataValueDictionaryCallbackBridge; -template class BufferedReadClientCallback; -class MTRDataValueDictionaryDecodableType; @interface MTRReadClientContainer : NSObject @property (nonatomic, readwrite) app::ReadClient * readClientPtr; @property (nonatomic, readwrite) app::AttributePathParams * pathParams; @property (nonatomic, readwrite) app::EventPathParams * eventPathParams; @property (nonatomic, readwrite) uint64_t deviceID; -@property (nonatomic, readwrite) BufferedReadClientCallback * callbackPtr; - (void)onDone; @end @@ -161,10 +158,6 @@ static void PurgeReadClientContainers( Platform::MemoryFree(container.eventPathParams); container.eventPathParams = nullptr; } - if (container.callbackPtr != nullptr) { - Platform::Delete(container.callbackPtr); - container.callbackPtr = nullptr; - } } [listToDelete removeAllObjects]; if (completion) { @@ -247,10 +240,6 @@ - (void)onDone Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; } - if (_callbackPtr) { - Platform::Delete(_callbackPtr); - _callbackPtr = nullptr; - } PurgeCompletedReadClientContainers(_deviceID); } @@ -270,10 +259,6 @@ - (void)dealloc Platform::MemoryFree(_eventPathParams); _eventPathParams = nullptr; } - if (_callbackPtr) { - Platform::Delete(_callbackPtr); - _callbackPtr = nullptr; - } } @end @@ -763,7 +748,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const static void OnSuccessFn(void * context, id value) { DispatchSuccess(context, value); } }; -template class BufferedReadClientCallback : public app::ReadClient::Callback { +template class BufferedReadClientCallback final : public app::ReadClient::Callback { public: using OnSuccessAttributeCallbackType = std::function; @@ -780,7 +765,11 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone, OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr, OnDeviceResubscriptionScheduledCallbackType aOnDeviceResubscriptionScheduled = nullptr) - : mOnAttributeSuccess(aOnAttributeSuccess) + : mAttributePathParamsList(aAttributePathParamsList) + , mAttributePathParamsSize(aAttributePathParamsSize) + , mEventPathParamsList(aEventPathParamsList) + , mEventPathParamsSize(aEventPathParamsSize) + , mOnAttributeSuccess(aOnAttributeSuccess) , mOnEventSuccess(aOnEventSuccess) , mOnError(aOnError) , mOnDone(aOnDone) @@ -788,17 +777,6 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const , mOnDeviceResubscriptionScheduled(aOnDeviceResubscriptionScheduled) , mBufferedReadAdapter(*this) { - if (aAttributePathParamsList != nullptr) { - mAttributePathParamsList = Platform::MakeMemoryUnique(aAttributePathParamsSize, sizeof(AttributePathParams)); - memcpy(mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams)); - mAttributePathParamsSize = aAttributePathParamsSize; - } - - if (aEventPathParamsList != nullptr) { - mEventPathParamsList = Platform::MakeMemoryUnique(aEventPathParamsSize, sizeof(EventPathParams)); - memcpy(mEventPathParamsList.get(), aEventPathParamsList, aEventPathParamsSize * sizeof(EventPathParams)); - mEventPathParamsSize = aEventPathParamsSize; - } } ~BufferedReadClientCallback() @@ -806,8 +784,6 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const // Ensure we release the ReadClient before we tear down anything else, // so it can call our OnDeallocatePaths properly. mReadClient = nullptr; - mAttributePathParamsList = nullptr; - mEventPathParamsList = nullptr; } app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; } @@ -833,9 +809,9 @@ void OnAttributeData( VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError()); VerifyOrExit( - std::find_if(mAttributePathParamsList.get(), mAttributePathParamsList.get() + mAttributePathParamsSize, + std::find_if(mAttributePathParamsList, mAttributePathParamsList + mAttributePathParamsSize, [aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); }) - != mAttributePathParamsList.get() + mAttributePathParamsSize, + != mAttributePathParamsList + mAttributePathParamsSize, err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -858,11 +834,11 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons VerifyOrExit(mEventPathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(std::find_if(mEventPathParamsList.get(), mEventPathParamsList.get() + mEventPathParamsSize, + VerifyOrExit(std::find_if(mEventPathParamsList, mEventPathParamsList + mEventPathParamsSize, [aEventHeader](app::EventPathParams & pathParam) -> bool { return pathParam.IsEventPathSupersetOf(aEventHeader.mPath); }) - != mEventPathParamsList.get() + mEventPathParamsSize, + != mEventPathParamsList + mEventPathParamsSize, err = CHIP_ERROR_SCHEMA_MISMATCH); VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -911,8 +887,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr OnDeviceResubscriptionScheduledCallbackType mOnDeviceResubscriptionScheduled; app::BufferedReadCallback mBufferedReadAdapter; Platform::UniquePtr mReadClient; - Platform::MemoryUniquePtr mAttributePathParamsList; - Platform::MemoryUniquePtr mEventPathParamsList; + app::AttributePathParams * mAttributePathParamsList; + app::EventPathParams * mEventPathParamsList; size_t mAttributePathParamsSize; size_t mEventPathParamsSize; }; @@ -1003,26 +979,32 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } }; - Platform::MemoryUniquePtr attributePathParamsList = nullptr; - Platform::MemoryUniquePtr eventPathParamsList = nullptr; + AttributePathParams * attributePathParamsList = nullptr; + EventPathParams * eventPathParamsList = nullptr; if (attributes != nil) { size_t count = 0; attributePathParamsList - = Platform::MakeMemoryUnique([attributes count], sizeof(AttributePathParams)); + = static_cast(Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attribute in attributes) { - [attribute convertToAttributePathParams:attributePathParamsList.get()[count++]]; + [attribute convertToAttributePathParams:attributePathParamsList[count++]]; } } if (events != nil) { size_t count = 0; eventPathParamsList - = Platform::MakeMemoryUnique([events count], sizeof(EventPathParams)); - VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); + = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); + if (eventPathParamsList == nullptr) { + if (attributePathParamsList != nullptr) { + Platform::MemoryFree(attributePathParamsList); + attributePathParamsList = nullptr; + } + return CHIP_ERROR_NO_MEMORY; + } for (MTREventRequestPath * event in events) { - [event convertToEventPathParams:eventPathParamsList.get()[count++]]; + [event convertToEventPathParams:eventPathParamsList[count++]]; } } @@ -1031,12 +1013,13 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri chip::app::ReadPrepareParams readParams(session); [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = attributePathParamsList.get(); + readParams.mpAttributePathParamsList = attributePathParamsList; readParams.mAttributePathParamsListSize = [attributePaths count]; - readParams.mpEventPathParamsList = eventPathParamsList.get(); + readParams.mpEventPathParamsList = eventPathParamsList; readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb](BufferedReadClientCallback * callback) { + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList, + eventPathParamsList](BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); @@ -1044,11 +1027,17 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // Success successCb(bridge, resultArray); } + if (attributePathParamsList != nullptr) { + Platform::MemoryFree(attributePathParamsList); + } + if (eventPathParamsList != nullptr) { + Platform::MemoryFree(eventPathParamsList); + } chip::Platform::Delete(callback); }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList.get(), readParams.mAttributePathParamsListSize, eventPathParamsList.get(), + attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList, readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); @@ -1448,7 +1437,6 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl readParams.mEventPathParamsListSize = eventPathSize; auto onDone = [container](BufferedReadClientCallback * callback) { - container.callbackPtr = nullptr; [container onDone]; // Make sure we delete callback last, because doing that actually destroys our // lambda, so we can't access captured values after that. @@ -1489,7 +1477,6 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl // Read clients will be purged when deregistered. container.readClientPtr = readClient; - container.callbackPtr = callback.get(); AddReadClientContainer(container.deviceID, container); callback.release(); }]; diff --git a/src/lib/support/CHIPMem.h b/src/lib/support/CHIPMem.h index 463366de3c92c3..a1e27c20b73ce3 100644 --- a/src/lib/support/CHIPMem.h +++ b/src/lib/support/CHIPMem.h @@ -175,30 +175,15 @@ struct Deleter void operator()(T * p) { Delete(p); } }; -template -struct MemoryFreer -{ - void operator()(T * p) { MemoryFree(p); } -}; - template using UniquePtr = std::unique_ptr>; -template -using MemoryUniquePtr = std::unique_ptr>; - template inline UniquePtr MakeUnique(Args &&... args) { return UniquePtr(New(std::forward(args)...)); } -template -inline MemoryUniquePtr MakeMemoryUnique(size_t num, size_t size) -{ - return MemoryUniquePtr(static_cast(MemoryCalloc(num, size))); -} - template using SharedPtr = std::shared_ptr; From b8cdaf14e2f76c9368e1c9eddffef53ae660d201 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 18 Apr 2023 09:08:22 +0900 Subject: [PATCH 70/72] modify using scopeBuffer --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 41 ++++++++++------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 6f1d8ec301bc75..7836c0e7905c5d 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -979,14 +979,12 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri } }; - AttributePathParams * attributePathParamsList = nullptr; - EventPathParams * eventPathParamsList = nullptr; + Platform::ScopedMemoryBuffer attributePathParamsList; + Platform::ScopedMemoryBuffer eventPathParamsList; if (attributes != nil) { size_t count = 0; - attributePathParamsList - = static_cast(Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams))); - VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(attributePathParamsList.Calloc([attributes count]), CHIP_ERROR_NO_MEMORY); for (MTRAttributeRequestPath * attribute in attributes) { [attribute convertToAttributePathParams:attributePathParamsList[count++]]; } @@ -994,15 +992,7 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri if (events != nil) { size_t count = 0; - eventPathParamsList - = static_cast(Platform::MemoryCalloc([events count], sizeof(EventPathParams))); - if (eventPathParamsList == nullptr) { - if (attributePathParamsList != nullptr) { - Platform::MemoryFree(attributePathParamsList); - attributePathParamsList = nullptr; - } - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrReturnError(eventPathParamsList.Calloc([events count]), CHIP_ERROR_NO_MEMORY); for (MTREventRequestPath * event in events) { [event convertToEventPathParams:eventPathParamsList[count++]]; } @@ -1013,13 +1003,16 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri chip::app::ReadPrepareParams readParams(session); [params toReadPrepareParams:readParams]; - readParams.mpAttributePathParamsList = attributePathParamsList; + readParams.mpAttributePathParamsList = attributePathParamsList.Get(); readParams.mAttributePathParamsListSize = [attributePaths count]; - readParams.mpEventPathParamsList = eventPathParamsList; + readParams.mpEventPathParamsList = eventPathParamsList.Get(); readParams.mEventPathParamsListSize = [eventPaths count]; - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList, - eventPathParamsList](BufferedReadClientCallback * callback) { + AttributePathParams * attributePathParamsListToFree = attributePathParamsList.Get(); + EventPathParams * eventPathParamsListToFree = eventPathParamsList.Get(); + + auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsListToFree, + eventPathParamsListToFree](BufferedReadClientCallback * callback) { if (*interactionStatus != CHIP_NO_ERROR) { // Failure failureCb(bridge, *interactionStatus); @@ -1027,17 +1020,17 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // Success successCb(bridge, resultArray); } - if (attributePathParamsList != nullptr) { - Platform::MemoryFree(attributePathParamsList); + if (attributePathParamsListToFree != nullptr) { + Platform::MemoryFree(attributePathParamsListToFree); } - if (eventPathParamsList != nullptr) { - Platform::MemoryFree(eventPathParamsList); + if (eventPathParamsListToFree != nullptr) { + Platform::MemoryFree(eventPathParamsListToFree); } chip::Platform::Delete(callback); }; auto callback = chip::Platform::MakeUnique>( - attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList, + attributePathParamsList.Get(), readParams.mAttributePathParamsListSize, eventPathParamsList.Get(), readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); @@ -1058,6 +1051,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // callback->AdoptReadClient(std::move(readClient)); callback.release(); + attributePathParamsList.Release(); + eventPathParamsList.Release(); return err; }); std::move(*bridge).DispatchAction(self); From d493f31c5a9697b5e0dcc799c084bf8c8aa8295c Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Tue, 18 Apr 2023 09:19:58 +0900 Subject: [PATCH 71/72] restyle --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 7836c0e7905c5d..32f0c4ae48c58b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1011,23 +1011,24 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri AttributePathParams * attributePathParamsListToFree = attributePathParamsList.Get(); EventPathParams * eventPathParamsListToFree = eventPathParamsList.Get(); - auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsListToFree, - eventPathParamsListToFree](BufferedReadClientCallback * callback) { - if (*interactionStatus != CHIP_NO_ERROR) { - // Failure - failureCb(bridge, *interactionStatus); - } else { - // Success - successCb(bridge, resultArray); - } - if (attributePathParamsListToFree != nullptr) { - Platform::MemoryFree(attributePathParamsListToFree); - } - if (eventPathParamsListToFree != nullptr) { - Platform::MemoryFree(eventPathParamsListToFree); - } - chip::Platform::Delete(callback); - }; + auto onDone + = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsListToFree, + eventPathParamsListToFree](BufferedReadClientCallback * callback) { + if (*interactionStatus != CHIP_NO_ERROR) { + // Failure + failureCb(bridge, *interactionStatus); + } else { + // Success + successCb(bridge, resultArray); + } + if (attributePathParamsListToFree != nullptr) { + Platform::MemoryFree(attributePathParamsListToFree); + } + if (eventPathParamsListToFree != nullptr) { + Platform::MemoryFree(eventPathParamsListToFree); + } + chip::Platform::Delete(callback); + }; auto callback = chip::Platform::MakeUnique>( attributePathParamsList.Get(), readParams.mAttributePathParamsListSize, eventPathParamsList.Get(), From 995d77faef657bdbafda9cfc6ac4d2946a9414cb Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 18 Apr 2023 00:17:43 -0400 Subject: [PATCH 72/72] Dispatch resubscription callback to the right queue. --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 32f0c4ae48c58b..a8e585d6bf33a9 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1384,11 +1384,14 @@ - (void)subscribeToAttributePaths:(NSArray * _Nullabl } }; - auto onResubscriptionScheduledCb = [resubscriptionScheduled](NSError * error, NSNumber * resubscriptionDelay) { - if (resubscriptionScheduled) { - resubscriptionScheduled(error, resubscriptionDelay); - } - }; + auto onResubscriptionScheduledCb + = [queue, resubscriptionScheduled](NSError * error, NSNumber * resubscriptionDelay) { + if (resubscriptionScheduled) { + dispatch_async(queue, ^{ + resubscriptionScheduled(error, resubscriptionDelay); + }); + } + }; MTRReadClientContainer * container = [[MTRReadClientContainer alloc] init]; container.deviceID = self.nodeID;