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