diff --git a/src/protocols/bdx/BdxTransferSession.cpp b/src/protocols/bdx/BdxTransferSession.cpp index 96aa2d205b71d9..f27f653ae4e4a5 100644 --- a/src/protocols/bdx/BdxTransferSession.cpp +++ b/src/protocols/bdx/BdxTransferSession.cpp @@ -648,9 +648,10 @@ void TransferSession::HandleBlock(System::PacketBufferHandle msgData) PrepareStatusReport(StatusCode::kLengthMismatch)); } - mBlockEventData.Data = blockMsg.Data; - mBlockEventData.Length = blockMsg.DataLength; - mBlockEventData.IsEof = false; + mBlockEventData.Data = blockMsg.Data; + mBlockEventData.Length = blockMsg.DataLength; + mBlockEventData.IsEof = false; + mBlockEventData.BlockCounter = blockMsg.BlockCounter; mPendingMsgHandle = std::move(msgData); mPendingOutput = OutputEventType::kBlockReceived; @@ -678,9 +679,10 @@ void TransferSession::HandleBlockEOF(System::PacketBufferHandle msgData) VerifyOrReturn(blockEOFMsg.BlockCounter == mLastQueryNum, PrepareStatusReport(StatusCode::kBadBlockCounter)); VerifyOrReturn(blockEOFMsg.DataLength <= mTransferMaxBlockSize, PrepareStatusReport(StatusCode::kBadMessageContents)); - mBlockEventData.Data = blockEOFMsg.Data; - mBlockEventData.Length = blockEOFMsg.DataLength; - mBlockEventData.IsEof = true; + mBlockEventData.Data = blockEOFMsg.Data; + mBlockEventData.Length = blockEOFMsg.DataLength; + mBlockEventData.IsEof = true; + mBlockEventData.BlockCounter = blockEOFMsg.BlockCounter; mPendingMsgHandle = std::move(msgData); mPendingOutput = OutputEventType::kBlockReceived; diff --git a/src/protocols/bdx/BdxTransferSession.h b/src/protocols/bdx/BdxTransferSession.h index 35882b05a15fe9..4082cc446fd2a3 100644 --- a/src/protocols/bdx/BdxTransferSession.h +++ b/src/protocols/bdx/BdxTransferSession.h @@ -77,9 +77,10 @@ class DLL_EXPORT TransferSession struct BlockData { - const uint8_t * Data = nullptr; - size_t Length = 0; - bool IsEof = false; + const uint8_t * Data = nullptr; + size_t Length = 0; + bool IsEof = false; + uint32_t BlockCounter = 0; }; struct MessageTypeData @@ -220,6 +221,17 @@ class DLL_EXPORT TransferSession */ CHIP_ERROR PrepareBlockQuery(); + /** + * @brief + * Prepare a BlockQueryWithSkip message. The Block counter will be populated automatically. + * + * @param bytesToSkip Number of bytes to seek skip + * + * @return CHIP_ERROR The result of the preparation of a BlockQueryWithSkip message. May also indicate if the TransferSession + * object is unable to handle this request. + */ + CHIP_ERROR PrepareBlockQueryWithSkip(const uint64_t & bytesToSkip); + /** * @brief * Prepare a Block message. The Block counter will be populated automatically. diff --git a/src/protocols/bdx/tests/TestBdxTransferSession.cpp b/src/protocols/bdx/tests/TestBdxTransferSession.cpp index 165b9e0a9c45df..f18487e2373af2 100644 --- a/src/protocols/bdx/tests/TestBdxTransferSession.cpp +++ b/src/protocols/bdx/tests/TestBdxTransferSession.cpp @@ -278,7 +278,7 @@ void SendAndVerifyQuery(nlTestSuite * inSuite, void * inContext, TransferSession // Helper method for preparing a sending a Block message between two TransferSession objects. The sender refers to the node that is // sending Blocks. Uses a static counter incremented with each call. Also verifies that block data received matches what was sent. void SendAndVerifyArbitraryBlock(nlTestSuite * inSuite, void * inContext, TransferSession & sender, TransferSession & receiver, - TransferSession::OutputEvent & outEvent, bool isEof) + TransferSession::OutputEvent & outEvent, bool isEof, uint32_t inBlockCounter) { CHIP_ERROR err = CHIP_NO_ERROR; static uint8_t dataCount = 0; @@ -319,6 +319,7 @@ void SendAndVerifyArbitraryBlock(nlTestSuite * inSuite, void * inContext, Transf if (outEvent.EventType == TransferSession::OutputEventType::kBlockReceived && outEvent.blockdata.Data != nullptr) { NL_TEST_ASSERT(inSuite, !memcmp(fakeBlockData, outEvent.blockdata.Data, outEvent.blockdata.Length)); + NL_TEST_ASSERT(inSuite, outEvent.blockdata.BlockCounter == inBlockCounter); } VerifyNoMoreOutput(inSuite, inContext, receiver); } @@ -414,7 +415,7 @@ void TestInitiatingReceiverReceiverDrive(nlTestSuite * inSuite, void * inContext // Test BlockQuery -> Block -> BlockAck SendAndVerifyQuery(inSuite, inContext, respondingSender, initiatingReceiver, outEvent); - SendAndVerifyArbitraryBlock(inSuite, inContext, respondingSender, initiatingReceiver, outEvent, false); + SendAndVerifyArbitraryBlock(inSuite, inContext, respondingSender, initiatingReceiver, outEvent, false, numBlocksSent); numBlocksSent++; // Test only one block can be prepared at a time, without receiving a response to the first @@ -441,7 +442,7 @@ void TestInitiatingReceiverReceiverDrive(nlTestSuite * inSuite, void * inContext bool isEof = (numBlocksSent == numBlockSends - 1); SendAndVerifyQuery(inSuite, inContext, respondingSender, initiatingReceiver, outEvent); - SendAndVerifyArbitraryBlock(inSuite, inContext, respondingSender, initiatingReceiver, outEvent, isEof); + SendAndVerifyArbitraryBlock(inSuite, inContext, respondingSender, initiatingReceiver, outEvent, isEof, numBlocksSent); numBlocksSent++; } @@ -509,14 +510,16 @@ void TestInitiatingSenderSenderDrive(nlTestSuite * inSuite, void * inContext) SendAndVerifyAcceptMsg(inSuite, inContext, outEvent, respondingReceiver, TransferRole::kReceiver, acceptData, initiatingSender, initOptions); + uint32_t numBlocksSent = 0; // Test multiple Block -> BlockAck -> Block for (int i = 0; i < 3; i++) { - SendAndVerifyArbitraryBlock(inSuite, inContext, initiatingSender, respondingReceiver, outEvent, false); + SendAndVerifyArbitraryBlock(inSuite, inContext, initiatingSender, respondingReceiver, outEvent, false, numBlocksSent); SendAndVerifyBlockAck(inSuite, inContext, initiatingSender, respondingReceiver, outEvent, false); + numBlocksSent++; } - SendAndVerifyArbitraryBlock(inSuite, inContext, initiatingSender, respondingReceiver, outEvent, true); + SendAndVerifyArbitraryBlock(inSuite, inContext, initiatingSender, respondingReceiver, outEvent, true, numBlocksSent); SendAndVerifyBlockAck(inSuite, inContext, initiatingSender, respondingReceiver, outEvent, true); }