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