1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 #include "api.h" 3 #include "compiler.h" 4 #include "dsp/base.h" 5 #include "msgbuf.h" 6 #include "msgbuf/platform.h" 7 8 #include <libpldm/base.h> 9 #include <libpldm/platform.h> 10 #include <libpldm/pldm_types.h> 11 12 #include <endian.h> 13 #include <stdint.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <uchar.h> 17 18 LIBPLDM_ABI_STABLE 19 int encode_state_effecter_pdr( 20 struct pldm_state_effecter_pdr *const effecter, 21 const size_t allocation_size, 22 const struct state_effecter_possible_states *const possible_states, 23 const size_t possible_states_size, size_t *const actual_size) 24 { 25 size_t calculated_possible_states_size = 0; 26 27 if (!effecter || !possible_states || !actual_size) { 28 return PLDM_ERROR; 29 } 30 31 if (SIZE_MAX - (sizeof(*effecter) - sizeof(effecter->possible_states)) < 32 possible_states_size) { 33 return PLDM_ERROR; 34 } 35 36 if (allocation_size < 37 (sizeof(*effecter) - sizeof(effecter->possible_states)) + 38 possible_states_size) { 39 return PLDM_ERROR_INVALID_LENGTH; 40 } 41 42 // Encode possible states 43 44 { 45 char *states_ptr = (char *)possible_states; 46 char *const begin_states_ptr = states_ptr; 47 48 for (int i = 0; i < effecter->composite_effecter_count; ++i) { 49 struct state_effecter_possible_states *states = 50 (struct state_effecter_possible_states *) 51 states_ptr; 52 53 HTOLE16(states->state_set_id); 54 55 states_ptr += 56 (sizeof(*states) - sizeof(states->states) + 57 states->possible_states_size); 58 } 59 60 calculated_possible_states_size = states_ptr - begin_states_ptr; 61 } 62 63 // Check lengths 64 65 if (possible_states_size != calculated_possible_states_size) { 66 *actual_size = 0; 67 return PLDM_ERROR; 68 } 69 70 *actual_size = 71 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size - 72 sizeof(effecter->possible_states)); 73 74 // Encode rest of PDR 75 76 effecter->hdr.version = 1; 77 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR; 78 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 79 80 memcpy(effecter->possible_states, possible_states, 81 possible_states_size); 82 83 // Convert effecter PDR body 84 HTOLE16(effecter->terminus_handle); 85 HTOLE16(effecter->effecter_id); 86 HTOLE16(effecter->entity_type); 87 HTOLE16(effecter->entity_instance); 88 HTOLE16(effecter->container_id); 89 HTOLE16(effecter->effecter_semantic_id); 90 91 // Convert header 92 HTOLE32(effecter->hdr.record_handle); 93 HTOLE16(effecter->hdr.record_change_num); 94 HTOLE16(effecter->hdr.length); 95 96 return PLDM_SUCCESS; 97 } 98 99 LIBPLDM_ABI_STABLE 100 int encode_state_sensor_pdr( 101 struct pldm_state_sensor_pdr *const sensor, 102 const size_t allocation_size, 103 const struct state_sensor_possible_states *const possible_states, 104 const size_t possible_states_size, size_t *const actual_size) 105 { 106 size_t calculated_possible_states_size = 0; 107 108 if (!sensor || !possible_states || !actual_size) { 109 return PLDM_ERROR; 110 } 111 112 if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) < 113 possible_states_size) { 114 return PLDM_ERROR; 115 } 116 117 if (allocation_size < 118 (sizeof(*sensor) - sizeof(sensor->possible_states) + 119 possible_states_size)) { 120 return PLDM_ERROR_INVALID_LENGTH; 121 } 122 123 { 124 // Encode possible states 125 char *states_ptr = (char *)possible_states; 126 char *const begin_states_ptr = states_ptr; 127 128 for (int i = 0; i < sensor->composite_sensor_count; ++i) { 129 struct state_sensor_possible_states *states = 130 (struct state_sensor_possible_states *) 131 states_ptr; 132 133 HTOLE16(states->state_set_id); 134 135 states_ptr += 136 (sizeof(*states) - sizeof(states->states) + 137 states->possible_states_size); 138 } 139 140 calculated_possible_states_size = states_ptr - begin_states_ptr; 141 } 142 143 // Check lengths 144 145 if (possible_states_size != calculated_possible_states_size) { 146 *actual_size = 0; 147 return PLDM_ERROR; 148 } 149 150 *actual_size = (sizeof(struct pldm_state_sensor_pdr) + 151 possible_states_size - sizeof(sensor->possible_states)); 152 153 // Encode rest of PDR 154 155 sensor->hdr.version = 1; 156 sensor->hdr.type = PLDM_STATE_SENSOR_PDR; 157 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 158 159 memcpy(sensor->possible_states, possible_states, possible_states_size); 160 161 // Convert sensor PDR body 162 HTOLE16(sensor->terminus_handle); 163 HTOLE16(sensor->sensor_id); 164 HTOLE16(sensor->entity_type); 165 HTOLE16(sensor->entity_instance); 166 HTOLE16(sensor->container_id); 167 168 // Convert header 169 HTOLE32(sensor->hdr.record_handle); 170 HTOLE16(sensor->hdr.record_change_num); 171 HTOLE16(sensor->hdr.length); 172 173 return PLDM_SUCCESS; 174 } 175 176 LIBPLDM_ABI_STABLE 177 int encode_set_state_effecter_states_resp(uint8_t instance_id, 178 uint8_t completion_code, 179 struct pldm_msg *msg) 180 { 181 if (msg == NULL) { 182 return PLDM_ERROR_INVALID_DATA; 183 } 184 185 struct pldm_header_info header = { 0 }; 186 header.msg_type = PLDM_RESPONSE; 187 header.instance = instance_id; 188 header.pldm_type = PLDM_PLATFORM; 189 header.command = PLDM_SET_STATE_EFFECTER_STATES; 190 191 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 192 if (rc != PLDM_SUCCESS) { 193 return rc; 194 } 195 196 msg->payload[0] = completion_code; 197 198 return PLDM_SUCCESS; 199 } 200 201 LIBPLDM_ABI_STABLE 202 int encode_set_state_effecter_states_req(uint8_t instance_id, 203 uint16_t effecter_id, 204 uint8_t comp_effecter_count, 205 set_effecter_state_field *field, 206 struct pldm_msg *msg) 207 { 208 if (msg == NULL) { 209 return PLDM_ERROR_INVALID_DATA; 210 } 211 212 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 || 213 field == NULL) { 214 return PLDM_ERROR_INVALID_DATA; 215 } 216 217 struct pldm_header_info header = { 0 }; 218 header.msg_type = PLDM_REQUEST; 219 header.instance = instance_id; 220 header.pldm_type = PLDM_PLATFORM; 221 header.command = PLDM_SET_STATE_EFFECTER_STATES; 222 223 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 224 if (rc != PLDM_SUCCESS) { 225 return rc; 226 } 227 228 struct pldm_set_state_effecter_states_req *request = 229 (struct pldm_set_state_effecter_states_req *)msg->payload; 230 effecter_id = htole16(effecter_id); 231 request->effecter_id = effecter_id; 232 request->comp_effecter_count = comp_effecter_count; 233 memcpy(request->field, field, 234 (sizeof(set_effecter_state_field) * comp_effecter_count)); 235 236 return PLDM_SUCCESS; 237 } 238 239 LIBPLDM_ABI_STABLE 240 int decode_set_state_effecter_states_resp(const struct pldm_msg *msg, 241 size_t payload_length, 242 uint8_t *completion_code) 243 { 244 if (msg == NULL || completion_code == NULL) { 245 return PLDM_ERROR_INVALID_DATA; 246 } 247 248 *completion_code = msg->payload[0]; 249 if (PLDM_SUCCESS != *completion_code) { 250 return PLDM_SUCCESS; 251 } 252 253 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) { 254 return PLDM_ERROR_INVALID_LENGTH; 255 } 256 257 return PLDM_SUCCESS; 258 } 259 260 #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3 261 LIBPLDM_ABI_STABLE 262 int decode_set_state_effecter_states_req(const struct pldm_msg *msg, 263 size_t payload_length, 264 uint16_t *effecter_id, 265 uint8_t *comp_effecter_count, 266 set_effecter_state_field *field) 267 { 268 struct pldm_msgbuf _buf; 269 struct pldm_msgbuf *buf = &_buf; 270 int rc; 271 int i; 272 273 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL || 274 field == NULL) { 275 return PLDM_ERROR_INVALID_DATA; 276 } 277 278 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) { 279 return PLDM_ERROR_INVALID_LENGTH; 280 } 281 282 rc = pldm_msgbuf_init_errno(buf, 283 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE, 284 msg->payload, payload_length); 285 if (rc) { 286 return pldm_xlate_errno(rc); 287 } 288 289 pldm_msgbuf_extract_p(buf, effecter_id); 290 pldm_msgbuf_extract_p(buf, comp_effecter_count); 291 292 if (*comp_effecter_count > 8) { 293 return PLDM_ERROR_INVALID_DATA; 294 } 295 296 for (i = 0; i < *comp_effecter_count; i++) { 297 pldm_msgbuf_extract(buf, field[i].set_request); 298 pldm_msgbuf_extract(buf, field[i].effecter_state); 299 } 300 301 rc = pldm_msgbuf_destroy(buf); 302 if (rc) { 303 return pldm_xlate_errno(rc); 304 } 305 306 return PLDM_SUCCESS; 307 } 308 309 LIBPLDM_ABI_STABLE 310 int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length, 311 uint32_t *record_hndl, uint32_t *data_transfer_hndl, 312 uint8_t *transfer_op_flag, uint16_t *request_cnt, 313 uint16_t *record_chg_num) 314 { 315 struct pldm_msgbuf _buf; 316 struct pldm_msgbuf *buf = &_buf; 317 int rc; 318 319 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL || 320 transfer_op_flag == NULL || request_cnt == NULL || 321 record_chg_num == NULL) { 322 return PLDM_ERROR_INVALID_DATA; 323 } 324 325 if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 326 return PLDM_ERROR_INVALID_LENGTH; 327 } 328 329 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload, 330 payload_length); 331 if (rc) { 332 return pldm_xlate_errno(rc); 333 } 334 335 pldm_msgbuf_extract_p(buf, record_hndl); 336 pldm_msgbuf_extract_p(buf, data_transfer_hndl); 337 pldm_msgbuf_extract_p(buf, transfer_op_flag); 338 pldm_msgbuf_extract_p(buf, request_cnt); 339 pldm_msgbuf_extract_p(buf, record_chg_num); 340 341 rc = pldm_msgbuf_destroy(buf); 342 if (rc) { 343 return pldm_xlate_errno(rc); 344 } 345 346 return PLDM_SUCCESS; 347 } 348 349 LIBPLDM_ABI_DEPRECATED_UNSAFE 350 int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code, 351 uint32_t next_record_hndl, 352 uint32_t next_data_transfer_hndl, uint8_t transfer_flag, 353 uint16_t resp_cnt, const uint8_t *record_data, 354 uint8_t transfer_crc, struct pldm_msg *msg) 355 { 356 if (msg == NULL) { 357 return PLDM_ERROR_INVALID_DATA; 358 } 359 360 struct pldm_header_info header = { 0 }; 361 header.msg_type = PLDM_RESPONSE; 362 header.instance = instance_id; 363 header.pldm_type = PLDM_PLATFORM; 364 header.command = PLDM_GET_PDR; 365 366 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 367 if (rc != PLDM_SUCCESS) { 368 return rc; 369 } 370 371 struct pldm_get_pdr_resp *response = 372 (struct pldm_get_pdr_resp *)msg->payload; 373 response->completion_code = completion_code; 374 375 if (response->completion_code == PLDM_SUCCESS) { 376 response->next_record_handle = htole32(next_record_hndl); 377 response->next_data_transfer_handle = 378 htole32(next_data_transfer_hndl); 379 response->transfer_flag = transfer_flag; 380 response->response_count = htole16(resp_cnt); 381 if (record_data != NULL && resp_cnt > 0) { 382 memcpy(response->record_data, record_data, resp_cnt); 383 } 384 if (transfer_flag == PLDM_END) { 385 uint8_t *dst = msg->payload; 386 dst += (sizeof(struct pldm_get_pdr_resp) - 1) + 387 resp_cnt; 388 *dst = transfer_crc; 389 } 390 } 391 392 return PLDM_SUCCESS; 393 } 394 395 LIBPLDM_ABI_STABLE 396 int encode_get_pdr_repository_info_resp( 397 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state, 398 const uint8_t *update_time, const uint8_t *oem_update_time, 399 uint32_t record_count, uint32_t repository_size, 400 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout, 401 struct pldm_msg *msg) 402 { 403 if (msg == NULL) { 404 return PLDM_ERROR_INVALID_DATA; 405 } 406 407 struct pldm_header_info header = { 0 }; 408 header.msg_type = PLDM_RESPONSE; 409 header.instance = instance_id; 410 header.pldm_type = PLDM_PLATFORM; 411 header.command = PLDM_GET_PDR_REPOSITORY_INFO; 412 413 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 414 if (rc != PLDM_SUCCESS) { 415 return rc; 416 } 417 418 struct pldm_pdr_repository_info_resp *response = 419 (struct pldm_pdr_repository_info_resp *)msg->payload; 420 response->completion_code = completion_code; 421 422 if (response->completion_code == PLDM_SUCCESS) { 423 response->repository_state = repository_state; 424 if (update_time != NULL) { 425 memcpy(response->update_time, update_time, 426 PLDM_TIMESTAMP104_SIZE); 427 } 428 if (oem_update_time != NULL) { 429 memcpy(response->oem_update_time, oem_update_time, 430 PLDM_TIMESTAMP104_SIZE); 431 } 432 response->record_count = htole32(record_count); 433 response->repository_size = htole32(repository_size); 434 response->largest_record_size = htole32(largest_record_size); 435 response->data_transfer_handle_timeout = 436 data_transfer_handle_timeout; 437 } 438 439 return PLDM_SUCCESS; 440 } 441 442 LIBPLDM_ABI_DEPRECATED 443 int decode_get_pdr_repository_info_resp( 444 const struct pldm_msg *msg, size_t payload_length, 445 uint8_t *completion_code, uint8_t *repository_state, 446 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count, 447 uint32_t *repository_size, uint32_t *largest_record_size, 448 uint8_t *data_transfer_handle_timeout) 449 { 450 struct pldm_msgbuf _buf; 451 struct pldm_msgbuf *buf = &_buf; 452 int rc; 453 454 if (msg == NULL || completion_code == NULL || 455 repository_state == NULL || update_time == NULL || 456 oem_update_time == NULL || record_count == NULL || 457 repository_size == NULL || largest_record_size == NULL || 458 data_transfer_handle_timeout == NULL) { 459 return PLDM_ERROR_INVALID_DATA; 460 } 461 462 rc = pldm_msgbuf_init_errno(buf, 463 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 464 msg->payload, payload_length); 465 if (rc) { 466 return pldm_xlate_errno(rc); 467 } 468 469 pldm_msgbuf_extract_p(buf, completion_code); 470 if (PLDM_SUCCESS != *completion_code) { 471 return PLDM_SUCCESS; 472 } 473 474 rc = pldm_msgbuf_extract_p(buf, repository_state); 475 if (rc) { 476 return pldm_xlate_errno(rc); 477 } 478 479 if (*repository_state > PLDM_FAILED) { 480 return PLDM_ERROR_INVALID_DATA; 481 } 482 483 /* NOTE: Memory safety */ 484 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time, 485 PLDM_TIMESTAMP104_SIZE); 486 if (rc) { 487 return pldm_xlate_errno(rc); 488 } 489 490 /* NOTE: Memory safety */ 491 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, 492 oem_update_time, PLDM_TIMESTAMP104_SIZE); 493 if (rc) { 494 return pldm_xlate_errno(rc); 495 } 496 497 pldm_msgbuf_extract_p(buf, record_count); 498 pldm_msgbuf_extract_p(buf, repository_size); 499 pldm_msgbuf_extract_p(buf, largest_record_size); 500 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout); 501 502 rc = pldm_msgbuf_destroy(buf); 503 if (rc) { 504 return pldm_xlate_errno(rc); 505 } 506 507 return PLDM_SUCCESS; 508 } 509 510 LIBPLDM_ABI_TESTING 511 int decode_get_pdr_repository_info_resp_safe( 512 const struct pldm_msg *msg, size_t payload_length, 513 struct pldm_pdr_repository_info_resp *resp) 514 { 515 struct pldm_msgbuf _buf; 516 struct pldm_msgbuf *buf = &_buf; 517 int rc; 518 519 if (msg == NULL || resp == NULL) { 520 return -EINVAL; 521 } 522 523 rc = pldm_msg_has_error(msg, payload_length); 524 if (rc) { 525 resp->completion_code = rc; 526 return 0; 527 } 528 529 rc = pldm_msgbuf_init_errno(buf, 530 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 531 msg->payload, payload_length); 532 if (rc) { 533 return rc; 534 } 535 536 rc = pldm_msgbuf_extract(buf, resp->completion_code); 537 if (rc) { 538 return rc; 539 } 540 541 pldm_msgbuf_extract(buf, resp->repository_state); 542 543 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time), 544 resp->update_time, 545 sizeof(resp->update_time)); 546 if (rc) { 547 return rc; 548 } 549 550 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time), 551 resp->oem_update_time, 552 sizeof(resp->oem_update_time)); 553 if (rc) { 554 return rc; 555 } 556 557 pldm_msgbuf_extract(buf, resp->record_count); 558 pldm_msgbuf_extract(buf, resp->repository_size); 559 pldm_msgbuf_extract(buf, resp->largest_record_size); 560 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout); 561 562 return pldm_msgbuf_destroy_consumed(buf); 563 } 564 565 LIBPLDM_ABI_STABLE 566 int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl, 567 uint32_t data_transfer_hndl, uint8_t transfer_op_flag, 568 uint16_t request_cnt, uint16_t record_chg_num, 569 struct pldm_msg *msg, size_t payload_length) 570 { 571 if (msg == NULL) { 572 return PLDM_ERROR_INVALID_DATA; 573 } 574 575 if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 576 return PLDM_ERROR_INVALID_LENGTH; 577 } 578 579 struct pldm_header_info header = { 0 }; 580 header.msg_type = PLDM_REQUEST; 581 header.instance = instance_id; 582 header.pldm_type = PLDM_PLATFORM; 583 header.command = PLDM_GET_PDR; 584 585 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 586 if (rc != PLDM_SUCCESS) { 587 return rc; 588 } 589 590 struct pldm_get_pdr_req *request = 591 (struct pldm_get_pdr_req *)msg->payload; 592 request->record_handle = htole32(record_hndl); 593 request->data_transfer_handle = htole32(data_transfer_hndl); 594 request->transfer_op_flag = transfer_op_flag; 595 request->request_count = htole16(request_cnt); 596 request->record_change_number = htole16(record_chg_num); 597 598 return PLDM_SUCCESS; 599 } 600 601 LIBPLDM_ABI_DEPRECATED 602 int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length, 603 uint8_t *completion_code, uint32_t *next_record_hndl, 604 uint32_t *next_data_transfer_hndl, 605 uint8_t *transfer_flag, uint16_t *resp_cnt, 606 uint8_t *record_data, size_t record_data_length, 607 uint8_t *transfer_crc) 608 { 609 struct pldm_msgbuf _buf; 610 struct pldm_msgbuf *buf = &_buf; 611 int rc; 612 613 if (msg == NULL || completion_code == NULL || 614 next_record_hndl == NULL || next_data_transfer_hndl == NULL || 615 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) { 616 return PLDM_ERROR_INVALID_DATA; 617 } 618 619 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 620 msg->payload, payload_length); 621 if (rc) { 622 return pldm_xlate_errno(rc); 623 } 624 625 rc = pldm_msgbuf_extract_p(buf, completion_code); 626 if (rc) { 627 return pldm_xlate_errno(rc); 628 } 629 630 if (PLDM_SUCCESS != *completion_code) { 631 return PLDM_SUCCESS; 632 } 633 634 pldm_msgbuf_extract_p(buf, next_record_hndl); 635 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl); 636 pldm_msgbuf_extract_p(buf, transfer_flag); 637 rc = pldm_msgbuf_extract_p(buf, resp_cnt); 638 if (rc) { 639 return pldm_xlate_errno(rc); 640 } 641 642 if (*resp_cnt > 0 && record_data != NULL) { 643 if (record_data_length < *resp_cnt) { 644 return PLDM_ERROR_INVALID_LENGTH; 645 } 646 /* NOTE: Memory safety */ 647 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data, 648 *resp_cnt); 649 if (rc) { 650 return pldm_xlate_errno(rc); 651 } 652 } 653 654 if (*transfer_flag == PLDM_END) { 655 pldm_msgbuf_extract_p(buf, transfer_crc); 656 } 657 658 rc = pldm_msgbuf_destroy(buf); 659 if (rc) { 660 return pldm_xlate_errno(rc); 661 } 662 663 return PLDM_SUCCESS; 664 } 665 666 LIBPLDM_ABI_TESTING 667 int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length, 668 struct pldm_get_pdr_resp *resp, size_t resp_len, 669 uint8_t *transfer_crc) 670 { 671 struct pldm_msgbuf _buf; 672 struct pldm_msgbuf *buf = &_buf; 673 int rc; 674 675 if (msg == NULL || resp == NULL || transfer_crc == NULL) { 676 return -EINVAL; 677 } 678 679 rc = pldm_msg_has_error(msg, payload_length); 680 if (rc) { 681 resp->completion_code = rc; 682 return 0; 683 } 684 685 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 686 msg->payload, payload_length); 687 if (rc) { 688 return rc; 689 } 690 691 pldm_msgbuf_extract(buf, resp->completion_code); 692 pldm_msgbuf_extract(buf, resp->next_record_handle); 693 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle); 694 695 rc = pldm_msgbuf_extract(buf, resp->transfer_flag); 696 if (rc) { 697 return rc; 698 } 699 700 rc = pldm_msgbuf_extract(buf, resp->response_count); 701 if (rc) { 702 return rc; 703 } 704 705 rc = pldm_msgbuf_extract_array( 706 buf, resp->response_count, resp->record_data, 707 resp_len - (sizeof(*resp) - sizeof(resp->record_data))); 708 if (rc) { 709 return rc; 710 } 711 712 if (resp->transfer_flag == PLDM_END) { 713 pldm_msgbuf_extract_p(buf, transfer_crc); 714 } 715 716 return pldm_msgbuf_destroy_consumed(buf); 717 } 718 719 LIBPLDM_ABI_STABLE 720 int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg, 721 size_t payload_length, 722 uint16_t *effecter_id, 723 uint8_t *effecter_data_size, 724 uint8_t effecter_value[4]) 725 { 726 struct pldm_msgbuf _buf; 727 struct pldm_msgbuf *buf = &_buf; 728 int rc; 729 730 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL || 731 effecter_value == NULL) { 732 return PLDM_ERROR_INVALID_DATA; 733 } 734 735 rc = pldm_msgbuf_init_errno( 736 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES, 737 msg->payload, payload_length); 738 if (rc) { 739 return pldm_xlate_errno(rc); 740 } 741 742 pldm_msgbuf_extract_p(buf, effecter_id); 743 rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 744 if (rc) { 745 return PLDM_ERROR_INVALID_DATA; 746 } 747 748 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 749 return PLDM_ERROR_INVALID_DATA; 750 } 751 752 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 753 effecter_value); 754 755 rc = pldm_msgbuf_destroy(buf); 756 if (rc) { 757 return pldm_xlate_errno(rc); 758 } 759 760 return PLDM_SUCCESS; 761 } 762 763 LIBPLDM_ABI_STABLE 764 int encode_set_numeric_effecter_value_resp(uint8_t instance_id, 765 uint8_t completion_code, 766 struct pldm_msg *msg, 767 size_t payload_length) 768 { 769 if (msg == NULL) { 770 return PLDM_ERROR_INVALID_DATA; 771 } 772 773 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 774 return PLDM_ERROR_INVALID_LENGTH; 775 } 776 777 struct pldm_header_info header = { 0 }; 778 header.msg_type = PLDM_RESPONSE; 779 header.instance = instance_id; 780 header.pldm_type = PLDM_PLATFORM; 781 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 782 783 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 784 if (rc != PLDM_SUCCESS) { 785 return rc; 786 } 787 788 msg->payload[0] = completion_code; 789 790 return rc; 791 } 792 793 LIBPLDM_ABI_STABLE 794 int encode_set_numeric_effecter_value_req(uint8_t instance_id, 795 uint16_t effecter_id, 796 uint8_t effecter_data_size, 797 const uint8_t *effecter_value, 798 struct pldm_msg *msg, 799 size_t payload_length) 800 { 801 if (msg == NULL || effecter_value == NULL) { 802 return PLDM_ERROR_INVALID_DATA; 803 } 804 805 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 806 return PLDM_ERROR_INVALID_DATA; 807 } 808 809 struct pldm_header_info header = { 0 }; 810 header.msg_type = PLDM_REQUEST; 811 header.instance = instance_id; 812 header.pldm_type = PLDM_PLATFORM; 813 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 814 815 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 816 if (rc != PLDM_SUCCESS) { 817 return rc; 818 } 819 820 struct pldm_set_numeric_effecter_value_req *request = 821 (struct pldm_set_numeric_effecter_value_req *)msg->payload; 822 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 823 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 824 if (payload_length != 825 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) { 826 return PLDM_ERROR_INVALID_LENGTH; 827 } 828 request->effecter_value[0] = *effecter_value; 829 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 830 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 831 if (payload_length != 832 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) { 833 return PLDM_ERROR_INVALID_LENGTH; 834 } 835 836 uint16_t val = *(uint16_t *)(effecter_value); 837 val = htole16(val); 838 memcpy(request->effecter_value, &val, sizeof(uint16_t)); 839 840 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 841 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 842 if (payload_length != 843 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) { 844 return PLDM_ERROR_INVALID_LENGTH; 845 } 846 847 uint32_t val = *(uint32_t *)(effecter_value); 848 val = htole32(val); 849 memcpy(request->effecter_value, &val, sizeof(uint32_t)); 850 } 851 852 request->effecter_id = htole16(effecter_id); 853 request->effecter_data_size = effecter_data_size; 854 855 return PLDM_SUCCESS; 856 } 857 858 LIBPLDM_ABI_STABLE 859 int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg, 860 size_t payload_length, 861 uint8_t *completion_code) 862 { 863 if (msg == NULL || completion_code == NULL) { 864 return PLDM_ERROR_INVALID_DATA; 865 } 866 867 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 868 return PLDM_ERROR_INVALID_LENGTH; 869 } 870 871 *completion_code = msg->payload[0]; 872 873 return PLDM_SUCCESS; 874 } 875 876 LIBPLDM_ABI_STABLE 877 int encode_get_state_sensor_readings_resp(uint8_t instance_id, 878 uint8_t completion_code, 879 uint8_t comp_sensor_count, 880 get_sensor_state_field *field, 881 struct pldm_msg *msg) 882 { 883 if (msg == NULL) { 884 return PLDM_ERROR_INVALID_DATA; 885 } 886 887 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) { 888 return PLDM_ERROR_INVALID_DATA; 889 } 890 891 struct pldm_header_info header = { 0 }; 892 header.msg_type = PLDM_RESPONSE; 893 header.instance = instance_id; 894 header.pldm_type = PLDM_PLATFORM; 895 header.command = PLDM_GET_STATE_SENSOR_READINGS; 896 897 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 898 if (rc != PLDM_SUCCESS) { 899 return rc; 900 } 901 902 struct pldm_get_state_sensor_readings_resp *response = 903 (struct pldm_get_state_sensor_readings_resp *)msg->payload; 904 905 response->completion_code = completion_code; 906 response->comp_sensor_count = comp_sensor_count; 907 memcpy(response->field, field, 908 (sizeof(get_sensor_state_field) * comp_sensor_count)); 909 910 return PLDM_SUCCESS; 911 } 912 913 LIBPLDM_ABI_STABLE 914 int encode_get_state_sensor_readings_req(uint8_t instance_id, 915 uint16_t sensor_id, 916 bitfield8_t sensor_rearm, 917 uint8_t reserved, struct pldm_msg *msg) 918 { 919 if (msg == NULL) { 920 return PLDM_ERROR_INVALID_DATA; 921 } 922 923 struct pldm_header_info header = { 0 }; 924 header.msg_type = PLDM_REQUEST; 925 header.instance = instance_id; 926 header.pldm_type = PLDM_PLATFORM; 927 header.command = PLDM_GET_STATE_SENSOR_READINGS; 928 929 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 930 if (rc != PLDM_SUCCESS) { 931 return rc; 932 } 933 934 struct pldm_get_state_sensor_readings_req *request = 935 (struct pldm_get_state_sensor_readings_req *)msg->payload; 936 937 request->sensor_id = htole16(sensor_id); 938 request->reserved = reserved; 939 request->sensor_rearm = sensor_rearm; 940 941 return PLDM_SUCCESS; 942 } 943 944 LIBPLDM_ABI_STABLE 945 int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg, 946 size_t payload_length, 947 uint8_t *completion_code, 948 uint8_t *comp_sensor_count, 949 get_sensor_state_field *field) 950 { 951 struct pldm_msgbuf _buf; 952 struct pldm_msgbuf *buf = &_buf; 953 uint8_t i; 954 int rc; 955 956 if (msg == NULL || completion_code == NULL || 957 comp_sensor_count == NULL || field == NULL) { 958 return PLDM_ERROR_INVALID_DATA; 959 } 960 961 rc = pldm_msgbuf_init_errno( 962 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES, 963 msg->payload, payload_length); 964 if (rc) { 965 return pldm_xlate_errno(rc); 966 } 967 968 rc = pldm_msgbuf_extract_p(buf, completion_code); 969 if (rc) { 970 return pldm_xlate_errno(rc); 971 } 972 973 if (PLDM_SUCCESS != *completion_code) { 974 return PLDM_SUCCESS; 975 } 976 977 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count); 978 if (rc) { 979 return pldm_xlate_errno(rc); 980 } 981 982 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) { 983 return PLDM_ERROR_INVALID_DATA; 984 } 985 986 for (i = 0; i < *comp_sensor_count; i++) { 987 pldm_msgbuf_extract(buf, field[i].sensor_op_state); 988 pldm_msgbuf_extract(buf, field[i].present_state); 989 pldm_msgbuf_extract(buf, field[i].previous_state); 990 pldm_msgbuf_extract(buf, field[i].event_state); 991 } 992 993 rc = pldm_msgbuf_destroy_consumed(buf); 994 if (rc) { 995 return pldm_xlate_errno(rc); 996 } 997 998 return PLDM_SUCCESS; 999 } 1000 1001 LIBPLDM_ABI_STABLE 1002 int decode_get_state_sensor_readings_req(const struct pldm_msg *msg, 1003 size_t payload_length, 1004 uint16_t *sensor_id, 1005 bitfield8_t *sensor_rearm, 1006 uint8_t *reserved) 1007 { 1008 struct pldm_msgbuf _buf; 1009 struct pldm_msgbuf *buf = &_buf; 1010 int rc; 1011 1012 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) { 1013 return PLDM_ERROR_INVALID_DATA; 1014 } 1015 1016 rc = pldm_msgbuf_init_errno(buf, 1017 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES, 1018 msg->payload, payload_length); 1019 if (rc) { 1020 return pldm_xlate_errno(rc); 1021 } 1022 1023 pldm_msgbuf_extract_p(buf, sensor_id); 1024 pldm_msgbuf_extract(buf, sensor_rearm->byte); 1025 pldm_msgbuf_extract_p(buf, reserved); 1026 1027 rc = pldm_msgbuf_destroy(buf); 1028 if (rc) { 1029 return pldm_xlate_errno(rc); 1030 } 1031 1032 return PLDM_SUCCESS; 1033 } 1034 1035 LIBPLDM_ABI_STABLE 1036 int encode_sensor_event_data( 1037 struct pldm_sensor_event_data *const event_data, 1038 const size_t event_data_size, const uint16_t sensor_id, 1039 const enum sensor_event_class_states sensor_event_class, 1040 const uint8_t sensor_offset, const uint8_t event_state, 1041 const uint8_t previous_event_state, 1042 size_t *const actual_event_data_size) 1043 { 1044 *actual_event_data_size = 1045 (sizeof(*event_data) - sizeof(event_data->event_class) + 1046 sizeof(struct pldm_sensor_event_state_sensor_state)); 1047 1048 if (!event_data) { 1049 return PLDM_SUCCESS; 1050 } 1051 1052 if (event_data_size < *actual_event_data_size) { 1053 *actual_event_data_size = 0; 1054 return PLDM_ERROR_INVALID_LENGTH; 1055 } 1056 1057 event_data->sensor_id = htole16(sensor_id); 1058 event_data->sensor_event_class_type = sensor_event_class; 1059 1060 struct pldm_sensor_event_state_sensor_state *const state_data = 1061 (struct pldm_sensor_event_state_sensor_state *) 1062 event_data->event_class; 1063 1064 state_data->sensor_offset = sensor_offset; 1065 state_data->event_state = event_state; 1066 state_data->previous_event_state = previous_event_state; 1067 1068 return PLDM_SUCCESS; 1069 } 1070 1071 LIBPLDM_ABI_STABLE 1072 int decode_platform_event_message_req(const struct pldm_msg *msg, 1073 size_t payload_length, 1074 uint8_t *format_version, uint8_t *tid, 1075 uint8_t *event_class, 1076 size_t *event_data_offset) 1077 { 1078 struct pldm_msgbuf _buf; 1079 struct pldm_msgbuf *buf = &_buf; 1080 int rc; 1081 1082 if (msg == NULL || format_version == NULL || tid == NULL || 1083 event_class == NULL || event_data_offset == NULL) { 1084 return PLDM_ERROR_INVALID_DATA; 1085 } 1086 1087 rc = pldm_msgbuf_init_errno(buf, 1088 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES, 1089 msg->payload, payload_length); 1090 if (rc) { 1091 return pldm_xlate_errno(rc); 1092 } 1093 1094 pldm_msgbuf_extract_p(buf, format_version); 1095 pldm_msgbuf_extract_p(buf, tid); 1096 pldm_msgbuf_extract_p(buf, event_class); 1097 1098 rc = pldm_msgbuf_destroy(buf); 1099 if (rc) { 1100 return pldm_xlate_errno(rc); 1101 } 1102 1103 *event_data_offset = 1104 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class); 1105 1106 return PLDM_SUCCESS; 1107 } 1108 1109 static int pldm_platform_poll_for_platform_event_message_validate( 1110 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge) 1111 { 1112 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) && 1113 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) || 1114 ((transfer_operation_flag == PLDM_GET_NEXTPART) && 1115 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1116 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 1117 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1118 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 1119 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) || 1120 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) { 1121 return -EPROTO; 1122 } 1123 1124 return 0; 1125 } 1126 1127 LIBPLDM_ABI_STABLE 1128 int decode_poll_for_platform_event_message_req( 1129 const struct pldm_msg *msg, size_t payload_length, 1130 uint8_t *format_version, uint8_t *transfer_operation_flag, 1131 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge) 1132 { 1133 struct pldm_msgbuf _buf; 1134 struct pldm_msgbuf *buf = &_buf; 1135 int rc; 1136 1137 if (msg == NULL || format_version == NULL || 1138 transfer_operation_flag == NULL || data_transfer_handle == NULL || 1139 event_id_to_acknowledge == NULL) { 1140 return PLDM_ERROR_INVALID_DATA; 1141 } 1142 1143 rc = pldm_msgbuf_init_errno( 1144 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, 1145 msg->payload, payload_length); 1146 if (rc) { 1147 return pldm_xlate_errno(rc); 1148 } 1149 1150 pldm_msgbuf_extract_p(buf, format_version); 1151 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag); 1152 if (rc) { 1153 return pldm_xlate_errno(rc); 1154 } 1155 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) { 1156 return PLDM_ERROR_INVALID_DATA; 1157 } 1158 1159 pldm_msgbuf_extract_p(buf, data_transfer_handle); 1160 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge); 1161 if (rc) { 1162 return pldm_xlate_errno(rc); 1163 } 1164 1165 rc = pldm_platform_poll_for_platform_event_message_validate( 1166 *transfer_operation_flag, *event_id_to_acknowledge); 1167 if (rc < 0) { 1168 return PLDM_ERROR_INVALID_DATA; 1169 } 1170 1171 rc = pldm_msgbuf_destroy(buf); 1172 if (rc) { 1173 return pldm_xlate_errno(rc); 1174 } 1175 1176 return PLDM_SUCCESS; 1177 } 1178 1179 LIBPLDM_ABI_STABLE 1180 int encode_platform_event_message_resp(uint8_t instance_id, 1181 uint8_t completion_code, 1182 uint8_t platform_event_status, 1183 struct pldm_msg *msg) 1184 { 1185 if (msg == NULL) { 1186 return PLDM_ERROR_INVALID_DATA; 1187 } 1188 1189 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 1190 return PLDM_ERROR_INVALID_DATA; 1191 } 1192 1193 struct pldm_header_info header = { 0 }; 1194 header.msg_type = PLDM_RESPONSE; 1195 header.instance = instance_id; 1196 header.pldm_type = PLDM_PLATFORM; 1197 header.command = PLDM_PLATFORM_EVENT_MESSAGE; 1198 1199 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1200 if (rc != PLDM_SUCCESS) { 1201 return rc; 1202 } 1203 1204 struct pldm_platform_event_message_resp *response = 1205 (struct pldm_platform_event_message_resp *)msg->payload; 1206 response->completion_code = completion_code; 1207 response->platform_event_status = platform_event_status; 1208 1209 return PLDM_SUCCESS; 1210 } 1211 1212 LIBPLDM_ABI_STABLE 1213 int encode_poll_for_platform_event_message_resp( 1214 uint8_t instance_id, uint8_t completion_code, uint8_t tid, 1215 uint16_t event_id, uint32_t next_data_transfer_handle, 1216 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size, 1217 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg, 1218 size_t payload_length) 1219 { 1220 struct pldm_msgbuf _buf; 1221 struct pldm_msgbuf *buf = &_buf; 1222 int rc; 1223 1224 if (!msg) { 1225 return PLDM_ERROR_INVALID_DATA; 1226 } 1227 1228 struct pldm_header_info header = { 0 }; 1229 header.msg_type = PLDM_RESPONSE; 1230 header.instance = instance_id; 1231 header.pldm_type = PLDM_PLATFORM; 1232 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 1233 1234 rc = pack_pldm_header(&header, &(msg->hdr)); 1235 if (rc != PLDM_SUCCESS) { 1236 return rc; 1237 } 1238 1239 rc = pldm_msgbuf_init_errno( 1240 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 1241 msg->payload, payload_length); 1242 if (rc) { 1243 return pldm_xlate_errno(rc); 1244 } 1245 1246 pldm_msgbuf_insert(buf, completion_code); 1247 pldm_msgbuf_insert(buf, tid); 1248 rc = pldm_msgbuf_insert(buf, event_id); 1249 if (rc) { 1250 return pldm_xlate_errno(rc); 1251 } 1252 1253 if (event_id == 0xffff || event_id == 0x0000) { 1254 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES != 1255 payload_length) { 1256 return PLDM_ERROR_INVALID_LENGTH; 1257 } 1258 1259 rc = pldm_msgbuf_destroy(buf); 1260 if (rc) { 1261 return pldm_xlate_errno(rc); 1262 } 1263 1264 return PLDM_SUCCESS; 1265 } 1266 1267 if ((event_data == NULL) && (event_data_size > 0)) { 1268 return PLDM_ERROR_INVALID_DATA; 1269 } 1270 1271 pldm_msgbuf_insert(buf, next_data_transfer_handle); 1272 pldm_msgbuf_insert(buf, transfer_flag); 1273 pldm_msgbuf_insert(buf, event_class); 1274 rc = pldm_msgbuf_insert(buf, event_data_size); 1275 if (rc) { 1276 return pldm_xlate_errno(rc); 1277 } 1278 1279 if ((event_data_size > 0) && event_data) { 1280 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data, 1281 event_data_size); 1282 if (rc) { 1283 return pldm_xlate_errno(rc); 1284 } 1285 } 1286 1287 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) { 1288 pldm_msgbuf_insert(buf, checksum); 1289 } 1290 1291 rc = pldm_msgbuf_destroy(buf); 1292 if (rc) { 1293 return pldm_xlate_errno(rc); 1294 } 1295 1296 return PLDM_SUCCESS; 1297 } 1298 1299 LIBPLDM_ABI_STABLE 1300 int encode_platform_event_message_req( 1301 uint8_t instance_id, uint8_t format_version, uint8_t tid, 1302 uint8_t event_class, const uint8_t *event_data, 1303 size_t event_data_length, struct pldm_msg *msg, size_t payload_length) 1304 1305 { 1306 if (format_version != 1) { 1307 return PLDM_ERROR_INVALID_DATA; 1308 } 1309 1310 if (msg == NULL || event_data == NULL) { 1311 return PLDM_ERROR_INVALID_DATA; 1312 } 1313 1314 if (event_data_length == 0) { 1315 return PLDM_ERROR_INVALID_DATA; 1316 } 1317 1318 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) < 1319 event_data_length) { 1320 return PLDM_ERROR_INVALID_LENGTH; 1321 } 1322 1323 if (payload_length != 1324 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) { 1325 return PLDM_ERROR_INVALID_LENGTH; 1326 } 1327 1328 if (event_class > PLDM_CPER_EVENT && 1329 !(event_class >= 0xf0 && event_class <= 0xfe)) { 1330 return PLDM_ERROR_INVALID_DATA; 1331 } 1332 1333 struct pldm_header_info header = { 0 }; 1334 header.msg_type = PLDM_REQUEST; 1335 header.instance = instance_id; 1336 header.pldm_type = PLDM_PLATFORM; 1337 header.command = PLDM_PLATFORM_EVENT_MESSAGE; 1338 1339 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1340 if (rc != PLDM_SUCCESS) { 1341 return rc; 1342 } 1343 1344 struct pldm_platform_event_message_req *request = 1345 (struct pldm_platform_event_message_req *)msg->payload; 1346 request->format_version = format_version; 1347 request->tid = tid; 1348 request->event_class = event_class; 1349 memcpy(request->event_data, event_data, event_data_length); 1350 1351 return PLDM_SUCCESS; 1352 } 1353 1354 LIBPLDM_ABI_STABLE 1355 int decode_platform_event_message_resp(const struct pldm_msg *msg, 1356 size_t payload_length, 1357 uint8_t *completion_code, 1358 uint8_t *platform_event_status) 1359 { 1360 struct pldm_msgbuf _buf; 1361 struct pldm_msgbuf *buf = &_buf; 1362 int rc; 1363 1364 if (msg == NULL || completion_code == NULL || 1365 platform_event_status == NULL) { 1366 return PLDM_ERROR_INVALID_DATA; 1367 } 1368 1369 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 1370 msg->payload, payload_length); 1371 if (rc) { 1372 return pldm_xlate_errno(rc); 1373 } 1374 1375 rc = pldm_msgbuf_extract_p(buf, completion_code); 1376 if (rc) { 1377 return pldm_xlate_errno(rc); 1378 } 1379 1380 if (PLDM_SUCCESS != *completion_code) { 1381 return PLDM_SUCCESS; 1382 } 1383 1384 rc = pldm_msgbuf_extract_p(buf, platform_event_status); 1385 if (rc) { 1386 return pldm_xlate_errno(rc); 1387 } 1388 1389 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 1390 return PLDM_ERROR_INVALID_DATA; 1391 } 1392 1393 rc = pldm_msgbuf_destroy(buf); 1394 if (rc) { 1395 return pldm_xlate_errno(rc); 1396 } 1397 1398 return PLDM_SUCCESS; 1399 } 1400 1401 LIBPLDM_ABI_STABLE 1402 int encode_event_message_buffer_size_req(uint8_t instance_id, 1403 uint16_t event_receiver_max_buffer_size, 1404 struct pldm_msg *msg) 1405 { 1406 struct pldm_header_info header = { 0 }; 1407 header.msg_type = PLDM_REQUEST; 1408 header.instance = instance_id; 1409 header.pldm_type = PLDM_PLATFORM; 1410 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE; 1411 1412 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1413 if (rc != PLDM_SUCCESS) { 1414 return rc; 1415 } 1416 1417 struct pldm_event_message_buffer_size_req *request = 1418 (struct pldm_event_message_buffer_size_req *)msg->payload; 1419 request->event_receiver_max_buffer_size = 1420 event_receiver_max_buffer_size; 1421 1422 return PLDM_SUCCESS; 1423 } 1424 1425 LIBPLDM_ABI_STABLE 1426 int decode_event_message_buffer_size_resp(const struct pldm_msg *msg, 1427 size_t payload_length, 1428 uint8_t *completion_code, 1429 uint16_t *terminus_max_buffer_size) 1430 { 1431 struct pldm_msgbuf _buf; 1432 struct pldm_msgbuf *buf = &_buf; 1433 int rc; 1434 1435 if (msg == NULL || completion_code == NULL || 1436 terminus_max_buffer_size == NULL) { 1437 return PLDM_ERROR_INVALID_DATA; 1438 } 1439 1440 rc = pldm_msgbuf_init_errno(buf, 1441 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES, 1442 msg->payload, payload_length); 1443 if (rc) { 1444 return pldm_xlate_errno(rc); 1445 } 1446 1447 rc = pldm_msgbuf_extract_p(buf, completion_code); 1448 if (rc) { 1449 return pldm_xlate_errno(rc); 1450 } 1451 1452 if (PLDM_SUCCESS != *completion_code) { 1453 return PLDM_SUCCESS; 1454 } 1455 1456 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size); 1457 1458 rc = pldm_msgbuf_destroy_consumed(buf); 1459 if (rc) { 1460 return pldm_xlate_errno(rc); 1461 } 1462 1463 return PLDM_SUCCESS; 1464 } 1465 1466 LIBPLDM_ABI_STABLE 1467 int encode_event_message_supported_req(uint8_t instance_id, 1468 uint8_t format_version, 1469 struct pldm_msg *msg) 1470 { 1471 if (format_version != 1) { 1472 return PLDM_ERROR_INVALID_DATA; 1473 } 1474 1475 if (msg == NULL) { 1476 return PLDM_ERROR_INVALID_DATA; 1477 } 1478 1479 struct pldm_header_info header = { 0 }; 1480 header.msg_type = PLDM_REQUEST; 1481 header.instance = instance_id; 1482 header.pldm_type = PLDM_PLATFORM; 1483 header.command = PLDM_EVENT_MESSAGE_SUPPORTED; 1484 1485 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1486 if (rc != PLDM_SUCCESS) { 1487 return rc; 1488 } 1489 1490 struct pldm_event_message_supported_req *request = 1491 (struct pldm_event_message_supported_req *)msg->payload; 1492 request->format_version = format_version; 1493 1494 return PLDM_SUCCESS; 1495 } 1496 1497 LIBPLDM_ABI_STABLE 1498 int decode_event_message_supported_resp(const struct pldm_msg *msg, 1499 size_t payload_length, 1500 uint8_t *completion_code, 1501 uint8_t *synchrony_config, 1502 bitfield8_t *synchrony_config_support, 1503 uint8_t *number_event_class_returned, 1504 uint8_t *event_class, 1505 uint8_t event_class_count) 1506 { 1507 struct pldm_msgbuf _buf; 1508 struct pldm_msgbuf *buf = &_buf; 1509 int i; 1510 int rc; 1511 1512 if (msg == NULL || completion_code == NULL || 1513 synchrony_config == NULL || synchrony_config_support == NULL || 1514 number_event_class_returned == NULL || event_class == NULL) { 1515 return PLDM_ERROR_INVALID_DATA; 1516 } 1517 1518 rc = pldm_msgbuf_init_errno(buf, 1519 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES, 1520 msg->payload, payload_length); 1521 if (rc) { 1522 return pldm_xlate_errno(rc); 1523 } 1524 1525 rc = pldm_msgbuf_extract_p(buf, completion_code); 1526 if (rc) { 1527 return pldm_xlate_errno(rc); 1528 } 1529 1530 if (PLDM_SUCCESS != *completion_code) { 1531 return PLDM_SUCCESS; 1532 } 1533 1534 rc = pldm_msgbuf_extract_p(buf, synchrony_config); 1535 if (rc) { 1536 return pldm_xlate_errno(rc); 1537 } 1538 1539 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) { 1540 return PLDM_ERROR_INVALID_DATA; 1541 } 1542 1543 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte); 1544 1545 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned); 1546 if (rc) { 1547 return pldm_xlate_errno(rc); 1548 } 1549 1550 if (*number_event_class_returned == 0) { 1551 rc = pldm_msgbuf_destroy(buf); 1552 if (rc) { 1553 return pldm_xlate_errno(rc); 1554 } 1555 1556 return PLDM_SUCCESS; 1557 } 1558 1559 if (event_class_count < *number_event_class_returned) { 1560 return PLDM_ERROR_INVALID_LENGTH; 1561 } 1562 1563 for (i = 0; i < *number_event_class_returned; i++) { 1564 pldm_msgbuf_extract(buf, event_class[i]); 1565 } 1566 1567 rc = pldm_msgbuf_destroy_consumed(buf); 1568 if (rc) { 1569 return pldm_xlate_errno(rc); 1570 } 1571 1572 return PLDM_SUCCESS; 1573 } 1574 1575 LIBPLDM_ABI_STABLE 1576 int decode_sensor_event_data(const uint8_t *event_data, 1577 size_t event_data_length, uint16_t *sensor_id, 1578 uint8_t *sensor_event_class_type, 1579 size_t *event_class_data_offset) 1580 { 1581 struct pldm_msgbuf _buf; 1582 struct pldm_msgbuf *buf = &_buf; 1583 int rc; 1584 1585 if (event_data == NULL || sensor_id == NULL || 1586 sensor_event_class_type == NULL || 1587 event_class_data_offset == NULL) { 1588 return PLDM_ERROR_INVALID_DATA; 1589 } 1590 1591 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH, 1592 event_data, event_data_length); 1593 if (rc) { 1594 return pldm_xlate_errno(rc); 1595 } 1596 1597 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) { 1598 return PLDM_ERROR_INVALID_LENGTH; 1599 } 1600 1601 size_t event_class_data_length = 1602 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES; 1603 1604 pldm_msgbuf_extract_p(buf, sensor_id); 1605 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type); 1606 if (rc) { 1607 return pldm_xlate_errno(rc); 1608 } 1609 1610 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) { 1611 if (event_class_data_length != 1612 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) { 1613 return PLDM_ERROR_INVALID_LENGTH; 1614 } 1615 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) { 1616 if (event_class_data_length != 1617 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) { 1618 return PLDM_ERROR_INVALID_LENGTH; 1619 } 1620 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) { 1621 if (event_class_data_length < 1622 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH || 1623 event_class_data_length > 1624 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 1625 return PLDM_ERROR_INVALID_LENGTH; 1626 } 1627 } else { 1628 return PLDM_ERROR_INVALID_DATA; 1629 } 1630 1631 *event_class_data_offset = 1632 sizeof(*sensor_id) + sizeof(*sensor_event_class_type); 1633 1634 rc = pldm_msgbuf_destroy(buf); 1635 if (rc) { 1636 return pldm_xlate_errno(rc); 1637 } 1638 1639 return PLDM_SUCCESS; 1640 } 1641 1642 LIBPLDM_ABI_STABLE 1643 int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length, 1644 uint8_t *present_op_state, uint8_t *previous_op_state) 1645 { 1646 struct pldm_msgbuf _buf; 1647 struct pldm_msgbuf *buf = &_buf; 1648 int rc; 1649 1650 if (sensor_data == NULL || present_op_state == NULL || 1651 previous_op_state == NULL) { 1652 return PLDM_ERROR_INVALID_DATA; 1653 } 1654 1655 rc = pldm_msgbuf_init_errno( 1656 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data, 1657 sensor_data_length); 1658 if (rc) { 1659 return pldm_xlate_errno(rc); 1660 } 1661 1662 pldm_msgbuf_extract_p(buf, present_op_state); 1663 pldm_msgbuf_extract_p(buf, previous_op_state); 1664 1665 rc = pldm_msgbuf_destroy_consumed(buf); 1666 if (rc) { 1667 return pldm_xlate_errno(rc); 1668 } 1669 1670 return PLDM_SUCCESS; 1671 } 1672 1673 LIBPLDM_ABI_STABLE 1674 int decode_state_sensor_data(const uint8_t *sensor_data, 1675 size_t sensor_data_length, uint8_t *sensor_offset, 1676 uint8_t *event_state, 1677 uint8_t *previous_event_state) 1678 { 1679 struct pldm_msgbuf _buf; 1680 struct pldm_msgbuf *buf = &_buf; 1681 int rc; 1682 1683 if (sensor_data == NULL || sensor_offset == NULL || 1684 event_state == NULL || previous_event_state == NULL) { 1685 return PLDM_ERROR_INVALID_DATA; 1686 } 1687 1688 rc = pldm_msgbuf_init_errno( 1689 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH, 1690 sensor_data, sensor_data_length); 1691 if (rc) { 1692 return pldm_xlate_errno(rc); 1693 } 1694 1695 pldm_msgbuf_extract_p(buf, sensor_offset); 1696 pldm_msgbuf_extract_p(buf, event_state); 1697 pldm_msgbuf_extract_p(buf, previous_event_state); 1698 1699 rc = pldm_msgbuf_destroy_consumed(buf); 1700 if (rc) { 1701 return pldm_xlate_errno(rc); 1702 } 1703 1704 return PLDM_SUCCESS; 1705 } 1706 1707 LIBPLDM_ABI_STABLE 1708 int decode_numeric_sensor_data(const uint8_t *sensor_data, 1709 size_t sensor_data_length, uint8_t *event_state, 1710 uint8_t *previous_event_state, 1711 uint8_t *sensor_data_size, 1712 uint32_t *present_reading) 1713 { 1714 struct pldm_msgbuf _buf; 1715 struct pldm_msgbuf *buf = &_buf; 1716 int rc; 1717 1718 if (sensor_data == NULL || sensor_data_size == NULL || 1719 event_state == NULL || previous_event_state == NULL || 1720 present_reading == NULL) { 1721 return PLDM_ERROR_INVALID_DATA; 1722 } 1723 1724 if (sensor_data_length > 1725 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 1726 return PLDM_ERROR_INVALID_LENGTH; 1727 } 1728 1729 rc = pldm_msgbuf_init_errno( 1730 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH, 1731 sensor_data, sensor_data_length); 1732 if (rc) { 1733 return pldm_xlate_errno(rc); 1734 } 1735 1736 pldm_msgbuf_extract_p(buf, event_state); 1737 pldm_msgbuf_extract_p(buf, previous_event_state); 1738 rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 1739 if (rc) { 1740 return pldm_xlate_errno(rc); 1741 } 1742 1743 /* 1744 * The implementation below is bonkers, but it's because the function 1745 * prototype is bonkers. The `present_reading` argument should have been 1746 * a tagged union. 1747 */ 1748 switch (*sensor_data_size) { 1749 case PLDM_SENSOR_DATA_SIZE_UINT8: { 1750 uint8_t val; 1751 if (!pldm_msgbuf_extract(buf, val)) { 1752 *present_reading = (uint32_t)val; 1753 } 1754 break; 1755 } 1756 case PLDM_SENSOR_DATA_SIZE_SINT8: { 1757 int8_t val; 1758 if (!pldm_msgbuf_extract(buf, val)) { 1759 *present_reading = (uint32_t)(int32_t)val; 1760 } 1761 break; 1762 } 1763 case PLDM_SENSOR_DATA_SIZE_UINT16: { 1764 uint16_t val; 1765 if (!pldm_msgbuf_extract(buf, val)) { 1766 *present_reading = (uint32_t)val; 1767 } 1768 break; 1769 } 1770 case PLDM_SENSOR_DATA_SIZE_SINT16: { 1771 int16_t val; 1772 if (!pldm_msgbuf_extract(buf, val)) { 1773 *present_reading = (uint32_t)(int32_t)val; 1774 } 1775 break; 1776 } 1777 case PLDM_SENSOR_DATA_SIZE_UINT32: { 1778 uint32_t val; 1779 if (!pldm_msgbuf_extract(buf, val)) { 1780 *present_reading = (uint32_t)val; 1781 } 1782 break; 1783 } 1784 case PLDM_SENSOR_DATA_SIZE_SINT32: { 1785 int32_t val; 1786 if (!pldm_msgbuf_extract(buf, val)) { 1787 *present_reading = (uint32_t)val; 1788 } 1789 break; 1790 } 1791 default: 1792 return PLDM_ERROR_INVALID_DATA; 1793 } 1794 1795 rc = pldm_msgbuf_destroy_consumed(buf); 1796 if (rc) { 1797 return pldm_xlate_errno(rc); 1798 } 1799 1800 return PLDM_SUCCESS; 1801 } 1802 1803 LIBPLDM_ABI_STABLE 1804 int decode_numeric_sensor_pdr_data( 1805 const void *pdr_data, size_t pdr_data_length, 1806 struct pldm_numeric_sensor_value_pdr *pdr_value) 1807 { 1808 struct pldm_msgbuf _buf; 1809 struct pldm_msgbuf *buf = &_buf; 1810 int rc; 1811 1812 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 1813 pdr_data, pdr_data_length); 1814 if (rc) { 1815 return pldm_xlate_errno(rc); 1816 } 1817 1818 rc = pldm_msgbuf_extract_value_pdr_hdr( 1819 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 1820 pdr_data_length); 1821 if (rc) { 1822 return pldm_xlate_errno(rc); 1823 } 1824 1825 pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 1826 pldm_msgbuf_extract(buf, pdr_value->sensor_id); 1827 pldm_msgbuf_extract(buf, pdr_value->entity_type); 1828 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num); 1829 pldm_msgbuf_extract(buf, pdr_value->container_id); 1830 pldm_msgbuf_extract(buf, pdr_value->sensor_init); 1831 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr); 1832 pldm_msgbuf_extract(buf, pdr_value->base_unit); 1833 pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 1834 pldm_msgbuf_extract(buf, pdr_value->rate_unit); 1835 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 1836 pldm_msgbuf_extract(buf, pdr_value->aux_unit); 1837 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 1838 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 1839 pldm_msgbuf_extract(buf, pdr_value->rel); 1840 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 1841 pldm_msgbuf_extract(buf, pdr_value->is_linear); 1842 1843 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size); 1844 if (rc) { 1845 return pldm_xlate_errno(rc); 1846 } 1847 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 1848 return PLDM_ERROR_INVALID_DATA; 1849 } 1850 1851 pldm_msgbuf_extract(buf, pdr_value->resolution); 1852 pldm_msgbuf_extract(buf, pdr_value->offset); 1853 pldm_msgbuf_extract(buf, pdr_value->accuracy); 1854 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 1855 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 1856 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 1857 &pdr_value->hysteresis); 1858 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte); 1859 pldm_msgbuf_extract( 1860 buf, pdr_value->threshold_and_hysteresis_volatility.byte); 1861 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 1862 pldm_msgbuf_extract(buf, pdr_value->update_interval); 1863 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 1864 &pdr_value->max_readable); 1865 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 1866 &pdr_value->min_readable); 1867 1868 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 1869 if (rc) { 1870 return pldm_xlate_errno(rc); 1871 } 1872 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 1873 return PLDM_ERROR_INVALID_DATA; 1874 } 1875 1876 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 1877 pldm_msgbuf_extract_range_field_format( 1878 buf, pdr_value->range_field_format, pdr_value->nominal_value); 1879 pldm_msgbuf_extract_range_field_format( 1880 buf, pdr_value->range_field_format, pdr_value->normal_max); 1881 pldm_msgbuf_extract_range_field_format( 1882 buf, pdr_value->range_field_format, pdr_value->normal_min); 1883 pldm_msgbuf_extract_range_field_format( 1884 buf, pdr_value->range_field_format, pdr_value->warning_high); 1885 pldm_msgbuf_extract_range_field_format( 1886 buf, pdr_value->range_field_format, pdr_value->warning_low); 1887 pldm_msgbuf_extract_range_field_format( 1888 buf, pdr_value->range_field_format, pdr_value->critical_high); 1889 pldm_msgbuf_extract_range_field_format( 1890 buf, pdr_value->range_field_format, pdr_value->critical_low); 1891 pldm_msgbuf_extract_range_field_format( 1892 buf, pdr_value->range_field_format, pdr_value->fatal_high); 1893 pldm_msgbuf_extract_range_field_format( 1894 buf, pdr_value->range_field_format, pdr_value->fatal_low); 1895 1896 rc = pldm_msgbuf_destroy(buf); 1897 if (rc) { 1898 return pldm_xlate_errno(rc); 1899 } 1900 1901 return PLDM_SUCCESS; 1902 } 1903 1904 LIBPLDM_ABI_STABLE 1905 int encode_get_numeric_effecter_value_req(uint8_t instance_id, 1906 uint16_t effecter_id, 1907 struct pldm_msg *msg) 1908 { 1909 if (msg == NULL) { 1910 return PLDM_ERROR_INVALID_DATA; 1911 } 1912 1913 struct pldm_header_info header = { 0 }; 1914 header.msg_type = PLDM_REQUEST; 1915 header.instance = instance_id; 1916 header.pldm_type = PLDM_PLATFORM; 1917 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 1918 1919 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1920 if (rc != PLDM_SUCCESS) { 1921 return rc; 1922 } 1923 1924 struct pldm_get_numeric_effecter_value_req *request = 1925 (struct pldm_get_numeric_effecter_value_req *)msg->payload; 1926 request->effecter_id = htole16(effecter_id); 1927 1928 return PLDM_SUCCESS; 1929 } 1930 1931 LIBPLDM_ABI_STABLE 1932 int encode_get_numeric_effecter_value_resp( 1933 uint8_t instance_id, uint8_t completion_code, 1934 uint8_t effecter_data_size, uint8_t effecter_oper_state, 1935 const uint8_t *pending_value, const uint8_t *present_value, 1936 struct pldm_msg *msg, size_t payload_length) 1937 { 1938 if (msg == NULL || pending_value == NULL || present_value == NULL) { 1939 return PLDM_ERROR_INVALID_DATA; 1940 } 1941 1942 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 1943 return PLDM_ERROR_INVALID_DATA; 1944 } 1945 1946 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 1947 return PLDM_ERROR_INVALID_DATA; 1948 } 1949 1950 struct pldm_header_info header = { 0 }; 1951 header.msg_type = PLDM_RESPONSE; 1952 header.instance = instance_id; 1953 header.pldm_type = PLDM_PLATFORM; 1954 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 1955 1956 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1957 if (rc != PLDM_SUCCESS) { 1958 return rc; 1959 } 1960 1961 struct pldm_get_numeric_effecter_value_resp *response = 1962 (struct pldm_get_numeric_effecter_value_resp *)msg->payload; 1963 1964 response->completion_code = completion_code; 1965 response->effecter_data_size = effecter_data_size; 1966 response->effecter_oper_state = effecter_oper_state; 1967 1968 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 1969 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 1970 if (payload_length != 1971 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) { 1972 return PLDM_ERROR_INVALID_LENGTH; 1973 } 1974 response->pending_and_present_values[0] = *pending_value; 1975 response->pending_and_present_values[1] = *present_value; 1976 1977 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 1978 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 1979 if (payload_length != 1980 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) { 1981 return PLDM_ERROR_INVALID_LENGTH; 1982 } 1983 uint16_t val_pending = *(uint16_t *)pending_value; 1984 val_pending = htole16(val_pending); 1985 memcpy(response->pending_and_present_values, &val_pending, 1986 sizeof(uint16_t)); 1987 uint16_t val_present = *(uint16_t *)present_value; 1988 val_present = htole16(val_present); 1989 memcpy((response->pending_and_present_values + 1990 sizeof(uint16_t)), 1991 &val_present, sizeof(uint16_t)); 1992 1993 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 1994 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 1995 if (payload_length != 1996 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) { 1997 return PLDM_ERROR_INVALID_LENGTH; 1998 } 1999 uint32_t val_pending = *(uint32_t *)pending_value; 2000 val_pending = htole32(val_pending); 2001 memcpy(response->pending_and_present_values, &val_pending, 2002 sizeof(uint32_t)); 2003 uint32_t val_present = *(uint32_t *)present_value; 2004 val_present = htole32(val_present); 2005 memcpy((response->pending_and_present_values + 2006 sizeof(uint32_t)), 2007 &val_present, sizeof(uint32_t)); 2008 } 2009 return PLDM_SUCCESS; 2010 } 2011 2012 LIBPLDM_ABI_STABLE 2013 int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg, 2014 size_t payload_length, 2015 uint16_t *effecter_id) 2016 { 2017 struct pldm_msgbuf _buf; 2018 struct pldm_msgbuf *buf = &_buf; 2019 int rc; 2020 2021 if (msg == NULL || effecter_id == NULL) { 2022 return PLDM_ERROR_INVALID_DATA; 2023 } 2024 2025 rc = pldm_msgbuf_init_errno(buf, 2026 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES, 2027 msg->payload, payload_length); 2028 if (rc) { 2029 return pldm_xlate_errno(rc); 2030 } 2031 2032 pldm_msgbuf_extract_p(buf, effecter_id); 2033 2034 rc = pldm_msgbuf_destroy_consumed(buf); 2035 if (rc) { 2036 return pldm_xlate_errno(rc); 2037 } 2038 2039 return PLDM_SUCCESS; 2040 } 2041 2042 LIBPLDM_ABI_STABLE 2043 int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg, 2044 size_t payload_length, 2045 uint8_t *completion_code, 2046 uint8_t *effecter_data_size, 2047 uint8_t *effecter_oper_state, 2048 uint8_t *pending_value, 2049 uint8_t *present_value) 2050 { 2051 struct pldm_msgbuf _buf; 2052 struct pldm_msgbuf *buf = &_buf; 2053 int rc; 2054 2055 if (msg == NULL || effecter_data_size == NULL || 2056 effecter_oper_state == NULL || pending_value == NULL || 2057 present_value == NULL) { 2058 return PLDM_ERROR_INVALID_DATA; 2059 } 2060 2061 rc = pldm_msgbuf_init_errno( 2062 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES, 2063 msg->payload, payload_length); 2064 if (rc) { 2065 return pldm_xlate_errno(rc); 2066 } 2067 2068 rc = pldm_msgbuf_extract_p(buf, completion_code); 2069 if (rc) { 2070 return pldm_xlate_errno(rc); 2071 } 2072 2073 if (PLDM_SUCCESS != *completion_code) { 2074 return PLDM_SUCCESS; 2075 } 2076 2077 rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 2078 if (rc) { 2079 return pldm_xlate_errno(rc); 2080 } 2081 2082 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 2083 return PLDM_ERROR_INVALID_DATA; 2084 } 2085 2086 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state); 2087 if (rc) { 2088 return pldm_xlate_errno(rc); 2089 } 2090 2091 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 2092 return PLDM_ERROR_INVALID_DATA; 2093 } 2094 2095 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 2096 pending_value); 2097 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 2098 present_value); 2099 2100 rc = pldm_msgbuf_destroy_consumed(buf); 2101 if (rc) { 2102 return pldm_xlate_errno(rc); 2103 } 2104 2105 return PLDM_SUCCESS; 2106 } 2107 2108 LIBPLDM_ABI_STABLE 2109 int encode_pldm_pdr_repository_chg_event_data( 2110 uint8_t event_data_format, uint8_t number_of_change_records, 2111 const uint8_t *event_data_operations, 2112 const uint8_t *numbers_of_change_entries, 2113 const uint32_t *const *change_entries, 2114 struct pldm_pdr_repository_chg_event_data *event_data, 2115 size_t *actual_change_records_size, size_t max_change_records_size) 2116 { 2117 if (event_data_operations == NULL || 2118 numbers_of_change_entries == NULL || change_entries == NULL) { 2119 return PLDM_ERROR_INVALID_DATA; 2120 } 2121 2122 size_t expected_size = 2123 sizeof(event_data_format) + sizeof(number_of_change_records); 2124 2125 expected_size += 2126 sizeof(*event_data_operations) * number_of_change_records; 2127 expected_size += 2128 sizeof(*numbers_of_change_entries) * number_of_change_records; 2129 2130 for (uint8_t i = 0; i < number_of_change_records; ++i) { 2131 expected_size += sizeof(*change_entries[0]) * 2132 numbers_of_change_entries[i]; 2133 } 2134 2135 *actual_change_records_size = expected_size; 2136 2137 if (event_data == NULL) { 2138 return PLDM_SUCCESS; 2139 } 2140 2141 if (max_change_records_size < expected_size) { 2142 return PLDM_ERROR_INVALID_LENGTH; 2143 } 2144 2145 event_data->event_data_format = event_data_format; 2146 event_data->number_of_change_records = number_of_change_records; 2147 2148 struct pldm_pdr_repository_change_record_data *record_data = 2149 (struct pldm_pdr_repository_change_record_data *) 2150 event_data->change_records; 2151 2152 for (uint8_t i = 0; i < number_of_change_records; ++i) { 2153 record_data->event_data_operation = event_data_operations[i]; 2154 record_data->number_of_change_entries = 2155 numbers_of_change_entries[i]; 2156 2157 for (uint8_t j = 0; j < record_data->number_of_change_entries; 2158 ++j) { 2159 record_data->change_entry[j] = 2160 htole32(change_entries[i][j]); 2161 } 2162 2163 record_data = 2164 (struct pldm_pdr_repository_change_record_data 2165 *)(record_data->change_entry + 2166 record_data->number_of_change_entries); 2167 } 2168 2169 return PLDM_SUCCESS; 2170 } 2171 2172 LIBPLDM_ABI_STABLE 2173 int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data, 2174 size_t event_data_size, 2175 uint8_t *event_data_format, 2176 uint8_t *number_of_change_records, 2177 size_t *change_record_data_offset) 2178 { 2179 struct pldm_msgbuf _buf; 2180 struct pldm_msgbuf *buf = &_buf; 2181 int rc; 2182 2183 if (event_data == NULL || event_data_format == NULL || 2184 number_of_change_records == NULL || 2185 change_record_data_offset == NULL) { 2186 return PLDM_ERROR_INVALID_DATA; 2187 } 2188 2189 rc = pldm_msgbuf_init_errno(buf, 2190 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH, 2191 event_data, event_data_size); 2192 if (rc) { 2193 return pldm_xlate_errno(rc); 2194 } 2195 2196 pldm_msgbuf_extract_p(buf, event_data_format); 2197 pldm_msgbuf_extract_p(buf, number_of_change_records); 2198 2199 *change_record_data_offset = 2200 sizeof(*event_data_format) + sizeof(*number_of_change_records); 2201 2202 rc = pldm_msgbuf_destroy(buf); 2203 if (rc) { 2204 return pldm_xlate_errno(rc); 2205 } 2206 2207 return PLDM_SUCCESS; 2208 } 2209 2210 LIBPLDM_ABI_STABLE 2211 int decode_pldm_message_poll_event_data( 2212 const void *event_data, size_t event_data_length, 2213 struct pldm_message_poll_event *poll_event) 2214 { 2215 struct pldm_msgbuf _buf; 2216 struct pldm_msgbuf *buf = &_buf; 2217 int rc; 2218 2219 if (!event_data || !poll_event) { 2220 return -EINVAL; 2221 } 2222 2223 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 2224 event_data_length); 2225 if (rc) { 2226 return rc; 2227 } 2228 2229 pldm_msgbuf_extract(buf, poll_event->format_version); 2230 rc = pldm_msgbuf_extract(buf, poll_event->event_id); 2231 if (rc) { 2232 return rc; 2233 } 2234 2235 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 2236 return -EPROTO; 2237 } 2238 2239 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle); 2240 2241 return pldm_msgbuf_destroy_consumed(buf); 2242 } 2243 2244 LIBPLDM_ABI_TESTING 2245 int encode_pldm_message_poll_event_data( 2246 const struct pldm_message_poll_event *poll_event, void *event_data, 2247 size_t event_data_length) 2248 { 2249 struct pldm_msgbuf _buf; 2250 struct pldm_msgbuf *buf = &_buf; 2251 int rc; 2252 2253 if (poll_event == NULL || event_data == NULL) { 2254 return -EINVAL; 2255 } 2256 2257 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 2258 return -EPROTO; 2259 } 2260 2261 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 2262 event_data_length); 2263 if (rc) { 2264 return rc; 2265 } 2266 pldm_msgbuf_insert(buf, poll_event->format_version); 2267 pldm_msgbuf_insert(buf, poll_event->event_id); 2268 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle); 2269 2270 return pldm_msgbuf_destroy_consumed(buf); 2271 } 2272 2273 LIBPLDM_ABI_STABLE 2274 int decode_pldm_pdr_repository_change_record_data( 2275 const uint8_t *change_record_data, size_t change_record_data_size, 2276 uint8_t *event_data_operation, uint8_t *number_of_change_entries, 2277 size_t *change_entry_data_offset) 2278 { 2279 struct pldm_msgbuf _buf; 2280 struct pldm_msgbuf *buf = &_buf; 2281 int rc; 2282 2283 if (change_record_data == NULL || event_data_operation == NULL || 2284 number_of_change_entries == NULL || 2285 change_entry_data_offset == NULL) { 2286 return PLDM_ERROR_INVALID_DATA; 2287 } 2288 2289 rc = pldm_msgbuf_init_errno( 2290 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH, 2291 change_record_data, change_record_data_size); 2292 if (rc) { 2293 return pldm_xlate_errno(rc); 2294 } 2295 2296 pldm_msgbuf_extract_p(buf, event_data_operation); 2297 pldm_msgbuf_extract_p(buf, number_of_change_entries); 2298 2299 *change_entry_data_offset = sizeof(*event_data_operation) + 2300 sizeof(*number_of_change_entries); 2301 2302 rc = pldm_msgbuf_destroy(buf); 2303 if (rc) { 2304 return pldm_xlate_errno(rc); 2305 } 2306 2307 return PLDM_SUCCESS; 2308 } 2309 2310 LIBPLDM_ABI_STABLE 2311 int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id, 2312 uint8_t rearm_event_state, 2313 struct pldm_msg *msg) 2314 { 2315 if (msg == NULL) { 2316 return PLDM_ERROR_INVALID_DATA; 2317 } 2318 2319 struct pldm_header_info header = { 0 }; 2320 header.msg_type = PLDM_REQUEST; 2321 header.instance = instance_id; 2322 header.pldm_type = PLDM_PLATFORM; 2323 header.command = PLDM_GET_SENSOR_READING; 2324 2325 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2326 if (rc != PLDM_SUCCESS) { 2327 return rc; 2328 } 2329 2330 struct pldm_get_sensor_reading_req *request = 2331 (struct pldm_get_sensor_reading_req *)msg->payload; 2332 2333 request->sensor_id = htole16(sensor_id); 2334 request->rearm_event_state = rearm_event_state; 2335 2336 return PLDM_SUCCESS; 2337 } 2338 2339 LIBPLDM_ABI_STABLE 2340 int decode_get_sensor_reading_resp( 2341 const struct pldm_msg *msg, size_t payload_length, 2342 uint8_t *completion_code, uint8_t *sensor_data_size, 2343 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable, 2344 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state, 2345 uint8_t *present_reading) 2346 { 2347 struct pldm_msgbuf _buf; 2348 struct pldm_msgbuf *buf = &_buf; 2349 int rc; 2350 2351 if (msg == NULL || completion_code == NULL || 2352 sensor_data_size == NULL || sensor_operational_state == NULL || 2353 sensor_event_message_enable == NULL || present_state == NULL || 2354 previous_state == NULL || event_state == NULL || 2355 present_reading == NULL) { 2356 return PLDM_ERROR_INVALID_DATA; 2357 } 2358 2359 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES, 2360 msg->payload, payload_length); 2361 if (rc) { 2362 return pldm_xlate_errno(rc); 2363 } 2364 2365 rc = pldm_msgbuf_extract_p(buf, completion_code); 2366 if (rc) { 2367 return pldm_xlate_errno(rc); 2368 } 2369 2370 if (PLDM_SUCCESS != *completion_code) { 2371 return PLDM_SUCCESS; 2372 } 2373 2374 rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 2375 if (rc) { 2376 return pldm_xlate_errno(rc); 2377 } 2378 2379 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) { 2380 return PLDM_ERROR_INVALID_DATA; 2381 } 2382 2383 pldm_msgbuf_extract_p(buf, sensor_operational_state); 2384 pldm_msgbuf_extract_p(buf, sensor_event_message_enable); 2385 pldm_msgbuf_extract_p(buf, present_state); 2386 pldm_msgbuf_extract_p(buf, previous_state); 2387 pldm_msgbuf_extract_p(buf, event_state); 2388 2389 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size, 2390 present_reading); 2391 2392 rc = pldm_msgbuf_destroy_consumed(buf); 2393 if (rc) { 2394 return pldm_xlate_errno(rc); 2395 } 2396 2397 return PLDM_SUCCESS; 2398 } 2399 2400 LIBPLDM_ABI_STABLE 2401 int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code, 2402 uint8_t sensor_data_size, 2403 uint8_t sensor_operational_state, 2404 uint8_t sensor_event_message_enable, 2405 uint8_t present_state, 2406 uint8_t previous_state, uint8_t event_state, 2407 const uint8_t *present_reading, 2408 struct pldm_msg *msg, size_t payload_length) 2409 { 2410 if (msg == NULL || present_reading == NULL) { 2411 return PLDM_ERROR_INVALID_DATA; 2412 } 2413 2414 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 2415 return PLDM_ERROR_INVALID_DATA; 2416 } 2417 2418 struct pldm_header_info header = { 0 }; 2419 header.msg_type = PLDM_RESPONSE; 2420 header.instance = instance_id; 2421 header.pldm_type = PLDM_PLATFORM; 2422 header.command = PLDM_GET_SENSOR_READING; 2423 2424 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2425 if (rc != PLDM_SUCCESS) { 2426 return rc; 2427 } 2428 2429 struct pldm_get_sensor_reading_resp *response = 2430 (struct pldm_get_sensor_reading_resp *)msg->payload; 2431 2432 response->completion_code = completion_code; 2433 response->sensor_data_size = sensor_data_size; 2434 response->sensor_operational_state = sensor_operational_state; 2435 response->sensor_event_message_enable = sensor_event_message_enable; 2436 response->present_state = present_state; 2437 response->previous_state = previous_state; 2438 response->event_state = event_state; 2439 2440 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 2441 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 2442 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) { 2443 return PLDM_ERROR_INVALID_LENGTH; 2444 } 2445 response->present_reading[0] = *present_reading; 2446 2447 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 2448 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 2449 if (payload_length != 2450 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) { 2451 return PLDM_ERROR_INVALID_LENGTH; 2452 } 2453 uint16_t val = *(uint16_t *)present_reading; 2454 val = htole16(val); 2455 memcpy(response->present_reading, &val, 2); 2456 2457 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 2458 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 2459 if (payload_length != 2460 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) { 2461 return PLDM_ERROR_INVALID_LENGTH; 2462 } 2463 uint32_t val = *(uint32_t *)present_reading; 2464 val = htole32(val); 2465 memcpy(response->present_reading, &val, 4); 2466 } 2467 2468 return PLDM_SUCCESS; 2469 } 2470 2471 LIBPLDM_ABI_STABLE 2472 int decode_get_sensor_reading_req(const struct pldm_msg *msg, 2473 size_t payload_length, uint16_t *sensor_id, 2474 uint8_t *rearm_event_state) 2475 { 2476 struct pldm_msgbuf _buf; 2477 struct pldm_msgbuf *buf = &_buf; 2478 int rc; 2479 2480 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) { 2481 return PLDM_ERROR_INVALID_DATA; 2482 } 2483 2484 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES, 2485 msg->payload, payload_length); 2486 if (rc) { 2487 return pldm_xlate_errno(rc); 2488 } 2489 2490 pldm_msgbuf_extract_p(buf, sensor_id); 2491 pldm_msgbuf_extract_p(buf, rearm_event_state); 2492 2493 rc = pldm_msgbuf_destroy(buf); 2494 if (rc) { 2495 return pldm_xlate_errno(rc); 2496 } 2497 2498 return PLDM_SUCCESS; 2499 } 2500 2501 LIBPLDM_ABI_STABLE 2502 int encode_set_event_receiver_req(uint8_t instance_id, 2503 uint8_t event_message_global_enable, 2504 uint8_t transport_protocol_type, 2505 uint8_t event_receiver_address_info, 2506 uint16_t heartbeat_timer, 2507 struct pldm_msg *msg) 2508 { 2509 if (msg == NULL) { 2510 return PLDM_ERROR_INVALID_DATA; 2511 } 2512 2513 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) { 2514 return PLDM_ERROR_INVALID_DATA; 2515 } 2516 2517 struct pldm_header_info header = { 0 }; 2518 header.msg_type = PLDM_REQUEST; 2519 header.instance = instance_id; 2520 header.pldm_type = PLDM_PLATFORM; 2521 header.command = PLDM_SET_EVENT_RECEIVER; 2522 2523 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2524 if (rc != PLDM_SUCCESS) { 2525 return rc; 2526 } 2527 2528 struct pldm_set_event_receiver_req *request = 2529 (struct pldm_set_event_receiver_req *)msg->payload; 2530 request->event_message_global_enable = event_message_global_enable; 2531 2532 request->transport_protocol_type = transport_protocol_type; 2533 request->event_receiver_address_info = event_receiver_address_info; 2534 2535 if (event_message_global_enable == 2536 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 2537 if (heartbeat_timer == 0) { 2538 return PLDM_ERROR_INVALID_DATA; 2539 } 2540 request->heartbeat_timer = htole16(heartbeat_timer); 2541 } 2542 2543 return PLDM_SUCCESS; 2544 } 2545 2546 LIBPLDM_ABI_STABLE 2547 int decode_set_event_receiver_resp(const struct pldm_msg *msg, 2548 size_t payload_length, 2549 uint8_t *completion_code) 2550 { 2551 struct pldm_msgbuf _buf; 2552 struct pldm_msgbuf *buf = &_buf; 2553 int rc; 2554 2555 if (msg == NULL || completion_code == NULL) { 2556 return PLDM_ERROR_INVALID_DATA; 2557 } 2558 2559 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES, 2560 msg->payload, payload_length); 2561 if (rc) { 2562 return pldm_xlate_errno(rc); 2563 } 2564 2565 pldm_msgbuf_extract_p(buf, completion_code); 2566 2567 rc = pldm_msgbuf_destroy(buf); 2568 if (rc) { 2569 return pldm_xlate_errno(rc); 2570 } 2571 2572 return PLDM_SUCCESS; 2573 } 2574 2575 LIBPLDM_ABI_STABLE 2576 int decode_set_event_receiver_req(const struct pldm_msg *msg, 2577 size_t payload_length, 2578 uint8_t *event_message_global_enable, 2579 uint8_t *transport_protocol_type, 2580 uint8_t *event_receiver_address_info, 2581 uint16_t *heartbeat_timer) 2582 2583 { 2584 struct pldm_msgbuf _buf; 2585 struct pldm_msgbuf *buf = &_buf; 2586 int rc; 2587 2588 if (msg == NULL || event_message_global_enable == NULL || 2589 transport_protocol_type == NULL || 2590 event_receiver_address_info == NULL || heartbeat_timer == NULL) { 2591 return PLDM_ERROR_INVALID_DATA; 2592 } 2593 2594 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_MIN_REQ_BYTES, 2595 msg->payload, payload_length); 2596 if (rc) { 2597 return pldm_xlate_errno(rc); 2598 } 2599 2600 pldm_msgbuf_extract_p(buf, event_message_global_enable); 2601 if (rc) { 2602 return pldm_xlate_errno(rc); 2603 } 2604 2605 pldm_msgbuf_extract_p(buf, transport_protocol_type); 2606 pldm_msgbuf_extract_p(buf, event_receiver_address_info); 2607 if (*event_message_global_enable == 2608 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 2609 pldm_msgbuf_extract_p(buf, heartbeat_timer); 2610 } 2611 2612 rc = pldm_msgbuf_destroy(buf); 2613 if (rc) { 2614 return pldm_xlate_errno(rc); 2615 } 2616 2617 if ((*event_message_global_enable == 2618 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) && 2619 (*heartbeat_timer == 0)) { 2620 return PLDM_ERROR_INVALID_DATA; 2621 } 2622 2623 return PLDM_SUCCESS; 2624 } 2625 2626 LIBPLDM_ABI_STABLE 2627 int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code, 2628 struct pldm_msg *msg) 2629 2630 { 2631 if (msg == NULL) { 2632 return PLDM_ERROR_INVALID_DATA; 2633 } 2634 2635 struct pldm_header_info header = { 0 }; 2636 header.instance = instance_id; 2637 header.msg_type = PLDM_RESPONSE; 2638 header.pldm_type = PLDM_PLATFORM; 2639 header.command = PLDM_SET_EVENT_RECEIVER; 2640 2641 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2642 if (rc != PLDM_SUCCESS) { 2643 return rc; 2644 } 2645 2646 msg->payload[0] = completion_code; 2647 2648 return PLDM_SUCCESS; 2649 } 2650 2651 LIBPLDM_ABI_STABLE 2652 int encode_poll_for_platform_event_message_req(uint8_t instance_id, 2653 uint8_t format_version, 2654 uint8_t transfer_operation_flag, 2655 uint32_t data_transfer_handle, 2656 uint16_t event_id_to_acknowledge, 2657 struct pldm_msg *msg, 2658 size_t payload_length) 2659 { 2660 struct pldm_msgbuf _buf; 2661 struct pldm_msgbuf *buf = &_buf; 2662 int rc; 2663 2664 if (msg == NULL) { 2665 return PLDM_ERROR_INVALID_DATA; 2666 } 2667 2668 rc = pldm_platform_poll_for_platform_event_message_validate( 2669 transfer_operation_flag, event_id_to_acknowledge); 2670 if (rc < 0) { 2671 return PLDM_ERROR_INVALID_DATA; 2672 } 2673 2674 struct pldm_header_info header = { 0 }; 2675 header.msg_type = PLDM_REQUEST; 2676 header.instance = instance_id; 2677 header.pldm_type = PLDM_PLATFORM; 2678 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 2679 2680 rc = pack_pldm_header(&header, &(msg->hdr)); 2681 if (rc != PLDM_SUCCESS) { 2682 return rc; 2683 } 2684 2685 rc = pldm_msgbuf_init_errno( 2686 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 2687 msg->payload, payload_length); 2688 if (rc) { 2689 return pldm_xlate_errno(rc); 2690 } 2691 2692 pldm_msgbuf_insert(buf, format_version); 2693 pldm_msgbuf_insert(buf, transfer_operation_flag); 2694 pldm_msgbuf_insert(buf, data_transfer_handle); 2695 pldm_msgbuf_insert(buf, event_id_to_acknowledge); 2696 2697 rc = pldm_msgbuf_destroy(buf); 2698 if (rc) { 2699 return pldm_xlate_errno(rc); 2700 } 2701 2702 return PLDM_SUCCESS; 2703 } 2704 2705 LIBPLDM_ABI_STABLE 2706 int decode_poll_for_platform_event_message_resp( 2707 const struct pldm_msg *msg, size_t payload_length, 2708 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id, 2709 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 2710 uint8_t *event_class, uint32_t *event_data_size, void **event_data, 2711 uint32_t *event_data_integrity_checksum) 2712 { 2713 struct pldm_msgbuf _buf; 2714 struct pldm_msgbuf *buf = &_buf; 2715 int rc; 2716 2717 if (msg == NULL || completion_code == NULL || tid == NULL || 2718 event_id == NULL || next_data_transfer_handle == NULL || 2719 transfer_flag == NULL || event_class == NULL || 2720 event_data_size == NULL || event_data == NULL || 2721 event_data_integrity_checksum == NULL) { 2722 return PLDM_ERROR_INVALID_DATA; 2723 } 2724 2725 rc = pldm_msgbuf_init_errno( 2726 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 2727 msg->payload, payload_length); 2728 if (rc) { 2729 return pldm_xlate_errno(rc); 2730 } 2731 2732 rc = pldm_msgbuf_extract_p(buf, completion_code); 2733 if (rc) { 2734 return pldm_xlate_errno(rc); 2735 } 2736 if (PLDM_SUCCESS != *completion_code) { 2737 return *completion_code; 2738 } 2739 2740 pldm_msgbuf_extract_p(buf, tid); 2741 rc = pldm_msgbuf_extract_p(buf, event_id); 2742 if (rc) { 2743 return pldm_xlate_errno(rc); 2744 } 2745 if ((*event_id == 0) || (*event_id == 0xffff)) { 2746 return PLDM_SUCCESS; 2747 } 2748 2749 pldm_msgbuf_extract_p(buf, next_data_transfer_handle); 2750 rc = pldm_msgbuf_extract_p(buf, transfer_flag); 2751 if (rc) { 2752 return pldm_xlate_errno(rc); 2753 } 2754 2755 pldm_msgbuf_extract_p(buf, event_class); 2756 rc = pldm_msgbuf_extract_p(buf, event_data_size); 2757 if (rc) { 2758 return pldm_xlate_errno(rc); 2759 } 2760 if (*event_data_size > payload_length) { 2761 return PLDM_ERROR_INVALID_DATA; 2762 } 2763 2764 if (*event_data_size > 0) { 2765 pldm_msgbuf_span_required(buf, *event_data_size, event_data); 2766 } 2767 2768 if (*transfer_flag == PLDM_END || 2769 *transfer_flag == PLDM_START_AND_END) { 2770 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum); 2771 } 2772 2773 rc = pldm_msgbuf_destroy_consumed(buf); 2774 if (rc) { 2775 return pldm_xlate_errno(rc); 2776 } 2777 2778 return PLDM_SUCCESS; 2779 } 2780 2781 LIBPLDM_ABI_TESTING 2782 int decode_numeric_effecter_pdr_data( 2783 const void *pdr_data, size_t pdr_data_length, 2784 struct pldm_numeric_effecter_value_pdr *pdr_value) 2785 { 2786 struct pldm_msgbuf _buf; 2787 struct pldm_msgbuf *buf = &_buf; 2788 struct pldm_value_pdr_hdr hdr; 2789 int rc; 2790 2791 if (!pdr_data || !pdr_value) { 2792 return PLDM_ERROR_INVALID_DATA; 2793 } 2794 2795 rc = pldm_msgbuf_init_errno(buf, 2796 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 2797 pdr_data, pdr_data_length); 2798 if (rc) { 2799 return pldm_xlate_errno(rc); 2800 } 2801 2802 rc = pldm_msgbuf_extract_value_pdr_hdr( 2803 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 2804 pdr_data_length); 2805 if (rc) { 2806 return pldm_xlate_errno(rc); 2807 } 2808 2809 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr)); 2810 2811 pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 2812 pldm_msgbuf_extract(buf, pdr_value->effecter_id); 2813 pldm_msgbuf_extract(buf, pdr_value->entity_type); 2814 pldm_msgbuf_extract(buf, pdr_value->entity_instance); 2815 pldm_msgbuf_extract(buf, pdr_value->container_id); 2816 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id); 2817 pldm_msgbuf_extract(buf, pdr_value->effecter_init); 2818 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names); 2819 pldm_msgbuf_extract(buf, pdr_value->base_unit); 2820 pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 2821 pldm_msgbuf_extract(buf, pdr_value->rate_unit); 2822 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 2823 pldm_msgbuf_extract(buf, pdr_value->aux_unit); 2824 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 2825 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 2826 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 2827 pldm_msgbuf_extract(buf, pdr_value->is_linear); 2828 2829 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size); 2830 if (rc) { 2831 return pldm_xlate_errno(rc); 2832 } 2833 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 2834 return PLDM_ERROR_INVALID_DATA; 2835 } 2836 2837 pldm_msgbuf_extract(buf, pdr_value->resolution); 2838 pldm_msgbuf_extract(buf, pdr_value->offset); 2839 pldm_msgbuf_extract(buf, pdr_value->accuracy); 2840 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 2841 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 2842 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 2843 pldm_msgbuf_extract(buf, pdr_value->transition_interval); 2844 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 2845 pdr_value->max_settable); 2846 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 2847 pdr_value->min_settable); 2848 2849 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 2850 if (rc) { 2851 return pldm_xlate_errno(rc); 2852 } 2853 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 2854 return PLDM_ERROR_INVALID_DATA; 2855 } 2856 2857 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 2858 pldm_msgbuf_extract_range_field_format( 2859 buf, pdr_value->range_field_format, pdr_value->nominal_value); 2860 pldm_msgbuf_extract_range_field_format( 2861 buf, pdr_value->range_field_format, pdr_value->normal_max); 2862 pldm_msgbuf_extract_range_field_format( 2863 buf, pdr_value->range_field_format, pdr_value->normal_min); 2864 pldm_msgbuf_extract_range_field_format( 2865 buf, pdr_value->range_field_format, pdr_value->rated_max); 2866 pldm_msgbuf_extract_range_field_format( 2867 buf, pdr_value->range_field_format, pdr_value->rated_min); 2868 2869 rc = pldm_msgbuf_destroy_consumed(buf); 2870 if (rc) { 2871 return pldm_xlate_errno(rc); 2872 } 2873 2874 return PLDM_SUCCESS; 2875 } 2876 2877 LIBPLDM_ABI_STABLE 2878 int encode_get_state_effecter_states_req(uint8_t instance_id, 2879 uint16_t effecter_id, 2880 struct pldm_msg *msg, 2881 size_t payload_length) 2882 { 2883 struct pldm_msgbuf _buf; 2884 struct pldm_msgbuf *buf = &_buf; 2885 int rc; 2886 2887 if (msg == NULL) { 2888 return -EINVAL; 2889 } 2890 2891 struct pldm_header_info header = { 0 }; 2892 header.msg_type = PLDM_REQUEST; 2893 header.instance = instance_id; 2894 header.pldm_type = PLDM_PLATFORM; 2895 header.command = PLDM_GET_STATE_EFFECTER_STATES; 2896 2897 rc = pack_pldm_header_errno(&header, &msg->hdr); 2898 if (rc < 0) { 2899 return rc; 2900 } 2901 2902 rc = pldm_msgbuf_init_errno(buf, 2903 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES, 2904 msg->payload, payload_length); 2905 if (rc) { 2906 return rc; 2907 } 2908 2909 pldm_msgbuf_insert(buf, effecter_id); 2910 2911 return pldm_msgbuf_destroy_consumed(buf); 2912 } 2913 2914 LIBPLDM_ABI_STABLE 2915 int decode_get_state_effecter_states_req(const struct pldm_msg *msg, 2916 size_t payload_length, 2917 uint16_t *effecter_id) 2918 { 2919 struct pldm_msgbuf _buf; 2920 struct pldm_msgbuf *buf = &_buf; 2921 int rc; 2922 2923 if (msg == NULL || effecter_id == NULL) { 2924 return -EINVAL; 2925 } 2926 2927 rc = pldm_msgbuf_init_errno( 2928 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2929 msg->payload, payload_length); 2930 if (rc) { 2931 return rc; 2932 } 2933 2934 pldm_msgbuf_extract_p(buf, effecter_id); 2935 2936 return pldm_msgbuf_destroy_consumed(buf); 2937 } 2938 2939 LIBPLDM_ABI_STABLE 2940 int decode_get_state_effecter_states_resp( 2941 const struct pldm_msg *msg, size_t payload_length, 2942 struct pldm_get_state_effecter_states_resp *resp) 2943 { 2944 struct pldm_msgbuf _buf; 2945 struct pldm_msgbuf *buf = &_buf; 2946 get_effecter_state_field *field; 2947 int rc; 2948 int i; 2949 2950 if (msg == NULL || resp == NULL) { 2951 return -EINVAL; 2952 } 2953 2954 rc = pldm_msgbuf_init_errno( 2955 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2956 msg->payload, payload_length); 2957 if (rc) { 2958 return rc; 2959 } 2960 2961 rc = pldm_msgbuf_extract(buf, resp->completion_code); 2962 if (rc) { 2963 return rc; 2964 } 2965 2966 if (PLDM_SUCCESS != resp->completion_code) { 2967 return 0; 2968 } 2969 2970 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count); 2971 if (rc) { 2972 return rc; 2973 } 2974 2975 uint8_t comp_effecter_count = resp->comp_effecter_count; 2976 2977 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 2978 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2979 return -EBADMSG; 2980 } 2981 2982 for (i = 0, field = resp->field; i < comp_effecter_count; 2983 i++, field++) { 2984 pldm_msgbuf_extract(buf, field->effecter_op_state); 2985 pldm_msgbuf_extract(buf, field->pending_state); 2986 pldm_msgbuf_extract(buf, field->present_state); 2987 } 2988 2989 return pldm_msgbuf_destroy_consumed(buf); 2990 } 2991 2992 LIBPLDM_ABI_STABLE 2993 int encode_get_state_effecter_states_resp( 2994 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp, 2995 struct pldm_msg *msg, size_t payload_length) 2996 { 2997 struct pldm_msgbuf _buf; 2998 struct pldm_msgbuf *buf = &_buf; 2999 get_effecter_state_field *field; 3000 int rc; 3001 int i; 3002 3003 if (msg == NULL || resp == NULL) { 3004 return -EINVAL; 3005 } 3006 3007 uint8_t comp_effecter_count = resp->comp_effecter_count; 3008 3009 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 3010 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 3011 return -EBADMSG; 3012 } 3013 3014 struct pldm_header_info header = { 0 }; 3015 header.msg_type = PLDM_RESPONSE; 3016 header.instance = instance_id; 3017 header.pldm_type = PLDM_PLATFORM; 3018 header.command = PLDM_GET_STATE_EFFECTER_STATES; 3019 3020 rc = pack_pldm_header_errno(&header, &msg->hdr); 3021 if (rc < 0) { 3022 return rc; 3023 } 3024 3025 rc = pldm_msgbuf_init_errno( 3026 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 3027 msg->payload, payload_length); 3028 if (rc) { 3029 return rc; 3030 } 3031 3032 pldm_msgbuf_insert(buf, resp->completion_code); 3033 pldm_msgbuf_insert(buf, comp_effecter_count); 3034 3035 for (i = 0, field = resp->field; i < comp_effecter_count; 3036 i++, field++) { 3037 pldm_msgbuf_insert(buf, field->effecter_op_state); 3038 pldm_msgbuf_insert(buf, field->pending_state); 3039 pldm_msgbuf_insert(buf, field->present_state); 3040 } 3041 3042 return pldm_msgbuf_destroy_consumed(buf); 3043 } 3044 3045 LIBPLDM_ABI_STABLE 3046 int decode_entity_auxiliary_names_pdr( 3047 const void *data, size_t data_length, 3048 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length) 3049 { 3050 struct pldm_msgbuf _buf; 3051 struct pldm_msgbuf *buf = &_buf; 3052 struct pldm_msgbuf _src; 3053 struct pldm_msgbuf *src = &_src; 3054 struct pldm_msgbuf _dst; 3055 struct pldm_msgbuf *dst = &_dst; 3056 size_t names_len = 0; 3057 void *names = NULL; 3058 int rc; 3059 int i; 3060 3061 if (!data || !pdr) { 3062 return -EINVAL; 3063 } 3064 3065 /* 3066 * Alignment of auxiliary_name_data is an invariant as we statically assert 3067 * its behaviour in the header. 3068 */ 3069 assert(!((uintptr_t)pdr->auxiliary_name_data & 3070 (alignof(pldm_utf16be) - 1))); 3071 3072 /* Reject any lengths that are obviously invalid */ 3073 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) { 3074 return -EINVAL; 3075 } 3076 3077 rc = pldm_msgbuf_init_errno( 3078 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data, 3079 data_length); 3080 if (rc) { 3081 return rc; 3082 } 3083 3084 rc = pldm_msgbuf_extract_value_pdr_hdr( 3085 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, 3086 data_length); 3087 if (rc) { 3088 return rc; 3089 } 3090 3091 pldm_msgbuf_extract(buf, pdr->container.entity_type); 3092 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num); 3093 pldm_msgbuf_extract(buf, pdr->container.entity_container_id); 3094 pldm_msgbuf_extract(buf, pdr->shared_name_count); 3095 rc = pldm_msgbuf_extract(buf, pdr->name_string_count); 3096 if (rc < 0) { 3097 return rc; 3098 } 3099 3100 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len); 3101 if (rc < 0) { 3102 return rc; 3103 } 3104 assert(names); 3105 3106 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr); 3107 3108 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size, 3109 pdr->auxiliary_name_data, 3110 pdr->auxiliary_name_data_size); 3111 if (rc < 0) { 3112 return rc; 3113 } 3114 3115 /* 3116 * Below we do two passes over the same region. This is to first pack the 3117 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings, 3118 * to maintain appropriate alignment. 3119 */ 3120 3121 /* Initialise for the first pass to extract the UTF16-BE name strings */ 3122 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 3123 if (rc < 0) { 3124 return rc; 3125 } 3126 3127 for (i = 0; i < pdr->name_string_count; i++) { 3128 pldm_msgbuf_span_string_ascii(src, NULL, NULL); 3129 rc = pldm_msgbuf_copy_string_utf16(dst, src); 3130 if (rc) { 3131 return rc; 3132 } 3133 } 3134 3135 rc = pldm_msgbuf_destroy_consumed(src); 3136 if (rc < 0) { 3137 return rc; 3138 } 3139 3140 /* Reinitialise for the second pass to extract the ASCII tag strings */ 3141 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 3142 if (rc < 0) { 3143 return rc; 3144 } 3145 3146 for (i = 0; i < pdr->name_string_count; i++) { 3147 rc = pldm_msgbuf_copy_string_ascii(dst, src); 3148 if (rc) { 3149 return rc; 3150 } 3151 pldm_msgbuf_span_string_utf16(src, NULL, NULL); 3152 } 3153 3154 if ((rc = pldm_msgbuf_destroy(dst)) || 3155 (rc = pldm_msgbuf_destroy(src)) || 3156 (rc = pldm_msgbuf_destroy(buf))) { 3157 return rc; 3158 } 3159 3160 return 0; 3161 } 3162 3163 LIBPLDM_ABI_STABLE 3164 int decode_pldm_entity_auxiliary_names_pdr_index( 3165 struct pldm_entity_auxiliary_names_pdr *pdr) 3166 { 3167 struct pldm_msgbuf _buf; 3168 struct pldm_msgbuf *buf = &_buf; 3169 int rc; 3170 int i; 3171 3172 if (!pdr) { 3173 return -EINVAL; 3174 } 3175 3176 if (pdr->name_string_count == 0 && pdr->names) { 3177 return -EINVAL; 3178 } 3179 3180 if (pdr->name_string_count > 0 && !pdr->names) { 3181 return -EINVAL; 3182 } 3183 3184 if (pdr->name_string_count == 0) { 3185 return 0; 3186 } 3187 3188 /* 3189 * Minimum size is one NUL for each member of each entry 3190 * 3191 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2 3192 * states the following: 3193 * 3194 * > A null-terminated ISO646 ASCII string ... 3195 * > 3196 * > special value: null string = 0x0000 = unspecified. 3197 * 3198 * Until proven otherwise we will assume the "0x0000" is a 3199 * misrepresentation of an ASCII NUL, and that ASCII NUL is 3200 * represented by a single byte. 3201 */ 3202 rc = pldm_msgbuf_init_errno( 3203 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)), 3204 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size); 3205 if (rc) { 3206 return rc; 3207 } 3208 3209 for (i = 0; i < pdr->name_string_count; i++) { 3210 void *loc = NULL; 3211 pldm_msgbuf_span_string_utf16(buf, &loc, NULL); 3212 pdr->names[i].name = loc; 3213 } 3214 3215 for (i = 0; i < pdr->name_string_count; i++) { 3216 void *loc = NULL; 3217 pldm_msgbuf_span_string_ascii(buf, &loc, NULL); 3218 pdr->names[i].tag = loc; 3219 } 3220 3221 return pldm_msgbuf_destroy_consumed(buf); 3222 } 3223 3224 LIBPLDM_ABI_STABLE 3225 int decode_pldm_platform_cper_event(const void *event_data, 3226 size_t event_data_length, 3227 struct pldm_platform_cper_event *cper_event, 3228 size_t cper_event_length) 3229 { 3230 struct pldm_msgbuf _buf; 3231 struct pldm_msgbuf *buf = &_buf; 3232 int rc; 3233 3234 if (!cper_event || !event_data) { 3235 return -EINVAL; 3236 } 3237 3238 if (cper_event_length < sizeof(*cper_event)) { 3239 return -EINVAL; 3240 } 3241 3242 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH, 3243 event_data, event_data_length); 3244 if (rc) { 3245 return rc; 3246 } 3247 3248 pldm_msgbuf_extract(buf, cper_event->format_version); 3249 rc = pldm_msgbuf_extract(buf, cper_event->format_type); 3250 if (rc) { 3251 return rc; 3252 } 3253 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER && 3254 cper_event->format_type != 3255 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) { 3256 return -EPROTO; 3257 } 3258 3259 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length); 3260 if (rc) { 3261 return rc; 3262 } 3263 3264 if (cper_event->event_data_length > 3265 (cper_event_length - sizeof(*cper_event))) { 3266 return -EOVERFLOW; 3267 } 3268 3269 rc = pldm_msgbuf_extract_array_uint8( 3270 buf, cper_event->event_data_length, cper_event->event_data, 3271 cper_event_length - sizeof(*cper_event)); 3272 if (rc) { 3273 return rc; 3274 } 3275 3276 return pldm_msgbuf_destroy_consumed(buf); 3277 } 3278 3279 LIBPLDM_ABI_STABLE 3280 uint8_t * 3281 pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event) 3282 { 3283 return event->event_data; 3284 } 3285