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 static int pldm_platform_poll_for_platform_event_message_validate( 1050 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge) 1051 { 1052 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) && 1053 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) || 1054 ((transfer_operation_flag == PLDM_GET_NEXTPART) && 1055 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1056 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 1057 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1058 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 1059 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) || 1060 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) { 1061 return -EPROTO; 1062 } 1063 1064 return 0; 1065 } 1066 1067 LIBPLDM_ABI_STABLE 1068 int decode_poll_for_platform_event_message_req( 1069 const struct pldm_msg *msg, size_t payload_length, 1070 uint8_t *format_version, uint8_t *transfer_operation_flag, 1071 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge) 1072 { 1073 struct pldm_msgbuf _buf; 1074 struct pldm_msgbuf *buf = &_buf; 1075 int rc; 1076 1077 if (msg == NULL || format_version == NULL || 1078 transfer_operation_flag == NULL || data_transfer_handle == NULL || 1079 event_id_to_acknowledge == NULL) { 1080 return PLDM_ERROR_INVALID_DATA; 1081 } 1082 1083 rc = pldm_msgbuf_init_cc(buf, 1084 PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, 1085 msg->payload, payload_length); 1086 if (rc) { 1087 return rc; 1088 } 1089 1090 pldm_msgbuf_extract_p(buf, format_version); 1091 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag); 1092 if (rc) { 1093 return rc; 1094 } 1095 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) { 1096 return PLDM_ERROR_INVALID_DATA; 1097 } 1098 1099 pldm_msgbuf_extract_p(buf, data_transfer_handle); 1100 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge); 1101 if (rc) { 1102 return rc; 1103 } 1104 1105 rc = pldm_platform_poll_for_platform_event_message_validate( 1106 *transfer_operation_flag, *event_id_to_acknowledge); 1107 if (rc < 0) { 1108 return PLDM_ERROR_INVALID_DATA; 1109 } 1110 1111 return pldm_msgbuf_destroy(buf); 1112 } 1113 1114 LIBPLDM_ABI_STABLE 1115 int encode_platform_event_message_resp(uint8_t instance_id, 1116 uint8_t completion_code, 1117 uint8_t platform_event_status, 1118 struct pldm_msg *msg) 1119 { 1120 if (msg == NULL) { 1121 return PLDM_ERROR_INVALID_DATA; 1122 } 1123 1124 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 1125 return PLDM_ERROR_INVALID_DATA; 1126 } 1127 1128 struct pldm_header_info header = { 0 }; 1129 header.msg_type = PLDM_RESPONSE; 1130 header.instance = instance_id; 1131 header.pldm_type = PLDM_PLATFORM; 1132 header.command = PLDM_PLATFORM_EVENT_MESSAGE; 1133 1134 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1135 if (rc != PLDM_SUCCESS) { 1136 return rc; 1137 } 1138 1139 struct pldm_platform_event_message_resp *response = 1140 (struct pldm_platform_event_message_resp *)msg->payload; 1141 response->completion_code = completion_code; 1142 response->platform_event_status = platform_event_status; 1143 1144 return PLDM_SUCCESS; 1145 } 1146 1147 LIBPLDM_ABI_STABLE 1148 int encode_poll_for_platform_event_message_resp( 1149 uint8_t instance_id, uint8_t completion_code, uint8_t tid, 1150 uint16_t event_id, uint32_t next_data_transfer_handle, 1151 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size, 1152 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg, 1153 size_t payload_length) 1154 { 1155 struct pldm_msgbuf _buf; 1156 struct pldm_msgbuf *buf = &_buf; 1157 int rc; 1158 1159 if (!msg) { 1160 return PLDM_ERROR_INVALID_DATA; 1161 } 1162 1163 struct pldm_header_info header = { 0 }; 1164 header.msg_type = PLDM_RESPONSE; 1165 header.instance = instance_id; 1166 header.pldm_type = PLDM_PLATFORM; 1167 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 1168 1169 rc = pack_pldm_header(&header, &(msg->hdr)); 1170 if (rc != PLDM_SUCCESS) { 1171 return rc; 1172 } 1173 1174 rc = pldm_msgbuf_init_cc( 1175 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 1176 msg->payload, payload_length); 1177 if (rc) { 1178 return rc; 1179 } 1180 1181 pldm_msgbuf_insert(buf, completion_code); 1182 pldm_msgbuf_insert(buf, tid); 1183 pldm_msgbuf_insert(buf, event_id); 1184 1185 if (event_id == 0xffff || event_id == 0x0000) { 1186 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES != 1187 payload_length) { 1188 return PLDM_ERROR_INVALID_LENGTH; 1189 } 1190 return pldm_msgbuf_destroy(buf); 1191 } 1192 1193 if ((event_data == NULL) && (event_data_size > 0)) { 1194 return PLDM_ERROR_INVALID_DATA; 1195 } 1196 1197 pldm_msgbuf_insert(buf, next_data_transfer_handle); 1198 pldm_msgbuf_insert(buf, transfer_flag); 1199 pldm_msgbuf_insert(buf, event_class); 1200 pldm_msgbuf_insert(buf, event_data_size); 1201 1202 if ((event_data_size > 0) && event_data) { 1203 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data, 1204 event_data_size); 1205 if (rc) { 1206 return rc; 1207 } 1208 } 1209 1210 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) { 1211 pldm_msgbuf_insert(buf, checksum); 1212 } 1213 1214 return pldm_msgbuf_destroy(buf); 1215 } 1216 1217 LIBPLDM_ABI_STABLE 1218 int encode_platform_event_message_req( 1219 uint8_t instance_id, uint8_t format_version, uint8_t tid, 1220 uint8_t event_class, const uint8_t *event_data, 1221 size_t event_data_length, struct pldm_msg *msg, size_t payload_length) 1222 1223 { 1224 if (format_version != 1) { 1225 return PLDM_ERROR_INVALID_DATA; 1226 } 1227 1228 if (msg == NULL || event_data == NULL) { 1229 return PLDM_ERROR_INVALID_DATA; 1230 } 1231 1232 if (event_data_length == 0) { 1233 return PLDM_ERROR_INVALID_DATA; 1234 } 1235 1236 if (payload_length != 1237 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) { 1238 return PLDM_ERROR_INVALID_LENGTH; 1239 } 1240 1241 if (event_class > PLDM_CPER_EVENT && 1242 !(event_class >= 0xf0 && event_class <= 0xfe)) { 1243 return PLDM_ERROR_INVALID_DATA; 1244 } 1245 1246 struct pldm_header_info header = { 0 }; 1247 header.msg_type = PLDM_REQUEST; 1248 header.instance = instance_id; 1249 header.pldm_type = PLDM_PLATFORM; 1250 header.command = PLDM_PLATFORM_EVENT_MESSAGE; 1251 1252 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1253 if (rc != PLDM_SUCCESS) { 1254 return rc; 1255 } 1256 1257 struct pldm_platform_event_message_req *request = 1258 (struct pldm_platform_event_message_req *)msg->payload; 1259 request->format_version = format_version; 1260 request->tid = tid; 1261 request->event_class = event_class; 1262 memcpy(request->event_data, event_data, event_data_length); 1263 1264 return PLDM_SUCCESS; 1265 } 1266 1267 LIBPLDM_ABI_STABLE 1268 int decode_platform_event_message_resp(const struct pldm_msg *msg, 1269 size_t payload_length, 1270 uint8_t *completion_code, 1271 uint8_t *platform_event_status) 1272 { 1273 struct pldm_msgbuf _buf; 1274 struct pldm_msgbuf *buf = &_buf; 1275 int rc; 1276 1277 if (msg == NULL || completion_code == NULL || 1278 platform_event_status == NULL) { 1279 return PLDM_ERROR_INVALID_DATA; 1280 } 1281 1282 rc = pldm_msgbuf_init_cc(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 1283 msg->payload, payload_length); 1284 if (rc) { 1285 return rc; 1286 } 1287 1288 rc = pldm_msgbuf_extract_p(buf, completion_code); 1289 if (rc) { 1290 return rc; 1291 } 1292 1293 if (PLDM_SUCCESS != *completion_code) { 1294 return PLDM_SUCCESS; 1295 } 1296 1297 rc = pldm_msgbuf_extract_p(buf, platform_event_status); 1298 if (rc) { 1299 return rc; 1300 } 1301 1302 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 1303 return PLDM_ERROR_INVALID_DATA; 1304 } 1305 1306 return pldm_msgbuf_destroy(buf); 1307 } 1308 1309 LIBPLDM_ABI_STABLE 1310 int encode_event_message_buffer_size_req(uint8_t instance_id, 1311 uint16_t event_receiver_max_buffer_size, 1312 struct pldm_msg *msg) 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_EVENT_MESSAGE_BUFFER_SIZE; 1319 1320 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1321 if (rc != PLDM_SUCCESS) { 1322 return rc; 1323 } 1324 1325 struct pldm_event_message_buffer_size_req *request = 1326 (struct pldm_event_message_buffer_size_req *)msg->payload; 1327 request->event_receiver_max_buffer_size = 1328 event_receiver_max_buffer_size; 1329 1330 return PLDM_SUCCESS; 1331 } 1332 1333 LIBPLDM_ABI_STABLE 1334 int decode_event_message_buffer_size_resp(const struct pldm_msg *msg, 1335 size_t payload_length, 1336 uint8_t *completion_code, 1337 uint16_t *terminus_max_buffer_size) 1338 { 1339 struct pldm_msgbuf _buf; 1340 struct pldm_msgbuf *buf = &_buf; 1341 int rc; 1342 1343 if (msg == NULL || completion_code == NULL || 1344 terminus_max_buffer_size == NULL) { 1345 return PLDM_ERROR_INVALID_DATA; 1346 } 1347 1348 rc = pldm_msgbuf_init_cc(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES, 1349 msg->payload, payload_length); 1350 if (rc) { 1351 return rc; 1352 } 1353 1354 rc = pldm_msgbuf_extract_p(buf, completion_code); 1355 if (rc) { 1356 return rc; 1357 } 1358 1359 if (PLDM_SUCCESS != *completion_code) { 1360 return PLDM_SUCCESS; 1361 } 1362 1363 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size); 1364 1365 return pldm_msgbuf_destroy_consumed(buf); 1366 } 1367 1368 LIBPLDM_ABI_STABLE 1369 int encode_event_message_supported_req(uint8_t instance_id, 1370 uint8_t format_version, 1371 struct pldm_msg *msg) 1372 { 1373 if (format_version != 1) { 1374 return PLDM_ERROR_INVALID_DATA; 1375 } 1376 1377 if (msg == NULL) { 1378 return PLDM_ERROR_INVALID_DATA; 1379 } 1380 1381 struct pldm_header_info header = { 0 }; 1382 header.msg_type = PLDM_REQUEST; 1383 header.instance = instance_id; 1384 header.pldm_type = PLDM_PLATFORM; 1385 header.command = PLDM_EVENT_MESSAGE_SUPPORTED; 1386 1387 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1388 if (rc != PLDM_SUCCESS) { 1389 return rc; 1390 } 1391 1392 struct pldm_event_message_supported_req *request = 1393 (struct pldm_event_message_supported_req *)msg->payload; 1394 request->format_version = format_version; 1395 1396 return PLDM_SUCCESS; 1397 } 1398 1399 LIBPLDM_ABI_STABLE 1400 int decode_event_message_supported_resp(const struct pldm_msg *msg, 1401 size_t payload_length, 1402 uint8_t *completion_code, 1403 uint8_t *synchrony_config, 1404 bitfield8_t *synchrony_config_support, 1405 uint8_t *number_event_class_returned, 1406 uint8_t *event_class, 1407 uint8_t event_class_count) 1408 { 1409 struct pldm_msgbuf _buf; 1410 struct pldm_msgbuf *buf = &_buf; 1411 int i; 1412 int rc; 1413 1414 if (msg == NULL || completion_code == NULL || 1415 synchrony_config == NULL || synchrony_config_support == NULL || 1416 number_event_class_returned == NULL || event_class == NULL) { 1417 return PLDM_ERROR_INVALID_DATA; 1418 } 1419 1420 rc = pldm_msgbuf_init_cc(buf, 1421 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES, 1422 msg->payload, payload_length); 1423 if (rc) { 1424 return rc; 1425 } 1426 1427 rc = pldm_msgbuf_extract_p(buf, completion_code); 1428 if (rc) { 1429 return rc; 1430 } 1431 1432 if (PLDM_SUCCESS != *completion_code) { 1433 return PLDM_SUCCESS; 1434 } 1435 1436 rc = pldm_msgbuf_extract_p(buf, synchrony_config); 1437 if (rc) { 1438 return rc; 1439 } 1440 1441 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) { 1442 return PLDM_ERROR_INVALID_DATA; 1443 } 1444 1445 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte); 1446 1447 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned); 1448 if (rc) { 1449 return rc; 1450 } 1451 1452 if (*number_event_class_returned == 0) { 1453 return pldm_msgbuf_destroy(buf); 1454 } 1455 1456 if (event_class_count < *number_event_class_returned) { 1457 return PLDM_ERROR_INVALID_LENGTH; 1458 } 1459 1460 for (i = 0; i < *number_event_class_returned; i++) { 1461 pldm_msgbuf_extract(buf, event_class[i]); 1462 } 1463 1464 return pldm_msgbuf_destroy_consumed(buf); 1465 } 1466 1467 LIBPLDM_ABI_STABLE 1468 int decode_sensor_event_data(const uint8_t *event_data, 1469 size_t event_data_length, uint16_t *sensor_id, 1470 uint8_t *sensor_event_class_type, 1471 size_t *event_class_data_offset) 1472 { 1473 struct pldm_msgbuf _buf; 1474 struct pldm_msgbuf *buf = &_buf; 1475 int rc; 1476 1477 if (event_data == NULL || sensor_id == NULL || 1478 sensor_event_class_type == NULL || 1479 event_class_data_offset == NULL) { 1480 return PLDM_ERROR_INVALID_DATA; 1481 } 1482 1483 rc = pldm_msgbuf_init_cc(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH, 1484 event_data, event_data_length); 1485 if (rc) { 1486 return rc; 1487 } 1488 1489 size_t event_class_data_length = 1490 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES; 1491 1492 pldm_msgbuf_extract_p(buf, sensor_id); 1493 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type); 1494 if (rc) { 1495 return rc; 1496 } 1497 1498 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) { 1499 if (event_class_data_length != 1500 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) { 1501 return PLDM_ERROR_INVALID_LENGTH; 1502 } 1503 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) { 1504 if (event_class_data_length != 1505 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) { 1506 return PLDM_ERROR_INVALID_LENGTH; 1507 } 1508 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) { 1509 if (event_class_data_length < 1510 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH || 1511 event_class_data_length > 1512 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 1513 return PLDM_ERROR_INVALID_LENGTH; 1514 } 1515 } else { 1516 return PLDM_ERROR_INVALID_DATA; 1517 } 1518 1519 *event_class_data_offset = 1520 sizeof(*sensor_id) + sizeof(*sensor_event_class_type); 1521 1522 return pldm_msgbuf_destroy(buf); 1523 } 1524 1525 LIBPLDM_ABI_STABLE 1526 int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length, 1527 uint8_t *present_op_state, uint8_t *previous_op_state) 1528 { 1529 struct pldm_msgbuf _buf; 1530 struct pldm_msgbuf *buf = &_buf; 1531 int rc; 1532 1533 if (sensor_data == NULL || present_op_state == NULL || 1534 previous_op_state == NULL) { 1535 return PLDM_ERROR_INVALID_DATA; 1536 } 1537 1538 rc = pldm_msgbuf_init_cc(buf, 1539 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, 1540 sensor_data, sensor_data_length); 1541 if (rc) { 1542 return rc; 1543 } 1544 1545 pldm_msgbuf_extract_p(buf, present_op_state); 1546 pldm_msgbuf_extract_p(buf, previous_op_state); 1547 1548 return pldm_msgbuf_destroy_consumed(buf); 1549 } 1550 1551 LIBPLDM_ABI_STABLE 1552 int decode_state_sensor_data(const uint8_t *sensor_data, 1553 size_t sensor_data_length, uint8_t *sensor_offset, 1554 uint8_t *event_state, 1555 uint8_t *previous_event_state) 1556 { 1557 struct pldm_msgbuf _buf; 1558 struct pldm_msgbuf *buf = &_buf; 1559 int rc; 1560 1561 if (sensor_data == NULL || sensor_offset == NULL || 1562 event_state == NULL || previous_event_state == NULL) { 1563 return PLDM_ERROR_INVALID_DATA; 1564 } 1565 1566 rc = pldm_msgbuf_init_cc( 1567 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH, 1568 sensor_data, sensor_data_length); 1569 if (rc) { 1570 return rc; 1571 } 1572 1573 pldm_msgbuf_extract_p(buf, sensor_offset); 1574 pldm_msgbuf_extract_p(buf, event_state); 1575 pldm_msgbuf_extract_p(buf, previous_event_state); 1576 1577 return pldm_msgbuf_destroy_consumed(buf); 1578 } 1579 1580 LIBPLDM_ABI_STABLE 1581 int decode_numeric_sensor_data(const uint8_t *sensor_data, 1582 size_t sensor_data_length, uint8_t *event_state, 1583 uint8_t *previous_event_state, 1584 uint8_t *sensor_data_size, 1585 uint32_t *present_reading) 1586 { 1587 struct pldm_msgbuf _buf; 1588 struct pldm_msgbuf *buf = &_buf; 1589 int rc; 1590 1591 if (sensor_data == NULL || sensor_data_size == NULL || 1592 event_state == NULL || previous_event_state == NULL || 1593 present_reading == NULL) { 1594 return PLDM_ERROR_INVALID_DATA; 1595 } 1596 1597 if (sensor_data_length > 1598 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 1599 return PLDM_ERROR_INVALID_LENGTH; 1600 } 1601 1602 rc = pldm_msgbuf_init_cc( 1603 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH, 1604 sensor_data, sensor_data_length); 1605 if (rc) { 1606 return rc; 1607 } 1608 1609 pldm_msgbuf_extract_p(buf, event_state); 1610 pldm_msgbuf_extract_p(buf, previous_event_state); 1611 rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 1612 if (rc) { 1613 return rc; 1614 } 1615 1616 /* 1617 * The implementation below is bonkers, but it's because the function 1618 * prototype is bonkers. The `present_reading` argument should have been 1619 * a tagged union. 1620 */ 1621 switch (*sensor_data_size) { 1622 case PLDM_SENSOR_DATA_SIZE_UINT8: { 1623 uint8_t val; 1624 if (!pldm_msgbuf_extract(buf, val)) { 1625 *present_reading = (uint32_t)val; 1626 } 1627 break; 1628 } 1629 case PLDM_SENSOR_DATA_SIZE_SINT8: { 1630 int8_t val; 1631 if (!pldm_msgbuf_extract(buf, val)) { 1632 *present_reading = (uint32_t)(int32_t)val; 1633 } 1634 break; 1635 } 1636 case PLDM_SENSOR_DATA_SIZE_UINT16: { 1637 uint16_t val; 1638 if (!pldm_msgbuf_extract(buf, val)) { 1639 *present_reading = (uint32_t)val; 1640 } 1641 break; 1642 } 1643 case PLDM_SENSOR_DATA_SIZE_SINT16: { 1644 int16_t val; 1645 if (!pldm_msgbuf_extract(buf, val)) { 1646 *present_reading = (uint32_t)(int32_t)val; 1647 } 1648 break; 1649 } 1650 case PLDM_SENSOR_DATA_SIZE_UINT32: { 1651 uint32_t val; 1652 if (!pldm_msgbuf_extract(buf, val)) { 1653 *present_reading = (uint32_t)val; 1654 } 1655 break; 1656 } 1657 case PLDM_SENSOR_DATA_SIZE_SINT32: { 1658 int32_t val; 1659 if (!pldm_msgbuf_extract(buf, val)) { 1660 *present_reading = (uint32_t)val; 1661 } 1662 break; 1663 } 1664 default: 1665 return PLDM_ERROR_INVALID_DATA; 1666 } 1667 1668 return pldm_msgbuf_destroy_consumed(buf); 1669 } 1670 1671 LIBPLDM_ABI_STABLE 1672 int decode_numeric_sensor_pdr_data( 1673 const void *pdr_data, size_t pdr_data_length, 1674 struct pldm_numeric_sensor_value_pdr *pdr_value) 1675 { 1676 struct pldm_msgbuf _buf; 1677 struct pldm_msgbuf *buf = &_buf; 1678 int rc; 1679 1680 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 1681 pdr_data, pdr_data_length); 1682 if (rc) { 1683 return rc; 1684 } 1685 1686 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr); 1687 if (rc) { 1688 return rc; 1689 } 1690 1691 rc = pldm_platform_pdr_hdr_validate( 1692 &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 1693 pdr_data_length); 1694 if (rc) { 1695 return rc; 1696 } 1697 1698 pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 1699 pldm_msgbuf_extract(buf, pdr_value->sensor_id); 1700 pldm_msgbuf_extract(buf, pdr_value->entity_type); 1701 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num); 1702 pldm_msgbuf_extract(buf, pdr_value->container_id); 1703 pldm_msgbuf_extract(buf, pdr_value->sensor_init); 1704 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr); 1705 pldm_msgbuf_extract(buf, pdr_value->base_unit); 1706 pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 1707 pldm_msgbuf_extract(buf, pdr_value->rate_unit); 1708 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 1709 pldm_msgbuf_extract(buf, pdr_value->aux_unit); 1710 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 1711 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 1712 pldm_msgbuf_extract(buf, pdr_value->rel); 1713 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 1714 pldm_msgbuf_extract(buf, pdr_value->is_linear); 1715 1716 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size); 1717 if (rc) { 1718 return rc; 1719 } 1720 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 1721 return PLDM_ERROR_INVALID_DATA; 1722 } 1723 1724 pldm_msgbuf_extract(buf, pdr_value->resolution); 1725 pldm_msgbuf_extract(buf, pdr_value->offset); 1726 pldm_msgbuf_extract(buf, pdr_value->accuracy); 1727 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 1728 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 1729 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 1730 &pdr_value->hysteresis); 1731 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte); 1732 pldm_msgbuf_extract( 1733 buf, pdr_value->threshold_and_hysteresis_volatility.byte); 1734 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 1735 pldm_msgbuf_extract(buf, pdr_value->update_interval); 1736 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 1737 &pdr_value->max_readable); 1738 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 1739 &pdr_value->min_readable); 1740 1741 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 1742 if (rc) { 1743 return rc; 1744 } 1745 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 1746 return PLDM_ERROR_INVALID_DATA; 1747 } 1748 1749 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 1750 pldm_msgbuf_extract_range_field_format( 1751 buf, pdr_value->range_field_format, pdr_value->nominal_value); 1752 pldm_msgbuf_extract_range_field_format( 1753 buf, pdr_value->range_field_format, pdr_value->normal_max); 1754 pldm_msgbuf_extract_range_field_format( 1755 buf, pdr_value->range_field_format, pdr_value->normal_min); 1756 pldm_msgbuf_extract_range_field_format( 1757 buf, pdr_value->range_field_format, pdr_value->warning_high); 1758 pldm_msgbuf_extract_range_field_format( 1759 buf, pdr_value->range_field_format, pdr_value->warning_low); 1760 pldm_msgbuf_extract_range_field_format( 1761 buf, pdr_value->range_field_format, pdr_value->critical_high); 1762 pldm_msgbuf_extract_range_field_format( 1763 buf, pdr_value->range_field_format, pdr_value->critical_low); 1764 pldm_msgbuf_extract_range_field_format( 1765 buf, pdr_value->range_field_format, pdr_value->fatal_high); 1766 pldm_msgbuf_extract_range_field_format( 1767 buf, pdr_value->range_field_format, pdr_value->fatal_low); 1768 1769 return pldm_msgbuf_destroy(buf); 1770 } 1771 1772 LIBPLDM_ABI_STABLE 1773 int encode_get_numeric_effecter_value_req(uint8_t instance_id, 1774 uint16_t effecter_id, 1775 struct pldm_msg *msg) 1776 { 1777 if (msg == NULL) { 1778 return PLDM_ERROR_INVALID_DATA; 1779 } 1780 1781 struct pldm_header_info header = { 0 }; 1782 header.msg_type = PLDM_REQUEST; 1783 header.instance = instance_id; 1784 header.pldm_type = PLDM_PLATFORM; 1785 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 1786 1787 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1788 if (rc != PLDM_SUCCESS) { 1789 return rc; 1790 } 1791 1792 struct pldm_get_numeric_effecter_value_req *request = 1793 (struct pldm_get_numeric_effecter_value_req *)msg->payload; 1794 request->effecter_id = htole16(effecter_id); 1795 1796 return PLDM_SUCCESS; 1797 } 1798 1799 LIBPLDM_ABI_STABLE 1800 int encode_get_numeric_effecter_value_resp( 1801 uint8_t instance_id, uint8_t completion_code, 1802 uint8_t effecter_data_size, uint8_t effecter_oper_state, 1803 const uint8_t *pending_value, const uint8_t *present_value, 1804 struct pldm_msg *msg, size_t payload_length) 1805 { 1806 if (msg == NULL || pending_value == NULL || present_value == NULL) { 1807 return PLDM_ERROR_INVALID_DATA; 1808 } 1809 1810 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 1811 return PLDM_ERROR_INVALID_DATA; 1812 } 1813 1814 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 1815 return PLDM_ERROR_INVALID_DATA; 1816 } 1817 1818 struct pldm_header_info header = { 0 }; 1819 header.msg_type = PLDM_RESPONSE; 1820 header.instance = instance_id; 1821 header.pldm_type = PLDM_PLATFORM; 1822 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 1823 1824 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 1825 if (rc != PLDM_SUCCESS) { 1826 return rc; 1827 } 1828 1829 struct pldm_get_numeric_effecter_value_resp *response = 1830 (struct pldm_get_numeric_effecter_value_resp *)msg->payload; 1831 1832 response->completion_code = completion_code; 1833 response->effecter_data_size = effecter_data_size; 1834 response->effecter_oper_state = effecter_oper_state; 1835 1836 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 1837 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 1838 if (payload_length != 1839 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) { 1840 return PLDM_ERROR_INVALID_LENGTH; 1841 } 1842 response->pending_and_present_values[0] = *pending_value; 1843 response->pending_and_present_values[1] = *present_value; 1844 1845 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 1846 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 1847 if (payload_length != 1848 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) { 1849 return PLDM_ERROR_INVALID_LENGTH; 1850 } 1851 uint16_t val_pending = *(uint16_t *)pending_value; 1852 val_pending = htole16(val_pending); 1853 memcpy(response->pending_and_present_values, &val_pending, 1854 sizeof(uint16_t)); 1855 uint16_t val_present = *(uint16_t *)present_value; 1856 val_present = htole16(val_present); 1857 memcpy((response->pending_and_present_values + 1858 sizeof(uint16_t)), 1859 &val_present, sizeof(uint16_t)); 1860 1861 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 1862 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 1863 if (payload_length != 1864 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) { 1865 return PLDM_ERROR_INVALID_LENGTH; 1866 } 1867 uint32_t val_pending = *(uint32_t *)pending_value; 1868 val_pending = htole32(val_pending); 1869 memcpy(response->pending_and_present_values, &val_pending, 1870 sizeof(uint32_t)); 1871 uint32_t val_present = *(uint32_t *)present_value; 1872 val_present = htole32(val_present); 1873 memcpy((response->pending_and_present_values + 1874 sizeof(uint32_t)), 1875 &val_present, sizeof(uint32_t)); 1876 } 1877 return PLDM_SUCCESS; 1878 } 1879 1880 LIBPLDM_ABI_STABLE 1881 int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg, 1882 size_t payload_length, 1883 uint16_t *effecter_id) 1884 { 1885 struct pldm_msgbuf _buf; 1886 struct pldm_msgbuf *buf = &_buf; 1887 int rc; 1888 1889 if (msg == NULL || effecter_id == NULL) { 1890 return PLDM_ERROR_INVALID_DATA; 1891 } 1892 1893 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES, 1894 msg->payload, payload_length); 1895 if (rc) { 1896 return rc; 1897 } 1898 1899 pldm_msgbuf_extract_p(buf, effecter_id); 1900 1901 return pldm_msgbuf_destroy_consumed(buf); 1902 } 1903 1904 LIBPLDM_ABI_STABLE 1905 int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg, 1906 size_t payload_length, 1907 uint8_t *completion_code, 1908 uint8_t *effecter_data_size, 1909 uint8_t *effecter_oper_state, 1910 uint8_t *pending_value, 1911 uint8_t *present_value) 1912 { 1913 struct pldm_msgbuf _buf; 1914 struct pldm_msgbuf *buf = &_buf; 1915 int rc; 1916 1917 if (msg == NULL || effecter_data_size == NULL || 1918 effecter_oper_state == NULL || pending_value == NULL || 1919 present_value == NULL) { 1920 return PLDM_ERROR_INVALID_DATA; 1921 } 1922 1923 rc = pldm_msgbuf_init_cc(buf, 1924 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES, 1925 msg->payload, payload_length); 1926 if (rc) { 1927 return rc; 1928 } 1929 1930 rc = pldm_msgbuf_extract_p(buf, completion_code); 1931 if (rc) { 1932 return rc; 1933 } 1934 1935 if (PLDM_SUCCESS != *completion_code) { 1936 return PLDM_SUCCESS; 1937 } 1938 1939 rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 1940 if (rc) { 1941 return rc; 1942 } 1943 1944 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 1945 return PLDM_ERROR_INVALID_DATA; 1946 } 1947 1948 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state); 1949 if (rc) { 1950 return rc; 1951 } 1952 1953 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 1954 return PLDM_ERROR_INVALID_DATA; 1955 } 1956 1957 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 1958 pending_value); 1959 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 1960 present_value); 1961 1962 return pldm_msgbuf_destroy_consumed(buf); 1963 } 1964 1965 LIBPLDM_ABI_STABLE 1966 int encode_pldm_pdr_repository_chg_event_data( 1967 uint8_t event_data_format, uint8_t number_of_change_records, 1968 const uint8_t *event_data_operations, 1969 const uint8_t *numbers_of_change_entries, 1970 const uint32_t *const *change_entries, 1971 struct pldm_pdr_repository_chg_event_data *event_data, 1972 size_t *actual_change_records_size, size_t max_change_records_size) 1973 { 1974 if (event_data_operations == NULL || 1975 numbers_of_change_entries == NULL || change_entries == NULL) { 1976 return PLDM_ERROR_INVALID_DATA; 1977 } 1978 1979 size_t expected_size = 1980 sizeof(event_data_format) + sizeof(number_of_change_records); 1981 1982 expected_size += 1983 sizeof(*event_data_operations) * number_of_change_records; 1984 expected_size += 1985 sizeof(*numbers_of_change_entries) * number_of_change_records; 1986 1987 for (uint8_t i = 0; i < number_of_change_records; ++i) { 1988 expected_size += sizeof(*change_entries[0]) * 1989 numbers_of_change_entries[i]; 1990 } 1991 1992 *actual_change_records_size = expected_size; 1993 1994 if (event_data == NULL) { 1995 return PLDM_SUCCESS; 1996 } 1997 1998 if (max_change_records_size < expected_size) { 1999 return PLDM_ERROR_INVALID_LENGTH; 2000 } 2001 2002 event_data->event_data_format = event_data_format; 2003 event_data->number_of_change_records = number_of_change_records; 2004 2005 struct pldm_pdr_repository_change_record_data *record_data = 2006 (struct pldm_pdr_repository_change_record_data *) 2007 event_data->change_records; 2008 2009 for (uint8_t i = 0; i < number_of_change_records; ++i) { 2010 record_data->event_data_operation = event_data_operations[i]; 2011 record_data->number_of_change_entries = 2012 numbers_of_change_entries[i]; 2013 2014 for (uint8_t j = 0; j < record_data->number_of_change_entries; 2015 ++j) { 2016 record_data->change_entry[j] = 2017 htole32(change_entries[i][j]); 2018 } 2019 2020 record_data = 2021 (struct pldm_pdr_repository_change_record_data 2022 *)(record_data->change_entry + 2023 record_data->number_of_change_entries); 2024 } 2025 2026 return PLDM_SUCCESS; 2027 } 2028 2029 LIBPLDM_ABI_STABLE 2030 int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data, 2031 size_t event_data_size, 2032 uint8_t *event_data_format, 2033 uint8_t *number_of_change_records, 2034 size_t *change_record_data_offset) 2035 { 2036 struct pldm_msgbuf _buf; 2037 struct pldm_msgbuf *buf = &_buf; 2038 int rc; 2039 2040 if (event_data == NULL || event_data_format == NULL || 2041 number_of_change_records == NULL || 2042 change_record_data_offset == NULL) { 2043 return PLDM_ERROR_INVALID_DATA; 2044 } 2045 2046 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH, 2047 event_data, event_data_size); 2048 if (rc) { 2049 return rc; 2050 } 2051 2052 pldm_msgbuf_extract_p(buf, event_data_format); 2053 pldm_msgbuf_extract_p(buf, number_of_change_records); 2054 2055 *change_record_data_offset = 2056 sizeof(*event_data_format) + sizeof(*number_of_change_records); 2057 2058 return pldm_msgbuf_destroy(buf); 2059 } 2060 2061 LIBPLDM_ABI_STABLE 2062 int decode_pldm_message_poll_event_data( 2063 const void *event_data, size_t event_data_length, 2064 struct pldm_message_poll_event *poll_event) 2065 { 2066 struct pldm_msgbuf _buf; 2067 struct pldm_msgbuf *buf = &_buf; 2068 int rc; 2069 2070 if (!event_data || !poll_event) { 2071 return -EINVAL; 2072 } 2073 2074 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 2075 event_data_length); 2076 if (rc) { 2077 return rc; 2078 } 2079 2080 pldm_msgbuf_extract(buf, poll_event->format_version); 2081 rc = pldm_msgbuf_extract(buf, poll_event->event_id); 2082 if (rc) { 2083 return rc; 2084 } 2085 2086 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 2087 return -EPROTO; 2088 } 2089 2090 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle); 2091 2092 return pldm_msgbuf_destroy_consumed(buf); 2093 } 2094 2095 LIBPLDM_ABI_TESTING 2096 int encode_pldm_message_poll_event_data( 2097 const struct pldm_message_poll_event *poll_event, void *event_data, 2098 size_t event_data_length) 2099 { 2100 struct pldm_msgbuf _buf; 2101 struct pldm_msgbuf *buf = &_buf; 2102 int rc; 2103 2104 if (poll_event == NULL || event_data == NULL) { 2105 return -EINVAL; 2106 } 2107 2108 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 2109 return -EPROTO; 2110 } 2111 2112 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 2113 event_data_length); 2114 if (rc) { 2115 return rc; 2116 } 2117 pldm_msgbuf_insert(buf, poll_event->format_version); 2118 pldm_msgbuf_insert(buf, poll_event->event_id); 2119 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle); 2120 2121 return pldm_msgbuf_destroy_consumed(buf); 2122 } 2123 2124 LIBPLDM_ABI_STABLE 2125 int decode_pldm_pdr_repository_change_record_data( 2126 const uint8_t *change_record_data, size_t change_record_data_size, 2127 uint8_t *event_data_operation, uint8_t *number_of_change_entries, 2128 size_t *change_entry_data_offset) 2129 { 2130 struct pldm_msgbuf _buf; 2131 struct pldm_msgbuf *buf = &_buf; 2132 int rc; 2133 2134 if (change_record_data == NULL || event_data_operation == NULL || 2135 number_of_change_entries == NULL || 2136 change_entry_data_offset == NULL) { 2137 return PLDM_ERROR_INVALID_DATA; 2138 } 2139 2140 rc = pldm_msgbuf_init_cc(buf, 2141 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH, 2142 change_record_data, change_record_data_size); 2143 if (rc) { 2144 return rc; 2145 } 2146 2147 pldm_msgbuf_extract_p(buf, event_data_operation); 2148 pldm_msgbuf_extract_p(buf, number_of_change_entries); 2149 2150 *change_entry_data_offset = sizeof(*event_data_operation) + 2151 sizeof(*number_of_change_entries); 2152 2153 return pldm_msgbuf_destroy(buf); 2154 } 2155 2156 LIBPLDM_ABI_STABLE 2157 int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id, 2158 uint8_t rearm_event_state, 2159 struct pldm_msg *msg) 2160 { 2161 if (msg == NULL) { 2162 return PLDM_ERROR_INVALID_DATA; 2163 } 2164 2165 struct pldm_header_info header = { 0 }; 2166 header.msg_type = PLDM_REQUEST; 2167 header.instance = instance_id; 2168 header.pldm_type = PLDM_PLATFORM; 2169 header.command = PLDM_GET_SENSOR_READING; 2170 2171 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2172 if (rc != PLDM_SUCCESS) { 2173 return rc; 2174 } 2175 2176 struct pldm_get_sensor_reading_req *request = 2177 (struct pldm_get_sensor_reading_req *)msg->payload; 2178 2179 request->sensor_id = htole16(sensor_id); 2180 request->rearm_event_state = rearm_event_state; 2181 2182 return PLDM_SUCCESS; 2183 } 2184 2185 LIBPLDM_ABI_STABLE 2186 int decode_get_sensor_reading_resp( 2187 const struct pldm_msg *msg, size_t payload_length, 2188 uint8_t *completion_code, uint8_t *sensor_data_size, 2189 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable, 2190 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state, 2191 uint8_t *present_reading) 2192 { 2193 struct pldm_msgbuf _buf; 2194 struct pldm_msgbuf *buf = &_buf; 2195 int rc; 2196 2197 if (msg == NULL || completion_code == NULL || 2198 sensor_data_size == NULL || sensor_operational_state == NULL || 2199 sensor_event_message_enable == NULL || present_state == NULL || 2200 previous_state == NULL || event_state == NULL || 2201 present_reading == NULL) { 2202 return PLDM_ERROR_INVALID_DATA; 2203 } 2204 2205 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES, 2206 msg->payload, payload_length); 2207 if (rc) { 2208 return rc; 2209 } 2210 2211 rc = pldm_msgbuf_extract_p(buf, completion_code); 2212 if (rc) { 2213 return rc; 2214 } 2215 2216 if (PLDM_SUCCESS != *completion_code) { 2217 return PLDM_SUCCESS; 2218 } 2219 2220 rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 2221 if (rc) { 2222 return rc; 2223 } 2224 2225 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) { 2226 return PLDM_ERROR_INVALID_DATA; 2227 } 2228 2229 pldm_msgbuf_extract_p(buf, sensor_operational_state); 2230 pldm_msgbuf_extract_p(buf, sensor_event_message_enable); 2231 pldm_msgbuf_extract_p(buf, present_state); 2232 pldm_msgbuf_extract_p(buf, previous_state); 2233 pldm_msgbuf_extract_p(buf, event_state); 2234 2235 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size, 2236 present_reading); 2237 2238 return pldm_msgbuf_destroy_consumed(buf); 2239 } 2240 2241 LIBPLDM_ABI_STABLE 2242 int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code, 2243 uint8_t sensor_data_size, 2244 uint8_t sensor_operational_state, 2245 uint8_t sensor_event_message_enable, 2246 uint8_t present_state, 2247 uint8_t previous_state, uint8_t event_state, 2248 const uint8_t *present_reading, 2249 struct pldm_msg *msg, size_t payload_length) 2250 { 2251 if (msg == NULL || present_reading == NULL) { 2252 return PLDM_ERROR_INVALID_DATA; 2253 } 2254 2255 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 2256 return PLDM_ERROR_INVALID_DATA; 2257 } 2258 2259 struct pldm_header_info header = { 0 }; 2260 header.msg_type = PLDM_RESPONSE; 2261 header.instance = instance_id; 2262 header.pldm_type = PLDM_PLATFORM; 2263 header.command = PLDM_GET_SENSOR_READING; 2264 2265 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2266 if (rc != PLDM_SUCCESS) { 2267 return rc; 2268 } 2269 2270 struct pldm_get_sensor_reading_resp *response = 2271 (struct pldm_get_sensor_reading_resp *)msg->payload; 2272 2273 response->completion_code = completion_code; 2274 response->sensor_data_size = sensor_data_size; 2275 response->sensor_operational_state = sensor_operational_state; 2276 response->sensor_event_message_enable = sensor_event_message_enable; 2277 response->present_state = present_state; 2278 response->previous_state = previous_state; 2279 response->event_state = event_state; 2280 2281 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 2282 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 2283 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) { 2284 return PLDM_ERROR_INVALID_LENGTH; 2285 } 2286 response->present_reading[0] = *present_reading; 2287 2288 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 2289 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 2290 if (payload_length != 2291 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) { 2292 return PLDM_ERROR_INVALID_LENGTH; 2293 } 2294 uint16_t val = *(uint16_t *)present_reading; 2295 val = htole16(val); 2296 memcpy(response->present_reading, &val, 2); 2297 2298 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 2299 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 2300 if (payload_length != 2301 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) { 2302 return PLDM_ERROR_INVALID_LENGTH; 2303 } 2304 uint32_t val = *(uint32_t *)present_reading; 2305 val = htole32(val); 2306 memcpy(response->present_reading, &val, 4); 2307 } 2308 2309 return PLDM_SUCCESS; 2310 } 2311 2312 LIBPLDM_ABI_STABLE 2313 int decode_get_sensor_reading_req(const struct pldm_msg *msg, 2314 size_t payload_length, uint16_t *sensor_id, 2315 uint8_t *rearm_event_state) 2316 { 2317 struct pldm_msgbuf _buf; 2318 struct pldm_msgbuf *buf = &_buf; 2319 int rc; 2320 2321 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) { 2322 return PLDM_ERROR_INVALID_DATA; 2323 } 2324 2325 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_REQ_BYTES, 2326 msg->payload, payload_length); 2327 if (rc) { 2328 return rc; 2329 } 2330 2331 pldm_msgbuf_extract_p(buf, sensor_id); 2332 pldm_msgbuf_extract_p(buf, rearm_event_state); 2333 2334 return pldm_msgbuf_destroy(buf); 2335 } 2336 2337 LIBPLDM_ABI_STABLE 2338 int encode_set_event_receiver_req(uint8_t instance_id, 2339 uint8_t event_message_global_enable, 2340 uint8_t transport_protocol_type, 2341 uint8_t event_receiver_address_info, 2342 uint16_t heartbeat_timer, 2343 struct pldm_msg *msg) 2344 { 2345 if (msg == NULL) { 2346 return PLDM_ERROR_INVALID_DATA; 2347 } 2348 2349 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) { 2350 return PLDM_ERROR_INVALID_DATA; 2351 } 2352 2353 struct pldm_header_info header = { 0 }; 2354 header.msg_type = PLDM_REQUEST; 2355 header.instance = instance_id; 2356 header.pldm_type = PLDM_PLATFORM; 2357 header.command = PLDM_SET_EVENT_RECEIVER; 2358 2359 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2360 if (rc != PLDM_SUCCESS) { 2361 return rc; 2362 } 2363 2364 struct pldm_set_event_receiver_req *request = 2365 (struct pldm_set_event_receiver_req *)msg->payload; 2366 request->event_message_global_enable = event_message_global_enable; 2367 2368 request->transport_protocol_type = transport_protocol_type; 2369 request->event_receiver_address_info = event_receiver_address_info; 2370 2371 if (event_message_global_enable == 2372 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 2373 if (heartbeat_timer == 0) { 2374 return PLDM_ERROR_INVALID_DATA; 2375 } 2376 request->heartbeat_timer = htole16(heartbeat_timer); 2377 } 2378 2379 return PLDM_SUCCESS; 2380 } 2381 2382 LIBPLDM_ABI_STABLE 2383 int decode_set_event_receiver_resp(const struct pldm_msg *msg, 2384 size_t payload_length, 2385 uint8_t *completion_code) 2386 { 2387 struct pldm_msgbuf _buf; 2388 struct pldm_msgbuf *buf = &_buf; 2389 int rc; 2390 2391 if (msg == NULL || completion_code == NULL) { 2392 return PLDM_ERROR_INVALID_DATA; 2393 } 2394 2395 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES, 2396 msg->payload, payload_length); 2397 if (rc) { 2398 return rc; 2399 } 2400 2401 pldm_msgbuf_extract_p(buf, completion_code); 2402 2403 return pldm_msgbuf_destroy(buf); 2404 } 2405 2406 LIBPLDM_ABI_STABLE 2407 int decode_set_event_receiver_req(const struct pldm_msg *msg, 2408 size_t payload_length, 2409 uint8_t *event_message_global_enable, 2410 uint8_t *transport_protocol_type, 2411 uint8_t *event_receiver_address_info, 2412 uint16_t *heartbeat_timer) 2413 2414 { 2415 struct pldm_msgbuf _buf; 2416 struct pldm_msgbuf *buf = &_buf; 2417 int rc; 2418 2419 if (msg == NULL || event_message_global_enable == NULL || 2420 transport_protocol_type == NULL || 2421 event_receiver_address_info == NULL || heartbeat_timer == NULL) { 2422 return PLDM_ERROR_INVALID_DATA; 2423 } 2424 2425 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES, 2426 msg->payload, payload_length); 2427 if (rc) { 2428 return rc; 2429 } 2430 2431 pldm_msgbuf_extract_p(buf, event_message_global_enable); 2432 pldm_msgbuf_extract_p(buf, transport_protocol_type); 2433 pldm_msgbuf_extract_p(buf, event_receiver_address_info); 2434 pldm_msgbuf_extract_p(buf, heartbeat_timer); 2435 2436 rc = pldm_msgbuf_destroy(buf); 2437 if (rc) { 2438 return rc; 2439 } 2440 2441 if ((*event_message_global_enable == 2442 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) && 2443 (*heartbeat_timer == 0)) { 2444 return PLDM_ERROR_INVALID_DATA; 2445 } 2446 2447 return PLDM_SUCCESS; 2448 } 2449 2450 LIBPLDM_ABI_STABLE 2451 int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code, 2452 struct pldm_msg *msg) 2453 2454 { 2455 if (msg == NULL) { 2456 return PLDM_ERROR_INVALID_DATA; 2457 } 2458 2459 struct pldm_header_info header = { 0 }; 2460 header.instance = instance_id; 2461 header.msg_type = PLDM_RESPONSE; 2462 header.pldm_type = PLDM_PLATFORM; 2463 header.command = PLDM_SET_EVENT_RECEIVER; 2464 2465 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2466 if (rc != PLDM_SUCCESS) { 2467 return rc; 2468 } 2469 2470 msg->payload[0] = completion_code; 2471 2472 return PLDM_SUCCESS; 2473 } 2474 2475 LIBPLDM_ABI_STABLE 2476 int encode_poll_for_platform_event_message_req(uint8_t instance_id, 2477 uint8_t format_version, 2478 uint8_t transfer_operation_flag, 2479 uint32_t data_transfer_handle, 2480 uint16_t event_id_to_acknowledge, 2481 struct pldm_msg *msg, 2482 size_t payload_length) 2483 { 2484 struct pldm_msgbuf _buf; 2485 struct pldm_msgbuf *buf = &_buf; 2486 int rc; 2487 2488 if (msg == NULL) { 2489 return PLDM_ERROR_INVALID_DATA; 2490 } 2491 2492 rc = pldm_platform_poll_for_platform_event_message_validate( 2493 transfer_operation_flag, event_id_to_acknowledge); 2494 if (rc < 0) { 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_POLL_FOR_PLATFORM_EVENT_MESSAGE; 2503 2504 rc = pack_pldm_header(&header, &(msg->hdr)); 2505 if (rc != PLDM_SUCCESS) { 2506 return rc; 2507 } 2508 2509 rc = pldm_msgbuf_init_cc( 2510 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 2511 msg->payload, payload_length); 2512 if (rc) { 2513 return rc; 2514 } 2515 2516 pldm_msgbuf_insert(buf, format_version); 2517 pldm_msgbuf_insert(buf, transfer_operation_flag); 2518 pldm_msgbuf_insert(buf, data_transfer_handle); 2519 pldm_msgbuf_insert(buf, event_id_to_acknowledge); 2520 2521 return pldm_msgbuf_destroy(buf); 2522 } 2523 2524 LIBPLDM_ABI_STABLE 2525 int decode_poll_for_platform_event_message_resp( 2526 const struct pldm_msg *msg, size_t payload_length, 2527 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id, 2528 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 2529 uint8_t *event_class, uint32_t *event_data_size, void **event_data, 2530 uint32_t *event_data_integrity_checksum) 2531 { 2532 struct pldm_msgbuf _buf; 2533 struct pldm_msgbuf *buf = &_buf; 2534 int rc; 2535 2536 if (msg == NULL || completion_code == NULL || tid == NULL || 2537 event_id == NULL || next_data_transfer_handle == NULL || 2538 transfer_flag == NULL || event_class == NULL || 2539 event_data_size == NULL || event_data == NULL || 2540 event_data_integrity_checksum == NULL) { 2541 return PLDM_ERROR_INVALID_DATA; 2542 } 2543 2544 rc = pldm_msgbuf_init_cc( 2545 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 2546 msg->payload, payload_length); 2547 if (rc) { 2548 return rc; 2549 } 2550 2551 rc = pldm_msgbuf_extract_p(buf, completion_code); 2552 if (rc) { 2553 return rc; 2554 } 2555 if (PLDM_SUCCESS != *completion_code) { 2556 return *completion_code; 2557 } 2558 2559 pldm_msgbuf_extract_p(buf, tid); 2560 rc = pldm_msgbuf_extract_p(buf, event_id); 2561 if (rc) { 2562 return rc; 2563 } 2564 if ((*event_id == 0) || (*event_id == 0xffff)) { 2565 return PLDM_SUCCESS; 2566 } 2567 2568 pldm_msgbuf_extract_p(buf, next_data_transfer_handle); 2569 rc = pldm_msgbuf_extract_p(buf, transfer_flag); 2570 if (rc) { 2571 return rc; 2572 } 2573 2574 pldm_msgbuf_extract_p(buf, event_class); 2575 rc = pldm_msgbuf_extract_p(buf, event_data_size); 2576 if (rc) { 2577 return rc; 2578 } 2579 if (*event_data_size > payload_length) { 2580 return PLDM_ERROR_INVALID_DATA; 2581 } 2582 2583 if (*event_data_size > 0) { 2584 pldm_msgbuf_span_required(buf, *event_data_size, event_data); 2585 } 2586 2587 if (*transfer_flag == PLDM_END || 2588 *transfer_flag == PLDM_START_AND_END) { 2589 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum); 2590 } 2591 2592 return pldm_msgbuf_destroy_consumed(buf); 2593 } 2594 2595 LIBPLDM_ABI_TESTING 2596 int decode_numeric_effecter_pdr_data( 2597 const void *pdr_data, size_t pdr_data_length, 2598 struct pldm_numeric_effecter_value_pdr *pdr_value) 2599 { 2600 struct pldm_msgbuf _buf; 2601 struct pldm_msgbuf *buf = &_buf; 2602 struct pldm_value_pdr_hdr hdr; 2603 int rc; 2604 2605 if (!pdr_data || !pdr_value) { 2606 return PLDM_ERROR_INVALID_DATA; 2607 } 2608 2609 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 2610 pdr_data, pdr_data_length); 2611 if (rc) { 2612 return rc; 2613 } 2614 2615 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &hdr); 2616 if (rc) { 2617 return rc; 2618 } 2619 2620 rc = pldm_platform_pdr_hdr_validate( 2621 &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 2622 pdr_data_length); 2623 if (rc) { 2624 return rc; 2625 } 2626 2627 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr)); 2628 2629 pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 2630 pldm_msgbuf_extract(buf, pdr_value->effecter_id); 2631 pldm_msgbuf_extract(buf, pdr_value->entity_type); 2632 pldm_msgbuf_extract(buf, pdr_value->entity_instance); 2633 pldm_msgbuf_extract(buf, pdr_value->container_id); 2634 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id); 2635 pldm_msgbuf_extract(buf, pdr_value->effecter_init); 2636 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names); 2637 pldm_msgbuf_extract(buf, pdr_value->base_unit); 2638 pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 2639 pldm_msgbuf_extract(buf, pdr_value->rate_unit); 2640 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 2641 pldm_msgbuf_extract(buf, pdr_value->aux_unit); 2642 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 2643 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 2644 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 2645 pldm_msgbuf_extract(buf, pdr_value->is_linear); 2646 2647 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size); 2648 if (rc) { 2649 return rc; 2650 } 2651 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 2652 return PLDM_ERROR_INVALID_DATA; 2653 } 2654 2655 pldm_msgbuf_extract(buf, pdr_value->resolution); 2656 pldm_msgbuf_extract(buf, pdr_value->offset); 2657 pldm_msgbuf_extract(buf, pdr_value->accuracy); 2658 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 2659 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 2660 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 2661 pldm_msgbuf_extract(buf, pdr_value->transition_interval); 2662 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 2663 pdr_value->max_settable); 2664 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 2665 pdr_value->min_settable); 2666 2667 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 2668 if (rc) { 2669 return rc; 2670 } 2671 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 2672 return PLDM_ERROR_INVALID_DATA; 2673 } 2674 2675 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 2676 pldm_msgbuf_extract_range_field_format( 2677 buf, pdr_value->range_field_format, pdr_value->nominal_value); 2678 pldm_msgbuf_extract_range_field_format( 2679 buf, pdr_value->range_field_format, pdr_value->normal_max); 2680 pldm_msgbuf_extract_range_field_format( 2681 buf, pdr_value->range_field_format, pdr_value->normal_min); 2682 pldm_msgbuf_extract_range_field_format( 2683 buf, pdr_value->range_field_format, pdr_value->rated_max); 2684 pldm_msgbuf_extract_range_field_format( 2685 buf, pdr_value->range_field_format, pdr_value->rated_min); 2686 2687 return pldm_msgbuf_destroy_consumed(buf); 2688 } 2689 2690 LIBPLDM_ABI_STABLE 2691 int encode_get_state_effecter_states_req(uint8_t instance_id, 2692 uint16_t effecter_id, 2693 struct pldm_msg *msg, 2694 size_t payload_length) 2695 { 2696 struct pldm_msgbuf _buf; 2697 struct pldm_msgbuf *buf = &_buf; 2698 int rc; 2699 2700 if (msg == NULL) { 2701 return -EINVAL; 2702 } 2703 2704 struct pldm_header_info header = { 0 }; 2705 header.msg_type = PLDM_REQUEST; 2706 header.instance = instance_id; 2707 header.pldm_type = PLDM_PLATFORM; 2708 header.command = PLDM_GET_STATE_EFFECTER_STATES; 2709 2710 rc = pack_pldm_header_errno(&header, &msg->hdr); 2711 if (rc < 0) { 2712 return rc; 2713 } 2714 2715 rc = pldm_msgbuf_init_errno(buf, 2716 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES, 2717 msg->payload, payload_length); 2718 if (rc) { 2719 return rc; 2720 } 2721 2722 pldm_msgbuf_insert(buf, effecter_id); 2723 2724 return pldm_msgbuf_destroy_consumed(buf); 2725 } 2726 2727 LIBPLDM_ABI_STABLE 2728 int decode_get_state_effecter_states_req(const struct pldm_msg *msg, 2729 size_t payload_length, 2730 uint16_t *effecter_id) 2731 { 2732 struct pldm_msgbuf _buf; 2733 struct pldm_msgbuf *buf = &_buf; 2734 int rc; 2735 2736 if (msg == NULL || effecter_id == NULL) { 2737 return -EINVAL; 2738 } 2739 2740 rc = pldm_msgbuf_init_errno( 2741 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2742 msg->payload, payload_length); 2743 if (rc) { 2744 return rc; 2745 } 2746 2747 pldm_msgbuf_extract_p(buf, effecter_id); 2748 2749 return pldm_msgbuf_destroy_consumed(buf); 2750 } 2751 2752 LIBPLDM_ABI_STABLE 2753 int decode_get_state_effecter_states_resp( 2754 const struct pldm_msg *msg, size_t payload_length, 2755 struct pldm_get_state_effecter_states_resp *resp) 2756 { 2757 struct pldm_msgbuf _buf; 2758 struct pldm_msgbuf *buf = &_buf; 2759 get_effecter_state_field *field; 2760 int rc; 2761 int i; 2762 2763 if (msg == NULL || resp == NULL) { 2764 return -EINVAL; 2765 } 2766 2767 rc = pldm_msgbuf_init_errno( 2768 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2769 msg->payload, payload_length); 2770 if (rc) { 2771 return rc; 2772 } 2773 2774 rc = pldm_msgbuf_extract(buf, resp->completion_code); 2775 if (rc) { 2776 return rc; 2777 } 2778 2779 if (PLDM_SUCCESS != resp->completion_code) { 2780 return 0; 2781 } 2782 2783 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count); 2784 if (rc) { 2785 return rc; 2786 } 2787 2788 uint8_t comp_effecter_count = resp->comp_effecter_count; 2789 2790 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 2791 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2792 return -EBADMSG; 2793 } 2794 2795 for (i = 0, field = resp->field; i < comp_effecter_count; 2796 i++, field++) { 2797 pldm_msgbuf_extract(buf, field->effecter_op_state); 2798 pldm_msgbuf_extract(buf, field->pending_state); 2799 pldm_msgbuf_extract(buf, field->present_state); 2800 } 2801 2802 return pldm_msgbuf_destroy_consumed(buf); 2803 } 2804 2805 LIBPLDM_ABI_STABLE 2806 int encode_get_state_effecter_states_resp( 2807 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp, 2808 struct pldm_msg *msg, size_t payload_length) 2809 { 2810 struct pldm_msgbuf _buf; 2811 struct pldm_msgbuf *buf = &_buf; 2812 get_effecter_state_field *field; 2813 int rc; 2814 int i; 2815 2816 if (msg == NULL || resp == NULL) { 2817 return -EINVAL; 2818 } 2819 2820 uint8_t comp_effecter_count = resp->comp_effecter_count; 2821 2822 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 2823 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2824 return -EBADMSG; 2825 } 2826 2827 struct pldm_header_info header = { 0 }; 2828 header.msg_type = PLDM_RESPONSE; 2829 header.instance = instance_id; 2830 header.pldm_type = PLDM_PLATFORM; 2831 header.command = PLDM_GET_STATE_EFFECTER_STATES; 2832 2833 rc = pack_pldm_header_errno(&header, &msg->hdr); 2834 if (rc < 0) { 2835 return rc; 2836 } 2837 2838 rc = pldm_msgbuf_init_errno( 2839 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2840 msg->payload, payload_length); 2841 if (rc) { 2842 return rc; 2843 } 2844 2845 pldm_msgbuf_insert(buf, resp->completion_code); 2846 pldm_msgbuf_insert(buf, comp_effecter_count); 2847 2848 for (i = 0, field = resp->field; i < comp_effecter_count; 2849 i++, field++) { 2850 pldm_msgbuf_insert(buf, field->effecter_op_state); 2851 pldm_msgbuf_insert(buf, field->pending_state); 2852 pldm_msgbuf_insert(buf, field->present_state); 2853 } 2854 2855 return pldm_msgbuf_destroy_consumed(buf); 2856 } 2857 2858 LIBPLDM_ABI_STABLE 2859 int decode_entity_auxiliary_names_pdr( 2860 const void *data, size_t data_length, 2861 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length) 2862 { 2863 struct pldm_msgbuf _buf; 2864 struct pldm_msgbuf *buf = &_buf; 2865 struct pldm_msgbuf _src; 2866 struct pldm_msgbuf *src = &_src; 2867 struct pldm_msgbuf _dst; 2868 struct pldm_msgbuf *dst = &_dst; 2869 size_t names_len = 0; 2870 void *names = NULL; 2871 int rc; 2872 int i; 2873 2874 if (!data || !pdr) { 2875 return -EINVAL; 2876 } 2877 2878 /* 2879 * Alignment of auxiliary_name_data is an invariant as we statically assert 2880 * its behaviour in the header. 2881 */ 2882 assert(!((uintptr_t)pdr->auxiliary_name_data & 2883 (alignof(pldm_utf16be) - 1))); 2884 2885 /* Reject any lengths that are obviously invalid */ 2886 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) { 2887 return -EINVAL; 2888 } 2889 2890 rc = pldm_msgbuf_init_errno( 2891 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data, 2892 data_length); 2893 if (rc) { 2894 return rc; 2895 } 2896 2897 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr->hdr); 2898 if (rc) { 2899 return rc; 2900 } 2901 2902 rc = pldm_platform_pdr_hdr_validate( 2903 &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, 2904 data_length); 2905 if (rc) { 2906 return rc; 2907 } 2908 2909 pldm_msgbuf_extract(buf, pdr->container.entity_type); 2910 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num); 2911 pldm_msgbuf_extract(buf, pdr->container.entity_container_id); 2912 pldm_msgbuf_extract(buf, pdr->shared_name_count); 2913 rc = pldm_msgbuf_extract(buf, pdr->name_string_count); 2914 if (rc < 0) { 2915 return rc; 2916 } 2917 2918 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len); 2919 if (rc < 0) { 2920 return rc; 2921 } 2922 assert(names); 2923 2924 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr); 2925 2926 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size, 2927 pdr->auxiliary_name_data, 2928 pdr->auxiliary_name_data_size); 2929 if (rc < 0) { 2930 return rc; 2931 } 2932 2933 /* 2934 * Below we do two passes over the same region. This is to first pack the 2935 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings, 2936 * to maintain appropriate alignment. 2937 */ 2938 2939 /* Initialise for the first pass to extract the UTF16-BE name strings */ 2940 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 2941 if (rc < 0) { 2942 return rc; 2943 } 2944 2945 for (i = 0; i < pdr->name_string_count; i++) { 2946 pldm_msgbuf_span_string_ascii(src, NULL, NULL); 2947 rc = pldm_msgbuf_copy_string_utf16(dst, src); 2948 if (rc) { 2949 return rc; 2950 } 2951 } 2952 2953 rc = pldm_msgbuf_destroy_consumed(src); 2954 if (rc < 0) { 2955 return rc; 2956 } 2957 2958 /* Reinitialise for the second pass to extract the ASCII tag strings */ 2959 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 2960 if (rc < 0) { 2961 return rc; 2962 } 2963 2964 for (i = 0; i < pdr->name_string_count; i++) { 2965 rc = pldm_msgbuf_copy_string_ascii(dst, src); 2966 if (rc) { 2967 return rc; 2968 } 2969 pldm_msgbuf_span_string_utf16(src, NULL, NULL); 2970 } 2971 2972 if ((rc = pldm_msgbuf_destroy(dst)) || 2973 (rc = pldm_msgbuf_destroy(src)) || 2974 (rc = pldm_msgbuf_destroy(buf))) { 2975 return rc; 2976 } 2977 2978 return 0; 2979 } 2980 2981 LIBPLDM_ABI_STABLE 2982 int decode_pldm_entity_auxiliary_names_pdr_index( 2983 struct pldm_entity_auxiliary_names_pdr *pdr) 2984 { 2985 struct pldm_msgbuf _buf; 2986 struct pldm_msgbuf *buf = &_buf; 2987 int rc; 2988 int i; 2989 2990 if (!pdr) { 2991 return -EINVAL; 2992 } 2993 2994 if (pdr->name_string_count == 0 && pdr->names) { 2995 return -EINVAL; 2996 } 2997 2998 if (pdr->name_string_count > 0 && !pdr->names) { 2999 return -EINVAL; 3000 } 3001 3002 if (pdr->name_string_count == 0) { 3003 return 0; 3004 } 3005 3006 /* 3007 * Minimum size is one NUL for each member of each entry 3008 * 3009 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2 3010 * states the following: 3011 * 3012 * > A null-terminated ISO646 ASCII string ... 3013 * > 3014 * > special value: null string = 0x0000 = unspecified. 3015 * 3016 * Until proven otherwise we will assume the "0x0000" is a 3017 * misrepresentation of an ASCII NUL, and that ASCII NUL is 3018 * represented by a single byte. 3019 */ 3020 rc = pldm_msgbuf_init_errno( 3021 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)), 3022 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size); 3023 if (rc) { 3024 return rc; 3025 } 3026 3027 for (i = 0; i < pdr->name_string_count; i++) { 3028 void *loc = NULL; 3029 pldm_msgbuf_span_string_utf16(buf, &loc, NULL); 3030 pdr->names[i].name = loc; 3031 } 3032 3033 for (i = 0; i < pdr->name_string_count; i++) { 3034 void *loc = NULL; 3035 pldm_msgbuf_span_string_ascii(buf, &loc, NULL); 3036 pdr->names[i].tag = loc; 3037 } 3038 3039 return pldm_msgbuf_destroy_consumed(buf); 3040 } 3041 3042 LIBPLDM_ABI_STABLE 3043 int decode_pldm_platform_cper_event(const void *event_data, 3044 size_t event_data_length, 3045 struct pldm_platform_cper_event *cper_event, 3046 size_t cper_event_length) 3047 { 3048 struct pldm_msgbuf _buf; 3049 struct pldm_msgbuf *buf = &_buf; 3050 int rc; 3051 3052 if (!cper_event || !event_data) { 3053 return -EINVAL; 3054 } 3055 3056 if (cper_event_length < sizeof(*cper_event)) { 3057 return -EINVAL; 3058 } 3059 3060 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH, 3061 event_data, event_data_length); 3062 if (rc) { 3063 return rc; 3064 } 3065 3066 pldm_msgbuf_extract(buf, cper_event->format_version); 3067 rc = pldm_msgbuf_extract(buf, cper_event->format_type); 3068 if (rc) { 3069 return rc; 3070 } 3071 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER && 3072 cper_event->format_type != 3073 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) { 3074 return -EPROTO; 3075 } 3076 3077 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length); 3078 if (rc) { 3079 return rc; 3080 } 3081 3082 if (cper_event->event_data_length > 3083 (cper_event_length - sizeof(*cper_event))) { 3084 return -EOVERFLOW; 3085 } 3086 3087 rc = pldm_msgbuf_extract_array_uint8( 3088 buf, cper_event->event_data_length, cper_event->event_data, 3089 cper_event_length - sizeof(*cper_event)); 3090 if (rc) { 3091 return rc; 3092 } 3093 3094 return pldm_msgbuf_destroy_consumed(buf); 3095 } 3096 3097 LIBPLDM_ABI_STABLE 3098 uint8_t * 3099 pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event) 3100 { 3101 return event->event_data; 3102 } 3103