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