* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "transfer/mctp_transfer.h"
uint32_t MctpTransfer::DeviceSendMessage(void* spdm_context, size_t message_size, const void* message, uint64_t timeout)
{
endRecvTempBufferLen = sizeof(sendRecvTempBuffer);
int32_t res = LCallbacks::send_recv(this->device_name, reinterpret_cast<const uint8_t*>(message), message_size,
sendRecvTempBuffer, &endRecvTempBufferLen);
return res == RET_OK ? LIBSPDM_STATUS_SUCCESS : LIBSPDM_STATUS_SESSION_MSG_ERROR;
}
uint32_t MctpTransfer::DeviceReceiveMessage(void* spdm_context, size_t* message_size, void** message, uint64_t timeout)
{
if (*message == nullptr) {
debug_log(DLOG_ERROR, "invalid parameter");
return LIBSPDM_STATUS_SESSION_MSG_ERROR;
}
memcpy_s(reinterpret_cast<uint8_t*>(*message), *message_size, sendRecvTempBuffer, endRecvTempBufferLen);
*message_size = endRecvTempBufferLen;
memset_s(sendRecvTempBuffer, SENDER_RECEIVER_MAX_BUFFER_SIZE, 0, SENDER_RECEIVER_MAX_BUFFER_SIZE);
endRecvTempBufferLen = SENDER_RECEIVER_MAX_BUFFER_SIZE;
return LIBSPDM_STATUS_SUCCESS;
}
uint32_t MctpSendCallback(void* spdm_context, size_t message_size, const void* message, uint64_t timeout)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->DeviceSendMessage(spdm_context, message_size, message, timeout);
}
uint32_t MctpReceiveCallback(void* spdm_context, size_t* message_size, void** message, uint64_t timeout)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->DeviceReceiveMessage(spdm_context, message_size, message, timeout);
}
uint32_t MctpTransfer::EncodeMessage(void* spdm_context, const uint32_t* session_id, bool is_app_message,
bool is_request_message, size_t message_size, void* message,
size_t* transport_message_size, void** transport_message)
{
return LIBSPDM_STATUS_SUCCESS;
}
uint32_t MctpTransfer::DecodeMessage(void* spdm_context, uint32_t** session_id, bool* is_app_message,
bool is_request_message, size_t transport_message_size, void* transport_message,
size_t* message_size, void** message)
{
return LIBSPDM_STATUS_SUCCESS;
}
uint32_t MctpEncodeCallback(void* spdm_context, const uint32_t* session_id, bool is_app_message,
bool is_request_message, size_t message_size, void* message, size_t* transport_message_size,
void** transport_message)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->EncodeMessage(spdm_context, session_id, is_app_message, is_request_message, message_size, message,
transport_message_size, transport_message);
}
uint32_t MctpDecodeCallback(void* spdm_context, uint32_t** session_id, bool* is_app_message, bool is_request_message,
size_t transport_message_size, void* transport_message, size_t* message_size,
void** message)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->DecodeMessage(spdm_context, session_id, is_app_message, is_request_message, transport_message_size,
transport_message, message_size, message);
}
uint32_t MctpTransfer::AcquireSenderBuffer(void* spdm_context, void** msg_buf_ptr)
{
if (sendReceiveBufferAcquired) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}
*msg_buf_ptr = sendReceiveBuffer;
ZeroMem(sendReceiveBuffer, sizeof(sendReceiveBuffer));
sendReceiveBufferAcquired = true;
return LIBSPDM_STATUS_SUCCESS;
}
void MctpTransfer::ReleaseSenderBuffer(void* spdm_context, const void* msg_buf_ptr)
{
sendReceiveBufferAcquired = false;
}
uint32_t MctpTransfer::AcquireReceiverBuffer(void* spdm_context, void** msg_buf_ptr)
{
if (sendReceiveBufferAcquired) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}
*msg_buf_ptr = sendReceiveBuffer;
ZeroMem(sendReceiveBuffer, sizeof(sendReceiveBuffer));
sendReceiveBufferAcquired = true;
return LIBSPDM_STATUS_SUCCESS;
}
void MctpTransfer::ReleaseReceiverBuffer(void* spdm_context, const void* msg_buf_ptr)
{
sendReceiveBufferAcquired = false;
}
uint32_t MctpAcquireSenderBufferCallback(void* spdm_context, void** msg_buf_ptr)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->AcquireSenderBuffer(spdm_context, msg_buf_ptr);
}
void MctpReleaseSenderBufferCallback(void* spdm_context, const void* msg_buf_ptr)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->ReleaseSenderBuffer(spdm_context, msg_buf_ptr);
}
uint32_t MctpAcquireReceiverBufferCallback(void* spdm_context, void** msg_buf_ptr)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->AcquireReceiverBuffer(spdm_context, msg_buf_ptr);
}
void MctpReleaseReceiverBufferCallback(void* spdm_context, const void* msg_buf_ptr)
{
libspdm_context_t* ctx = static_cast<libspdm_context_t*>(spdm_context);
MctpTransfer* transfer = static_cast<MctpTransfer*>(ctx->app_context_data_ptr);
return transfer->ReleaseReceiverBuffer(spdm_context, msg_buf_ptr);
}
int32_t MctpTransfer::RegisterFunctions(void* spdm_context)
{
RegisterDeviceIoFunc(spdm_context, MctpSendCallback, MctpReceiveCallback);
RegisterTransportLayerFunc(spdm_context, msgMaxSize, msgHeaderSize, msgTailSize, MctpEncodeCallback,
MctpDecodeCallback);
RegisterDeviceBufferFunc(spdm_context, SENDER_BUFFER_SIZE, RECEIVER_BUFFER_SIZE, MctpAcquireSenderBufferCallback,
MctpReleaseSenderBufferCallback, MctpAcquireReceiverBufferCallback,
MctpReleaseReceiverBufferCallback);
size_t scratch_buffer_size = GetRequiredScratchBufferSize(spdm_context);
debug_log(DLOG_INFO, "scratch_buffer_size = %lu", scratch_buffer_size);
if (scratch_buffer_size != 0) {
scratchBuffer = (void*)malloc(scratch_buffer_size);
if (scratchBuffer == nullptr) {
debug_log(DLOG_ERROR, "malloc scratch buffer failed");
return RET_ERR;
}
SetScratchBuffer(spdm_context, scratchBuffer, scratch_buffer_size);
}
return RET_OK;
}