blob: 071d5e98ebea6c6570cb621de3672c4ba1c06892 [file] [log] [blame] [edit]
#pragma once
#include "libpldmresponder/platform.hpp"
#include <libpldm/base.h>
#include <sdeventplus/source/event.hpp>
#include <cstdint>
#include <vector>
using namespace pldm::responder;
namespace pldm
{
namespace responder
{
namespace base
{
#define PLDM_TYPES_MAX 63
#define PLDM_MIN_PART_SIZE 256
// TODO: We can make the part size configurable for different platforms
#define PLDM_RESPONDER_PART_SIZE 4096
class Handler : public CmdHandler
{
public:
Handler(sdeventplus::Event& event) : event(event)
{
handlers.emplace(
PLDM_GET_PLDM_TYPES,
[this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
return this->getPLDMTypes(request, payloadLength);
});
handlers.emplace(
PLDM_GET_PLDM_COMMANDS,
[this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
return this->getPLDMCommands(request, payloadLength);
});
handlers.emplace(
PLDM_GET_PLDM_VERSION,
[this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
return this->getPLDMVersion(request, payloadLength);
});
handlers.emplace(
PLDM_GET_TID,
[this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
return this->getTID(request, payloadLength);
});
handlers.emplace(PLDM_NEGOTIATE_TRANSFER_PARAMETERS,
[this](pldm_tid_t tid, const pldm_msg* request,
size_t payloadLength) {
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
*
* @param[in] request - Request message payload
* @param[in] payload_length - Request message payload length
* @param[return] Response - PLDM Response message
*/
Response getPLDMTypes(const pldm_msg* request, size_t payloadLength);
/** @brief Handler for getPLDMCommands
*
* @param[in] request - Request message payload
* @param[in] payload_length - Request message payload length
* @param[return] Response - PLDM Response message
*/
Response getPLDMCommands(const pldm_msg* request, size_t payloadLength);
/** @brief Handler for getPLDMCommands
*
* @param[in] request - Request message payload
* @param[in] payload_length - Request message payload length
* @param[return] Response - PLDM Response message
*/
Response getPLDMVersion(const pldm_msg* request, size_t payloadLength);
/** @brief _processSetEventReceiver does the actual work that needs
* to be carried out for setEventReceiver command. This is deferred
* after sending response for getTID command to the host
*
* @param[in] source - sdeventplus event source
*/
void _processSetEventReceiver(sdeventplus::source::EventBase& source);
/** @brief Handler for getTID
*
* @param[in] request - Request message payload
* @param[in] payload_length - Request message payload length
* @param[return] Response - PLDM Response message
*/
Response getTID(const pldm_msg* request, size_t payloadLength);
/** @brief Handler for negotiate transfer parameters
*
* This will save the negotiated part size based on the TID
*
* @param[in] tid - TID of the requester
* @param[in] request - Request message payload
* @param[in] payload_length - Request message payload length
* @param[return] Response - PLDM Response message
*/
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
*/
inline void setOemPlatformHandler(
pldm::responder::oem_platform::Handler* handler)
{
oemPlatformHandler = handler;
}
/* @brief Returns the negotiated part size for a given TID and PLDM type.
*
* If no negotiation has occurred for the given TID and type, it returns a
* default minimum part size.
*
* @param[in] tid - The Terminus ID.
* @param[in] pldmType - The PLDM type.
* @return The negotiated part size.
*/
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
*/
sdeventplus::Event& event;
/** @brief OEM platform handler */
pldm::responder::oem_platform::Handler* oemPlatformHandler = nullptr;
/** @brief sdeventplus event source */
std::unique_ptr<sdeventplus::source::Defer> survEvent;
/** 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
} // namespace responder
} // namespace pldm