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