blob: 33e88eca47418a7b67b13379d63d415fa9b7f2ed [file] [log] [blame]
#include "pldm_interface.hpp"
#include <signal.h>
#include <sys/socket.h>
#include <stdplus/print.hpp>
#include <cstring>
#include <vector>
constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1;
pldm_requester_rc_t PldmInterface::pldmSendAtNetwork(mctp_eid_t eid,
int networkId, int mctpFd,
const uint8_t* pldmReqMsg,
size_t reqMsgLen)
{
struct sockaddr_mctp addr;
addr.smctp_family = AF_MCTP;
addr.smctp_network = networkId;
addr.smctp_addr.s_addr = eid;
addr.smctp_type = MCTP_MSG_TYPE_PLDM;
addr.smctp_tag = DESTINATION_MCTP_TAG_OWNER;
int rc =
sendto(mctpFd, reinterpret_cast<const uint8_t*>(pldmReqMsg), reqMsgLen,
0, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
if (rc == -1)
{
perror("Failed on sending MCTP packet");
stdplus::print(stderr,
"Failed to send packet over MCTP socket with rc: "
"{}\n",
rc);
return PLDM_REQUESTER_SEND_FAIL;
}
return PLDM_REQUESTER_SUCCESS;
}
pldm_requester_rc_t PldmInterface::mctpRecvAtNetwork(mctp_eid_t eid, int mctpFd,
uint8_t** pldmRespMsg,
size_t* respMsgLen,
int networkId)
{
ssize_t minLen = sizeof(struct pldm_msg_hdr);
struct sockaddr_mctp addr;
memset(&addr, 0, sizeof(addr));
addr.smctp_family = AF_MCTP;
addr.smctp_addr.s_addr = eid;
addr.smctp_type = MCTP_MSG_TYPE_PLDM;
addr.smctp_tag = MCTP_TAG_OWNER;
addr.smctp_network = networkId;
socklen_t addrLen = sizeof(addr);
ssize_t length =
recvfrom(mctpFd, nullptr, 0, MSG_PEEK | MSG_TRUNC,
reinterpret_cast<struct sockaddr*>(&addr), &addrLen);
if (length == 0)
{
stdplus::print(
stderr, "Failure at MCTP socket: No length received, errno: {}\n",
strerror(errno));
return PLDM_REQUESTER_RECV_FAIL;
}
if (length < minLen)
{
/* read and discard */
std::vector<uint8_t> buf(length);
recv(mctpFd, buf.data(), length, 0);
stdplus::print(stderr,
"Failure at MCTP socket: Length less than min"
"bytes, length: {} and minimum length required: {}\n",
std::to_string(length), std::to_string(minLen));
return PLDM_REQUESTER_INVALID_RECV_LEN;
}
ssize_t bytes = recvfrom(mctpFd, *pldmRespMsg, length, MSG_TRUNC,
(struct sockaddr*)&addr, &addrLen);
if (length != bytes)
{
stdplus::print(stderr,
"Failure at MCTP socket: Length is not equal"
"to the bytes read, with length: {} and"
"bytes: {}\n",
length, bytes);
return PLDM_REQUESTER_INVALID_RECV_LEN;
}
*respMsgLen = length;
return PLDM_REQUESTER_SUCCESS;
}
pldm_requester_rc_t PldmInterface::recvAtNetwork(mctp_eid_t eid, int mctpFd,
uint8_t** pldmRespMsg,
size_t* respMsgLen,
int networkId)
{
pldm_requester_rc_t rc =
mctpRecvAtNetwork(eid, mctpFd, pldmRespMsg, respMsgLen, networkId);
if (rc != PLDM_REQUESTER_SUCCESS)
{
stdplus::print(
stderr,
"Failed to receive message at MCTP socket with eid: {} and netId: "
"{}\n",
eid, networkId);
return rc;
}
struct pldm_msg_hdr* hdr =
reinterpret_cast<struct pldm_msg_hdr*>(*pldmRespMsg);
if (hdr->request != PLDM_RESPONSE)
{
stdplus::print(
stderr,
"Failure at MCTP socket: Header is not a response for eid: {} and "
"netId: {}\n",
eid, networkId);
return PLDM_REQUESTER_NOT_RESP_MSG;
}
if (*respMsgLen < (sizeof(struct pldm_msg_hdr) + sizeof(uint8_t)))
{
stdplus::print(
stderr,
"Failure at MCTP socket: Received message is smaller than expected "
"for eid: {} and netId: {}\n",
eid, networkId);
return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
}
return PLDM_REQUESTER_SUCCESS;
}
pldm_requester_rc_t PldmInterface::pldmRecvAtNetwork(mctp_eid_t eid,
int networkId, int mctpFd,
uint8_t instanceId,
uint8_t** pldmRespMsg,
size_t* respMsgLen)
{
pldm_requester_rc_t rc =
recvAtNetwork(eid, mctpFd, pldmRespMsg, respMsgLen, networkId);
if (rc != PLDM_REQUESTER_SUCCESS)
{
return rc;
}
struct pldm_msg_hdr* hdr =
reinterpret_cast<struct pldm_msg_hdr*>(*pldmRespMsg);
if (hdr->instance_id != instanceId)
{
stdplus::print(stderr,
"Failure at MCTP socket receive: Instance id"
"mismatch: Found: {}, Expected: {}\n",
std::to_string(hdr->instance_id), instanceId);
return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
}
return PLDM_REQUESTER_SUCCESS;
}