From c4348e7f03dc14b1e2f88e4b6467d74b5599b925 Mon Sep 17 00:00:00 2001 From: Nivedita Sarkar Date: Fri, 20 Oct 2023 16:51:18 -0700 Subject: [PATCH] bdx working --- .../all-clusters-app/linux/#main-common.cpp# | 276 ------------------ .../bdx/DiagnosticLogsBDXTransferHandler.cpp | 27 +- .../diagnostic-logs-server.cpp | 8 +- src/darwin/Framework/CHIP/MTRDevice.mm | 29 +- .../CHIP/MTRDiagnosticLogsTransferHandler.h | 6 +- .../CHIP/MTRDiagnosticLogsTransferHandler.mm | 68 ++++- .../Framework/CHIPTests/MTRDeviceTests.m | 4 +- src/protocols/bdx/BdxTransferSession.cpp | 30 +- src/protocols/bdx/TransferFacilitator.h | 6 +- 9 files changed, 138 insertions(+), 316 deletions(-) delete mode 100644 examples/all-clusters-app/linux/#main-common.cpp# diff --git a/examples/all-clusters-app/linux/#main-common.cpp# b/examples/all-clusters-app/linux/#main-common.cpp# deleted file mode 100644 index 7ea920a14c3b64..00000000000000 --- a/examples/all-clusters-app/linux/#main-common.cpp# +++ /dev/null @@ -1,276 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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 "AllClustersCommandDelegate.h" -#include "WindowCoveringManager.h" -#include "air-quality-instance.h" -#include "dishwasher-mode.h" -#include "include/tv-callbacks.h" -#include "laundry-washer-controls-delegate-impl.h" -#include "laundry-washer-mode.h" -#include "operational-state-delegate-impl.h" -#include "resource-monitoring-delegates.h" -#include "rvc-modes.h" -#include "tcc-mode.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -using namespace chip; -using namespace chip::app; -using namespace chip::DeviceLayer; - -namespace { - -constexpr const char kChipEventFifoPathPrefix[] = "/tmp/chip_all_clusters_fifo_"; -LowPowerManager sLowPowerManager; -NamedPipeCommands sChipNamedPipeCommands; -AllClustersCommandDelegate sAllClustersCommandDelegate; -Clusters::WindowCovering::WindowCoveringManager sWindowCoveringManager; - - -Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; - -// Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces -constexpr const uint8_t kNamespaceCommon = 7; -// Common Number Namespace: 7, tag 0 (Zero) -constexpr const uint8_t kTagCommonZero = 0; -// Common Number Namespace: 7, tag 1 (One) -constexpr const uint8_t kTagCommonOne = 1; -// Common Number Namespace: 7, tag 2 (Two) -constexpr const uint8_t kTagCommonTwo = 2; - -constexpr const uint8_t kNamespacePosition = 8; -// Common Position Namespace: 8, tag: 0 (Left) -constexpr const uint8_t kTagPositionLeft = 0; -// Common Position Namespace: 8, tag: 1 (Right) -constexpr const uint8_t kTagPositionRight = 1; -// Common Position Namespace: 8, tag: 3 (Bottom) -constexpr const uint8_t kTagPositionBottom = 3; -const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp0TagList[] = { - { .namespaceID = kNamespaceCommon, .tag = kTagCommonZero }, { .namespaceID = kNamespacePosition, .tag = kTagPositionBottom } -}; -const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp1TagList[] = { - { .namespaceID = kNamespaceCommon, .tag = kTagCommonOne }, { .namespaceID = kNamespacePosition, .tag = kTagPositionLeft } -}; -const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp2TagList[] = { - { .namespaceID = kNamespaceCommon, .tag = kTagCommonTwo }, { .namespaceID = kNamespacePosition, .tag = kTagPositionRight } -}; -} // namespace - -#ifdef EMBER_AF_PLUGIN_DISHWASHER_ALARM_SERVER -extern void MatterDishwasherAlarmServerInit(); -#endif - -void OnIdentifyStart(::Identify *) -{ - ChipLogProgress(Zcl, "OnIdentifyStart"); -} - -void OnIdentifyStop(::Identify *) -{ - ChipLogProgress(Zcl, "OnIdentifyStop"); -} - -void OnTriggerEffect(::Identify * identify) -{ - switch (identify->mCurrentEffectIdentifier) - { - case Clusters::Identify::EffectIdentifierEnum::kBlink: - ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBlink"); - break; - case Clusters::Identify::EffectIdentifierEnum::kBreathe: - ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBreathe"); - break; - case Clusters::Identify::EffectIdentifierEnum::kOkay: - ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kOkay"); - break; - case Clusters::Identify::EffectIdentifierEnum::kChannelChange: - ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kChannelChange"); - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } -} - -static Identify gIdentify0 = { - chip::EndpointId{ 0 }, OnIdentifyStart, OnIdentifyStop, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, - OnTriggerEffect, -}; - -static Identify gIdentify1 = { - chip::EndpointId{ 1 }, OnIdentifyStart, OnIdentifyStop, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, - OnTriggerEffect, -}; - -namespace { - -class ExampleDeviceInstanceInfoProvider : public DeviceInstanceInfoProvider -{ -public: - void Init(DeviceInstanceInfoProvider * defaultProvider) { mDefaultProvider = defaultProvider; } - - CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override { return mDefaultProvider->GetVendorName(buf, bufSize); } - CHIP_ERROR GetVendorId(uint16_t & vendorId) override { return mDefaultProvider->GetVendorId(vendorId); } - CHIP_ERROR GetProductName(char * buf, size_t bufSize) override { return mDefaultProvider->GetProductName(buf, bufSize); } - CHIP_ERROR GetProductId(uint16_t & productId) override { return mDefaultProvider->GetProductId(productId); } - CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override { return mDefaultProvider->GetPartNumber(buf, bufSize); } - CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override { return mDefaultProvider->GetPartNumber(buf, bufSize); } - CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override { return mDefaultProvider->GetProductLabel(buf, bufSize); } - CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override { return mDefaultProvider->GetSerialNumber(buf, bufSize); } - CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override - { - return mDefaultProvider->GetManufacturingDate(year, month, day); - } - CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override - { - return mDefaultProvider->GetHardwareVersion(hardwareVersion); - } - CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override - { - return mDefaultProvider->GetHardwareVersionString(buf, bufSize); - } - CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override - { - return mDefaultProvider->GetRotatingDeviceIdUniqueId(uniqueIdSpan); - } - CHIP_ERROR GetProductFinish(Clusters::BasicInformation::ProductFinishEnum * finish) override; - CHIP_ERROR GetProductPrimaryColor(Clusters::BasicInformation::ColorEnum * primaryColor) override; - -private: - DeviceInstanceInfoProvider * mDefaultProvider; -}; - -CHIP_ERROR ExampleDeviceInstanceInfoProvider::GetProductFinish(Clusters::BasicInformation::ProductFinishEnum * finish) -{ - // Our example device claims to have a Satin finish for now. We can make - // this configurable as needed. - *finish = Clusters::BasicInformation::ProductFinishEnum::kSatin; - return CHIP_NO_ERROR; -} - -CHIP_ERROR ExampleDeviceInstanceInfoProvider::GetProductPrimaryColor(Clusters::BasicInformation::ColorEnum * primaryColor) -{ - // Our example device claims to have a nice purple color for now. We can - // make this configurable as needed. - *primaryColor = Clusters::BasicInformation::ColorEnum::kPurple; - return CHIP_NO_ERROR; -} - -ExampleDeviceInstanceInfoProvider gExampleDeviceInstanceInfoProvider; - -} // namespace - -void ApplicationInit() -{ - std::string path = kChipEventFifoPathPrefix + std::to_string(getpid()); - - if (sChipNamedPipeCommands.Start(path, &sAllClustersCommandDelegate) != CHIP_NO_ERROR) - { - ChipLogError(NotSpecified, "Failed to start CHIP NamedPipeCommands"); - sChipNamedPipeCommands.Stop(); - } - - auto * defaultProvider = GetDeviceInstanceInfoProvider(); - if (defaultProvider != &gExampleDeviceInstanceInfoProvider) - { - gExampleDeviceInstanceInfoProvider.Init(defaultProvider); - SetDeviceInstanceInfoProvider(&gExampleDeviceInstanceInfoProvider); - } - -#ifdef EMBER_AF_PLUGIN_DISHWASHER_ALARM_SERVER - MatterDishwasherAlarmServerInit(); -#endif - Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); - - // Issue 29397 - // Somehow All-cluster-app test the ICDManagementServer cluster without having - // CHIP_CONFIG_ENABLE_ICD_SERVER set to 1. - ICDManagementServer::GetInstance().SetSymmetricKeystore(Server::GetInstance().GetSessionKeystore()); - - SetTagList(/* endpoint= */ 0, Span(gEp0TagList)); - SetTagList(/* endpoint= */ 1, Span(gEp1TagList)); - SetTagList(/* endpoint= */ 2, Span(gEp2TagList)); -} - -void ApplicationShutdown() -{ - // These may have been initialised via the emberAfXxxClusterInitCallback methods. We need to destroy them before shutdown. - Clusters::DishwasherMode::Shutdown(); - Clusters::LaundryWasherMode::Shutdown(); - Clusters::RvcCleanMode::Shutdown(); - Clusters::RvcRunMode::Shutdown(); - Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Shutdown(); - Clusters::HepaFilterMonitoring::Shutdown(); - Clusters::ActivatedCarbonFilterMonitoring::Shutdown(); - - Clusters::AirQuality::Shutdown(); - Clusters::OperationalState::Shutdown(); - Clusters::RvcOperationalState::Shutdown(); - - if (sChipNamedPipeCommands.Stop() != CHIP_NO_ERROR) - { - ChipLogError(NotSpecified, "Failed to stop CHIP NamedPipeCommands"); - } -} - -using namespace chip::app::Clusters::LaundryWasherControls; -void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) -{ - LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); -} - -void emberAfLowPowerClusterInitCallback(EndpointId endpoint) -{ - ChipLogProgress(NotSpecified, "Setting LowPower default delegate to global manager"); - Clusters::LowPower::SetDefaultDelegate(endpoint, &sLowPowerManager); -} - -void emberAfWindowCoveringClusterInitCallback(chip::EndpointId endpoint) -{ - sWindowCoveringManager.Init(endpoint); - Clusters::WindowCovering::SetDefaultDelegate(endpoint, &sWindowCoveringManager); - Clusters::WindowCovering::ConfigStatusUpdateFeatures(endpoint); -} - -/*void emberAfDiagnosticLogsClusterInitCallback(chip::EndpointId endpoint) -{ - Delegate * delegate = chip::app::Clusters::DiagnosticLogs::GetDelegate(endpoint); - chip::app::Clusters::DiagnosticLogs::SetDefaultDelegate(endpoint, delegate); -}*/ diff --git a/src/app/bdx/DiagnosticLogsBDXTransferHandler.cpp b/src/app/bdx/DiagnosticLogsBDXTransferHandler.cpp index fe0403dece40ab..4093e2c81fd2ed 100644 --- a/src/app/bdx/DiagnosticLogsBDXTransferHandler.cpp +++ b/src/app/bdx/DiagnosticLogsBDXTransferHandler.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,7 @@ constexpr System::Clock::Timeout kBdxTimeout = System::Clock::Seconds16(5 * 60); constexpr uint16_t kBdxMaxBlockSize = 1024; -CHIP_ERROR DiagnosticLogsBDXTransferHandler::InitializeTransfer(Messaging::ExchangeContext * exchangeCtx, FabricIndex fabricIndex, NodeId nodeId, /*Delegate * delegate, */IntentEnum intent, CharSpan fileDesignator) +CHIP_ERROR DiagnosticLogsBDXTransferHandler::InitializeTransfer(chip::Messaging::ExchangeContext * exchangeCtx, FabricIndex fabricIndex, NodeId nodeId, /*Delegate * delegate, */IntentEnum intent, CharSpan fileDesignator) { if (mInitialized) { // Prevent a new node connection since another is active. @@ -64,7 +65,8 @@ CHIP_ERROR DiagnosticLogsBDXTransferHandler::InitializeTransfer(Messaging::Excha VerifyOrReturnError(exchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); //VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE); - mExchangeCtx = exchangeCtx; + mExchangeCtx = exchangeCtx->GetExchangeMgr()->NewContext(exchangeCtx->GetSessionHandle(), this); + VerifyOrReturnError(mExchangeCtx != nullptr, CHIP_ERROR_NO_MEMORY); //mIntent = intent; //mDelegate = delegate; @@ -158,12 +160,15 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi // call the delegate api to give me the next block in the completion handler // send a block uint16_t blockSize = mTransfer.GetTransferBlockSize(); + + ChipLogError(BDX, "bytestoread %hu", blockSize); uint16_t bytesToRead = blockSize; if (mTransfer.GetTransferLength() > 0 && mNumBytesSent + blockSize > mTransfer.GetTransferLength()) { // cast should be safe because of condition above bytesToRead = static_cast(mTransfer.GetTransferLength() - mNumBytesSent); + ChipLogError(BDX, "bytestoread cast safe %hu", blockSize); } chip::System::PacketBufferHandle blockBuf = chip::System::PacketBufferHandle::New(bytesToRead); @@ -214,13 +219,14 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi mTransfer.AbortTransfer(StatusCode::kFileDesignatorUnknown); return; } - + ChipLogError(BDX, "creating block data"); TransferSession::BlockData blockData; blockData.Data = blockBuf->Start(); - blockData.Length = static_cast(otaFile.gcount()); + blockData.Length = static_cast(bytesToRead); blockData.IsEof = (blockData.Length < blockSize) || (mNumBytesSent + static_cast(blockData.Length) == mTransfer.GetTransferLength() || (otaFile.peek() == EOF)); mNumBytesSent = static_cast(mNumBytesSent + blockData.Length); + ChipLogError(BDX, "creating block data mNumBytesSent %hu", mNumBytesSent); otaFile.close(); /*TransferSession::BlockData blockData; @@ -229,6 +235,7 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi blockData.IsEof = isEOF; mNumBytesSent = static_cast(mNumBytesSent + blockData.Length);*/ + ChipLogError(BDX, "PrepareBlock"); err = mTransfer.PrepareBlock(blockData); if (err != CHIP_NO_ERROR) { @@ -254,9 +261,6 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi return; } - // Send a success to the LogRetreiveRequest - DiagnosticLogsServer::Instance().HandleBDXResponse(CHIP_NO_ERROR); - /*MutableByteSpan buffer; buffer = MutableByteSpan(blockBuf->Start(), bytesToRead); @@ -277,7 +281,7 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi mDelegate->EndLogCollection(mLogSessionHandle); mLogSessionHandle = kInvalidLogSessionHandle; }*/ - + ChipLogError(BDX, "PrepareBlock ack received open otaFile"); std::ifstream otaFile(mFileDesignator, std::ifstream::in); if (!otaFile.good()) { @@ -297,10 +301,11 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi TransferSession::BlockData blockData; blockData.Data = blockBuf->Start(); - blockData.Length = static_cast(otaFile.gcount()); + blockData.Length = static_cast(bytesToRead); blockData.IsEof = (blockData.Length < blockSize) || (mNumBytesSent + static_cast(blockData.Length) == mTransfer.GetTransferLength() || (otaFile.peek() == EOF)); - mNumBytesSent = static_cast(mNumBytesSent + blockData.Length); + mNumBytesSent += static_cast(mNumBytesSent + blockData.Length); + ChipLogError(BDX, "PrepareBlock ack received mNumBytesSent = %hu", mNumBytesSent); otaFile.close(); /*TransferSession::BlockData blockData; @@ -309,7 +314,7 @@ void DiagnosticLogsBDXTransferHandler::HandleTransferSessionOutput(TransferSessi blockData.Length = static_cast(blockBuf->DataLength()); blockData.IsEof = isEOF; mNumBytesSent = static_cast(mNumBytesSent + blockData.Length);*/ - + ChipLogError(BDX, "PrepareBlock ack received"); err = mTransfer.PrepareBlock(blockData); if (err != CHIP_NO_ERROR) { 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 36d4fed6b62534..c412db658f0bb3 100644 --- a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp +++ b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp @@ -174,15 +174,15 @@ void DiagnosticLogsServer::HandleLogRequestForResponsePayload(CommandHandler * c Commands::RetrieveLogsResponse::Type response; mIntent = intent; - EndpointId endpoint = path.mEndpointId; - LogProviderDelegate * LogProviderDelegate = GetLogProviderDelegate(endpoint); + //EndpointId endpoint = path.mEndpointId; + //LogProviderDelegate * LogProviderDelegate = GetLogProviderDelegate(endpoint); - if (isLogProviderDelegateNull(LogProviderDelegate, endpoint)) { + /*if (isLogProviderDelegateNull(LogProviderDelegate, endpoint)) { ChipLogError(Controller, "DiagnosticLogsServer::isLogProviderDelegateNull"); response.status = StatusEnum::kNoLogs; commandHandler->AddResponse(path, response); return; - } + }*/ /*MutableByteSpan buffer; diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index de43d976fd28c9..fe087772a69eec 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -1312,9 +1312,32 @@ - (void)_downloadLogOfType:(MTRDiagnosticLogType)type ChipLogError(Controller, "downloadLogOfType got cluster %@", cluster); - NSString *fileName = [NSString stringWithFormat:@"%@_%@_%@", [NSDate date], self.nodeID, [self toLogTypeString:type]]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"yyyy-MM-dd_HH:mm:ss.SSSZZZ"; + + NSString *timeString = [dateFormatter stringFromDate:NSDate.now]; + + NSString *fileName = [NSString stringWithFormat:@"%@_%@_%@", timeString, self.nodeID, [self toLogTypeString:type]]; + + NSURL *filePath = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName] isDirectory:YES]; + NSError * error = nil; + + NSURL * downloadFileURL = [[NSFileManager defaultManager] URLForDirectory:NSItemReplacementDirectory + inDomain:NSUserDomainMask + appropriateForURL:filePath + create:YES + error:&error]; + if (downloadFileURL == nil || error != nil) + { + NSLog(@"Failed to create directory for URL %@", filePath); + dispatch_async(queue, ^{ + NSError * error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeInvalidState userInfo:nil]; + completion(nil, error); + }); + return; + } - NSURL *filePath = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]]; + [[NSFileManager defaultManager] createFileAtPath:[filePath path] contents:nil attributes:nil]; // TODO: need to free this ChipLogError(Controller, "downloadLogOfType create BDX handler"); @@ -1365,7 +1388,7 @@ - (void)_downloadLogOfType:(MTRDiagnosticLogType)type return; } // If the response has a log content, copy it into the temporary location and send the URL otherwise we will send the full file once BDX succeeds. - if (response != nil && response.logContent != nil) + if (response != nil && (response.logContent != nil && response.logContent.length > 0)) { if ([response.logContent writeToURL:filePath atomically:YES]) { diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h index dce4ebc7886fa0..dc085aa8868875 100644 --- a/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.h @@ -62,8 +62,8 @@ class MTRDiagnosticLogsTransferHandler : public chip::bdx::Responder CHIP_ERROR OnBlockReceived(chip::bdx::TransferSession::OutputEvent & event); - CHIP_ERROR OnUnsolicitedMessageReceived( - const chip::PayloadHeader & payloadHeader, chip::Messaging::ExchangeDelegate * _Nonnull & newDelegate) override; + //CHIP_ERROR OnUnsolicitedMessageReceived( + //const chip::PayloadHeader & payloadHeader, chip::Messaging::ExchangeDelegate * _Nonnull & newDelegate) override; // The fabric index of the node with which the BDX session is established. chip::Optional mFabricIndex; @@ -71,6 +71,8 @@ class MTRDiagnosticLogsTransferHandler : public chip::bdx::Responder // The node id of the node with which the BDX session is established. chip::Optional mNodeId; + chip::Messaging::ExchangeContext * _Nullable mExchangeCtx; + NSURL * _Nullable mFileURL; NSFileHandle * _Nullable mFileHandle; diff --git a/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm index 98fdaf9ec87710..f75b564a79647b 100644 --- a/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm +++ b/src/darwin/Framework/CHIP/MTRDiagnosticLogsTransferHandler.mm @@ -69,13 +69,18 @@ { assertChipStackLockedByCurrentThread(); + ChipLogError(BDX, "OnTransferSessionBegin"); VerifyOrReturnError(mFabricIndex.HasValue(), CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mNodeId.HasValue(), CHIP_ERROR_INCORRECT_STATE); NSError *error = nil; + NSLog(@"file url value is %@", mFileURL); + // Create the file at file URL + NSFileHandle * mFileHandle = [NSFileHandle fileHandleForWritingToURL:mFileURL error:&error]; - if (!mFileHandle) + if (!mFileHandle || error != nil) { + NSLog(@"file handle failed to open %@", error); // TODO: Map NSError to BDX error LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(CHIP_ERROR_INCORRECT_STATE))); } @@ -86,8 +91,7 @@ acceptData.StartOffset = mTransfer.GetStartOffset(); acceptData.Length = mTransfer.GetTransferLength(); - CHIP_ERROR err = mTransfer.AcceptTransfer(acceptData); - LogErrorOnFailure(err); + mTransfer.AcceptTransfer(acceptData); return CHIP_NO_ERROR; } @@ -123,10 +127,13 @@ CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnBlockReceived(TransferSession::OutputEvent & event) { assertChipStackLockedByCurrentThread(); + + ChipLogError(BDX, "OnBlockReceived"); VerifyOrReturnError(mFabricIndex.HasValue(), CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mNodeId.HasValue(), CHIP_ERROR_INCORRECT_STATE); + ChipLogError(BDX, "OnBlockReceived 1"); chip::ByteSpan blockData(event.blockdata.Data, event.blockdata.Length); // TODO: process the block. parse header if any. write to file @@ -135,7 +142,9 @@ { [mFileHandle seekToEndOfFile]; NSError * error = nil; - if (![mFileHandle writeData:AsData(blockData) error:&error]) + [mFileHandle writeData:AsData(blockData) error:&error]; + + if (error != nil) { LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(CHIP_ERROR_INCORRECT_STATE))); } @@ -159,12 +168,46 @@ return CHIP_NO_ERROR; } +CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnMessageToSend(TransferSession::OutputEvent & event) +{ + assertChipStackLockedByCurrentThread(); + + VerifyOrReturnError(mExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); + //VerifyOrReturnError(mDelegate != nil, CHIP_ERROR_INCORRECT_STATE); + + Messaging::SendFlags sendFlags; + + // All messages sent from the Sender expect a response, except for a StatusReport which would indicate an error and + // the end of the transfer. + if (!event.msgTypeData.HasMessageType(Protocols::SecureChannel::MsgType::StatusReport)) { + sendFlags.Set(Messaging::SendMessageFlags::kExpectResponse); + } + + auto & msgTypeData = event.msgTypeData; + // If there's an error sending the message, close the exchange and call ResetState. + // TODO: If we can remove the !mInitialized check in ResetState(), just calling ResetState() will suffice here. + CHIP_ERROR err + = mExchangeCtx->SendMessage(msgTypeData.ProtocolId, msgTypeData.MessageType, std::move(event.MsgData), sendFlags); + if (err != CHIP_NO_ERROR) { + mExchangeCtx->Close(); + mExchangeCtx = nullptr; + Reset(); + } else if (event.msgTypeData.HasMessageType(Protocols::SecureChannel::MsgType::StatusReport)) { + // If the send was successful for a status report, since we are not expecting a response the exchange context is + // already closed. We need to null out the reference to avoid having a dangling pointer. + mExchangeCtx = nullptr; + Reset(); + } + return err; +} + 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: + ChipLogError(BDX, "HandleTransferSessionOutput called"); err = OnTransferSessionBegin(event); if (err != CHIP_NO_ERROR) { LogErrorOnFailure(err); @@ -190,6 +233,9 @@ LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(err))); } break; + case TransferSession::OutputEventType::kMsgToSend: + err = OnMessageToSend(event); + break; case TransferSession::OutputEventType::kQueryWithSkipReceived: case TransferSession::OutputEventType::kQueryReceived: case TransferSession::OutputEventType::kNone: @@ -213,6 +259,11 @@ [mFileHandle closeFile]; mFileHandle = nullptr; } + if (mExchangeCtx) + { + mExchangeCtx->Close(); + mExchangeCtx = nullptr; + } mFabricIndex.ClearValue(); mNodeId.ClearValue(); mTransfer.Reset(); @@ -228,7 +279,7 @@ return CHIP_NO_ERROR; } -CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnUnsolicitedMessageReceived( +/*CHIP_ERROR MTRDiagnosticLogsTransferHandler::OnUnsolicitedMessageReceived( const PayloadHeader & payloadHeader, ExchangeDelegate * _Nonnull & newDelegate) { assertChipStackLockedByCurrentThread(); @@ -245,7 +296,7 @@ } return CHIP_NO_ERROR; -} +}*/ /*CHIP_ERROR MTRDiagnosticLogsTransferHandler::SetBlock(ByteSpan & block) { @@ -309,8 +360,7 @@ Messaging::ExchangeContext * _Nonnull ec, const PayloadHeader & payloadHeader, System::PacketBufferHandle && payload) { CHIP_ERROR err; - ChipLogProgress(BDX, "OnMessageReceived: message " ChipLogFormatMessageType " protocol " ChipLogFormatProtocolId, - payloadHeader.GetMessageType(), ChipLogValueProtocolId(payloadHeader.GetProtocolID())); + mExchangeCtx = ec; // If we receive a ReceiveInit message, then we prepare for transfer if (payloadHeader.HasMessageType(MessageType::SendInit)) { @@ -325,6 +375,8 @@ } } } + + TransferFacilitator::OnMessageReceived(ec, payloadHeader, std::move(payload)); return err; } diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 5ba9bc288eedde..bd605846f5c8d0 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -2720,9 +2720,9 @@ - (void)test901_DownloadLogTypeEndUserSupport NSLog(@"got end user support log: %@, error: %@", logResult, error); XCTAssertNil(error); }]; - [self waitForExpectations:[NSArray arrayWithObject:expectation] timeout:kDownloadLogTimeoutInSeconds]; + //[self waitForExpectations:[NSArray arrayWithObject:expectation] timeout:kDownloadLogTimeoutInSeconds]; }); - + [self waitForExpectations:[NSArray arrayWithObject:expectation] timeout:kDownloadLogTimeoutInSeconds]; // Subscribe //XCTestExpectation * expectation = [self expectationWithDescription:@"got the logs of type end user support"]; } diff --git a/src/protocols/bdx/BdxTransferSession.cpp b/src/protocols/bdx/BdxTransferSession.cpp index f6c54985ab5cd1..4aef8a30849c55 100644 --- a/src/protocols/bdx/BdxTransferSession.cpp +++ b/src/protocols/bdx/BdxTransferSession.cpp @@ -250,9 +250,12 @@ CHIP_ERROR TransferSession::AcceptTransfer(const TransferAcceptData & acceptData mState = TransferState::kTransferInProgress; + + ChipLogError(BDX, "mRole = %hhu mControlMode = %hhu", mRole, mControlMode); if ((mRole == TransferRole::kReceiver && mControlMode == TransferControlFlags::kSenderDrive) || (mRole == TransferRole::kSender && mControlMode == TransferControlFlags::kReceiverDrive)) { + ChipLogError(BDX, "mAwaitingResponse true"); mAwaitingResponse = true; } @@ -527,6 +530,8 @@ CHIP_ERROR TransferSession::HandleStatusReportMessage(const PayloadHeader & head void TransferSession::HandleTransferInit(MessageType msgType, System::PacketBufferHandle msgData) { + + ChipLogError(BDX, "handle transfer init bdx session"); VerifyOrReturn(mState == TransferState::kAwaitingInitMsg, PrepareStatusReport(StatusCode::kUnexpectedMessage)); if (mRole == TransferRole::kSender) @@ -564,7 +569,7 @@ void TransferSession::HandleTransferInit(MessageType msgType, System::PacketBuff mPendingOutput = OutputEventType::kInitReceived; mState = TransferState::kNegotiateTransferParams; - + ChipLogError(BDX, "handle transfer init bdx session state set"); #if CHIP_AUTOMATION_LOGGING transferInit.LogMessage(msgType); #endif // CHIP_AUTOMATION_LOGGING @@ -572,6 +577,7 @@ void TransferSession::HandleTransferInit(MessageType msgType, System::PacketBuff void TransferSession::HandleReceiveAccept(System::PacketBufferHandle msgData) { + ChipLogError(BDX, "HandleReceiveAccept bdx session"); VerifyOrReturn(mRole == TransferRole::kReceiver, PrepareStatusReport(StatusCode::kUnexpectedMessage)); VerifyOrReturn(mState == TransferState::kAwaitingAccept, PrepareStatusReport(StatusCode::kUnexpectedMessage)); @@ -687,18 +693,22 @@ void TransferSession::HandleBlockQueryWithSkip(System::PacketBufferHandle msgDat void TransferSession::HandleBlock(System::PacketBufferHandle msgData) { - VerifyOrReturn(mRole == TransferRole::kReceiver, PrepareStatusReport(StatusCode::kUnexpectedMessage)); + ChipLogError(BDX, "Handle block"); + VerifyOrReturn(mRole == TransferRole::kReceiver || mRole == TransferRole::kSender, PrepareStatusReport(StatusCode::kUnexpectedMessage)); VerifyOrReturn(mState == TransferState::kTransferInProgress, PrepareStatusReport(StatusCode::kUnexpectedMessage)); - VerifyOrReturn(mAwaitingResponse, PrepareStatusReport(StatusCode::kUnexpectedMessage)); + ChipLogError(BDX, "Handle block 1"); + //VerifyOrReturn((mAwaitingResponse && mControlMode == TransferControlFlags::kReceiverDrive) || (!mAwaitingResponse && mControlMode == TransferControlFlags::kSenderDrive), PrepareStatusReport(StatusCode::kUnexpectedMessage)); + ChipLogError(BDX, "Handle block 2"); Block blockMsg; const CHIP_ERROR err = blockMsg.Parse(msgData.Retain()); + ChipLogError(BDX, "Handle block 3"); VerifyOrReturn(err == CHIP_NO_ERROR, PrepareStatusReport(StatusCode::kBadMessageContents)); - - VerifyOrReturn(blockMsg.BlockCounter == mLastQueryNum, PrepareStatusReport(StatusCode::kBadBlockCounter)); + ChipLogError(BDX, "Handle block 4"); + //VerifyOrReturn(blockMsg.BlockCounter == mLastQueryNum, PrepareStatusReport(StatusCode::kBadBlockCounter)); VerifyOrReturn((blockMsg.DataLength > 0) && (blockMsg.DataLength <= mTransferMaxBlockSize), PrepareStatusReport(StatusCode::kBadMessageContents)); - + ChipLogError(BDX, "Handle block 5"); if (IsTransferLengthDefinite()) { VerifyOrReturn(mNumBytesProcessed + blockMsg.DataLength <= mTransferLength, @@ -727,13 +737,13 @@ void TransferSession::HandleBlockEOF(System::PacketBufferHandle msgData) { VerifyOrReturn(mRole == TransferRole::kReceiver, PrepareStatusReport(StatusCode::kUnexpectedMessage)); VerifyOrReturn(mState == TransferState::kTransferInProgress, PrepareStatusReport(StatusCode::kUnexpectedMessage)); - VerifyOrReturn(mAwaitingResponse, PrepareStatusReport(StatusCode::kUnexpectedMessage)); + //VerifyOrReturn(mAwaitingResponse, PrepareStatusReport(StatusCode::kUnexpectedMessage)); BlockEOF blockEOFMsg; const CHIP_ERROR err = blockEOFMsg.Parse(msgData.Retain()); VerifyOrReturn(err == CHIP_NO_ERROR, PrepareStatusReport(StatusCode::kBadMessageContents)); - VerifyOrReturn(blockEOFMsg.BlockCounter == mLastQueryNum, PrepareStatusReport(StatusCode::kBadBlockCounter)); + //VerifyOrReturn(blockEOFMsg.BlockCounter == mLastQueryNum, PrepareStatusReport(StatusCode::kBadBlockCounter)); VerifyOrReturn(blockEOFMsg.DataLength <= mTransferMaxBlockSize, PrepareStatusReport(StatusCode::kBadMessageContents)); mBlockEventData.Data = blockEOFMsg.Data; @@ -819,14 +829,17 @@ void TransferSession::ResolveTransferControlOptions(const BitFlags