blob: 0c82f822eae1b1003690943c6df2ea595432f4a0 [file] [log] [blame]
/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
#include <libpldm/oem/meta/file_io.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "api.h"
#include "msgbuf.h"
#include "dsp/base.h"
LIBPLDM_ABI_TESTING
void *pldm_oem_meta_file_io_write_req_data(
struct pldm_oem_meta_file_io_write_req *req)
{
return req->data;
}
LIBPLDM_ABI_TESTING
int decode_oem_meta_file_io_write_req(
const struct pldm_msg *msg, size_t payload_length,
struct pldm_oem_meta_file_io_write_req *req, size_t req_length)
{
struct pldm_msgbuf _buf;
struct pldm_msgbuf *buf = &_buf;
int rc;
if (msg == NULL || req == NULL) {
return -EINVAL;
}
if (req_length < sizeof(*req)) {
return -EINVAL;
}
rc = pldm_msgbuf_init_errno(buf,
PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH,
msg->payload, payload_length);
if (rc) {
return rc;
}
pldm_msgbuf_extract(buf, req->handle);
rc = pldm_msgbuf_extract(buf, req->length);
if (rc) {
return rc;
}
rc = pldm_msgbuf_extract_array(buf, req->length, req->data,
req_length - sizeof(*req));
if (rc) {
return rc;
}
return pldm_msgbuf_destroy_consumed(buf);
}
LIBPLDM_ABI_DEPRECATED
int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
size_t payload_length, uint8_t *file_handle,
uint32_t *length, uint8_t *data)
{
struct pldm_oem_meta_file_io_write_req *request_msg;
size_t request_msg_len;
int rc;
if (msg == NULL || file_handle == NULL || length == NULL ||
data == NULL) {
return pldm_xlate_errno(-EINVAL);
}
request_msg_len = sizeof(*request_msg) + payload_length;
request_msg = malloc(request_msg_len);
rc = decode_oem_meta_file_io_write_req(msg, payload_length, request_msg,
request_msg_len);
if (rc < 0) {
free(request_msg);
return pldm_xlate_errno(rc);
}
*file_handle = request_msg->handle;
*length = request_msg->length;
/* NOTE: Unsafe, memory safety is not possible due to API constraints. */
memcpy(data, request_msg->data, request_msg->length);
free(request_msg);
return 0;
}
LIBPLDM_ABI_TESTING
int decode_oem_meta_file_io_read_req(const struct pldm_msg *msg,
size_t payload_length,
struct pldm_oem_meta_file_io_read_req *req)
{
struct pldm_msgbuf _buf;
struct pldm_msgbuf *buf = &_buf;
if (msg == NULL || req == NULL) {
return -EINVAL;
}
if (req->version > sizeof(struct pldm_oem_meta_file_io_read_req)) {
return -E2BIG;
}
int rc = pldm_msgbuf_init_errno(
buf, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH, msg->payload,
payload_length);
if (rc) {
return rc;
}
pldm_msgbuf_extract(buf, req->handle);
rc = pldm_msgbuf_extract(buf, req->option);
if (rc) {
return rc;
}
rc = pldm_msgbuf_extract(buf, req->length);
if (rc) {
return rc;
}
switch (req->option) {
case PLDM_OEM_META_FILE_IO_READ_ATTR:
if (req->length != 0) {
return -EPROTO;
}
break;
case PLDM_OEM_META_FILE_IO_READ_DATA:
pldm_msgbuf_extract(buf, req->info.data.transferFlag);
pldm_msgbuf_extract(buf, req->info.data.offset);
break;
default:
return -EPROTO;
}
return pldm_msgbuf_destroy_consumed(buf);
}