blob: d3e7a6d6f709dc710248c6757a1d35182a506b0b [file] [log] [blame]
Delphine CC Chiu22fad392023-10-27 11:05:01 +08001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2#include <libpldm/oem/meta/file_io.h>
3#include <endian.h>
Lora Lin0f5be282024-07-22 09:46:18 +08004#include <stdlib.h>
Delphine CC Chiu22fad392023-10-27 11:05:01 +08005#include <string.h>
6#include <stdio.h>
Delphine CC Chiu22fad392023-10-27 11:05:01 +08007
Lora Lin0f5be282024-07-22 09:46:18 +08008#include "api.h"
9#include "msgbuf.h"
10#include "dsp/base.h"
11
Lora Linea0bf3a2024-09-20 10:09:56 +080012LIBPLDM_ABI_STABLE
Lora Lin0f5be282024-07-22 09:46:18 +080013void *pldm_oem_meta_file_io_write_req_data(
14 struct pldm_oem_meta_file_io_write_req *req)
15{
16 return req->data;
17}
18
Lora Linea0bf3a2024-09-20 10:09:56 +080019LIBPLDM_ABI_STABLE
Lora Lin0f5be282024-07-22 09:46:18 +080020int decode_oem_meta_file_io_write_req(
21 const struct pldm_msg *msg, size_t payload_length,
22 struct pldm_oem_meta_file_io_write_req *req, size_t req_length)
Delphine CC Chiu22fad392023-10-27 11:05:01 +080023{
Andrew Jefferya1896962025-03-03 21:41:25 +103024 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000025 int rc;
Delphine CC Chiu22fad392023-10-27 11:05:01 +080026
Lora Lin0f5be282024-07-22 09:46:18 +080027 if (msg == NULL || req == NULL) {
28 return -EINVAL;
Delphine CC Chiu22fad392023-10-27 11:05:01 +080029 }
30
Lora Lin0f5be282024-07-22 09:46:18 +080031 if (req_length < sizeof(*req)) {
32 return -EINVAL;
33 }
34
35 rc = pldm_msgbuf_init_errno(buf,
36 PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH,
37 msg->payload, payload_length);
Delphine CC Chiu22fad392023-10-27 11:05:01 +080038 if (rc) {
39 return rc;
40 }
41
Lora Lin0f5be282024-07-22 09:46:18 +080042 pldm_msgbuf_extract(buf, req->handle);
43 rc = pldm_msgbuf_extract(buf, req->length);
44 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +103045 return pldm_msgbuf_discard(buf, rc);
Lora Lin0f5be282024-07-22 09:46:18 +080046 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000047
Lora Lin0f5be282024-07-22 09:46:18 +080048 rc = pldm_msgbuf_extract_array(buf, req->length, req->data,
49 req_length - sizeof(*req));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000050 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +103051 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000052 }
Delphine CC Chiu22fad392023-10-27 11:05:01 +080053
Andrew Jeffery70d21c92025-03-05 12:59:42 +103054 return pldm_msgbuf_complete_consumed(buf);
Delphine CC Chiu22fad392023-10-27 11:05:01 +080055}
Lora Lin0f5be282024-07-22 09:46:18 +080056
Andrew Jeffery36324f62024-09-25 13:41:41 +093057LIBPLDM_ABI_DEPRECATED_UNSAFE
Lora Lin0f5be282024-07-22 09:46:18 +080058int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
59 size_t payload_length, uint8_t *file_handle,
60 uint32_t *length, uint8_t *data)
61{
62 struct pldm_oem_meta_file_io_write_req *request_msg;
63 size_t request_msg_len;
64 int rc;
65
66 if (msg == NULL || file_handle == NULL || length == NULL ||
67 data == NULL) {
68 return pldm_xlate_errno(-EINVAL);
69 }
70
Andrew Jeffery36324f62024-09-25 13:41:41 +093071 if (SIZE_MAX - sizeof(*request_msg) < payload_length) {
72 return pldm_xlate_errno(-EOVERFLOW);
73 }
74
Lora Lin0f5be282024-07-22 09:46:18 +080075 request_msg_len = sizeof(*request_msg) + payload_length;
76 request_msg = malloc(request_msg_len);
77
78 rc = decode_oem_meta_file_io_write_req(msg, payload_length, request_msg,
79 request_msg_len);
80 if (rc < 0) {
81 free(request_msg);
82 return pldm_xlate_errno(rc);
83 }
84
85 *file_handle = request_msg->handle;
86 *length = request_msg->length;
87
88 /* NOTE: Unsafe, memory safety is not possible due to API constraints. */
89 memcpy(data, request_msg->data, request_msg->length);
90
91 free(request_msg);
92
93 return 0;
94}
Lora Lin893a08f2024-07-16 15:03:31 +080095
Lora Linea0bf3a2024-09-20 10:09:56 +080096LIBPLDM_ABI_STABLE
Lora Lin893a08f2024-07-16 15:03:31 +080097int decode_oem_meta_file_io_read_req(const struct pldm_msg *msg,
98 size_t payload_length,
99 struct pldm_oem_meta_file_io_read_req *req)
100{
Andrew Jefferya1896962025-03-03 21:41:25 +1030101 PLDM_MSGBUF_DEFINE_P(buf);
Lora Lin893a08f2024-07-16 15:03:31 +0800102
103 if (msg == NULL || req == NULL) {
104 return -EINVAL;
105 }
106
107 if (req->version > sizeof(struct pldm_oem_meta_file_io_read_req)) {
108 return -E2BIG;
109 }
110
111 int rc = pldm_msgbuf_init_errno(
112 buf, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH, msg->payload,
113 payload_length);
114 if (rc) {
115 return rc;
116 }
117
118 pldm_msgbuf_extract(buf, req->handle);
119 rc = pldm_msgbuf_extract(buf, req->option);
120 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030121 return pldm_msgbuf_discard(buf, rc);
Lora Lin893a08f2024-07-16 15:03:31 +0800122 }
123
124 rc = pldm_msgbuf_extract(buf, req->length);
125 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030126 return pldm_msgbuf_discard(buf, rc);
Lora Lin893a08f2024-07-16 15:03:31 +0800127 }
128
129 switch (req->option) {
130 case PLDM_OEM_META_FILE_IO_READ_ATTR:
131 if (req->length != 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030132 return pldm_msgbuf_discard(buf, -EPROTO);
Lora Lin893a08f2024-07-16 15:03:31 +0800133 }
134 break;
135 case PLDM_OEM_META_FILE_IO_READ_DATA:
136 pldm_msgbuf_extract(buf, req->info.data.transferFlag);
137 pldm_msgbuf_extract(buf, req->info.data.offset);
138 break;
139 default:
Andrew Jefferya1896962025-03-03 21:41:25 +1030140 return pldm_msgbuf_discard(buf, -EPROTO);
Lora Lin893a08f2024-07-16 15:03:31 +0800141 }
142
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030143 return pldm_msgbuf_complete_consumed(buf);
Lora Lin893a08f2024-07-16 15:03:31 +0800144}
Lora Lin6476c962024-07-26 14:01:16 +0800145
Lora Linea0bf3a2024-09-20 10:09:56 +0800146LIBPLDM_ABI_STABLE
Lora Lin6476c962024-07-26 14:01:16 +0800147void *pldm_oem_meta_file_io_read_resp_data(
148 struct pldm_oem_meta_file_io_read_resp *resp)
149{
150 return resp->data;
151}
152
Lora Linea0bf3a2024-09-20 10:09:56 +0800153LIBPLDM_ABI_STABLE
Lora Lin6476c962024-07-26 14:01:16 +0800154int encode_oem_meta_file_io_read_resp(
155 uint8_t instance_id, struct pldm_oem_meta_file_io_read_resp *resp,
156 size_t resp_len, struct pldm_msg *responseMsg, size_t payload_length)
157{
158 int rc;
Andrew Jefferya1896962025-03-03 21:41:25 +1030159 PLDM_MSGBUF_DEFINE_P(buf);
Lora Lin6476c962024-07-26 14:01:16 +0800160 struct pldm_header_info header = { 0 };
161
162 if (resp == NULL || responseMsg == NULL) {
163 return -EINVAL;
164 }
165
166 if (resp_len < sizeof(*resp)) {
167 return -EINVAL;
168 }
169
170 if (resp->version > sizeof(*resp)) {
171 return -E2BIG;
172 }
173
174 header.instance = instance_id;
175 header.msg_type = PLDM_RESPONSE;
176 header.pldm_type = PLDM_OEM;
177 header.command = PLDM_OEM_META_FILE_IO_CMD_READ_FILE;
178 rc = pack_pldm_header_errno(&header, &(responseMsg->hdr));
179 if (rc) {
180 return rc;
181 }
182
183 rc = pldm_msgbuf_init_errno(buf,
184 PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE,
185 responseMsg->payload, payload_length);
186 if (rc) {
187 return rc;
188 }
189
190 pldm_msgbuf_insert(buf, resp->completion_code);
191 pldm_msgbuf_insert(buf, resp->handle);
192 pldm_msgbuf_insert(buf, resp->option);
193 pldm_msgbuf_insert(buf, resp->length);
194
195 switch (resp->option) {
196 case PLDM_OEM_META_FILE_IO_READ_ATTR:
197 pldm_msgbuf_insert(buf, resp->info.attr.size);
198 pldm_msgbuf_insert(buf, resp->info.attr.crc32);
199 break;
200 case PLDM_OEM_META_FILE_IO_READ_DATA:
201 pldm_msgbuf_insert(buf, resp->info.data.transferFlag);
202 pldm_msgbuf_insert(buf, resp->info.data.offset);
203 rc = pldm_msgbuf_insert_array_uint8(buf, resp->length,
204 resp->data,
205 resp_len - sizeof(*resp));
206 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030207 return pldm_msgbuf_discard(buf, rc);
Lora Lin6476c962024-07-26 14:01:16 +0800208 }
209 break;
210 default:
Andrew Jefferya1896962025-03-03 21:41:25 +1030211 return pldm_msgbuf_discard(buf, -EPROTO);
Lora Lin6476c962024-07-26 14:01:16 +0800212 }
213
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030214 return pldm_msgbuf_complete(buf);
Lora Lin6476c962024-07-26 14:01:16 +0800215}