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