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