xref: /openbmc/libpldm/src/oem/ibm/file_io.c (revision f89befe3ef7bfc8efc139711e5bc27bdc08502e0)
1 #include "libpldm/file_io.h"
2 #include "base.h"
3 #include <endian.h>
4 #include <string.h>
5 
6 LIBPLDM_ABI_STABLE
7 int decode_rw_file_memory_req(const struct pldm_msg *msg, size_t payload_length,
8 			      uint32_t *file_handle, uint32_t *offset,
9 			      uint32_t *length, uint64_t *address)
10 {
11 	if (msg == NULL || file_handle == NULL || offset == NULL ||
12 	    length == NULL || address == NULL) {
13 		return PLDM_ERROR_INVALID_DATA;
14 	}
15 
16 	if (payload_length != PLDM_RW_FILE_MEM_REQ_BYTES) {
17 		return PLDM_ERROR_INVALID_LENGTH;
18 	}
19 
20 	struct pldm_read_write_file_memory_req *request =
21 		(struct pldm_read_write_file_memory_req *)msg->payload;
22 
23 	*file_handle = le32toh(request->file_handle);
24 	*offset = le32toh(request->offset);
25 	*length = le32toh(request->length);
26 	*address = le64toh(request->address);
27 
28 	return PLDM_SUCCESS;
29 }
30 
31 LIBPLDM_ABI_STABLE
32 int encode_rw_file_memory_resp(uint8_t instance_id, uint8_t command,
33 			       uint8_t completion_code, uint32_t length,
34 			       struct pldm_msg *msg)
35 {
36 	if (msg == NULL) {
37 		return PLDM_ERROR_INVALID_LENGTH;
38 	}
39 
40 	struct pldm_header_info header = { 0 };
41 	header.msg_type = PLDM_RESPONSE;
42 	header.instance = instance_id;
43 	header.pldm_type = PLDM_OEM;
44 	header.command = command;
45 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
46 	if (rc != PLDM_SUCCESS) {
47 		return rc;
48 	}
49 
50 	struct pldm_read_write_file_memory_resp *response =
51 		(struct pldm_read_write_file_memory_resp *)msg->payload;
52 	response->completion_code = completion_code;
53 	if (response->completion_code == PLDM_SUCCESS) {
54 		response->length = htole32(length);
55 	}
56 
57 	return PLDM_SUCCESS;
58 }
59 
60 LIBPLDM_ABI_STABLE
61 int encode_rw_file_memory_req(uint8_t instance_id, uint8_t command,
62 			      uint32_t file_handle, uint32_t offset,
63 			      uint32_t length, uint64_t address,
64 			      struct pldm_msg *msg)
65 {
66 	if (msg == NULL) {
67 		return PLDM_ERROR_INVALID_DATA;
68 	}
69 
70 	struct pldm_header_info header = { 0 };
71 	header.msg_type = PLDM_REQUEST;
72 	header.instance = instance_id;
73 	header.pldm_type = PLDM_OEM;
74 	header.command = command;
75 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
76 	if (rc != PLDM_SUCCESS) {
77 		return rc;
78 	}
79 
80 	struct pldm_read_write_file_memory_req *req =
81 		(struct pldm_read_write_file_memory_req *)msg->payload;
82 	req->file_handle = htole32(file_handle);
83 	req->offset = htole32(offset);
84 	req->length = htole32(length);
85 	req->address = htole64(address);
86 	return PLDM_SUCCESS;
87 }
88 
89 LIBPLDM_ABI_STABLE
90 int decode_rw_file_memory_resp(const struct pldm_msg *msg,
91 			       size_t payload_length, uint8_t *completion_code,
92 			       uint32_t *length)
93 {
94 	if (msg == NULL || length == NULL || completion_code == NULL) {
95 		return PLDM_ERROR_INVALID_DATA;
96 	}
97 
98 	if (payload_length != PLDM_RW_FILE_MEM_RESP_BYTES) {
99 		return PLDM_ERROR_INVALID_LENGTH;
100 	}
101 
102 	struct pldm_read_write_file_memory_resp *response =
103 		(struct pldm_read_write_file_memory_resp *)msg->payload;
104 	*completion_code = response->completion_code;
105 	if (*completion_code == PLDM_SUCCESS) {
106 		*length = le32toh(response->length);
107 	}
108 
109 	return PLDM_SUCCESS;
110 }
111 
112 LIBPLDM_ABI_STABLE
113 int decode_get_file_table_req(const struct pldm_msg *msg, size_t payload_length,
114 			      uint32_t *transfer_handle,
115 			      uint8_t *transfer_opflag, uint8_t *table_type)
116 {
117 	if (msg == NULL || transfer_handle == NULL || transfer_opflag == NULL ||
118 	    table_type == NULL) {
119 		return PLDM_ERROR_INVALID_DATA;
120 	}
121 
122 	if (payload_length != PLDM_GET_FILE_TABLE_REQ_BYTES) {
123 		return PLDM_ERROR_INVALID_LENGTH;
124 	}
125 
126 	struct pldm_get_file_table_req *request =
127 		(struct pldm_get_file_table_req *)msg->payload;
128 
129 	*transfer_handle = le32toh(request->transfer_handle);
130 	*transfer_opflag = request->operation_flag;
131 	*table_type = request->table_type;
132 
133 	return PLDM_SUCCESS;
134 }
135 
136 LIBPLDM_ABI_STABLE
137 int encode_get_file_table_resp(uint8_t instance_id, uint8_t completion_code,
138 			       uint32_t next_transfer_handle,
139 			       uint8_t transfer_flag, const uint8_t *table_data,
140 			       size_t table_size, struct pldm_msg *msg)
141 {
142 	if (msg == NULL) {
143 		return PLDM_ERROR_INVALID_LENGTH;
144 	}
145 
146 	struct pldm_header_info header = { 0 };
147 	header.msg_type = PLDM_RESPONSE;
148 	header.instance = instance_id;
149 	header.pldm_type = PLDM_OEM;
150 	header.command = PLDM_GET_FILE_TABLE;
151 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
152 	if (rc != PLDM_SUCCESS) {
153 		return rc;
154 	}
155 
156 	struct pldm_get_file_table_resp *response =
157 		(struct pldm_get_file_table_resp *)msg->payload;
158 	response->completion_code = completion_code;
159 
160 	if (completion_code == PLDM_SUCCESS) {
161 		response->next_transfer_handle = htole32(next_transfer_handle);
162 		response->transfer_flag = transfer_flag;
163 		memcpy(response->table_data, table_data, table_size);
164 	}
165 
166 	return PLDM_SUCCESS;
167 }
168 
169 LIBPLDM_ABI_STABLE
170 int encode_get_file_table_req(uint8_t instance_id, uint32_t transfer_handle,
171 			      uint8_t transfer_opflag, uint8_t table_type,
172 			      struct pldm_msg *msg)
173 {
174 	if (msg == NULL) {
175 		return PLDM_ERROR_INVALID_DATA;
176 	}
177 
178 	struct pldm_header_info header = { 0 };
179 	header.msg_type = PLDM_REQUEST;
180 	header.instance = instance_id;
181 	header.pldm_type = PLDM_OEM;
182 	header.command = PLDM_GET_FILE_TABLE;
183 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
184 	if (rc != PLDM_SUCCESS) {
185 		return rc;
186 	}
187 
188 	struct pldm_get_file_table_req *request =
189 		(struct pldm_get_file_table_req *)msg->payload;
190 
191 	request->transfer_handle = htole32(transfer_handle);
192 	request->operation_flag = transfer_opflag;
193 	request->table_type = table_type;
194 	return PLDM_SUCCESS;
195 }
196 
197 LIBPLDM_ABI_STABLE
198 int decode_get_file_table_resp(const struct pldm_msg *msg,
199 			       size_t payload_length, uint8_t *completion_code,
200 			       uint32_t *next_transfer_handle,
201 			       uint8_t *transfer_flag,
202 			       uint8_t *file_table_data_start_offset,
203 			       size_t *file_table_length)
204 {
205 	if (msg == NULL || transfer_flag == NULL ||
206 	    next_transfer_handle == NULL || completion_code == NULL ||
207 	    file_table_data_start_offset == NULL || file_table_length == NULL) {
208 		return PLDM_ERROR_INVALID_DATA;
209 	}
210 
211 	if (payload_length <= PLDM_GET_FILE_TABLE_MIN_RESP_BYTES) {
212 		return PLDM_ERROR_INVALID_LENGTH;
213 	}
214 
215 	*completion_code = msg->payload[0];
216 
217 	if (PLDM_SUCCESS != *completion_code) {
218 		return PLDM_SUCCESS;
219 	}
220 
221 	struct pldm_get_file_table_resp *response =
222 		(struct pldm_get_file_table_resp *)msg->payload;
223 
224 	*next_transfer_handle = le32toh(response->next_transfer_handle);
225 	*transfer_flag = response->transfer_flag;
226 	*file_table_data_start_offset = sizeof(*completion_code) +
227 					sizeof(*next_transfer_handle) +
228 					sizeof(*transfer_flag);
229 	*file_table_length =
230 		payload_length - PLDM_GET_FILE_TABLE_MIN_RESP_BYTES;
231 
232 	return PLDM_SUCCESS;
233 }
234 
235 LIBPLDM_ABI_STABLE
236 int decode_read_file_req(const struct pldm_msg *msg, size_t payload_length,
237 			 uint32_t *file_handle, uint32_t *offset,
238 			 uint32_t *length)
239 {
240 	if (msg == NULL || file_handle == NULL || offset == NULL ||
241 	    length == NULL) {
242 		return PLDM_ERROR_INVALID_DATA;
243 	}
244 
245 	if (payload_length != PLDM_READ_FILE_REQ_BYTES) {
246 		return PLDM_ERROR_INVALID_LENGTH;
247 	}
248 
249 	struct pldm_read_file_req *request =
250 		(struct pldm_read_file_req *)msg->payload;
251 
252 	*file_handle = le32toh(request->file_handle);
253 	*offset = le32toh(request->offset);
254 	*length = le32toh(request->length);
255 
256 	return PLDM_SUCCESS;
257 }
258 
259 LIBPLDM_ABI_STABLE
260 int encode_read_file_req(uint8_t instance_id, uint32_t file_handle,
261 			 uint32_t offset, uint32_t length, struct pldm_msg *msg)
262 {
263 	if (msg == NULL) {
264 		return PLDM_ERROR_INVALID_DATA;
265 	}
266 
267 	if (length == 0) {
268 		return PLDM_ERROR_INVALID_LENGTH;
269 	}
270 
271 	struct pldm_header_info header = { 0 };
272 	header.msg_type = PLDM_REQUEST;
273 	header.instance = instance_id;
274 	header.pldm_type = PLDM_OEM;
275 	header.command = PLDM_READ_FILE;
276 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
277 	if (rc != PLDM_SUCCESS) {
278 		return rc;
279 	}
280 
281 	struct pldm_read_file_req *request =
282 		(struct pldm_read_file_req *)msg->payload;
283 
284 	request->file_handle = htole32(file_handle);
285 	request->offset = htole32(offset);
286 	request->length = htole32(length);
287 
288 	return PLDM_SUCCESS;
289 }
290 
291 LIBPLDM_ABI_STABLE
292 int decode_read_file_resp(const struct pldm_msg *msg, size_t payload_length,
293 			  uint8_t *completion_code, uint32_t *length,
294 			  size_t *file_data_offset)
295 {
296 	if (msg == NULL || completion_code == NULL || length == NULL) {
297 		return PLDM_ERROR_INVALID_DATA;
298 	}
299 
300 	if (payload_length < PLDM_READ_FILE_RESP_BYTES) {
301 		return PLDM_ERROR_INVALID_LENGTH;
302 	}
303 
304 	struct pldm_read_file_resp *response =
305 		(struct pldm_read_file_resp *)msg->payload;
306 
307 	*completion_code = response->completion_code;
308 	if (*completion_code == PLDM_SUCCESS) {
309 		*length = le32toh(response->length);
310 		if (payload_length != PLDM_READ_FILE_RESP_BYTES + *length) {
311 			return PLDM_ERROR_INVALID_LENGTH;
312 		}
313 		*file_data_offset = sizeof(*completion_code) + sizeof(*length);
314 	}
315 
316 	return PLDM_SUCCESS;
317 }
318 
319 LIBPLDM_ABI_STABLE
320 int encode_read_file_resp(uint8_t instance_id, uint8_t completion_code,
321 			  uint32_t length, struct pldm_msg *msg)
322 {
323 	if (msg == NULL) {
324 		return PLDM_ERROR_INVALID_DATA;
325 	}
326 
327 	struct pldm_header_info header = { 0 };
328 	header.msg_type = PLDM_RESPONSE;
329 	header.instance = instance_id;
330 	header.pldm_type = PLDM_OEM;
331 	header.command = PLDM_READ_FILE;
332 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
333 	if (rc != PLDM_SUCCESS) {
334 		return rc;
335 	}
336 
337 	struct pldm_read_file_resp *response =
338 		(struct pldm_read_file_resp *)msg->payload;
339 	response->completion_code = completion_code;
340 
341 	if (response->completion_code == PLDM_SUCCESS) {
342 		response->length = htole32(length);
343 	}
344 
345 	return PLDM_SUCCESS;
346 }
347 
348 LIBPLDM_ABI_STABLE
349 int decode_write_file_req(const struct pldm_msg *msg, size_t payload_length,
350 			  uint32_t *file_handle, uint32_t *offset,
351 			  uint32_t *length, size_t *file_data_offset)
352 {
353 	if (msg == NULL || file_handle == NULL || length == NULL) {
354 		return PLDM_ERROR_INVALID_DATA;
355 	}
356 
357 	if (payload_length < PLDM_WRITE_FILE_REQ_BYTES) {
358 		return PLDM_ERROR_INVALID_LENGTH;
359 	}
360 
361 	struct pldm_write_file_req *request =
362 		(struct pldm_write_file_req *)msg->payload;
363 
364 	*file_handle = le32toh(request->file_handle);
365 	*offset = le32toh(request->offset);
366 	*length = le32toh(request->length);
367 	if (payload_length != PLDM_WRITE_FILE_REQ_BYTES + *length) {
368 		return PLDM_ERROR_INVALID_LENGTH;
369 	}
370 	*file_data_offset =
371 		sizeof(*file_handle) + sizeof(*offset) + sizeof(*length);
372 
373 	return PLDM_SUCCESS;
374 }
375 
376 LIBPLDM_ABI_STABLE
377 int encode_write_file_req(uint8_t instance_id, uint32_t file_handle,
378 			  uint32_t offset, uint32_t length,
379 			  struct pldm_msg *msg)
380 {
381 	if (msg == NULL) {
382 		return PLDM_ERROR_INVALID_DATA;
383 	}
384 
385 	if (length == 0) {
386 		return PLDM_ERROR_INVALID_LENGTH;
387 	}
388 
389 	struct pldm_header_info header = { 0 };
390 	header.msg_type = PLDM_REQUEST;
391 	header.instance = instance_id;
392 	header.pldm_type = PLDM_OEM;
393 	header.command = PLDM_WRITE_FILE;
394 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
395 	if (rc != PLDM_SUCCESS) {
396 		return rc;
397 	}
398 
399 	struct pldm_write_file_req *request =
400 		(struct pldm_write_file_req *)msg->payload;
401 
402 	request->file_handle = htole32(file_handle);
403 	request->offset = htole32(offset);
404 	request->length = htole32(length);
405 
406 	return PLDM_SUCCESS;
407 }
408 
409 LIBPLDM_ABI_STABLE
410 int decode_write_file_resp(const struct pldm_msg *msg, size_t payload_length,
411 			   uint8_t *completion_code, uint32_t *length)
412 {
413 	if (msg == NULL || completion_code == NULL || length == NULL) {
414 		return PLDM_ERROR_INVALID_DATA;
415 	}
416 
417 	if (payload_length != PLDM_WRITE_FILE_RESP_BYTES) {
418 		return PLDM_ERROR_INVALID_LENGTH;
419 	}
420 
421 	struct pldm_write_file_resp *response =
422 		(struct pldm_write_file_resp *)msg->payload;
423 
424 	*completion_code = le32toh(response->completion_code);
425 	if (response->completion_code == PLDM_SUCCESS) {
426 		*length = le32toh(response->length);
427 	}
428 
429 	return PLDM_SUCCESS;
430 }
431 
432 LIBPLDM_ABI_STABLE
433 int encode_write_file_resp(uint8_t instance_id, uint8_t completion_code,
434 			   uint32_t length, struct pldm_msg *msg)
435 {
436 	if (msg == NULL) {
437 		return PLDM_ERROR_INVALID_DATA;
438 	}
439 
440 	struct pldm_header_info header = { 0 };
441 	header.msg_type = PLDM_RESPONSE;
442 	header.instance = instance_id;
443 	header.pldm_type = PLDM_OEM;
444 	header.command = PLDM_WRITE_FILE;
445 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
446 	if (rc != PLDM_SUCCESS) {
447 		return rc;
448 	}
449 
450 	struct pldm_write_file_resp *response =
451 		(struct pldm_write_file_resp *)msg->payload;
452 	response->completion_code = completion_code;
453 
454 	if (response->completion_code == PLDM_SUCCESS) {
455 		response->length = htole32(length);
456 	}
457 
458 	return PLDM_SUCCESS;
459 }
460 
461 LIBPLDM_ABI_STABLE
462 int decode_rw_file_by_type_memory_req(const struct pldm_msg *msg,
463 				      size_t payload_length,
464 				      uint16_t *file_type,
465 				      uint32_t *file_handle, uint32_t *offset,
466 				      uint32_t *length, uint64_t *address)
467 {
468 	if (msg == NULL || file_type == NULL || file_handle == NULL ||
469 	    offset == NULL || length == NULL || address == NULL) {
470 		return PLDM_ERROR_INVALID_DATA;
471 	}
472 
473 	if (payload_length != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES) {
474 		return PLDM_ERROR_INVALID_LENGTH;
475 	}
476 
477 	struct pldm_read_write_file_by_type_memory_req *request =
478 		(struct pldm_read_write_file_by_type_memory_req *)msg->payload;
479 	*file_type = le16toh(request->file_type);
480 	*file_handle = le32toh(request->file_handle);
481 	*offset = le32toh(request->offset);
482 	*length = le32toh(request->length);
483 	*address = le64toh(request->address);
484 
485 	return PLDM_SUCCESS;
486 }
487 
488 LIBPLDM_ABI_STABLE
489 int encode_rw_file_by_type_memory_resp(uint8_t instance_id, uint8_t command,
490 				       uint8_t completion_code, uint32_t length,
491 				       struct pldm_msg *msg)
492 {
493 	if (msg == NULL) {
494 		return PLDM_ERROR_INVALID_DATA;
495 	}
496 
497 	struct pldm_header_info header = { 0 };
498 	header.msg_type = PLDM_RESPONSE;
499 	header.instance = instance_id;
500 	header.pldm_type = PLDM_OEM;
501 	header.command = command;
502 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
503 	if (rc != PLDM_SUCCESS) {
504 		return rc;
505 	}
506 
507 	struct pldm_read_write_file_by_type_memory_resp *response =
508 		(struct pldm_read_write_file_by_type_memory_resp *)msg->payload;
509 	response->completion_code = completion_code;
510 	if (response->completion_code == PLDM_SUCCESS) {
511 		response->length = htole32(length);
512 	}
513 
514 	return PLDM_SUCCESS;
515 }
516 
517 LIBPLDM_ABI_STABLE
518 int encode_rw_file_by_type_memory_req(uint8_t instance_id, uint8_t command,
519 				      uint16_t file_type, uint32_t file_handle,
520 				      uint32_t offset, uint32_t length,
521 				      uint64_t address, struct pldm_msg *msg)
522 {
523 	if (msg == NULL) {
524 		return PLDM_ERROR_INVALID_DATA;
525 	}
526 
527 	struct pldm_header_info header = { 0 };
528 	header.msg_type = PLDM_REQUEST;
529 	header.instance = instance_id;
530 	header.pldm_type = PLDM_OEM;
531 	header.command = command;
532 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
533 	if (rc != PLDM_SUCCESS) {
534 		return rc;
535 	}
536 
537 	struct pldm_read_write_file_by_type_memory_req *req =
538 		(struct pldm_read_write_file_by_type_memory_req *)msg->payload;
539 	req->file_type = htole16(file_type);
540 	req->file_handle = htole32(file_handle);
541 	req->offset = htole32(offset);
542 	req->length = htole32(length);
543 	req->address = htole64(address);
544 
545 	return PLDM_SUCCESS;
546 }
547 
548 LIBPLDM_ABI_STABLE
549 int decode_rw_file_by_type_memory_resp(const struct pldm_msg *msg,
550 				       size_t payload_length,
551 				       uint8_t *completion_code,
552 				       uint32_t *length)
553 {
554 	if (msg == NULL || length == NULL || completion_code == NULL) {
555 		return PLDM_ERROR_INVALID_DATA;
556 	}
557 
558 	if (payload_length != PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES) {
559 		return PLDM_ERROR_INVALID_LENGTH;
560 	}
561 
562 	struct pldm_read_write_file_by_type_memory_resp *response =
563 		(struct pldm_read_write_file_by_type_memory_resp *)msg->payload;
564 	*completion_code = response->completion_code;
565 	if (*completion_code == PLDM_SUCCESS) {
566 		*length = le32toh(response->length);
567 	}
568 
569 	return PLDM_SUCCESS;
570 }
571 
572 LIBPLDM_ABI_STABLE
573 int decode_new_file_req(const struct pldm_msg *msg, size_t payload_length,
574 			uint16_t *file_type, uint32_t *file_handle,
575 			uint64_t *length)
576 {
577 	if (msg == NULL || file_type == NULL || file_handle == NULL ||
578 	    length == NULL) {
579 		return PLDM_ERROR_INVALID_DATA;
580 	}
581 
582 	if (payload_length != PLDM_NEW_FILE_REQ_BYTES) {
583 		return PLDM_ERROR_INVALID_LENGTH;
584 	}
585 
586 	struct pldm_new_file_req *request =
587 		(struct pldm_new_file_req *)msg->payload;
588 	*file_type = le16toh(request->file_type);
589 	*file_handle = le32toh(request->file_handle);
590 	*length = le64toh(request->length);
591 
592 	return PLDM_SUCCESS;
593 }
594 
595 LIBPLDM_ABI_STABLE
596 int encode_new_file_resp(uint8_t instance_id, uint8_t completion_code,
597 			 struct pldm_msg *msg)
598 {
599 	if (msg == NULL) {
600 		return PLDM_ERROR_INVALID_DATA;
601 	}
602 
603 	struct pldm_header_info header = { 0 };
604 	header.msg_type = PLDM_RESPONSE;
605 	header.instance = instance_id;
606 	header.pldm_type = PLDM_OEM;
607 	header.command = PLDM_NEW_FILE_AVAILABLE;
608 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
609 	if (rc != PLDM_SUCCESS) {
610 		return rc;
611 	}
612 
613 	struct pldm_new_file_resp *response =
614 		(struct pldm_new_file_resp *)msg->payload;
615 	response->completion_code = completion_code;
616 
617 	return PLDM_SUCCESS;
618 }
619 
620 LIBPLDM_ABI_STABLE
621 int encode_new_file_req(uint8_t instance_id, uint16_t file_type,
622 			uint32_t file_handle, uint64_t length,
623 			struct pldm_msg *msg)
624 {
625 	if (msg == NULL) {
626 		return PLDM_ERROR_INVALID_DATA;
627 	}
628 
629 	struct pldm_header_info header = { 0 };
630 	header.msg_type = PLDM_REQUEST;
631 	header.instance = instance_id;
632 	header.pldm_type = PLDM_OEM;
633 	header.command = PLDM_NEW_FILE_AVAILABLE;
634 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
635 	if (rc != PLDM_SUCCESS) {
636 		return rc;
637 	}
638 
639 	struct pldm_new_file_req *req =
640 		(struct pldm_new_file_req *)msg->payload;
641 	req->file_type = htole16(file_type);
642 	req->file_handle = htole32(file_handle);
643 	req->length = htole64(length);
644 
645 	return PLDM_SUCCESS;
646 }
647 
648 LIBPLDM_ABI_STABLE
649 int decode_new_file_resp(const struct pldm_msg *msg, size_t payload_length,
650 			 uint8_t *completion_code)
651 {
652 	if (msg == NULL || completion_code == NULL) {
653 		return PLDM_ERROR_INVALID_DATA;
654 	}
655 
656 	if (payload_length != PLDM_NEW_FILE_RESP_BYTES) {
657 		return PLDM_ERROR_INVALID_LENGTH;
658 	}
659 
660 	struct pldm_new_file_resp *response =
661 		(struct pldm_new_file_resp *)msg->payload;
662 	*completion_code = response->completion_code;
663 
664 	return PLDM_SUCCESS;
665 }
666 
667 LIBPLDM_ABI_STABLE
668 int decode_rw_file_by_type_req(const struct pldm_msg *msg,
669 			       size_t payload_length, uint16_t *file_type,
670 			       uint32_t *file_handle, uint32_t *offset,
671 			       uint32_t *length)
672 {
673 	if (msg == NULL || file_type == NULL || file_handle == NULL ||
674 	    offset == NULL || length == NULL) {
675 		return PLDM_ERROR_INVALID_DATA;
676 	}
677 
678 	if (payload_length < PLDM_RW_FILE_BY_TYPE_REQ_BYTES) {
679 		return PLDM_ERROR_INVALID_LENGTH;
680 	}
681 
682 	struct pldm_read_write_file_by_type_req *request =
683 		(struct pldm_read_write_file_by_type_req *)msg->payload;
684 	*file_type = le16toh(request->file_type);
685 	*file_handle = le32toh(request->file_handle);
686 	*offset = le32toh(request->offset);
687 	*length = le32toh(request->length);
688 
689 	return PLDM_SUCCESS;
690 }
691 
692 LIBPLDM_ABI_STABLE
693 int encode_rw_file_by_type_resp(uint8_t instance_id, uint8_t command,
694 				uint8_t completion_code, uint32_t length,
695 				struct pldm_msg *msg)
696 {
697 	if (msg == NULL) {
698 		return PLDM_ERROR_INVALID_DATA;
699 	}
700 	if (command != PLDM_READ_FILE_BY_TYPE &&
701 	    command != PLDM_WRITE_FILE_BY_TYPE) {
702 		return PLDM_ERROR_INVALID_DATA;
703 	}
704 
705 	struct pldm_header_info header = { 0 };
706 	header.msg_type = PLDM_RESPONSE;
707 	header.instance = instance_id;
708 	header.pldm_type = PLDM_OEM;
709 	header.command = command;
710 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
711 	if (rc != PLDM_SUCCESS) {
712 		return rc;
713 	}
714 
715 	struct pldm_read_write_file_by_type_resp *response =
716 		(struct pldm_read_write_file_by_type_resp *)msg->payload;
717 	response->completion_code = completion_code;
718 	if (response->completion_code == PLDM_SUCCESS) {
719 		response->length = htole32(length);
720 	}
721 
722 	return PLDM_SUCCESS;
723 }
724 
725 LIBPLDM_ABI_STABLE
726 int encode_rw_file_by_type_req(uint8_t instance_id, uint8_t command,
727 			       uint16_t file_type, uint32_t file_handle,
728 			       uint32_t offset, uint32_t length,
729 			       struct pldm_msg *msg)
730 {
731 	if (msg == NULL) {
732 		return PLDM_ERROR_INVALID_DATA;
733 	}
734 	if (command != PLDM_READ_FILE_BY_TYPE &&
735 	    command != PLDM_WRITE_FILE_BY_TYPE) {
736 		return PLDM_ERROR_INVALID_DATA;
737 	}
738 
739 	struct pldm_header_info header = { 0 };
740 	header.msg_type = PLDM_REQUEST;
741 	header.instance = instance_id;
742 	header.pldm_type = PLDM_OEM;
743 	header.command = command;
744 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
745 	if (rc != PLDM_SUCCESS) {
746 		return rc;
747 	}
748 
749 	struct pldm_read_write_file_by_type_req *req =
750 		(struct pldm_read_write_file_by_type_req *)msg->payload;
751 	req->file_type = htole16(file_type);
752 	req->file_handle = htole32(file_handle);
753 	req->offset = htole32(offset);
754 	req->length = htole32(length);
755 
756 	return PLDM_SUCCESS;
757 }
758 
759 LIBPLDM_ABI_STABLE
760 int decode_rw_file_by_type_resp(const struct pldm_msg *msg,
761 				size_t payload_length, uint8_t *completion_code,
762 				uint32_t *length)
763 {
764 	if (msg == NULL || length == NULL || completion_code == NULL) {
765 		return PLDM_ERROR_INVALID_DATA;
766 	}
767 
768 	if (payload_length != PLDM_RW_FILE_BY_TYPE_RESP_BYTES) {
769 		return PLDM_ERROR_INVALID_LENGTH;
770 	}
771 
772 	struct pldm_read_write_file_by_type_resp *response =
773 		(struct pldm_read_write_file_by_type_resp *)msg->payload;
774 	*completion_code = response->completion_code;
775 	if (*completion_code == PLDM_SUCCESS) {
776 		*length = le32toh(response->length);
777 	}
778 
779 	return PLDM_SUCCESS;
780 }
781 
782 LIBPLDM_ABI_STABLE
783 int decode_file_ack_req(const struct pldm_msg *msg, size_t payload_length,
784 			uint16_t *file_type, uint32_t *file_handle,
785 			uint8_t *file_status)
786 {
787 	if (msg == NULL || file_type == NULL || file_handle == NULL) {
788 		return PLDM_ERROR_INVALID_DATA;
789 	}
790 
791 	if (payload_length != PLDM_FILE_ACK_REQ_BYTES) {
792 		return PLDM_ERROR_INVALID_LENGTH;
793 	}
794 
795 	struct pldm_file_ack_req *request =
796 		(struct pldm_file_ack_req *)msg->payload;
797 	*file_type = le16toh(request->file_type);
798 	*file_handle = le32toh(request->file_handle);
799 	*file_status = request->file_status;
800 
801 	return PLDM_SUCCESS;
802 }
803 
804 LIBPLDM_ABI_STABLE
805 int encode_file_ack_resp(uint8_t instance_id, uint8_t completion_code,
806 			 struct pldm_msg *msg)
807 {
808 	if (msg == NULL) {
809 		return PLDM_ERROR_INVALID_DATA;
810 	}
811 
812 	struct pldm_header_info header = { 0 };
813 	header.msg_type = PLDM_RESPONSE;
814 	header.instance = instance_id;
815 	header.pldm_type = PLDM_OEM;
816 	header.command = PLDM_FILE_ACK;
817 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
818 	if (rc != PLDM_SUCCESS) {
819 		return rc;
820 	}
821 
822 	struct pldm_file_ack_resp *response =
823 		(struct pldm_file_ack_resp *)msg->payload;
824 	response->completion_code = completion_code;
825 
826 	return PLDM_SUCCESS;
827 }
828 
829 LIBPLDM_ABI_STABLE
830 int encode_file_ack_req(uint8_t instance_id, uint16_t file_type,
831 			uint32_t file_handle, uint8_t file_status,
832 			struct pldm_msg *msg)
833 {
834 	if (msg == NULL) {
835 		return PLDM_ERROR_INVALID_DATA;
836 	}
837 
838 	struct pldm_header_info header = { 0 };
839 	header.msg_type = PLDM_REQUEST;
840 	header.instance = instance_id;
841 	header.pldm_type = PLDM_OEM;
842 	header.command = PLDM_FILE_ACK;
843 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
844 	if (rc != PLDM_SUCCESS) {
845 		return rc;
846 	}
847 
848 	struct pldm_file_ack_req *req =
849 		(struct pldm_file_ack_req *)msg->payload;
850 	req->file_type = htole16(file_type);
851 	req->file_handle = htole32(file_handle);
852 	req->file_status = file_status;
853 
854 	return PLDM_SUCCESS;
855 }
856 
857 LIBPLDM_ABI_STABLE
858 int decode_file_ack_resp(const struct pldm_msg *msg, size_t payload_length,
859 			 uint8_t *completion_code)
860 {
861 	if (msg == NULL || completion_code == NULL) {
862 		return PLDM_ERROR_INVALID_DATA;
863 	}
864 
865 	if (payload_length != PLDM_FILE_ACK_RESP_BYTES) {
866 		return PLDM_ERROR_INVALID_LENGTH;
867 	}
868 
869 	struct pldm_file_ack_resp *response =
870 		(struct pldm_file_ack_resp *)msg->payload;
871 	*completion_code = response->completion_code;
872 
873 	return PLDM_SUCCESS;
874 }
875 
876 LIBPLDM_ABI_STABLE
877 int encode_file_ack_with_meta_data_req(
878 	uint8_t instance_id, uint16_t file_type, uint32_t file_handle,
879 	uint8_t file_status, uint32_t file_meta_data_1,
880 	uint32_t file_meta_data_2, uint32_t file_meta_data_3,
881 	uint32_t file_meta_data_4, struct pldm_msg *msg)
882 {
883 	if (msg == NULL) {
884 		return PLDM_ERROR_INVALID_DATA;
885 	}
886 
887 	struct pldm_header_info header = { 0 };
888 	header.msg_type = PLDM_REQUEST;
889 	header.instance = instance_id;
890 	header.pldm_type = PLDM_OEM;
891 	header.command = PLDM_FILE_ACK_WITH_META_DATA;
892 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
893 	if (rc != PLDM_SUCCESS) {
894 		return rc;
895 	}
896 
897 	struct pldm_file_ack_with_meta_data_req *req =
898 		(struct pldm_file_ack_with_meta_data_req *)msg->payload;
899 	req->file_type = htole16(file_type);
900 	req->file_handle = htole32(file_handle);
901 	req->file_status = file_status;
902 	req->file_meta_data_1 = htole32(file_meta_data_1);
903 	req->file_meta_data_2 = htole32(file_meta_data_2);
904 	req->file_meta_data_3 = htole32(file_meta_data_3);
905 	req->file_meta_data_4 = htole32(file_meta_data_4);
906 
907 	return PLDM_SUCCESS;
908 }
909 
910 LIBPLDM_ABI_STABLE
911 int decode_file_ack_with_meta_data_resp(const struct pldm_msg *msg,
912 					size_t payload_length,
913 					uint8_t *completion_code)
914 {
915 	if (msg == NULL || completion_code == NULL) {
916 		return PLDM_ERROR_INVALID_DATA;
917 	}
918 
919 	if (payload_length != PLDM_FILE_ACK_WITH_META_DATA_RESP_BYTES) {
920 		return PLDM_ERROR_INVALID_LENGTH;
921 	}
922 
923 	struct pldm_file_ack_with_meta_data_resp *response =
924 		(struct pldm_file_ack_with_meta_data_resp *)msg->payload;
925 	*completion_code = response->completion_code;
926 
927 	return PLDM_SUCCESS;
928 }
929 
930 LIBPLDM_ABI_STABLE
931 int decode_file_ack_with_meta_data_req(
932 	const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type,
933 	uint32_t *file_handle, uint8_t *file_status, uint32_t *file_meta_data_1,
934 	uint32_t *file_meta_data_2, uint32_t *file_meta_data_3,
935 	uint32_t *file_meta_data_4)
936 {
937 	if (msg == NULL || file_type == NULL || file_handle == NULL) {
938 		return PLDM_ERROR_INVALID_DATA;
939 	}
940 
941 	if (payload_length != PLDM_FILE_ACK_WITH_META_DATA_REQ_BYTES) {
942 		return PLDM_ERROR_INVALID_LENGTH;
943 	}
944 
945 	struct pldm_file_ack_with_meta_data_req *request =
946 		(struct pldm_file_ack_with_meta_data_req *)msg->payload;
947 	*file_type = le16toh(request->file_type);
948 	*file_handle = le32toh(request->file_handle);
949 	*file_status = request->file_status;
950 	*file_meta_data_1 = le32toh(request->file_meta_data_1);
951 	*file_meta_data_2 = le32toh(request->file_meta_data_2);
952 	*file_meta_data_3 = le32toh(request->file_meta_data_3);
953 	*file_meta_data_4 = le32toh(request->file_meta_data_4);
954 
955 	return PLDM_SUCCESS;
956 }
957 
958 LIBPLDM_ABI_STABLE
959 int encode_file_ack_with_meta_data_resp(uint8_t instance_id,
960 					uint8_t completion_code,
961 					struct pldm_msg *msg)
962 {
963 	if (msg == NULL) {
964 		return PLDM_ERROR_INVALID_DATA;
965 	}
966 
967 	struct pldm_header_info header = { 0 };
968 	header.msg_type = PLDM_RESPONSE;
969 	header.instance = instance_id;
970 	header.pldm_type = PLDM_OEM;
971 	header.command = PLDM_FILE_ACK_WITH_META_DATA;
972 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
973 	if (rc != PLDM_SUCCESS) {
974 		return rc;
975 	}
976 
977 	struct pldm_file_ack_with_meta_data_resp *response =
978 		(struct pldm_file_ack_with_meta_data_resp *)msg->payload;
979 	response->completion_code = completion_code;
980 
981 	return PLDM_SUCCESS;
982 }
983 
984 LIBPLDM_ABI_STABLE
985 int encode_new_file_with_metadata_req(uint8_t instance_id, uint16_t file_type,
986 				      uint32_t file_handle, uint64_t length,
987 				      uint32_t file_meta_data_1,
988 				      uint32_t file_meta_data_2,
989 				      uint32_t file_meta_data_3,
990 				      uint32_t file_meta_data_4,
991 				      struct pldm_msg *msg)
992 {
993 	if (msg == NULL) {
994 		return PLDM_ERROR_INVALID_DATA;
995 	}
996 
997 	struct pldm_header_info header = { 0 };
998 	header.msg_type = PLDM_REQUEST;
999 	header.instance = instance_id;
1000 	header.pldm_type = PLDM_OEM;
1001 	header.command = PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA;
1002 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1003 	if (rc != PLDM_SUCCESS) {
1004 		return rc;
1005 	}
1006 
1007 	struct pldm_new_file_with_metadata_req *req =
1008 		(struct pldm_new_file_with_metadata_req *)msg->payload;
1009 	req->file_type = htole16(file_type);
1010 	req->file_handle = htole32(file_handle);
1011 	req->length = htole64(length);
1012 	req->file_meta_data_1 = htole32(file_meta_data_1);
1013 	req->file_meta_data_2 = htole32(file_meta_data_2);
1014 	req->file_meta_data_3 = htole32(file_meta_data_3);
1015 	req->file_meta_data_4 = htole32(file_meta_data_4);
1016 
1017 	return PLDM_SUCCESS;
1018 }
1019 
1020 LIBPLDM_ABI_STABLE
1021 int decode_new_file_with_metadata_resp(const struct pldm_msg *msg,
1022 				       size_t payload_length,
1023 				       uint8_t *completion_code)
1024 {
1025 	if (msg == NULL || completion_code == NULL) {
1026 		return PLDM_ERROR_INVALID_DATA;
1027 	}
1028 
1029 	if (payload_length !=
1030 	    PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_RESP_BYTES) {
1031 		return PLDM_ERROR_INVALID_LENGTH;
1032 	}
1033 
1034 	struct pldm_new_file_with_metadata_resp *response =
1035 		(struct pldm_new_file_with_metadata_resp *)msg->payload;
1036 
1037 	*completion_code = msg->payload[0];
1038 	if (*completion_code == PLDM_SUCCESS) {
1039 		*completion_code = response->completion_code;
1040 	}
1041 	return PLDM_SUCCESS;
1042 }
1043 
1044 LIBPLDM_ABI_STABLE
1045 int decode_new_file_with_metadata_req(
1046 	const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type,
1047 	uint32_t *file_handle, uint64_t *length, uint32_t *file_meta_data_1,
1048 	uint32_t *file_meta_data_2, uint32_t *file_meta_data_3,
1049 	uint32_t *file_meta_data_4)
1050 {
1051 	if (msg == NULL || file_type == NULL || file_handle == NULL ||
1052 	    length == NULL) {
1053 		return PLDM_ERROR_INVALID_DATA;
1054 	}
1055 
1056 	if (payload_length !=
1057 	    PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_REQ_BYTES) {
1058 		return PLDM_ERROR_INVALID_LENGTH;
1059 	}
1060 
1061 	struct pldm_new_file_with_metadata_req *request =
1062 		(struct pldm_new_file_with_metadata_req *)msg->payload;
1063 	*file_type = le16toh(request->file_type);
1064 	*file_handle = le32toh(request->file_handle);
1065 	*length = le64toh(request->length);
1066 	*file_meta_data_1 = le32toh(request->file_meta_data_1);
1067 	*file_meta_data_2 = le32toh(request->file_meta_data_2);
1068 	*file_meta_data_3 = le32toh(request->file_meta_data_3);
1069 	*file_meta_data_4 = le32toh(request->file_meta_data_4);
1070 
1071 	return PLDM_SUCCESS;
1072 }
1073 
1074 LIBPLDM_ABI_STABLE
1075 int encode_new_file_with_metadata_resp(uint8_t instance_id,
1076 				       uint8_t completion_code,
1077 				       struct pldm_msg *msg)
1078 {
1079 	if (msg == NULL) {
1080 		return PLDM_ERROR_INVALID_DATA;
1081 	}
1082 
1083 	struct pldm_header_info header = { 0 };
1084 	header.msg_type = PLDM_RESPONSE;
1085 	header.instance = instance_id;
1086 	header.pldm_type = PLDM_OEM;
1087 	header.command = PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA;
1088 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1089 	if (rc != PLDM_SUCCESS) {
1090 		return rc;
1091 	}
1092 
1093 	struct pldm_new_file_with_metadata_resp *response =
1094 		(struct pldm_new_file_with_metadata_resp *)msg->payload;
1095 
1096 	if (response->completion_code == PLDM_SUCCESS) {
1097 		response->completion_code = completion_code;
1098 	}
1099 
1100 	return PLDM_SUCCESS;
1101 }
1102