xref: /openbmc/libpldm/src/dsp/file.c (revision 340bb6286f6e5fd55dc05fe1915e7f179992c500)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #include "dsp/base.h"
3 #include "msgbuf.h"
4 
5 #include <libpldm/base.h>
6 #include <libpldm/file.h>
7 #include <libpldm/utils.h>
8 
9 #include <assert.h>
10 #include <errno.h>
11 #include <stdbool.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <stdlib.h>
15 
16 LIBPLDM_ABI_TESTING
17 int encode_pldm_file_df_open_req(uint8_t instance_id,
18 				 const struct pldm_file_df_open_req *req,
19 				 struct pldm_msg *msg, size_t payload_length)
20 {
21 	PLDM_MSGBUF_DEFINE_P(buf);
22 	int rc;
23 
24 	if (req == NULL || msg == NULL) {
25 		return -EINVAL;
26 	}
27 
28 	struct pldm_header_info header = { 0 };
29 	header.instance = instance_id;
30 	header.msg_type = PLDM_REQUEST;
31 	header.pldm_type = PLDM_FILE;
32 	header.command = PLDM_FILE_CMD_DF_OPEN;
33 
34 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
35 	if (rc) {
36 		return rc;
37 	}
38 
39 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_REQ_BYTES, msg->payload,
40 				    payload_length);
41 	if (rc) {
42 		return rc;
43 	}
44 
45 	pldm_msgbuf_insert(buf, req->file_identifier);
46 	pldm_msgbuf_insert(buf, req->file_attribute.value);
47 
48 	return pldm_msgbuf_complete(buf);
49 }
50 
51 LIBPLDM_ABI_TESTING
52 int decode_pldm_file_df_open_req(const struct pldm_msg *msg,
53 				 size_t payload_length,
54 				 struct pldm_file_df_open_req *req)
55 {
56 	PLDM_MSGBUF_DEFINE_P(buf);
57 	int rc;
58 
59 	if (!msg || !req) {
60 		return -EINVAL;
61 	}
62 
63 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_REQ_BYTES, msg->payload,
64 				    payload_length);
65 	if (rc) {
66 		return rc;
67 	}
68 
69 	pldm_msgbuf_extract(buf, req->file_identifier);
70 	pldm_msgbuf_extract(buf, req->file_attribute.value);
71 
72 	return pldm_msgbuf_complete_consumed(buf);
73 }
74 
75 LIBPLDM_ABI_TESTING
76 int encode_pldm_file_df_open_resp(uint8_t instance_id,
77 				  const struct pldm_file_df_open_resp *resp,
78 				  struct pldm_msg *msg, size_t *payload_length)
79 {
80 	PLDM_MSGBUF_DEFINE_P(buf);
81 	int rc;
82 
83 	if (!msg || !resp) {
84 		return -EINVAL;
85 	}
86 
87 	struct pldm_header_info header = { 0 };
88 	header.instance = instance_id;
89 	header.msg_type = PLDM_RESPONSE;
90 	header.pldm_type = PLDM_FILE;
91 	header.command = PLDM_FILE_CMD_DF_OPEN;
92 
93 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
94 	if (rc) {
95 		return rc;
96 	}
97 
98 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_RESP_BYTES, msg->payload,
99 				    *payload_length);
100 	if (rc) {
101 		return rc;
102 	}
103 
104 	pldm_msgbuf_insert(buf, resp->completion_code);
105 	if (resp->completion_code == PLDM_SUCCESS) {
106 		pldm_msgbuf_insert(buf, resp->file_descriptor);
107 	}
108 
109 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
110 }
111 
112 LIBPLDM_ABI_TESTING
113 int decode_pldm_file_df_open_resp(const struct pldm_msg *msg,
114 				  size_t payload_length,
115 				  struct pldm_file_df_open_resp *resp)
116 {
117 	PLDM_MSGBUF_DEFINE_P(buf);
118 	int rc;
119 
120 	if (!msg || !resp) {
121 		return -EINVAL;
122 	}
123 
124 	rc = pldm_msg_has_error(msg, payload_length);
125 	if (rc) {
126 		resp->completion_code = rc;
127 		return 0;
128 	}
129 
130 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_OPEN_RESP_BYTES, msg->payload,
131 				    payload_length);
132 	if (rc) {
133 		return rc;
134 	}
135 
136 	pldm_msgbuf_extract(buf, resp->completion_code);
137 	if (resp->completion_code != PLDM_SUCCESS) {
138 		// Return the CC directly without decoding the rest of the payload
139 		return pldm_msgbuf_complete(buf);
140 	}
141 
142 	pldm_msgbuf_extract(buf, resp->file_descriptor);
143 
144 	return pldm_msgbuf_complete_consumed(buf);
145 }
146 
147 LIBPLDM_ABI_TESTING
148 int encode_pldm_file_df_close_req(uint8_t instance_id,
149 				  const struct pldm_file_df_close_req *req,
150 				  struct pldm_msg *msg, size_t payload_length)
151 {
152 	PLDM_MSGBUF_DEFINE_P(buf);
153 	int rc;
154 
155 	if (!req || !msg) {
156 		return -EINVAL;
157 	}
158 
159 	struct pldm_header_info header = { 0 };
160 	header.instance = instance_id;
161 	header.msg_type = PLDM_REQUEST;
162 	header.pldm_type = PLDM_FILE;
163 	header.command = PLDM_FILE_CMD_DF_CLOSE;
164 
165 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
166 	if (rc) {
167 		return rc;
168 	}
169 
170 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_CLOSE_REQ_BYTES, msg->payload,
171 				    payload_length);
172 	if (rc) {
173 		return rc;
174 	}
175 
176 	pldm_msgbuf_insert(buf, req->file_descriptor);
177 	pldm_msgbuf_insert(buf, req->df_close_options.value);
178 
179 	return pldm_msgbuf_complete(buf);
180 }
181 
182 LIBPLDM_ABI_TESTING
183 int decode_pldm_file_df_close_req(const struct pldm_msg *msg,
184 				  size_t payload_length,
185 				  struct pldm_file_df_close_req *req)
186 {
187 	PLDM_MSGBUF_DEFINE_P(buf);
188 	int rc;
189 
190 	if (!msg || !req) {
191 		return -EINVAL;
192 	}
193 
194 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_CLOSE_REQ_BYTES, msg->payload,
195 				    payload_length);
196 	if (rc) {
197 		return rc;
198 	}
199 
200 	pldm_msgbuf_extract(buf, req->file_descriptor);
201 	pldm_msgbuf_extract(buf, req->df_close_options.value);
202 
203 	return pldm_msgbuf_complete_consumed(buf);
204 }
205 
206 LIBPLDM_ABI_TESTING
207 int encode_pldm_file_df_close_resp(uint8_t instance_id,
208 				   const struct pldm_file_df_close_resp *resp,
209 				   struct pldm_msg *msg, size_t *payload_length)
210 {
211 	PLDM_MSGBUF_DEFINE_P(buf);
212 	int rc;
213 
214 	if (!msg || !resp) {
215 		return -EINVAL;
216 	}
217 
218 	struct pldm_header_info header = { 0 };
219 	header.instance = instance_id;
220 	header.msg_type = PLDM_RESPONSE;
221 	header.pldm_type = PLDM_FILE;
222 	header.command = PLDM_FILE_CMD_DF_CLOSE;
223 
224 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
225 	if (rc) {
226 		return rc;
227 	}
228 
229 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_CLOSE_RESP_BYTES, msg->payload,
230 				    *payload_length);
231 	if (rc) {
232 		return rc;
233 	}
234 
235 	pldm_msgbuf_insert(buf, resp->completion_code);
236 
237 	return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
238 }
239 
240 LIBPLDM_ABI_TESTING
241 int decode_pldm_file_df_close_resp(const struct pldm_msg *msg,
242 				   size_t payload_length,
243 				   struct pldm_file_df_close_resp *resp)
244 {
245 	if (!msg || !resp) {
246 		return -EINVAL;
247 	}
248 
249 	resp->completion_code = pldm_msg_has_error(msg, payload_length);
250 
251 	return 0;
252 }
253 
254 LIBPLDM_ABI_TESTING
255 int encode_pldm_file_df_heartbeat_req(
256 	uint8_t instance_id, const struct pldm_file_df_heartbeat_req *req,
257 	struct pldm_msg *msg, size_t payload_length)
258 {
259 	PLDM_MSGBUF_DEFINE_P(buf);
260 	int rc;
261 
262 	if (!req || !msg) {
263 		return -EINVAL;
264 	}
265 
266 	struct pldm_header_info header = { 0 };
267 	header.instance = instance_id;
268 	header.msg_type = PLDM_REQUEST;
269 	header.pldm_type = PLDM_FILE;
270 	header.command = PLDM_FILE_CMD_DF_HEARTBEAT;
271 
272 	rc = pack_pldm_header_errno(&header, &(msg->hdr));
273 	if (rc) {
274 		return rc;
275 	}
276 
277 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_HEARTBEAT_REQ_BYTES,
278 				    msg->payload, payload_length);
279 	if (rc) {
280 		return rc;
281 	}
282 
283 	pldm_msgbuf_insert(buf, req->file_descriptor);
284 	pldm_msgbuf_insert(buf, req->requester_max_interval);
285 
286 	return pldm_msgbuf_complete(buf);
287 }
288 
289 LIBPLDM_ABI_TESTING
290 int decode_pldm_file_df_heartbeat_resp(const struct pldm_msg *msg,
291 				       size_t payload_length,
292 				       struct pldm_file_df_heartbeat_resp *resp)
293 {
294 	PLDM_MSGBUF_DEFINE_P(buf);
295 	int rc;
296 
297 	if (!msg || !resp) {
298 		return -EINVAL;
299 	}
300 
301 	rc = pldm_msg_has_error(msg, payload_length);
302 	if (rc) {
303 		resp->completion_code = rc;
304 		return 0;
305 	}
306 
307 	rc = pldm_msgbuf_init_errno(buf, PLDM_DF_HEARTBEAT_RESP_BYTES,
308 				    msg->payload, payload_length);
309 	if (rc) {
310 		return rc;
311 	}
312 
313 	pldm_msgbuf_extract(buf, resp->completion_code);
314 	pldm_msgbuf_extract(buf, resp->responder_max_interval);
315 
316 	return pldm_msgbuf_complete_consumed(buf);
317 }
318