diff --git a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp index 7d530a001db140..16dc12be524f07 100644 --- a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp +++ b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp @@ -47,12 +47,13 @@ static_assert(kDiagnosticLogsDelegateTableSize < kEmberInvalidEndpointIndex, "Di // ----------------------------------------------------------------------------- // Delegate Implementation -using ::Delegate; +// namespace { Delegate * gDelegateTable[kDiagnosticLogsDelegateTableSize] = { nullptr }; + Delegate * GetDelegate(EndpointId endpoint) { uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, Id, @@ -87,6 +88,15 @@ void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) gDelegateTable[ep] = delegate; } } + +} // namespace DiagnosticLogs +} // namespace Clusters +} // namespace app +} // namespace chip + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::DiagnosticLogs; DiagnosticLogsServer DiagnosticLogsServer::mInstance; @@ -295,11 +305,6 @@ void DiagnosticLogsServer::InvokeCommand(HandlerContext & handlerContext) }); } -} // namespace DiagnosticLogs -} // namespace Clusters -} // namespace app -} // namespace chip - bool emberAfDiagnosticLogsClusterRetrieveLogsRequestCallback( CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::RetrieveLogsRequest::DecodableType & commandData) diff --git a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.h b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.h index 5a8407dc9b4aff..642e19d8903308 100644 --- a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.h +++ b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.h @@ -32,6 +32,15 @@ namespace app { namespace Clusters { namespace DiagnosticLogs { +/** + * Set the default delegate of the diagnostic logs cluster for the specified endpoint + * + * @param endpoint ID of the endpoint + * + * @param delegate The default delegate at the endpoint + */ +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + /// A reference implementation for DiagnosticLogs source. class DiagnosticLogsServer : public CommandHandlerInterface { @@ -52,15 +61,6 @@ class DiagnosticLogsServer : public CommandHandlerInterface CHIP_ERROR Init(); void Shutdown(); - /** - * Set the default delegate of the diagnostic logs cluster for the specified endpoint - * - * @param endpoint ID of the endpoint - * - * @param delegate The default delegate at the endpoint - */ - void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); - // Inherited from CommandHandlerInterface void InvokeCommand(HandlerContext & handlerContext) override; diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index 8d5c1d33c6cd8a..78d952cd8e66c4 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -38,11 +38,10 @@ typedef NS_ENUM(NSInteger, MTRDiagnosticLogType) { MTRDiagnosticLogTypeEndUserSupport = 0, // End user support log is requested MTRDiagnosticLogTypeNetworkDiagnostics = 1, // Network Diagnostics log is requested MTRDiagnosticLogTypeCrash = 2 // Crash log is requested -} MTR_PROVISIONALLY_AVAILABLE; +}; @protocol MTRDeviceDelegate; -MTR_PROVISIONALLY_AVAILABLE @interface MTRDiagnosticLogResult : NSObject /** @@ -252,7 +251,7 @@ MTR_PROVISIONALLY_AVAILABLE - (void)downloadLogOfType:(MTRDiagnosticLogType)type timeout:(NSTimeInterval)timeout queue:(dispatch_queue_t)queue - completion:(void (^)(MTRDiagnosticLogResult * _Nullable logResult, NSError * error))completion MTR_PROVISIONALLY_AVAILABLE; + completion:(void (^)(MTRDiagnosticLogResult * _Nullable logResult, NSError * error))completion; @end diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 799def6fb12080..b8991c208a0aac 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -23,6 +23,8 @@ #import "MTRBaseDevice_Internal.h" #import "MTRBaseSubscriptionCallback.h" #import "MTRCluster.h" +#import "MTRClusters.h" +#import "MTRClusters_Internal.h" #import "MTRClusterConstants.h" #import "MTRDeviceController_Internal.h" #import "MTRDevice_Internal.h" @@ -1140,17 +1142,17 @@ - (void)openCommissioningWindowWithDiscriminator:(NSNumber *)discriminator [baseDevice openCommissioningWindowWithDiscriminator:discriminator duration:duration queue:queue completion:completion]; } -- (NSString*)getFileDesignatorForLogType(NSInteger logType) +/*- (NSString*)getFileDesignatorForLogType(MTRDiagnosticLogType type) { NSString *fileDesignator = [NSString stringWithFormat:@"%@%i", @"/tmp/", self.nodeID]; - switch (logType) + switch (type) { case MTRDiagnosticLogTypeEndUserSupport: - return @"/tmp/endusersupport.log case MTRDiagnosticLogTypeNetworkDiagnostics: case MTRDiagnosticLogTypeCrash: } -} + return fileDesignator; +}*/ // Once the consumer calls this API- @@ -1170,9 +1172,8 @@ - (void)_downloadLogOfType:(MTRDiagnosticLogType)type queue:(dispatch_queue_t)queue completion:(void (^)(MTRDiagnosticLogResult * _Nullable logResult, NSError * error))completion { - if (type != MTRDiagnosticLogTypeEndUserSupport && type != MTRDiagnosticLogTypeEndUserSupport && type != MTRDiagnosticLogTypeCrash) + if (type != MTRDiagnosticLogTypeEndUserSupport && type != MTRDiagnosticLogTypeNetworkDiagnostics && type != MTRDiagnosticLogTypeCrash) { - MTRDiagnosticLogResult logResult = [[MTRDiagnosticLogResult alloc] init]; NSError * error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeInvalidArgument userInfo:nil]; completion(nil, error); return; @@ -1181,35 +1182,34 @@ - (void)_downloadLogOfType:(MTRDiagnosticLogType)type // Start a timer for the timeout and abort transfer and return the log result if (timeout > 0) { - NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:timeout target:self selector:@selector(timerFire:) userInfo:nil repeats:NO]; + // NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:timeout target:self selector:@selector(timerFire:) userInfo:nil repeats:NO]; } - // Get the first type from the array. if any of the types are invalid should we return no logs. - __block NSMutableArray * logTypes = [NSMutableArray arrayWithArray:types]; - - NSInteger logType = logTypes[0]; - // Create a handler for BDX and start listening for sendinit // send a command with the intent type mapping the values // remove the object at index 0. // completiion handler // TODO: fix the endpoint id part of the code. Take in input - MTRBaseClusterDiagnosticLogs * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:self endpointID:@(0) queue:queue]; + MTRClusterDiagnosticLogs * cluster = [[MTRClusterDiagnosticLogs alloc] initWithDevice:self endpointID:@(0) queue:queue]; if (cluster == nil) { NSError * error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeInvalidState userInfo:nil]; - completion(error, nil); + completion(nil, error); return; } - auto * commandParams = [[MTRDiagnosticLogsClusterRetrieveLogsRequestParams alloc] init]; - commandParams.intent = logType; - commandParams.requestedProtocol = chip::app::Clusters::DiagnosticLogs::TransferProtocolEnum::kBdx; - commandParams.transferFileDesignator = + MTRDiagnosticLogsClusterRetrieveLogsRequestParams * requestParams = [[MTRDiagnosticLogsClusterRetrieveLogsRequestParams alloc] init]; + requestParams.intent = [NSNumber numberWithInt:type]; + requestParams.requestedProtocol = [NSNumber numberWithUnsignedChar:chip::to_underlying(chip::app::Clusters::DiagnosticLogs::TransferProtocolEnum::kBdx)]; + requestParams.transferFileDesignator = @"bdx_file"; - [cluster retrieveLogsRequestWithParams:commandParams completion:(void (^)(MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable data, NSError * _Nullable error)) { - }; + + [cluster retrieveLogsRequestWithParams:requestParams completion:^(MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable data, NSError * _Nullable error) { + if (error) { + completion(nil, error); + } + }]; } - (void)downloadLogOfType:(MTRDiagnosticLogType)type diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h new file mode 100644 index 00000000000000..ea78103e0bcc2c --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h @@ -0,0 +1,78 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +//#include +//#include +//#include + +/** + * This class inherits from the AsyncResponder class and handles the BDX messages for a BDX transfer session. + * It overrides the HandleTransferSessionOutput virtual method and provides an implementation for it to handle + * the OutputEvents that are generated by the BDX transfer session state machine. + * + * An MTRDiagnosticLogsTransferHandler will be associated with a specific BDX transfer session. + * + * The lifecycle of this class is managed by the AsyncFacilitator class which calls the virtual CleanUp method + * that is implemented by this class to clean up and destroy itself and the AsyncFacilitator instances. + * Note: An object of this class can't be used after CleanUp has been called. + */ +class MTRDiagnosticLogsTransferHandler : public chip::bdx::Responder +{ +public: + MTRDiagnosticLogsTransferHandler(); + ~MTRDiagnosticLogsTransferHandler(); + + void HandleTransferSessionOutput(chip::bdx::TransferSession::OutputEvent & event) override; + + void CleanUp(); + +protected: + CHIP_ERROR OnMessageReceived(chip::Messaging::ExchangeContext * ec, const chip::PayloadHeader & payloadHeader, + chip::System::PacketBufferHandle && payload) override; + +private: + CHIP_ERROR PrepareForTransfer(chip::System::Layer * layer, chip::FabricIndex fabricIndex, chip::NodeId nodeId); + + CHIP_ERROR ConfigureState(chip::FabricIndex fabricIndex, chip::NodeId nodeId); + + CHIP_ERROR OnMessageToSend(chip::bdx::TransferSession::OutputEvent & event); + + CHIP_ERROR OnTransferSessionBegin(chip::bdx::TransferSession::OutputEvent & event); + + CHIP_ERROR OnTransferSessionEnd(chip::bdx::TransferSession::OutputEvent & event); + + CHIP_ERROR OnBlockReceived(chip::bdx::TransferSession::OutputEvent & event); + + CHIP_ERROR OnUnsolicitedMessageReceived( + const chip::PayloadHeader & payloadHeader, chip::Messaging::ExchangeDelegate * _Nonnull & newDelegate); + + // The fabric index of the node with which the BDX session is established. + chip::Optional mFabricIndex; + + // The node id of the node with which the BDX session is established. + chip::Optional mNodeId; + + // write to a file temporarily + // std::ofstream mOfs; + //MutableByteSpan mBlock; + //OTAImageHeaderParser mHeaderParser; + + uint64_t downloadedBytes = 0; + uint64_t totalFileBytes = 0; +}; diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm new file mode 100644 index 00000000000000..9616e48aef4616 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm @@ -0,0 +1,310 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRDeviceControllerFactory_Internal.h" +#import "MTRDeviceController_Internal.h" +#import "NSStringSpanConversion.h" + +#import "NSStringSpanConversion.h" + +#include "MTRDiagnosticLogsTransferHandler.h" +#include + +using namespace chip; +using namespace chip::bdx; +using namespace chip::app; + +// TODO Expose a method onto the delegate to make that configurable. +constexpr uint32_t kMaxBdxBlockSize = 1024; + +// Timeout for the BDX transfer session. The OTA Spec mandates this should be >= 5 minutes. +constexpr System::Clock::Timeout kBdxTimeout = System::Clock::Seconds16(5 * 60); +constexpr bdx::TransferRole kBdxRole = bdx::TransferRole::kReceiver; + +// Need DiagnosticLogsProcessorInterface handle to process block which will be implemented in darwin/linux + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::PrepareForTransfer(System::Layer * layer, FabricIndex fabricIndex, NodeId nodeId) +{ + assertChipStackLockedByCurrentThread(); + + ReturnErrorOnFailure(ConfigureState(fabricIndex, nodeId)); + + BitFlags flags(bdx::TransferControlFlags::kReceiverDrive); + + return Responder::PrepareForTransfer(layer, kBdxRole, flags, kMaxBdxBlockSize, kBdxTimeout); +} + +MTRDiagnosticLogsTransferHandler::~MTRDiagnosticLogsTransferHandler() +{ + mFabricIndex.ClearValue(); + mNodeId.ClearValue(); +} + +bdx::StatusCode GetBdxStatusCodeFromChipError(CHIP_ERROR err) +{ + if (err == CHIP_ERROR_INCORRECT_STATE) { + return bdx::StatusCode::kUnexpectedMessage; + } + if (err == CHIP_ERROR_INVALID_ARGUMENT) { + return bdx::StatusCode::kBadMessageContents; + } + return bdx::StatusCode::kUnknown; +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnTransferSessionBegin(TransferSession::OutputEvent & event) +{ + assertChipStackLockedByCurrentThread(); + + VerifyOrReturnError(mFabricIndex.HasValue(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mNodeId.HasValue(), CHIP_ERROR_INCORRECT_STATE); + uint16_t fdl = 0; + const unsigned char * fd = mTransfer.GetFileDesignator(fdl); + + VerifyOrReturnError(fdl <= bdx::kMaxFileDesignatorLen, CHIP_ERROR_INVALID_ARGUMENT); + + TransferSession::TransferAcceptData acceptData; + acceptData.ControlMode = bdx::TransferControlFlags::kSenderDrive; + acceptData.MaxBlockSize = mTransfer.GetTransferBlockSize(); + acceptData.StartOffset = mTransfer.GetStartOffset(); + acceptData.Length = mTransfer.GetTransferLength(); + + CHIP_ERROR err = mTransfer.AcceptTransfer(acceptData); + LogErrorOnFailure(err); + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnTransferSessionEnd(TransferSession::OutputEvent & event) +{ + assertChipStackLockedByCurrentThread(); + + VerifyOrReturnError(mFabricIndex.HasValue(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mNodeId.HasValue(), CHIP_ERROR_INCORRECT_STATE); + + CHIP_ERROR error = CHIP_NO_ERROR; + if (event.EventType == TransferSession::OutputEventType::kTransferTimeout) { + error = CHIP_ERROR_TIMEOUT; + } else if (event.EventType != TransferSession::OutputEventType::kBlockReceived || !event.blockdata.IsEof) { + error = CHIP_ERROR_INTERNAL; + } + + /*auto controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; + VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); + //auto nodeId = @(mNodeId.Value()); + + auto strongDelegate = mDelegate; + auto delagateQueue = mDelegateNotificationQueue; + if (strongDelegate == nil || delagateQueue == nil) { + LogErrorOnFailure(CHIP_ERROR_INCORRECT_STATE); + AsyncResponder::NotifyEventHandled(CHIP_ERROR_INCORRECT_STATE); + return CHIP_ERROR_INCORRECT_STATE; + } + + if ([strongDelegate respondsToSelector:@selector(handleBDXTransferSessionEndForNodeID:controller:error:)]) { + dispatch_async(delagateQueue, ^{ + [strongDelegate handleBDXTransferSessionEndForNodeID:nodeId + controller:controller + error:[MTRError errorForCHIPErrorCode:error]]; + }); + }*/ + mTransfer.Reset(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnBlockReceived(TransferSession::OutputEvent & event) +{ + assertChipStackLockedByCurrentThread(); + + VerifyOrReturnError(mFabricIndex.HasValue(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mNodeId.HasValue(), CHIP_ERROR_INCORRECT_STATE); + + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:mFabricIndex.Value()]; + VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); + + chip::ByteSpan blockData(event.blockdata.Data, event.blockdata.Length); + + // TODO: process the block. parse header if any. write to file + downloadedBytes += blockData.size(); + ChipLogError(BDX, "Got block data of size %llu", downloadedBytes); + mTransfer.PrepareBlockAck(); + //LogErrorOnFailure(err); + if (event.blockdata.IsEof) { + OnTransferSessionEnd(event); + } + LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(CHIP_ERROR_INCORRECT_STATE))); + + return CHIP_NO_ERROR; +} + +void MTRDiagnosticLogsTransferHandler::HandleTransferSessionOutput(TransferSession::OutputEvent & event) +{ + ChipLogError(BDX, "Got an event %s", event.ToString(event.EventType)); + CHIP_ERROR err = CHIP_NO_ERROR; + switch (event.EventType) { + case TransferSession::OutputEventType::kInitReceived: + err = OnTransferSessionBegin(event); + if (err != CHIP_NO_ERROR) { + LogErrorOnFailure(err); + LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(err))); + } + break; + case TransferSession::OutputEventType::kStatusReceived: + ChipLogError(BDX, "Got StatusReport %x", static_cast(event.statusData.statusCode)); + [[fallthrough]]; + case TransferSession::OutputEventType::kInternalError: + case TransferSession::OutputEventType::kTransferTimeout: + err = OnTransferSessionEnd(event); + break; + case TransferSession::OutputEventType::kBlockReceived: + // TODO: if BlockEOF is received process it and call OnTransferSessionEnd(event) + err = OnBlockReceived(event); + if (err != CHIP_NO_ERROR) { + LogErrorOnFailure(err); + LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(err))); + } + break; + case TransferSession::OutputEventType::kQueryWithSkipReceived: + case TransferSession::OutputEventType::kQueryReceived: + case TransferSession::OutputEventType::kNone: + case TransferSession::OutputEventType::kAckReceived: + case TransferSession::OutputEventType::kAcceptReceived: + // Nothing to do. + break; + default: + // Should never happens. + chipDie(); + break; + } +} + +void MTRDiagnosticLogsTransferHandler::CleanUp() { + mTransfer.Reset(); +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::ConfigureState(chip::FabricIndex fabricIndex, chip::NodeId nodeId) +{ + assertChipStackLockedByCurrentThread(); + + auto * controller = [[MTRDeviceControllerFactory sharedInstance] runningControllerForFabricIndex:fabricIndex]; + VerifyOrReturnError(controller != nil, CHIP_ERROR_INCORRECT_STATE); + + mFabricIndex.SetValue(fabricIndex); + mNodeId.SetValue(nodeId); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnUnsolicitedMessageReceived( + const PayloadHeader & payloadHeader, ExchangeDelegate * _Nonnull & newDelegate) +{ + assertChipStackLockedByCurrentThread(); + + ChipLogDetail(BDX, "MTRDiagnosticLogsTransferHandler OnUnsolicitedMessageReceived: message " ChipLogFormatMessageType " protocol " ChipLogFormatProtocolId, + payloadHeader.GetMessageType(), ChipLogValueProtocolId(payloadHeader.GetProtocolID())); + + //VerifyOrReturnError(mExchangeMgr != nullptr, CHIP_ERROR_INCORRECT_STATE); + + // If we receive a ReceiveInit BDX message, create a new MTROTAImageTransferHandler and register it + // as the handler for all BDX messages that will come over this exchange. + if (payloadHeader.HasMessageType(MessageType::SendInit)) { + newDelegate = this; + + } + return CHIP_NO_ERROR; +} + +/*CHIP_ERROR MTRDiagnosticLogsTransferHandler::SetBlock(ByteSpan & block) +{ + if (block.empty()) + { + ReleaseBlock(); + return CHIP_NO_ERROR; + } + if (mBlock.size() < block.size()) + { + if (!mBlock.empty()) + { + ReleaseBlock(); + } + uint8_t * mBlock_ptr = static_cast(chip::Platform::MemoryAlloc(block.size())); + if (mBlock_ptr == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + mBlock = MutableByteSpan(mBlock_ptr, block.size()); + } + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::ProcessHeader(ByteSpan & block) +{ + if (mHeaderParser.IsInitialized()) + { + OTAImageHeader header; + CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); + + // Needs more data to decode the header + ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + ReturnErrorOnFailure(error); + + totalFileBytes = header.mPayloadSize; + mHeaderParser.Clear(); + } + + return CHIP_NO_ERROR; +}*/ + +CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnMessageReceived( + Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, System::PacketBufferHandle && payload) +{ + VerifyOrReturnError(ec != nullptr, CHIP_ERROR_INCORRECT_STATE); + CHIP_ERROR err; + ChipLogProgress(BDX, "OnMessageReceived: message " ChipLogFormatMessageType " protocol " ChipLogFormatProtocolId, + payloadHeader.GetMessageType(), ChipLogValueProtocolId(payloadHeader.GetProtocolID())); + + // If we receive a ReceiveInit message, then we prepare for transfer + if (payloadHeader.HasMessageType(MessageType::SendInit)) { + NodeId nodeId = ec->GetSessionHandle()->GetPeer().GetNodeId(); + FabricIndex fabricIndex = ec->GetSessionHandle()->GetFabricIndex(); + + if (nodeId != kUndefinedNodeId && fabricIndex != kUndefinedFabricIndex) { + err = PrepareForTransfer(&DeviceLayer::SystemLayer(), fabricIndex, nodeId); + if (err != CHIP_NO_ERROR) { + ChipLogError(Controller, "Failed to prepare for transfer for BDX"); + return err; + } + } + } + + return err; +} diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index fa5d008b28d197..bb19f3b0d3878d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -2972,7 +2972,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy) NSNumber * _Nonnull requestedProtocol MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -@property (nonatomic, copy) NSString * _Nullable transferFileDesignator MTR_AVAILABLE(ios(16.5), macos(13.4), watchos(9.5), tvos(16.5)); +@property (nonatomic, copy) NSString * _Nullable transferFileDesignator MTR_AVAILABLE(ios(16.5), macos(13.0), watchos(9.5), tvos(16.5)); /** * Controls whether the command is a timed command (using Timed Invoke). * diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index b5a63a11efa6df..bdbd393fe6da52 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -298,6 +298,8 @@ B4E2621B2AA0D02000DBA5BC /* SleepCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4E262192AA0D01D00DBA5BC /* SleepCommand.mm */; }; B4E2621E2AA0D02D00DBA5BC /* WaitForCommissioneeCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4E2621C2AA0D02A00DBA5BC /* WaitForCommissioneeCommand.mm */; }; BA09EB43247477BA00605257 /* libCHIP.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BA09EB3F2474762900605257 /* libCHIP.a */; }; + CFA0EDAD2AD9D75600C7FA40 /* MTRDiagnosticLogsTransferHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = CFA0EDAC2AD9D75600C7FA40 /* MTRDiagnosticLogsTransferHandler.mm */; }; + CFA0EDAF2AD9D76000C7FA40 /* MTRDiagnosticLogsTransferHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = CFA0EDAE2AD9D76000C7FA40 /* MTRDiagnosticLogsTransferHandler.h */; }; D4772A46285AE98400383630 /* MTRClusterConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = D4772A45285AE98300383630 /* MTRClusterConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ @@ -662,6 +664,8 @@ B4E2621C2AA0D02A00DBA5BC /* WaitForCommissioneeCommand.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WaitForCommissioneeCommand.mm; sourceTree = ""; }; BA09EB3F2474762900605257 /* libCHIP.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCHIP.a; path = lib/libCHIP.a; sourceTree = BUILT_PRODUCTS_DIR; }; BA107AEE2470CFBB004287EB /* chip_xcode_build_connector.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = chip_xcode_build_connector.sh; sourceTree = ""; }; + CFA0EDAC2AD9D75600C7FA40 /* MTRDiagnosticLogsTransferHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDiagnosticLogsTransferHandler.mm; sourceTree = ""; }; + CFA0EDAE2AD9D76000C7FA40 /* MTRDiagnosticLogsTransferHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDiagnosticLogsTransferHandler.h; sourceTree = ""; }; D437613E285BDC0D0051FEA2 /* MTRErrorTestUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRErrorTestUtils.h; sourceTree = ""; }; D437613F285BDC0D0051FEA2 /* MTRTestKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRTestKeys.h; sourceTree = ""; }; D4376140285BDC0D0051FEA2 /* MTRTestStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRTestStorage.h; sourceTree = ""; }; @@ -1088,6 +1092,8 @@ B202528F2459E34F00F97062 /* CHIP */ = { isa = PBXGroup; children = ( + CFA0EDAE2AD9D76000C7FA40 /* MTRDiagnosticLogsTransferHandler.h */, + CFA0EDAC2AD9D75600C7FA40 /* MTRDiagnosticLogsTransferHandler.mm */, 1E4D655129C30A8700BC3478 /* MTRCommissionableBrowser.mm */, 1E4D654C29C208DD00BC3478 /* MTRCommissionableBrowser.h */, 1E4D654D29C208DD00BC3478 /* MTRCommissionableBrowserDelegate.h */, @@ -1420,6 +1426,7 @@ 3CF134AF289D90FF0017A19E /* MTROperationalCertificateIssuer.h in Headers */, 3CF134AB289D8DF70017A19E /* MTRDeviceAttestationInfo.h in Headers */, B2E0D7B2245B0B5C003C5B48 /* MTRManualSetupPayloadParser.h in Headers */, + CFA0EDAF2AD9D76000C7FA40 /* MTRDiagnosticLogsTransferHandler.h in Headers */, 3CF134A7289D8ADA0017A19E /* MTRCSRInfo.h in Headers */, B2E0D7B1245B0B5C003C5B48 /* Matter.h in Headers */, 7596A84428762729004DAE0E /* MTRDevice.h in Headers */, @@ -1751,6 +1758,7 @@ 5A6FEC9827B5C6AF00F25F42 /* MTRDeviceOverXPC.mm in Sources */, 514654492A72F9DF00904E61 /* MTRDemuxingStorage.mm in Sources */, 1E4D655229C30A8700BC3478 /* MTRCommissionableBrowser.mm in Sources */, + CFA0EDAD2AD9D75600C7FA40 /* MTRDiagnosticLogsTransferHandler.mm in Sources */, 3DA1A3562ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm in Sources */, 3DECCB722934AFE200585AEC /* MTRLogging.mm in Sources */, 7596A84528762729004DAE0E /* MTRDevice.mm in Sources */,