Add support for using base type multipart receive This change adds the support for using PLDM type 0 multipart receive for other PLDM types. Tested: Tested with unit tests Google-Bug-Id: 423027264 Change-Id: I7a158838623d273164b4e72aaae0821de5a50bdf Signed-off-by: Kasun Athukorala <kasunath@google.com>
diff --git a/libpldmresponder/base.cpp b/libpldmresponder/base.cpp index 318c3ee..311ad1a 100644 --- a/libpldmresponder/base.cpp +++ b/libpldmresponder/base.cpp
@@ -37,7 +37,8 @@ static const std::map<Type, Cmd> capabilities{ {PLDM_BASE, {PLDM_GET_TID, PLDM_GET_PLDM_VERSION, PLDM_GET_PLDM_TYPES, - PLDM_GET_PLDM_COMMANDS, PLDM_NEGOTIATE_TRANSFER_PARAMETERS}}, + PLDM_GET_PLDM_COMMANDS, PLDM_NEGOTIATE_TRANSFER_PARAMETERS, + PLDM_MULTIPART_RECEIVE}}, {PLDM_PLATFORM, {PLDM_GET_PDR, PLDM_SET_STATE_EFFECTER_STATES, PLDM_SET_EVENT_RECEIVER, PLDM_GET_SENSOR_READING, PLDM_GET_STATE_SENSOR_READINGS, @@ -311,6 +312,36 @@ return type_it->second; } +Response Handler::getMultipartReceive(pldm_tid_t tid, const pldm_msg* request, + size_t payloadLength) +{ + if (payloadLength != PLDM_MULTIPART_RECEIVE_REQ_BYTES) + { + error("Invalid MultipartReceive request length. Received: '{LEN}'", + "LEN", payloadLength); + return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); + } + + // First byte in the payload is the sub PLDM type. + uint8_t pldmType = *request->payload; + + auto it = multipartReceivehandlers.find(pldmType); + if (it == multipartReceivehandlers.end()) + { + error("No multipart receive handler registered for PLDM type '{TYPE}'", + "TYPE", pldmType); + return CmdHandler::ccOnlyResponse(request, PLDM_ERROR); + } + + return it->second->handleMultipartReceive(tid, request, payloadLength); +} + +void Handler::registerMultipartReceiveHandler(uint8_t pldmType, + CmdHandler* handler) +{ + multipartReceivehandlers.emplace(pldmType, handler); +} + } // namespace base } // namespace responder } // namespace pldm
diff --git a/libpldmresponder/base.hpp b/libpldmresponder/base.hpp index 98d1554..071d5e9 100644 --- a/libpldmresponder/base.hpp +++ b/libpldmresponder/base.hpp
@@ -54,6 +54,11 @@ return this->getNegotiateTransferParam( tid, request, payloadLength); }); + handlers.emplace(PLDM_MULTIPART_RECEIVE, [this](pldm_tid_t tid, + const pldm_msg* request, + size_t payloadLength) { + return this->getMultipartReceive(tid, request, payloadLength); + }); } /** @brief Handler for getPLDMTypes @@ -108,6 +113,19 @@ Response getNegotiateTransferParam(pldm_tid_t tid, const pldm_msg* request, size_t payloadLength); + /** @brief Handler for MultipartReceive requests + * + * This will call the corresponding MultipartReceive handler based on the + * PLDM type in the request. + * + * @param[in] tid - TID of the requester + * @param[in] request - Request message payload + * @param[in] payloadLength - Request message payload length + * @param[return] Response - PLDM Response message + */ + Response getMultipartReceive(pldm_tid_t tid, const pldm_msg* request, + size_t payloadLength); + /* @brief Method to set the oem platform handler in base handler class * * @param[in] handler - oem platform handler @@ -129,6 +147,16 @@ */ uint16_t getNegotiatedPartSize(pldm_tid_t tid, uint8_t pldmType); + /** @brief Registers a handler for MultipartReceive commands for a specific + * PLDM type. + * + * @param[in] pldmType - The PLDM type for which the handler is registered. + * @param[in] handler - A pointer to the CmdHandler instance that will + * handle the MultipartReceive command for the given + * PLDM type. + */ + void registerMultipartReceiveHandler(uint8_t pldmType, CmdHandler* handler); + private: /** @brief reference of main event loop of pldmd, primarily used to schedule * work @@ -144,6 +172,9 @@ /** Negotiated multi part size of each possible PLDM type for different * devices. */ std::map<pldm_tid_t, std::map<uint8_t, uint16_t>> negotiatedPartSizes; + + /** Store handlers to be called for multipart receive commands*/ + std::map<uint8_t, CmdHandler*> multipartReceivehandlers; }; } // namespace base
diff --git a/libpldmresponder/file_transfer.cpp b/libpldmresponder/file_transfer.cpp index 2e3b866..1374017 100644 --- a/libpldmresponder/file_transfer.cpp +++ b/libpldmresponder/file_transfer.cpp
@@ -103,12 +103,6 @@ [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) { return this->dfClose(request, payloadLength); }); - - handlers.emplace( - PLDM_FILE_CMD_DF_READ, - [this](pldm_tid_t tid, const pldm_msg* request, size_t payloadLength) { - return this->dfRead(tid, request, payloadLength); - }); } std::optional<uint16_t> Handler::getFreeFileDescriptor(uint16_t fileIdentifier) @@ -576,6 +570,12 @@ return CmdHandler::ccOnlyResponse(request, PLDM_ERROR); } +Response Handler::handleMultipartReceive( + pldm_tid_t tid, const pldm_msg* request, size_t reqMsgLen) +{ + return dfRead(tid, request, reqMsgLen); +} + } // namespace file_transfer } // namespace responder } // namespace pldm
diff --git a/libpldmresponder/file_transfer.hpp b/libpldmresponder/file_transfer.hpp index 88f7500..8677093 100644 --- a/libpldmresponder/file_transfer.hpp +++ b/libpldmresponder/file_transfer.hpp
@@ -122,6 +122,9 @@ Response dfRead(pldm_tid_t tid, const pldm_msg* request, size_t payloadLength); + Response handleMultipartReceive(pldm_tid_t tid, const pldm_msg* request, + size_t reqMsgLen) override; + responder::base::Handler* baseHandler; // PLDM Platform type handler. File pointers will be initialized during file
diff --git a/libpldmresponder/test/libpldmresponder_base_test.cpp b/libpldmresponder/test/libpldmresponder_base_test.cpp index 93a7c7d..7e271ef 100644 --- a/libpldmresponder/test/libpldmresponder_base_test.cpp +++ b/libpldmresponder/test/libpldmresponder_base_test.cpp
@@ -55,7 +55,7 @@ uint8_t* payload_ptr = responsePtr->payload; ASSERT_EQ(payload_ptr[0], 0); ASSERT_EQ(payload_ptr[1], 188); // 188 = 0b10111100 - ASSERT_EQ(payload_ptr[2], 0); + ASSERT_EQ(payload_ptr[2], 2); // 2 = 0b00000010 } TEST_F(TestBaseCommands, testGetPLDMCommandsBadRequest)
diff --git a/libpldmresponder/test/libpldmresponder_file_transfer_test.cpp b/libpldmresponder/test/libpldmresponder_file_transfer_test.cpp index 313f5d3..ef7b2c0 100644 --- a/libpldmresponder/test/libpldmresponder_file_transfer_test.cpp +++ b/libpldmresponder/test/libpldmresponder_file_transfer_test.cpp
@@ -1,3 +1,4 @@ +#include "libpldmresponder/base.hpp" #include "libpldmresponder/file_transfer.hpp" #include "libpldmresponder/platform.hpp" @@ -124,7 +125,9 @@ platformHandler(nullptr, 0, nullptr, pdrDir, pdrRepo.get(), nullptr, nullptr, nullptr, nullptr, nullptr, event, true), baseHandler(event), handler(&baseHandler, &platformHandler) - {} + { + baseHandler.registerMultipartReceiveHandler(PLDM_FILE, &handler); + } void SetUp() override { @@ -295,7 +298,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handlers - auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse.data(), nullptr); @@ -514,7 +517,7 @@ // Send the request to the handler auto readResponse = - handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse.data(), nullptr); @@ -561,7 +564,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse.data(), nullptr); auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data()); @@ -626,7 +629,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse.data(), nullptr); auto readResponsePtr = reinterpret_cast<pldm_msg*>(readResponse.data()); @@ -696,7 +699,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse1 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest1, + auto readResponse1 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest1, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse1.data(), nullptr); auto readResponsePtr1 = reinterpret_cast<pldm_msg*>(readResponse1.data()); @@ -735,7 +738,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse2 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest2, + auto readResponse2 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest2, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse2.data(), nullptr); @@ -808,7 +811,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse1 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse1 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse1.data(), nullptr); auto readResponsePtr1 = reinterpret_cast<pldm_msg*>(readResponse1.data()); @@ -843,7 +846,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse2 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse2 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse2.data(), nullptr); auto readResponsePtr2 = reinterpret_cast<pldm_msg*>(readResponse2.data()); @@ -874,7 +877,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse3 = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse3 = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(readResponse3.data(), nullptr); auto readResponsePtr3 = reinterpret_cast<pldm_msg*>(readResponse3.data()); @@ -942,7 +945,7 @@ // Send the request to the handler auto firstReadResponse = - handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(firstReadResponse.data(), nullptr); auto firstReadResponsePtr = @@ -960,7 +963,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto abortResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto abortResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); // Verify the abort response @@ -1028,7 +1031,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); // Verify the error response @@ -1092,7 +1095,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); // Verify the error response @@ -1156,7 +1159,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto readResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto readResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); // Verify the error response @@ -1223,7 +1226,7 @@ // Send the request to the handler auto firstReadResponse = - handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(firstReadResponse.data(), nullptr); auto firstReadResponsePtr = @@ -1251,7 +1254,7 @@ ASSERT_EQ(rc, 0); // Send the request to the handler - auto errorResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto errorResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, readRequestPayloadLength); // Verify the error response @@ -1316,7 +1319,7 @@ &readRequestPayloadLength); ASSERT_EQ(rc, 0); auto firstReadResponse = - handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); ASSERT_NE(firstReadResponse.data(), nullptr); auto firstReadResponsePtr = @@ -1343,7 +1346,7 @@ rc = encode_pldm_base_multipart_receive_req(0, &read_req2, readRequest, &readRequestPayloadLength); ASSERT_EQ(rc, 0); - auto errorResponse = handler.handle(0, PLDM_FILE_CMD_DF_READ, readRequest, + auto errorResponse = baseHandler.handle(0, PLDM_MULTIPART_RECEIVE, readRequest, PLDM_MULTIPART_RECEIVE_REQ_BYTES); // Verify the error response
diff --git a/pldmd/handler.hpp b/pldmd/handler.hpp index 89b8a7f..b8c97e1 100644 --- a/pldmd/handler.hpp +++ b/pldmd/handler.hpp
@@ -56,6 +56,12 @@ return response; } + virtual Response handleMultipartReceive(pldm_tid_t, const pldm_msg* request, + size_t /*reqMsgLen*/) + { + return ccOnlyResponse(request, PLDM_ERROR); + } + protected: /** @brief map of PLDM command code to handler - to be populated by derived * classes.