blob: 966a262a349162117a0f69d5e9bfaa0363691fba [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{
24 struct pldm_msgbuf _buf;
25 struct pldm_msgbuf *buf = &_buf;
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000026 int rc;
Delphine CC Chiu22fad392023-10-27 11:05:01 +080027
Lora Lin0f5be282024-07-22 09:46:18 +080028 if (msg == NULL || req == NULL) {
29 return -EINVAL;
Delphine CC Chiu22fad392023-10-27 11:05:01 +080030 }
31
Lora Lin0f5be282024-07-22 09:46:18 +080032 if (req_length < sizeof(*req)) {
33 return -EINVAL;
34 }
35
36 rc = pldm_msgbuf_init_errno(buf,
37 PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH,
38 msg->payload, payload_length);
Delphine CC Chiu22fad392023-10-27 11:05:01 +080039 if (rc) {
40 return rc;
41 }
42
Lora Lin0f5be282024-07-22 09:46:18 +080043 pldm_msgbuf_extract(buf, req->handle);
44 rc = pldm_msgbuf_extract(buf, req->length);
45 if (rc) {
46 return rc;
47 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000048
Lora Lin0f5be282024-07-22 09:46:18 +080049 rc = pldm_msgbuf_extract_array(buf, req->length, req->data,
50 req_length - sizeof(*req));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000051 if (rc) {
52 return rc;
53 }
Delphine CC Chiu22fad392023-10-27 11:05:01 +080054
55 return pldm_msgbuf_destroy_consumed(buf);
56}
Lora Lin0f5be282024-07-22 09:46:18 +080057
58LIBPLDM_ABI_DEPRECATED
59int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
60 size_t payload_length, uint8_t *file_handle,
61 uint32_t *length, uint8_t *data)
62{
63 struct pldm_oem_meta_file_io_write_req *request_msg;
64 size_t request_msg_len;
65 int rc;
66
67 if (msg == NULL || file_handle == NULL || length == NULL ||
68 data == NULL) {
69 return pldm_xlate_errno(-EINVAL);
70 }
71
72 request_msg_len = sizeof(*request_msg) + payload_length;
73 request_msg = malloc(request_msg_len);
74
75 rc = decode_oem_meta_file_io_write_req(msg, payload_length, request_msg,
76 request_msg_len);
77 if (rc < 0) {
78 free(request_msg);
79 return pldm_xlate_errno(rc);
80 }
81
82 *file_handle = request_msg->handle;
83 *length = request_msg->length;
84
85 /* NOTE: Unsafe, memory safety is not possible due to API constraints. */
86 memcpy(data, request_msg->data, request_msg->length);
87
88 free(request_msg);
89
90 return 0;
91}
Lora Lin893a08f2024-07-16 15:03:31 +080092
Lora Linea0bf3a2024-09-20 10:09:56 +080093LIBPLDM_ABI_STABLE
Lora Lin893a08f2024-07-16 15:03:31 +080094int decode_oem_meta_file_io_read_req(const struct pldm_msg *msg,
95 size_t payload_length,
96 struct pldm_oem_meta_file_io_read_req *req)
97{
98 struct pldm_msgbuf _buf;
99 struct pldm_msgbuf *buf = &_buf;
100
101 if (msg == NULL || req == NULL) {
102 return -EINVAL;
103 }
104
105 if (req->version > sizeof(struct pldm_oem_meta_file_io_read_req)) {
106 return -E2BIG;
107 }
108
109 int rc = pldm_msgbuf_init_errno(
110 buf, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH, msg->payload,
111 payload_length);
112 if (rc) {
113 return rc;
114 }
115
116 pldm_msgbuf_extract(buf, req->handle);
117 rc = pldm_msgbuf_extract(buf, req->option);
118 if (rc) {
119 return rc;
120 }
121
122 rc = pldm_msgbuf_extract(buf, req->length);
123 if (rc) {
124 return rc;
125 }
126
127 switch (req->option) {
128 case PLDM_OEM_META_FILE_IO_READ_ATTR:
129 if (req->length != 0) {
130 return -EPROTO;
131 }
132 break;
133 case PLDM_OEM_META_FILE_IO_READ_DATA:
134 pldm_msgbuf_extract(buf, req->info.data.transferFlag);
135 pldm_msgbuf_extract(buf, req->info.data.offset);
136 break;
137 default:
138 return -EPROTO;
139 }
140
141 return pldm_msgbuf_destroy_consumed(buf);
142}
Lora Lin6476c962024-07-26 14:01:16 +0800143
Lora Linea0bf3a2024-09-20 10:09:56 +0800144LIBPLDM_ABI_STABLE
Lora Lin6476c962024-07-26 14:01:16 +0800145void *pldm_oem_meta_file_io_read_resp_data(
146 struct pldm_oem_meta_file_io_read_resp *resp)
147{
148 return resp->data;
149}
150
Lora Linea0bf3a2024-09-20 10:09:56 +0800151LIBPLDM_ABI_STABLE
Lora Lin6476c962024-07-26 14:01:16 +0800152int encode_oem_meta_file_io_read_resp(
153 uint8_t instance_id, struct pldm_oem_meta_file_io_read_resp *resp,
154 size_t resp_len, struct pldm_msg *responseMsg, size_t payload_length)
155{
156 int rc;
157 struct pldm_msgbuf _buf;
158 struct pldm_msgbuf *buf = &_buf;
159 struct pldm_header_info header = { 0 };
160
161 if (resp == NULL || responseMsg == NULL) {
162 return -EINVAL;
163 }
164
165 if (resp_len < sizeof(*resp)) {
166 return -EINVAL;
167 }
168
169 if (resp->version > sizeof(*resp)) {
170 return -E2BIG;
171 }
172
173 header.instance = instance_id;
174 header.msg_type = PLDM_RESPONSE;
175 header.pldm_type = PLDM_OEM;
176 header.command = PLDM_OEM_META_FILE_IO_CMD_READ_FILE;
177 rc = pack_pldm_header_errno(&header, &(responseMsg->hdr));
178 if (rc) {
179 return rc;
180 }
181
182 rc = pldm_msgbuf_init_errno(buf,
183 PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE,
184 responseMsg->payload, payload_length);
185 if (rc) {
186 return rc;
187 }
188
189 pldm_msgbuf_insert(buf, resp->completion_code);
190 pldm_msgbuf_insert(buf, resp->handle);
191 pldm_msgbuf_insert(buf, resp->option);
192 pldm_msgbuf_insert(buf, resp->length);
193
194 switch (resp->option) {
195 case PLDM_OEM_META_FILE_IO_READ_ATTR:
196 pldm_msgbuf_insert(buf, resp->info.attr.size);
197 pldm_msgbuf_insert(buf, resp->info.attr.crc32);
198 break;
199 case PLDM_OEM_META_FILE_IO_READ_DATA:
200 pldm_msgbuf_insert(buf, resp->info.data.transferFlag);
201 pldm_msgbuf_insert(buf, resp->info.data.offset);
202 rc = pldm_msgbuf_insert_array_uint8(buf, resp->length,
203 resp->data,
204 resp_len - sizeof(*resp));
205 if (rc) {
206 return rc;
207 }
208 break;
209 default:
210 return -EPROTO;
211 }
212
213 return pldm_msgbuf_destroy(buf);
214}