LCOV - code coverage report
Current view: top level - protocols/bdx - BdxTransferDiagnosticLog.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 0 92 0.0 %
Date: 2024-02-15 08:20:41 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2024 Project CHIP Authors
       4             :  *    All rights reserved.
       5             :  *
       6             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7             :  *    you may not use this file except in compliance with the License.
       8             :  *    You may obtain a copy of the License at
       9             :  *
      10             :  *        http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  *    Unless required by applicable law or agreed to in writing, software
      13             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  *    See the License for the specific language governing permissions and
      16             :  *    limitations under the License.
      17             :  */
      18             : 
      19             : #include "BdxTransferDiagnosticLog.h"
      20             : 
      21             : namespace chip {
      22             : namespace bdx {
      23             : 
      24             : namespace {
      25             : // Max block size for the BDX transfer.
      26             : constexpr uint32_t kMaxBdxBlockSize = 1024;
      27             : 
      28             : // Timeout for the BDX transfer session..
      29             : constexpr System::Clock::Timeout kBdxTimeout = System::Clock::Seconds16(5 * 60);
      30             : constexpr TransferRole kBdxRole              = TransferRole::kReceiver;
      31             : } // namespace
      32             : 
      33           0 : void BdxTransferDiagnosticLog::HandleTransferSessionOutput(TransferSession::OutputEvent & event)
      34             : {
      35           0 :     assertChipStackLockedByCurrentThread();
      36             : 
      37           0 :     ChipLogDetail(BDX, "Got an event %s", event.ToString(event.EventType));
      38             : 
      39           0 :     switch (event.EventType)
      40             :     {
      41           0 :     case TransferSession::OutputEventType::kInitReceived:
      42           0 :         AbortTransferOnFailure(OnTransferSessionBegin(event));
      43           0 :         break;
      44           0 :     case TransferSession::OutputEventType::kStatusReceived:
      45           0 :         ChipLogError(BDX, "Got StatusReport %x", static_cast<uint16_t>(event.statusData.statusCode));
      46           0 :         LogErrorOnFailure(OnTransferSessionEnd(CHIP_ERROR_INTERNAL));
      47           0 :         break;
      48           0 :     case TransferSession::OutputEventType::kInternalError:
      49           0 :         LogErrorOnFailure(OnTransferSessionEnd(CHIP_ERROR_INTERNAL));
      50           0 :         break;
      51           0 :     case TransferSession::OutputEventType::kTransferTimeout:
      52           0 :         LogErrorOnFailure(OnTransferSessionEnd(CHIP_ERROR_TIMEOUT));
      53           0 :         break;
      54           0 :     case TransferSession::OutputEventType::kBlockReceived:
      55           0 :         AbortTransferOnFailure(OnBlockReceived(event));
      56           0 :         break;
      57           0 :     case TransferSession::OutputEventType::kMsgToSend:
      58           0 :         LogErrorOnFailure(OnMessageToSend(event));
      59             : 
      60           0 :         if (event.msgTypeData.HasMessageType(MessageType::BlockAckEOF))
      61             :         {
      62           0 :             LogErrorOnFailure(OnTransferSessionEnd(CHIP_NO_ERROR));
      63             :         }
      64           0 :         break;
      65           0 :     case TransferSession::OutputEventType::kAckEOFReceived:
      66             :     case TransferSession::OutputEventType::kNone:
      67             :     case TransferSession::OutputEventType::kQueryWithSkipReceived:
      68             :     case TransferSession::OutputEventType::kQueryReceived:
      69             :     case TransferSession::OutputEventType::kAckReceived:
      70             :     case TransferSession::OutputEventType::kAcceptReceived:
      71             :         // Nothing to do.
      72           0 :         break;
      73           0 :     default:
      74             :         // Should never happen.
      75           0 :         chipDie();
      76             :         break;
      77             :     }
      78           0 : }
      79             : 
      80           0 : CHIP_ERROR BdxTransferDiagnosticLog::OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
      81             :                                                        System::PacketBufferHandle && payload)
      82             : {
      83           0 :     assertChipStackLockedByCurrentThread();
      84             : 
      85           0 :     VerifyOrReturnError(ec != nullptr, CHIP_ERROR_INCORRECT_STATE);
      86             : 
      87             :     // If we receive a SendInit message, then we prepare for transfer
      88           0 :     if (payloadHeader.HasMessageType(MessageType::SendInit))
      89             :     {
      90           0 :         FabricIndex fabricIndex = ec->GetSessionHandle()->GetFabricIndex();
      91           0 :         NodeId peerNodeId       = ec->GetSessionHandle()->GetPeer().GetNodeId();
      92           0 :         VerifyOrReturnError(fabricIndex != kUndefinedFabricIndex, CHIP_ERROR_INVALID_ARGUMENT);
      93           0 :         VerifyOrReturnError(peerNodeId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
      94             : 
      95           0 :         mTransferProxy.SetFabricIndex(fabricIndex);
      96           0 :         mTransferProxy.SetPeerNodeId(peerNodeId);
      97           0 :         auto flags(TransferControlFlags::kSenderDrive);
      98           0 :         ReturnLogErrorOnFailure(Responder::PrepareForTransfer(mSystemLayer, kBdxRole, flags, kMaxBdxBlockSize, kBdxTimeout));
      99             :     }
     100             : 
     101           0 :     return TransferFacilitator::OnMessageReceived(ec, payloadHeader, std::move(payload));
     102             : }
     103             : 
     104           0 : CHIP_ERROR BdxTransferDiagnosticLog::OnMessageToSend(TransferSession::OutputEvent & event)
     105             : {
     106           0 :     assertChipStackLockedByCurrentThread();
     107             : 
     108           0 :     VerifyOrReturnError(mExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE);
     109             : 
     110           0 :     auto & msgTypeData  = event.msgTypeData;
     111           0 :     bool isStatusReport = msgTypeData.HasMessageType(Protocols::SecureChannel::MsgType::StatusReport);
     112             : 
     113             :     // All messages sent from the Sender expect a response, except for a StatusReport which would indicate an error and
     114             :     // the end of the transfer.
     115           0 :     Messaging::SendFlags sendFlags;
     116           0 :     VerifyOrDo(isStatusReport, sendFlags.Set(Messaging::SendMessageFlags::kExpectResponse));
     117             : 
     118             :     // If there's an error sending the message, close the exchange by calling Reset.
     119           0 :     auto err = mExchangeCtx->SendMessage(msgTypeData.ProtocolId, msgTypeData.MessageType, std::move(event.MsgData), sendFlags);
     120           0 :     VerifyOrDo(CHIP_NO_ERROR == err, OnTransferSessionEnd(err));
     121             : 
     122           0 :     return err;
     123             : }
     124             : 
     125           0 : CHIP_ERROR BdxTransferDiagnosticLog::OnTransferSessionBegin(TransferSession::OutputEvent & event)
     126             : {
     127           0 :     assertChipStackLockedByCurrentThread();
     128           0 :     VerifyOrReturnError(nullptr != mDelegate, CHIP_ERROR_INCORRECT_STATE);
     129             : 
     130           0 :     ReturnErrorOnFailure(mTransferProxy.Init(&mTransfer));
     131           0 :     return mDelegate->OnTransferBegin(&mTransferProxy);
     132             : }
     133             : 
     134           0 : CHIP_ERROR BdxTransferDiagnosticLog::OnTransferSessionEnd(CHIP_ERROR error)
     135             : {
     136           0 :     assertChipStackLockedByCurrentThread();
     137           0 :     VerifyOrReturnError(nullptr != mDelegate, CHIP_ERROR_INCORRECT_STATE);
     138             : 
     139           0 :     LogErrorOnFailure(mDelegate->OnTransferEnd(&mTransferProxy, error));
     140           0 :     Reset();
     141           0 :     return CHIP_NO_ERROR;
     142             : }
     143             : 
     144           0 : CHIP_ERROR BdxTransferDiagnosticLog::OnBlockReceived(TransferSession::OutputEvent & event)
     145             : {
     146           0 :     assertChipStackLockedByCurrentThread();
     147           0 :     VerifyOrReturnError(nullptr != mDelegate, CHIP_ERROR_INCORRECT_STATE);
     148             : 
     149           0 :     ByteSpan blockData(event.blockdata.Data, event.blockdata.Length);
     150           0 :     return mDelegate->OnTransferData(&mTransferProxy, blockData);
     151             : }
     152             : 
     153           0 : void BdxTransferDiagnosticLog::AbortTransferOnFailure(CHIP_ERROR error)
     154             : {
     155           0 :     VerifyOrReturn(CHIP_NO_ERROR != error);
     156           0 :     LogErrorOnFailure(error);
     157           0 :     LogErrorOnFailure(mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(error)));
     158             : }
     159             : 
     160           0 : void BdxTransferDiagnosticLog::Reset()
     161             : {
     162           0 :     assertChipStackLockedByCurrentThread();
     163             : 
     164           0 :     Responder::ResetTransfer();
     165             : 
     166           0 :     if (mExchangeCtx)
     167             :     {
     168           0 :         mIsExchangeClosing = true;
     169           0 :         mExchangeCtx->Close();
     170           0 :         mIsExchangeClosing = false;
     171           0 :         mExchangeCtx       = nullptr;
     172             :     }
     173             : 
     174           0 :     mTransferProxy.Reset();
     175           0 : }
     176             : 
     177           0 : void BdxTransferDiagnosticLog::OnExchangeClosing(Messaging::ExchangeContext * ec)
     178             : {
     179             :     // The exchange can be closing while TransferFacilitator is still accessing us, so
     180             :     // the BdxTransferDiagnosticLog can not be released "right now".
     181           0 :     mSystemLayer->ScheduleWork(
     182           0 :         [](auto * systemLayer, auto * appState) -> void {
     183           0 :             auto * _this = static_cast<BdxTransferDiagnosticLog *>(appState);
     184           0 :             _this->mPoolDelegate->Release(_this);
     185           0 :         },
     186             :         this);
     187             : 
     188             :     // This block checks and handles the scenario where the exchange is closed externally (e.g., receiving a StatusReport).
     189             :     // Continuing to use it could lead to a use-after-free error and such an error might occur when the poll timer triggers and
     190             :     // OnTransferSessionEnd is called.
     191             :     // We know it's not just us normally closing the exchange if mIsExchangeClosing is false.
     192           0 :     VerifyOrReturn(!mIsExchangeClosing);
     193           0 :     mExchangeCtx = nullptr;
     194           0 :     LogErrorOnFailure(OnTransferSessionEnd(CHIP_ERROR_INTERNAL));
     195             : }
     196             : 
     197             : } // namespace bdx
     198             : } // namespace chip

Generated by: LCOV version 1.14