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