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_TESTING 1906 int decode_pldm_message_poll_event_data(const uint8_t *event_data, 1907 size_t event_data_length, 1908 uint8_t *format_version, 1909 uint16_t *event_id, 1910 uint32_t *data_transfer_handle) 1911 { 1912 struct pldm_msgbuf _buf; 1913 struct pldm_msgbuf *buf = &_buf; 1914 int rc; 1915 1916 if (event_data == NULL || format_version == NULL || event_id == NULL || 1917 data_transfer_handle == NULL) { 1918 return PLDM_ERROR_INVALID_DATA; 1919 } 1920 1921 rc = pldm_msgbuf_init_cc(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 1922 event_data_length); 1923 if (rc) { 1924 return rc; 1925 } 1926 1927 pldm_msgbuf_extract_p(buf, format_version); 1928 rc = pldm_msgbuf_extract_p(buf, event_id); 1929 if (rc) { 1930 return rc; 1931 } 1932 1933 if (*event_id == 0x0000 || *event_id == 0xffff) { 1934 return PLDM_ERROR_INVALID_DATA; 1935 } 1936 1937 pldm_msgbuf_extract_p(buf, data_transfer_handle); 1938 1939 return pldm_msgbuf_destroy_consumed(buf); 1940 } 1941 1942 LIBPLDM_ABI_TESTING 1943 int encode_pldm_message_poll_event_data(uint8_t format_version, 1944 uint16_t event_id, 1945 uint32_t data_transfer_handle, 1946 uint8_t *event_data, 1947 size_t event_data_length) 1948 { 1949 struct pldm_msgbuf _buf; 1950 struct pldm_msgbuf *buf = &_buf; 1951 int rc; 1952 1953 if (event_data == NULL) { 1954 return PLDM_ERROR_INVALID_DATA; 1955 } 1956 1957 if (event_id == 0x0000 || event_id == 0xffff) { 1958 return PLDM_ERROR_INVALID_DATA; 1959 } 1960 1961 rc = pldm_msgbuf_init_cc(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 1962 event_data_length); 1963 if (rc) { 1964 return rc; 1965 } 1966 pldm_msgbuf_insert(buf, format_version); 1967 pldm_msgbuf_insert(buf, event_id); 1968 pldm_msgbuf_insert(buf, data_transfer_handle); 1969 1970 return pldm_msgbuf_destroy(buf); 1971 } 1972 1973 LIBPLDM_ABI_STABLE 1974 int decode_pldm_pdr_repository_change_record_data( 1975 const uint8_t *change_record_data, size_t change_record_data_size, 1976 uint8_t *event_data_operation, uint8_t *number_of_change_entries, 1977 size_t *change_entry_data_offset) 1978 { 1979 struct pldm_msgbuf _buf; 1980 struct pldm_msgbuf *buf = &_buf; 1981 int rc; 1982 1983 if (event_data_operation == NULL || number_of_change_entries == NULL || 1984 change_entry_data_offset == NULL) { 1985 return PLDM_ERROR_INVALID_DATA; 1986 } 1987 1988 rc = pldm_msgbuf_init_cc(buf, 1989 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH, 1990 change_record_data, change_record_data_size); 1991 if (rc) { 1992 return rc; 1993 } 1994 1995 pldm_msgbuf_extract_p(buf, event_data_operation); 1996 pldm_msgbuf_extract_p(buf, number_of_change_entries); 1997 1998 *change_entry_data_offset = sizeof(*event_data_operation) + 1999 sizeof(*number_of_change_entries); 2000 2001 return pldm_msgbuf_destroy(buf); 2002 } 2003 2004 LIBPLDM_ABI_STABLE 2005 int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id, 2006 uint8_t rearm_event_state, 2007 struct pldm_msg *msg) 2008 { 2009 if (msg == NULL) { 2010 return PLDM_ERROR_INVALID_DATA; 2011 } 2012 2013 struct pldm_header_info header = { 0 }; 2014 header.msg_type = PLDM_REQUEST; 2015 header.instance = instance_id; 2016 header.pldm_type = PLDM_PLATFORM; 2017 header.command = PLDM_GET_SENSOR_READING; 2018 2019 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2020 if (rc != PLDM_SUCCESS) { 2021 return rc; 2022 } 2023 2024 struct pldm_get_sensor_reading_req *request = 2025 (struct pldm_get_sensor_reading_req *)msg->payload; 2026 2027 request->sensor_id = htole16(sensor_id); 2028 request->rearm_event_state = rearm_event_state; 2029 2030 return PLDM_SUCCESS; 2031 } 2032 2033 LIBPLDM_ABI_STABLE 2034 int decode_get_sensor_reading_resp( 2035 const struct pldm_msg *msg, size_t payload_length, 2036 uint8_t *completion_code, uint8_t *sensor_data_size, 2037 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable, 2038 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state, 2039 uint8_t *present_reading) 2040 { 2041 struct pldm_msgbuf _buf; 2042 struct pldm_msgbuf *buf = &_buf; 2043 int rc; 2044 2045 if (msg == NULL || completion_code == NULL || 2046 sensor_data_size == NULL || sensor_operational_state == NULL || 2047 sensor_event_message_enable == NULL || present_state == NULL || 2048 previous_state == NULL || event_state == NULL || 2049 present_reading == NULL) { 2050 return PLDM_ERROR_INVALID_DATA; 2051 } 2052 2053 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES, 2054 msg->payload, payload_length); 2055 if (rc) { 2056 return rc; 2057 } 2058 2059 rc = pldm_msgbuf_extract_p(buf, completion_code); 2060 if (rc) { 2061 return rc; 2062 } 2063 2064 if (PLDM_SUCCESS != *completion_code) { 2065 return PLDM_SUCCESS; 2066 } 2067 2068 rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 2069 if (rc) { 2070 return rc; 2071 } 2072 2073 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) { 2074 return PLDM_ERROR_INVALID_DATA; 2075 } 2076 2077 pldm_msgbuf_extract_p(buf, sensor_operational_state); 2078 pldm_msgbuf_extract_p(buf, sensor_event_message_enable); 2079 pldm_msgbuf_extract_p(buf, present_state); 2080 pldm_msgbuf_extract_p(buf, previous_state); 2081 pldm_msgbuf_extract_p(buf, event_state); 2082 2083 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size, 2084 present_reading); 2085 2086 return pldm_msgbuf_destroy_consumed(buf); 2087 } 2088 2089 LIBPLDM_ABI_STABLE 2090 int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code, 2091 uint8_t sensor_data_size, 2092 uint8_t sensor_operational_state, 2093 uint8_t sensor_event_message_enable, 2094 uint8_t present_state, 2095 uint8_t previous_state, uint8_t event_state, 2096 const uint8_t *present_reading, 2097 struct pldm_msg *msg, size_t payload_length) 2098 { 2099 if (msg == NULL || present_reading == NULL) { 2100 return PLDM_ERROR_INVALID_DATA; 2101 } 2102 2103 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 2104 return PLDM_ERROR_INVALID_DATA; 2105 } 2106 2107 struct pldm_header_info header = { 0 }; 2108 header.msg_type = PLDM_RESPONSE; 2109 header.instance = instance_id; 2110 header.pldm_type = PLDM_PLATFORM; 2111 header.command = PLDM_GET_SENSOR_READING; 2112 2113 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2114 if (rc != PLDM_SUCCESS) { 2115 return rc; 2116 } 2117 2118 struct pldm_get_sensor_reading_resp *response = 2119 (struct pldm_get_sensor_reading_resp *)msg->payload; 2120 2121 response->completion_code = completion_code; 2122 response->sensor_data_size = sensor_data_size; 2123 response->sensor_operational_state = sensor_operational_state; 2124 response->sensor_event_message_enable = sensor_event_message_enable; 2125 response->present_state = present_state; 2126 response->previous_state = previous_state; 2127 response->event_state = event_state; 2128 2129 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 2130 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 2131 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) { 2132 return PLDM_ERROR_INVALID_LENGTH; 2133 } 2134 response->present_reading[0] = *present_reading; 2135 2136 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 2137 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 2138 if (payload_length != 2139 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) { 2140 return PLDM_ERROR_INVALID_LENGTH; 2141 } 2142 uint16_t val = *(uint16_t *)present_reading; 2143 val = htole16(val); 2144 memcpy(response->present_reading, &val, 2); 2145 2146 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 2147 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 2148 if (payload_length != 2149 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) { 2150 return PLDM_ERROR_INVALID_LENGTH; 2151 } 2152 uint32_t val = *(uint32_t *)present_reading; 2153 val = htole32(val); 2154 memcpy(response->present_reading, &val, 4); 2155 } 2156 2157 return PLDM_SUCCESS; 2158 } 2159 2160 LIBPLDM_ABI_STABLE 2161 int decode_get_sensor_reading_req(const struct pldm_msg *msg, 2162 size_t payload_length, uint16_t *sensor_id, 2163 uint8_t *rearm_event_state) 2164 { 2165 struct pldm_msgbuf _buf; 2166 struct pldm_msgbuf *buf = &_buf; 2167 int rc; 2168 2169 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) { 2170 return PLDM_ERROR_INVALID_DATA; 2171 } 2172 2173 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_REQ_BYTES, 2174 msg->payload, payload_length); 2175 if (rc) { 2176 return rc; 2177 } 2178 2179 pldm_msgbuf_extract_p(buf, sensor_id); 2180 pldm_msgbuf_extract_p(buf, rearm_event_state); 2181 2182 return pldm_msgbuf_destroy(buf); 2183 } 2184 2185 LIBPLDM_ABI_STABLE 2186 int encode_set_event_receiver_req(uint8_t instance_id, 2187 uint8_t event_message_global_enable, 2188 uint8_t transport_protocol_type, 2189 uint8_t event_receiver_address_info, 2190 uint16_t heartbeat_timer, 2191 struct pldm_msg *msg) 2192 { 2193 if (msg == NULL) { 2194 return PLDM_ERROR_INVALID_DATA; 2195 } 2196 2197 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) { 2198 return PLDM_ERROR_INVALID_DATA; 2199 } 2200 2201 struct pldm_header_info header = { 0 }; 2202 header.msg_type = PLDM_REQUEST; 2203 header.instance = instance_id; 2204 header.pldm_type = PLDM_PLATFORM; 2205 header.command = PLDM_SET_EVENT_RECEIVER; 2206 2207 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2208 if (rc != PLDM_SUCCESS) { 2209 return rc; 2210 } 2211 2212 struct pldm_set_event_receiver_req *request = 2213 (struct pldm_set_event_receiver_req *)msg->payload; 2214 request->event_message_global_enable = event_message_global_enable; 2215 2216 request->transport_protocol_type = transport_protocol_type; 2217 request->event_receiver_address_info = event_receiver_address_info; 2218 2219 if (event_message_global_enable == 2220 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 2221 if (heartbeat_timer == 0) { 2222 return PLDM_ERROR_INVALID_DATA; 2223 } 2224 request->heartbeat_timer = htole16(heartbeat_timer); 2225 } 2226 2227 return PLDM_SUCCESS; 2228 } 2229 2230 LIBPLDM_ABI_STABLE 2231 int decode_set_event_receiver_resp(const struct pldm_msg *msg, 2232 size_t payload_length, 2233 uint8_t *completion_code) 2234 { 2235 struct pldm_msgbuf _buf; 2236 struct pldm_msgbuf *buf = &_buf; 2237 int rc; 2238 2239 if (msg == NULL || completion_code == NULL) { 2240 return PLDM_ERROR_INVALID_DATA; 2241 } 2242 2243 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES, 2244 msg->payload, payload_length); 2245 if (rc) { 2246 return rc; 2247 } 2248 2249 pldm_msgbuf_extract_p(buf, completion_code); 2250 2251 return pldm_msgbuf_destroy(buf); 2252 } 2253 2254 LIBPLDM_ABI_STABLE 2255 int decode_set_event_receiver_req(const struct pldm_msg *msg, 2256 size_t payload_length, 2257 uint8_t *event_message_global_enable, 2258 uint8_t *transport_protocol_type, 2259 uint8_t *event_receiver_address_info, 2260 uint16_t *heartbeat_timer) 2261 2262 { 2263 struct pldm_msgbuf _buf; 2264 struct pldm_msgbuf *buf = &_buf; 2265 int rc; 2266 2267 if (msg == NULL || event_message_global_enable == NULL || 2268 transport_protocol_type == NULL || 2269 event_receiver_address_info == NULL || heartbeat_timer == NULL) { 2270 return PLDM_ERROR_INVALID_DATA; 2271 } 2272 2273 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES, 2274 msg->payload, payload_length); 2275 if (rc) { 2276 return rc; 2277 } 2278 2279 pldm_msgbuf_extract_p(buf, event_message_global_enable); 2280 pldm_msgbuf_extract_p(buf, transport_protocol_type); 2281 pldm_msgbuf_extract_p(buf, event_receiver_address_info); 2282 pldm_msgbuf_extract_p(buf, heartbeat_timer); 2283 2284 rc = pldm_msgbuf_destroy(buf); 2285 if (rc) { 2286 return rc; 2287 } 2288 2289 if ((*event_message_global_enable == 2290 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) && 2291 (*heartbeat_timer == 0)) { 2292 return PLDM_ERROR_INVALID_DATA; 2293 } 2294 2295 return PLDM_SUCCESS; 2296 } 2297 2298 LIBPLDM_ABI_STABLE 2299 int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code, 2300 struct pldm_msg *msg) 2301 2302 { 2303 if (msg == NULL) { 2304 return PLDM_ERROR_INVALID_DATA; 2305 } 2306 2307 struct pldm_header_info header = { 0 }; 2308 header.instance = instance_id; 2309 header.msg_type = PLDM_RESPONSE; 2310 header.pldm_type = PLDM_PLATFORM; 2311 header.command = PLDM_SET_EVENT_RECEIVER; 2312 2313 uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 2314 if (rc != PLDM_SUCCESS) { 2315 return rc; 2316 } 2317 2318 msg->payload[0] = completion_code; 2319 2320 return PLDM_SUCCESS; 2321 } 2322 2323 LIBPLDM_ABI_STABLE 2324 int encode_poll_for_platform_event_message_req(uint8_t instance_id, 2325 uint8_t format_version, 2326 uint8_t transfer_operation_flag, 2327 uint32_t data_transfer_handle, 2328 uint16_t event_id_to_acknowledge, 2329 struct pldm_msg *msg, 2330 size_t payload_length) 2331 { 2332 struct pldm_msgbuf _buf; 2333 struct pldm_msgbuf *buf = &_buf; 2334 int rc; 2335 2336 if (msg == NULL) { 2337 return PLDM_ERROR_INVALID_DATA; 2338 } 2339 2340 struct pldm_header_info header = { 0 }; 2341 header.msg_type = PLDM_REQUEST; 2342 header.instance = instance_id; 2343 header.pldm_type = PLDM_PLATFORM; 2344 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 2345 2346 rc = pack_pldm_header(&header, &(msg->hdr)); 2347 if (rc != PLDM_SUCCESS) { 2348 return rc; 2349 } 2350 2351 rc = pldm_msgbuf_init_cc( 2352 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 2353 msg->payload, payload_length); 2354 if (rc) { 2355 return rc; 2356 } 2357 2358 pldm_msgbuf_insert(buf, format_version); 2359 pldm_msgbuf_insert(buf, transfer_operation_flag); 2360 pldm_msgbuf_insert(buf, data_transfer_handle); 2361 pldm_msgbuf_insert(buf, event_id_to_acknowledge); 2362 2363 return pldm_msgbuf_destroy(buf); 2364 } 2365 2366 LIBPLDM_ABI_STABLE 2367 int decode_poll_for_platform_event_message_resp( 2368 const struct pldm_msg *msg, size_t payload_length, 2369 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id, 2370 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 2371 uint8_t *event_class, uint32_t *event_data_size, void **event_data, 2372 uint32_t *event_data_integrity_checksum) 2373 { 2374 struct pldm_msgbuf _buf; 2375 struct pldm_msgbuf *buf = &_buf; 2376 int rc; 2377 2378 if (msg == NULL || completion_code == NULL || tid == NULL || 2379 event_id == NULL || next_data_transfer_handle == NULL || 2380 transfer_flag == NULL || event_class == NULL || 2381 event_data_size == NULL || event_data == NULL || 2382 event_data_integrity_checksum == NULL) { 2383 return PLDM_ERROR_INVALID_DATA; 2384 } 2385 2386 rc = pldm_msgbuf_init_cc( 2387 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 2388 msg->payload, payload_length); 2389 if (rc) { 2390 return rc; 2391 } 2392 2393 rc = pldm_msgbuf_extract_p(buf, completion_code); 2394 if (rc) { 2395 return rc; 2396 } 2397 if (PLDM_SUCCESS != *completion_code) { 2398 return *completion_code; 2399 } 2400 2401 pldm_msgbuf_extract_p(buf, tid); 2402 rc = pldm_msgbuf_extract_p(buf, event_id); 2403 if (rc) { 2404 return rc; 2405 } 2406 if ((*event_id == 0) || (*event_id == 0xffff)) { 2407 return PLDM_SUCCESS; 2408 } 2409 2410 pldm_msgbuf_extract_p(buf, next_data_transfer_handle); 2411 rc = pldm_msgbuf_extract_p(buf, transfer_flag); 2412 if (rc) { 2413 return rc; 2414 } 2415 2416 pldm_msgbuf_extract_p(buf, event_class); 2417 rc = pldm_msgbuf_extract_p(buf, event_data_size); 2418 if (rc) { 2419 return rc; 2420 } 2421 if (*event_data_size > payload_length) { 2422 return PLDM_ERROR_INVALID_DATA; 2423 } 2424 2425 if (*event_data_size > 0) { 2426 pldm_msgbuf_span_required(buf, *event_data_size, event_data); 2427 } 2428 2429 if (*transfer_flag == PLDM_END || 2430 *transfer_flag == PLDM_START_AND_END) { 2431 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum); 2432 } 2433 2434 return pldm_msgbuf_destroy_consumed(buf); 2435 } 2436 2437 LIBPLDM_ABI_TESTING 2438 int decode_numeric_effecter_pdr_data( 2439 const void *pdr_data, size_t pdr_data_length, 2440 struct pldm_numeric_effecter_value_pdr *pdr_value) 2441 { 2442 struct pldm_msgbuf _buf; 2443 struct pldm_msgbuf *buf = &_buf; 2444 struct pldm_value_pdr_hdr hdr; 2445 int rc; 2446 2447 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 2448 pdr_data, pdr_data_length); 2449 if (rc) { 2450 return rc; 2451 } 2452 2453 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &hdr); 2454 if (rc) { 2455 return rc; 2456 } 2457 2458 rc = pldm_platform_pdr_hdr_validate( 2459 &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 2460 pdr_data_length); 2461 if (rc) { 2462 return rc; 2463 } 2464 2465 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr)); 2466 2467 pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 2468 pldm_msgbuf_extract(buf, pdr_value->effecter_id); 2469 pldm_msgbuf_extract(buf, pdr_value->entity_type); 2470 pldm_msgbuf_extract(buf, pdr_value->entity_instance); 2471 pldm_msgbuf_extract(buf, pdr_value->container_id); 2472 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id); 2473 pldm_msgbuf_extract(buf, pdr_value->effecter_init); 2474 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names); 2475 pldm_msgbuf_extract(buf, pdr_value->base_unit); 2476 pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 2477 pldm_msgbuf_extract(buf, pdr_value->rate_unit); 2478 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 2479 pldm_msgbuf_extract(buf, pdr_value->aux_unit); 2480 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 2481 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 2482 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 2483 pldm_msgbuf_extract(buf, pdr_value->is_linear); 2484 2485 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size); 2486 if (rc) { 2487 return rc; 2488 } 2489 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 2490 return PLDM_ERROR_INVALID_DATA; 2491 } 2492 2493 pldm_msgbuf_extract(buf, pdr_value->resolution); 2494 pldm_msgbuf_extract(buf, pdr_value->offset); 2495 pldm_msgbuf_extract(buf, pdr_value->accuracy); 2496 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 2497 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 2498 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 2499 pldm_msgbuf_extract(buf, pdr_value->transition_interval); 2500 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 2501 pdr_value->max_settable); 2502 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 2503 pdr_value->min_settable); 2504 2505 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 2506 if (rc) { 2507 return rc; 2508 } 2509 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 2510 return PLDM_ERROR_INVALID_DATA; 2511 } 2512 2513 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 2514 pldm_msgbuf_extract_range_field_format( 2515 buf, pdr_value->range_field_format, pdr_value->nominal_value); 2516 pldm_msgbuf_extract_range_field_format( 2517 buf, pdr_value->range_field_format, pdr_value->normal_max); 2518 pldm_msgbuf_extract_range_field_format( 2519 buf, pdr_value->range_field_format, pdr_value->normal_min); 2520 pldm_msgbuf_extract_range_field_format( 2521 buf, pdr_value->range_field_format, pdr_value->rated_max); 2522 pldm_msgbuf_extract_range_field_format( 2523 buf, pdr_value->range_field_format, pdr_value->rated_min); 2524 2525 return pldm_msgbuf_destroy_consumed(buf); 2526 } 2527 2528 LIBPLDM_ABI_STABLE 2529 int encode_get_state_effecter_states_req(uint8_t instance_id, 2530 uint16_t effecter_id, 2531 struct pldm_msg *msg, 2532 size_t payload_length) 2533 { 2534 struct pldm_msgbuf _buf; 2535 struct pldm_msgbuf *buf = &_buf; 2536 int rc; 2537 2538 if (msg == NULL) { 2539 return -EINVAL; 2540 } 2541 2542 struct pldm_header_info header = { 0 }; 2543 header.msg_type = PLDM_REQUEST; 2544 header.instance = instance_id; 2545 header.pldm_type = PLDM_PLATFORM; 2546 header.command = PLDM_GET_STATE_EFFECTER_STATES; 2547 2548 rc = pack_pldm_header_errno(&header, &msg->hdr); 2549 if (rc < 0) { 2550 return rc; 2551 } 2552 2553 rc = pldm_msgbuf_init_errno(buf, 2554 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES, 2555 msg->payload, payload_length); 2556 if (rc) { 2557 return rc; 2558 } 2559 2560 pldm_msgbuf_insert(buf, effecter_id); 2561 2562 return pldm_msgbuf_destroy_consumed(buf); 2563 } 2564 2565 LIBPLDM_ABI_STABLE 2566 int decode_get_state_effecter_states_req(const struct pldm_msg *msg, 2567 size_t payload_length, 2568 uint16_t *effecter_id) 2569 { 2570 struct pldm_msgbuf _buf; 2571 struct pldm_msgbuf *buf = &_buf; 2572 int rc; 2573 2574 if (msg == NULL || effecter_id == NULL) { 2575 return -EINVAL; 2576 } 2577 2578 rc = pldm_msgbuf_init_errno( 2579 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2580 msg->payload, payload_length); 2581 if (rc) { 2582 return rc; 2583 } 2584 2585 pldm_msgbuf_extract_p(buf, effecter_id); 2586 2587 return pldm_msgbuf_destroy_consumed(buf); 2588 } 2589 2590 LIBPLDM_ABI_STABLE 2591 int decode_get_state_effecter_states_resp( 2592 const struct pldm_msg *msg, size_t payload_length, 2593 struct pldm_get_state_effecter_states_resp *resp) 2594 { 2595 struct pldm_msgbuf _buf; 2596 struct pldm_msgbuf *buf = &_buf; 2597 get_effecter_state_field *field; 2598 int rc; 2599 int i; 2600 2601 if (msg == NULL || resp == NULL) { 2602 return -EINVAL; 2603 } 2604 2605 rc = pldm_msgbuf_init_errno( 2606 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2607 msg->payload, payload_length); 2608 if (rc) { 2609 return rc; 2610 } 2611 2612 rc = pldm_msgbuf_extract(buf, resp->completion_code); 2613 if (rc) { 2614 return rc; 2615 } 2616 2617 if (PLDM_SUCCESS != resp->completion_code) { 2618 return 0; 2619 } 2620 2621 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count); 2622 if (rc) { 2623 return rc; 2624 } 2625 2626 uint8_t comp_effecter_count = resp->comp_effecter_count; 2627 2628 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 2629 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2630 return -EBADMSG; 2631 } 2632 2633 for (i = 0, field = resp->field; i < comp_effecter_count; 2634 i++, field++) { 2635 pldm_msgbuf_extract(buf, field->effecter_op_state); 2636 pldm_msgbuf_extract(buf, field->pending_state); 2637 pldm_msgbuf_extract(buf, field->present_state); 2638 } 2639 2640 return pldm_msgbuf_destroy_consumed(buf); 2641 } 2642 2643 LIBPLDM_ABI_STABLE 2644 int encode_get_state_effecter_states_resp( 2645 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp, 2646 struct pldm_msg *msg, size_t payload_length) 2647 { 2648 struct pldm_msgbuf _buf; 2649 struct pldm_msgbuf *buf = &_buf; 2650 get_effecter_state_field *field; 2651 int rc; 2652 int i; 2653 2654 if (msg == NULL || resp == NULL) { 2655 return -EINVAL; 2656 } 2657 2658 uint8_t comp_effecter_count = resp->comp_effecter_count; 2659 2660 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 2661 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2662 return -EBADMSG; 2663 } 2664 2665 struct pldm_header_info header = { 0 }; 2666 header.msg_type = PLDM_RESPONSE; 2667 header.instance = instance_id; 2668 header.pldm_type = PLDM_PLATFORM; 2669 header.command = PLDM_GET_STATE_EFFECTER_STATES; 2670 2671 rc = pack_pldm_header_errno(&header, &msg->hdr); 2672 if (rc < 0) { 2673 return rc; 2674 } 2675 2676 rc = pldm_msgbuf_init_errno( 2677 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 2678 msg->payload, payload_length); 2679 if (rc) { 2680 return rc; 2681 } 2682 2683 pldm_msgbuf_insert(buf, resp->completion_code); 2684 pldm_msgbuf_insert(buf, comp_effecter_count); 2685 2686 for (i = 0, field = resp->field; i < comp_effecter_count; 2687 i++, field++) { 2688 pldm_msgbuf_insert(buf, field->effecter_op_state); 2689 pldm_msgbuf_insert(buf, field->pending_state); 2690 pldm_msgbuf_insert(buf, field->present_state); 2691 } 2692 2693 return pldm_msgbuf_destroy_consumed(buf); 2694 } 2695 2696 LIBPLDM_ABI_STABLE 2697 int decode_entity_auxiliary_names_pdr( 2698 const void *data, size_t data_length, 2699 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length) 2700 { 2701 struct pldm_msgbuf _buf; 2702 struct pldm_msgbuf *buf = &_buf; 2703 struct pldm_msgbuf _src; 2704 struct pldm_msgbuf *src = &_src; 2705 struct pldm_msgbuf _dst; 2706 struct pldm_msgbuf *dst = &_dst; 2707 size_t names_len = 0; 2708 void *names = NULL; 2709 int rc; 2710 int i; 2711 2712 /* 2713 * Alignment of auxiliary_name_data is an invariant as we statically assert 2714 * its behaviour in the header. 2715 */ 2716 assert(!((uintptr_t)pdr->auxiliary_name_data & 2717 (alignof(pldm_utf16be) - 1))); 2718 2719 /* Reject any lengths that are obviously invalid */ 2720 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) { 2721 return -EINVAL; 2722 } 2723 2724 rc = pldm_msgbuf_init_errno( 2725 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data, 2726 data_length); 2727 if (rc) { 2728 return rc; 2729 } 2730 2731 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr->hdr); 2732 if (rc) { 2733 return rc; 2734 } 2735 2736 rc = pldm_platform_pdr_hdr_validate( 2737 &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, 2738 data_length); 2739 if (rc) { 2740 return rc; 2741 } 2742 2743 pldm_msgbuf_extract(buf, pdr->container.entity_type); 2744 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num); 2745 pldm_msgbuf_extract(buf, pdr->container.entity_container_id); 2746 pldm_msgbuf_extract(buf, pdr->shared_name_count); 2747 rc = pldm_msgbuf_extract(buf, pdr->name_string_count); 2748 if (rc < 0) { 2749 return rc; 2750 } 2751 2752 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len); 2753 if (rc < 0) { 2754 return rc; 2755 } 2756 2757 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr); 2758 2759 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size, 2760 pdr->auxiliary_name_data, 2761 pdr->auxiliary_name_data_size); 2762 if (rc < 0) { 2763 return rc; 2764 } 2765 2766 /* 2767 * Below we do two passes over the same region. This is to first pack the 2768 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings, 2769 * to maintain appropriate alignment. 2770 */ 2771 2772 /* Initialise for the first pass to extract the UTF16-BE name strings */ 2773 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 2774 if (rc < 0) { 2775 return rc; 2776 } 2777 2778 for (i = 0; i < pdr->name_string_count; i++) { 2779 pldm_msgbuf_span_string_ascii(src, NULL, NULL); 2780 pldm_msgbuf_copy_string_utf16(dst, src); 2781 } 2782 2783 rc = pldm_msgbuf_destroy_consumed(src); 2784 if (rc < 0) { 2785 return rc; 2786 } 2787 2788 /* Reinitialise for the second pass to extract the ASCII tag strings */ 2789 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 2790 if (rc < 0) { 2791 return rc; 2792 } 2793 2794 for (i = 0; i < pdr->name_string_count; i++) { 2795 pldm_msgbuf_copy_string_ascii(dst, src); 2796 pldm_msgbuf_span_string_utf16(src, NULL, NULL); 2797 } 2798 2799 if ((rc = pldm_msgbuf_destroy(dst)) || 2800 (rc = pldm_msgbuf_destroy(src)) || 2801 (rc = pldm_msgbuf_destroy(buf))) { 2802 return rc; 2803 } 2804 2805 return 0; 2806 } 2807 2808 LIBPLDM_ABI_STABLE 2809 int decode_pldm_entity_auxiliary_names_pdr_index( 2810 struct pldm_entity_auxiliary_names_pdr *pdr) 2811 { 2812 struct pldm_msgbuf _buf; 2813 struct pldm_msgbuf *buf = &_buf; 2814 int rc; 2815 int i; 2816 2817 if (!pdr) { 2818 return -EINVAL; 2819 } 2820 2821 if (pdr->name_string_count == 0 && pdr->names) { 2822 return -EINVAL; 2823 } 2824 2825 if (pdr->name_string_count > 0 && !pdr->names) { 2826 return -EINVAL; 2827 } 2828 2829 if (pdr->name_string_count == 0) { 2830 return 0; 2831 } 2832 2833 /* 2834 * Minimum size is one NUL for each member of each entry 2835 * 2836 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2 2837 * states the following: 2838 * 2839 * > A null-terminated ISO646 ASCII string ... 2840 * > 2841 * > special value: null string = 0x0000 = unspecified. 2842 * 2843 * Until proven otherwise we will assume the "0x0000" is a 2844 * misrepresentation of an ASCII NUL, and that ASCII NUL is 2845 * represented by a single byte. 2846 */ 2847 rc = pldm_msgbuf_init_errno( 2848 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)), 2849 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size); 2850 if (rc) { 2851 return rc; 2852 } 2853 2854 for (i = 0; i < pdr->name_string_count; i++) { 2855 void *loc = NULL; 2856 pldm_msgbuf_span_string_utf16(buf, &loc, NULL); 2857 pdr->names[i].name = loc; 2858 } 2859 2860 for (i = 0; i < pdr->name_string_count; i++) { 2861 void *loc = NULL; 2862 pldm_msgbuf_span_string_ascii(buf, &loc, NULL); 2863 pdr->names[i].tag = loc; 2864 } 2865 2866 return pldm_msgbuf_destroy_consumed(buf); 2867 } 2868