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