/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ #include #include #include #include #include #include "api.h" #include "msgbuf.h" #include "dsp/base.h" LIBPLDM_ABI_STABLE void *pldm_oem_meta_file_io_write_req_data( struct pldm_oem_meta_file_io_write_req *req) { return req->data; } LIBPLDM_ABI_STABLE 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_STABLE 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); } LIBPLDM_ABI_STABLE void *pldm_oem_meta_file_io_read_resp_data( struct pldm_oem_meta_file_io_read_resp *resp) { return resp->data; } LIBPLDM_ABI_STABLE int encode_oem_meta_file_io_read_resp( uint8_t instance_id, struct pldm_oem_meta_file_io_read_resp *resp, size_t resp_len, struct pldm_msg *responseMsg, size_t payload_length) { int rc; struct pldm_msgbuf _buf; struct pldm_msgbuf *buf = &_buf; struct pldm_header_info header = { 0 }; if (resp == NULL || responseMsg == NULL) { return -EINVAL; } if (resp_len < sizeof(*resp)) { return -EINVAL; } if (resp->version > sizeof(*resp)) { return -E2BIG; } header.instance = instance_id; header.msg_type = PLDM_RESPONSE; header.pldm_type = PLDM_OEM; header.command = PLDM_OEM_META_FILE_IO_CMD_READ_FILE; rc = pack_pldm_header_errno(&header, &(responseMsg->hdr)); if (rc) { return rc; } rc = pldm_msgbuf_init_errno(buf, PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE, responseMsg->payload, payload_length); if (rc) { return rc; } pldm_msgbuf_insert(buf, resp->completion_code); pldm_msgbuf_insert(buf, resp->handle); pldm_msgbuf_insert(buf, resp->option); pldm_msgbuf_insert(buf, resp->length); switch (resp->option) { case PLDM_OEM_META_FILE_IO_READ_ATTR: pldm_msgbuf_insert(buf, resp->info.attr.size); pldm_msgbuf_insert(buf, resp->info.attr.crc32); break; case PLDM_OEM_META_FILE_IO_READ_DATA: pldm_msgbuf_insert(buf, resp->info.data.transferFlag); pldm_msgbuf_insert(buf, resp->info.data.offset); rc = pldm_msgbuf_insert_array_uint8(buf, resp->length, resp->data, resp_len - sizeof(*resp)); if (rc) { return rc; } break; default: return -EPROTO; } return pldm_msgbuf_destroy(buf); }