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