148761c62SAndrew Jeffery /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2f490a38fSTal Yacobi #include "dsp/base.h" 348761c62SAndrew Jeffery #include "msgbuf.h" 448761c62SAndrew Jeffery #include "msgbuf/platform.h" 548761c62SAndrew Jeffery 648761c62SAndrew Jeffery #include <libpldm/base.h> 748761c62SAndrew Jeffery #include <libpldm/platform.h> 848761c62SAndrew Jeffery #include <libpldm/pldm_types.h> 948761c62SAndrew Jeffery 1048761c62SAndrew Jeffery #include <endian.h> 1148761c62SAndrew Jeffery #include <stdint.h> 1248761c62SAndrew Jeffery #include <stdlib.h> 1348761c62SAndrew Jeffery #include <string.h> 14dacfa354SThu Nguyen #include <uchar.h> 1548761c62SAndrew Jeffery 1648761c62SAndrew Jeffery static int pldm_platform_pdr_hdr_validate(struct pldm_value_pdr_hdr *ctx, 1748761c62SAndrew Jeffery size_t lower, size_t upper) 1848761c62SAndrew Jeffery { 1948761c62SAndrew Jeffery if (ctx->length + sizeof(*ctx) < lower) { 2048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 2148761c62SAndrew Jeffery } 2248761c62SAndrew Jeffery 2348761c62SAndrew Jeffery if (ctx->length > upper) { 2448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 2548761c62SAndrew Jeffery } 2648761c62SAndrew Jeffery 2748761c62SAndrew Jeffery return PLDM_SUCCESS; 2848761c62SAndrew Jeffery } 2948761c62SAndrew Jeffery 3048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 3148761c62SAndrew Jeffery int encode_state_effecter_pdr( 3248761c62SAndrew Jeffery struct pldm_state_effecter_pdr *const effecter, 3348761c62SAndrew Jeffery const size_t allocation_size, 3448761c62SAndrew Jeffery const struct state_effecter_possible_states *const possible_states, 3548761c62SAndrew Jeffery const size_t possible_states_size, size_t *const actual_size) 3648761c62SAndrew Jeffery { 3748761c62SAndrew Jeffery // Encode possible states 3848761c62SAndrew Jeffery 3948761c62SAndrew Jeffery size_t calculated_possible_states_size = 0; 4048761c62SAndrew Jeffery 4148761c62SAndrew Jeffery { 4248761c62SAndrew Jeffery char *states_ptr = (char *)possible_states; 4348761c62SAndrew Jeffery char *const begin_states_ptr = states_ptr; 4448761c62SAndrew Jeffery 4548761c62SAndrew Jeffery for (int i = 0; i < effecter->composite_effecter_count; ++i) { 4648761c62SAndrew Jeffery struct state_effecter_possible_states *states = 4748761c62SAndrew Jeffery (struct state_effecter_possible_states *) 4848761c62SAndrew Jeffery states_ptr; 4948761c62SAndrew Jeffery 5048761c62SAndrew Jeffery HTOLE16(states->state_set_id); 5148761c62SAndrew Jeffery 5248761c62SAndrew Jeffery states_ptr += 5348761c62SAndrew Jeffery (sizeof(*states) - sizeof(states->states) + 5448761c62SAndrew Jeffery states->possible_states_size); 5548761c62SAndrew Jeffery } 5648761c62SAndrew Jeffery 5748761c62SAndrew Jeffery calculated_possible_states_size = states_ptr - begin_states_ptr; 5848761c62SAndrew Jeffery } 5948761c62SAndrew Jeffery 6048761c62SAndrew Jeffery // Check lengths 6148761c62SAndrew Jeffery 6248761c62SAndrew Jeffery if (possible_states_size != calculated_possible_states_size) { 6348761c62SAndrew Jeffery *actual_size = 0; 6448761c62SAndrew Jeffery return PLDM_ERROR; 6548761c62SAndrew Jeffery } 6648761c62SAndrew Jeffery 6748761c62SAndrew Jeffery *actual_size = 6848761c62SAndrew Jeffery (sizeof(struct pldm_state_effecter_pdr) + possible_states_size - 6948761c62SAndrew Jeffery sizeof(effecter->possible_states)); 7048761c62SAndrew Jeffery 7148761c62SAndrew Jeffery if (allocation_size < *actual_size) { 7248761c62SAndrew Jeffery *actual_size = 0; 7348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 7448761c62SAndrew Jeffery } 7548761c62SAndrew Jeffery 7648761c62SAndrew Jeffery // Encode rest of PDR 7748761c62SAndrew Jeffery 7848761c62SAndrew Jeffery effecter->hdr.version = 1; 7948761c62SAndrew Jeffery effecter->hdr.type = PLDM_STATE_EFFECTER_PDR; 8048761c62SAndrew Jeffery effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 8148761c62SAndrew Jeffery 8248761c62SAndrew Jeffery memcpy(effecter->possible_states, possible_states, 8348761c62SAndrew Jeffery possible_states_size); 8448761c62SAndrew Jeffery 8548761c62SAndrew Jeffery // Convert effecter PDR body 8648761c62SAndrew Jeffery HTOLE16(effecter->terminus_handle); 8748761c62SAndrew Jeffery HTOLE16(effecter->effecter_id); 8848761c62SAndrew Jeffery HTOLE16(effecter->entity_type); 8948761c62SAndrew Jeffery HTOLE16(effecter->entity_instance); 9048761c62SAndrew Jeffery HTOLE16(effecter->container_id); 9148761c62SAndrew Jeffery HTOLE16(effecter->effecter_semantic_id); 9248761c62SAndrew Jeffery 9348761c62SAndrew Jeffery // Convert header 9448761c62SAndrew Jeffery HTOLE32(effecter->hdr.record_handle); 9548761c62SAndrew Jeffery HTOLE16(effecter->hdr.record_change_num); 9648761c62SAndrew Jeffery HTOLE16(effecter->hdr.length); 9748761c62SAndrew Jeffery 9848761c62SAndrew Jeffery return PLDM_SUCCESS; 9948761c62SAndrew Jeffery } 10048761c62SAndrew Jeffery 10148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 10248761c62SAndrew Jeffery int encode_state_sensor_pdr( 10348761c62SAndrew Jeffery struct pldm_state_sensor_pdr *const sensor, 10448761c62SAndrew Jeffery const size_t allocation_size, 10548761c62SAndrew Jeffery const struct state_sensor_possible_states *const possible_states, 10648761c62SAndrew Jeffery const size_t possible_states_size, size_t *const actual_size) 10748761c62SAndrew Jeffery { 10848761c62SAndrew Jeffery // Encode possible states 10948761c62SAndrew Jeffery 11048761c62SAndrew Jeffery size_t calculated_possible_states_size = 0; 11148761c62SAndrew Jeffery 11248761c62SAndrew Jeffery { 11348761c62SAndrew Jeffery char *states_ptr = (char *)possible_states; 11448761c62SAndrew Jeffery char *const begin_states_ptr = states_ptr; 11548761c62SAndrew Jeffery 11648761c62SAndrew Jeffery for (int i = 0; i < sensor->composite_sensor_count; ++i) { 11748761c62SAndrew Jeffery struct state_sensor_possible_states *states = 11848761c62SAndrew Jeffery (struct state_sensor_possible_states *) 11948761c62SAndrew Jeffery states_ptr; 12048761c62SAndrew Jeffery 12148761c62SAndrew Jeffery HTOLE16(states->state_set_id); 12248761c62SAndrew Jeffery 12348761c62SAndrew Jeffery states_ptr += 12448761c62SAndrew Jeffery (sizeof(*states) - sizeof(states->states) + 12548761c62SAndrew Jeffery states->possible_states_size); 12648761c62SAndrew Jeffery } 12748761c62SAndrew Jeffery 12848761c62SAndrew Jeffery calculated_possible_states_size = states_ptr - begin_states_ptr; 12948761c62SAndrew Jeffery } 13048761c62SAndrew Jeffery 13148761c62SAndrew Jeffery // Check lengths 13248761c62SAndrew Jeffery 13348761c62SAndrew Jeffery if (possible_states_size != calculated_possible_states_size) { 13448761c62SAndrew Jeffery *actual_size = 0; 13548761c62SAndrew Jeffery return PLDM_ERROR; 13648761c62SAndrew Jeffery } 13748761c62SAndrew Jeffery 13848761c62SAndrew Jeffery *actual_size = (sizeof(struct pldm_state_sensor_pdr) + 13948761c62SAndrew Jeffery possible_states_size - sizeof(sensor->possible_states)); 14048761c62SAndrew Jeffery 14148761c62SAndrew Jeffery if (allocation_size < *actual_size) { 14248761c62SAndrew Jeffery *actual_size = 0; 14348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 14448761c62SAndrew Jeffery } 14548761c62SAndrew Jeffery 14648761c62SAndrew Jeffery // Encode rest of PDR 14748761c62SAndrew Jeffery 14848761c62SAndrew Jeffery sensor->hdr.version = 1; 14948761c62SAndrew Jeffery sensor->hdr.type = PLDM_STATE_SENSOR_PDR; 15048761c62SAndrew Jeffery sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 15148761c62SAndrew Jeffery 15248761c62SAndrew Jeffery memcpy(sensor->possible_states, possible_states, possible_states_size); 15348761c62SAndrew Jeffery 15448761c62SAndrew Jeffery // Convert sensor PDR body 15548761c62SAndrew Jeffery HTOLE16(sensor->terminus_handle); 15648761c62SAndrew Jeffery HTOLE16(sensor->sensor_id); 15748761c62SAndrew Jeffery HTOLE16(sensor->entity_type); 15848761c62SAndrew Jeffery HTOLE16(sensor->entity_instance); 15948761c62SAndrew Jeffery HTOLE16(sensor->container_id); 16048761c62SAndrew Jeffery 16148761c62SAndrew Jeffery // Convert header 16248761c62SAndrew Jeffery HTOLE32(sensor->hdr.record_handle); 16348761c62SAndrew Jeffery HTOLE16(sensor->hdr.record_change_num); 16448761c62SAndrew Jeffery HTOLE16(sensor->hdr.length); 16548761c62SAndrew Jeffery 16648761c62SAndrew Jeffery return PLDM_SUCCESS; 16748761c62SAndrew Jeffery } 16848761c62SAndrew Jeffery 16948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 17048761c62SAndrew Jeffery int encode_set_state_effecter_states_resp(uint8_t instance_id, 17148761c62SAndrew Jeffery uint8_t completion_code, 17248761c62SAndrew Jeffery struct pldm_msg *msg) 17348761c62SAndrew Jeffery { 17448761c62SAndrew Jeffery if (msg == NULL) { 17548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 17648761c62SAndrew Jeffery } 17748761c62SAndrew Jeffery 17848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 17948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 18048761c62SAndrew Jeffery header.instance = instance_id; 18148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 18248761c62SAndrew Jeffery header.command = PLDM_SET_STATE_EFFECTER_STATES; 18348761c62SAndrew Jeffery 18448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 18548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 18648761c62SAndrew Jeffery return rc; 18748761c62SAndrew Jeffery } 18848761c62SAndrew Jeffery 18948761c62SAndrew Jeffery msg->payload[0] = completion_code; 19048761c62SAndrew Jeffery 19148761c62SAndrew Jeffery return PLDM_SUCCESS; 19248761c62SAndrew Jeffery } 19348761c62SAndrew Jeffery 19448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 19548761c62SAndrew Jeffery int encode_set_state_effecter_states_req(uint8_t instance_id, 19648761c62SAndrew Jeffery uint16_t effecter_id, 19748761c62SAndrew Jeffery uint8_t comp_effecter_count, 19848761c62SAndrew Jeffery set_effecter_state_field *field, 19948761c62SAndrew Jeffery struct pldm_msg *msg) 20048761c62SAndrew Jeffery { 20148761c62SAndrew Jeffery if (msg == NULL) { 20248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 20348761c62SAndrew Jeffery } 20448761c62SAndrew Jeffery 20548761c62SAndrew Jeffery if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 || 20648761c62SAndrew Jeffery field == NULL) { 20748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 20848761c62SAndrew Jeffery } 20948761c62SAndrew Jeffery 21048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 21148761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 21248761c62SAndrew Jeffery header.instance = instance_id; 21348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 21448761c62SAndrew Jeffery header.command = PLDM_SET_STATE_EFFECTER_STATES; 21548761c62SAndrew Jeffery 21648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 21748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 21848761c62SAndrew Jeffery return rc; 21948761c62SAndrew Jeffery } 22048761c62SAndrew Jeffery 22148761c62SAndrew Jeffery struct pldm_set_state_effecter_states_req *request = 22248761c62SAndrew Jeffery (struct pldm_set_state_effecter_states_req *)msg->payload; 22348761c62SAndrew Jeffery effecter_id = htole16(effecter_id); 22448761c62SAndrew Jeffery request->effecter_id = effecter_id; 22548761c62SAndrew Jeffery request->comp_effecter_count = comp_effecter_count; 22648761c62SAndrew Jeffery memcpy(request->field, field, 22748761c62SAndrew Jeffery (sizeof(set_effecter_state_field) * comp_effecter_count)); 22848761c62SAndrew Jeffery 22948761c62SAndrew Jeffery return PLDM_SUCCESS; 23048761c62SAndrew Jeffery } 23148761c62SAndrew Jeffery 23248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 23348761c62SAndrew Jeffery int decode_set_state_effecter_states_resp(const struct pldm_msg *msg, 23448761c62SAndrew Jeffery size_t payload_length, 23548761c62SAndrew Jeffery uint8_t *completion_code) 23648761c62SAndrew Jeffery { 23748761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 23848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 23948761c62SAndrew Jeffery } 24048761c62SAndrew Jeffery 24148761c62SAndrew Jeffery *completion_code = msg->payload[0]; 24248761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 24348761c62SAndrew Jeffery return PLDM_SUCCESS; 24448761c62SAndrew Jeffery } 24548761c62SAndrew Jeffery 24648761c62SAndrew Jeffery if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) { 24748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 24848761c62SAndrew Jeffery } 24948761c62SAndrew Jeffery 25048761c62SAndrew Jeffery return PLDM_SUCCESS; 25148761c62SAndrew Jeffery } 25248761c62SAndrew Jeffery 25348761c62SAndrew Jeffery #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3 25448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 25548761c62SAndrew Jeffery int decode_set_state_effecter_states_req(const struct pldm_msg *msg, 25648761c62SAndrew Jeffery size_t payload_length, 25748761c62SAndrew Jeffery uint16_t *effecter_id, 25848761c62SAndrew Jeffery uint8_t *comp_effecter_count, 25948761c62SAndrew Jeffery set_effecter_state_field *field) 26048761c62SAndrew Jeffery { 26148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 26248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 26348761c62SAndrew Jeffery int rc; 26448761c62SAndrew Jeffery int i; 26548761c62SAndrew Jeffery 26648761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL || 26748761c62SAndrew Jeffery field == NULL) { 26848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 26948761c62SAndrew Jeffery } 27048761c62SAndrew Jeffery 27148761c62SAndrew Jeffery if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) { 27248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 27348761c62SAndrew Jeffery } 27448761c62SAndrew Jeffery 27548761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE, 27648761c62SAndrew Jeffery msg->payload, payload_length); 27748761c62SAndrew Jeffery if (rc) { 27848761c62SAndrew Jeffery return rc; 27948761c62SAndrew Jeffery } 28048761c62SAndrew Jeffery 28148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 28248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, comp_effecter_count); 28348761c62SAndrew Jeffery 28448761c62SAndrew Jeffery if (*comp_effecter_count > 8) { 28548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 28648761c62SAndrew Jeffery } 28748761c62SAndrew Jeffery 28848761c62SAndrew Jeffery for (i = 0; i < *comp_effecter_count; i++) { 28948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].set_request); 29048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].effecter_state); 29148761c62SAndrew Jeffery } 29248761c62SAndrew Jeffery 29348761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 29448761c62SAndrew Jeffery } 29548761c62SAndrew Jeffery 29648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 29748761c62SAndrew Jeffery int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length, 29848761c62SAndrew Jeffery uint32_t *record_hndl, uint32_t *data_transfer_hndl, 29948761c62SAndrew Jeffery uint8_t *transfer_op_flag, uint16_t *request_cnt, 30048761c62SAndrew Jeffery uint16_t *record_chg_num) 30148761c62SAndrew Jeffery { 30248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 30348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 30448761c62SAndrew Jeffery int rc; 30548761c62SAndrew Jeffery 30648761c62SAndrew Jeffery if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL || 30748761c62SAndrew Jeffery transfer_op_flag == NULL || request_cnt == NULL || 30848761c62SAndrew Jeffery record_chg_num == NULL) { 30948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 31048761c62SAndrew Jeffery } 31148761c62SAndrew Jeffery 31248761c62SAndrew Jeffery if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 31348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 31448761c62SAndrew Jeffery } 31548761c62SAndrew Jeffery 31648761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload, 31748761c62SAndrew Jeffery payload_length); 31848761c62SAndrew Jeffery if (rc) { 31948761c62SAndrew Jeffery return rc; 32048761c62SAndrew Jeffery } 32148761c62SAndrew Jeffery 32248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_hndl); 32348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_hndl); 32448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_op_flag); 32548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, request_cnt); 32648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_chg_num); 32748761c62SAndrew Jeffery 32848761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 32948761c62SAndrew Jeffery } 33048761c62SAndrew Jeffery 33148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 33248761c62SAndrew Jeffery int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code, 33348761c62SAndrew Jeffery uint32_t next_record_hndl, 33448761c62SAndrew Jeffery uint32_t next_data_transfer_hndl, uint8_t transfer_flag, 33548761c62SAndrew Jeffery uint16_t resp_cnt, const uint8_t *record_data, 33648761c62SAndrew Jeffery uint8_t transfer_crc, struct pldm_msg *msg) 33748761c62SAndrew Jeffery { 33848761c62SAndrew Jeffery if (msg == NULL) { 33948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 34048761c62SAndrew Jeffery } 34148761c62SAndrew Jeffery 34248761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 34348761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 34448761c62SAndrew Jeffery header.instance = instance_id; 34548761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 34648761c62SAndrew Jeffery header.command = PLDM_GET_PDR; 34748761c62SAndrew Jeffery 34848761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 34948761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 35048761c62SAndrew Jeffery return rc; 35148761c62SAndrew Jeffery } 35248761c62SAndrew Jeffery 35348761c62SAndrew Jeffery struct pldm_get_pdr_resp *response = 35448761c62SAndrew Jeffery (struct pldm_get_pdr_resp *)msg->payload; 35548761c62SAndrew Jeffery response->completion_code = completion_code; 35648761c62SAndrew Jeffery 35748761c62SAndrew Jeffery if (response->completion_code == PLDM_SUCCESS) { 35848761c62SAndrew Jeffery response->next_record_handle = htole32(next_record_hndl); 35948761c62SAndrew Jeffery response->next_data_transfer_handle = 36048761c62SAndrew Jeffery htole32(next_data_transfer_hndl); 36148761c62SAndrew Jeffery response->transfer_flag = transfer_flag; 36248761c62SAndrew Jeffery response->response_count = htole16(resp_cnt); 36348761c62SAndrew Jeffery if (record_data != NULL && resp_cnt > 0) { 36448761c62SAndrew Jeffery memcpy(response->record_data, record_data, resp_cnt); 36548761c62SAndrew Jeffery } 36648761c62SAndrew Jeffery if (transfer_flag == PLDM_END) { 36748761c62SAndrew Jeffery uint8_t *dst = msg->payload; 36848761c62SAndrew Jeffery dst += (sizeof(struct pldm_get_pdr_resp) - 1) + 36948761c62SAndrew Jeffery resp_cnt; 37048761c62SAndrew Jeffery *dst = transfer_crc; 37148761c62SAndrew Jeffery } 37248761c62SAndrew Jeffery } 37348761c62SAndrew Jeffery 37448761c62SAndrew Jeffery return PLDM_SUCCESS; 37548761c62SAndrew Jeffery } 37648761c62SAndrew Jeffery 37748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 37848761c62SAndrew Jeffery int encode_get_pdr_repository_info_resp( 37948761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, uint8_t repository_state, 38048761c62SAndrew Jeffery const uint8_t *update_time, const uint8_t *oem_update_time, 38148761c62SAndrew Jeffery uint32_t record_count, uint32_t repository_size, 38248761c62SAndrew Jeffery uint32_t largest_record_size, uint8_t data_transfer_handle_timeout, 38348761c62SAndrew Jeffery struct pldm_msg *msg) 38448761c62SAndrew Jeffery { 38548761c62SAndrew Jeffery if (msg == NULL) { 38648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 38748761c62SAndrew Jeffery } 38848761c62SAndrew Jeffery 38948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 39048761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 39148761c62SAndrew Jeffery header.instance = instance_id; 39248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 39348761c62SAndrew Jeffery header.command = PLDM_GET_PDR_REPOSITORY_INFO; 39448761c62SAndrew Jeffery 39548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 39648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 39748761c62SAndrew Jeffery return rc; 39848761c62SAndrew Jeffery } 39948761c62SAndrew Jeffery 40048761c62SAndrew Jeffery struct pldm_pdr_repository_info_resp *response = 40148761c62SAndrew Jeffery (struct pldm_pdr_repository_info_resp *)msg->payload; 40248761c62SAndrew Jeffery response->completion_code = completion_code; 40348761c62SAndrew Jeffery 40448761c62SAndrew Jeffery if (response->completion_code == PLDM_SUCCESS) { 40548761c62SAndrew Jeffery response->repository_state = repository_state; 40648761c62SAndrew Jeffery if (update_time != NULL) { 40748761c62SAndrew Jeffery memcpy(response->update_time, update_time, 40848761c62SAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 40948761c62SAndrew Jeffery } 41048761c62SAndrew Jeffery if (oem_update_time != NULL) { 41148761c62SAndrew Jeffery memcpy(response->oem_update_time, oem_update_time, 41248761c62SAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 41348761c62SAndrew Jeffery } 41448761c62SAndrew Jeffery response->record_count = htole32(record_count); 41548761c62SAndrew Jeffery response->repository_size = htole32(repository_size); 41648761c62SAndrew Jeffery response->largest_record_size = htole32(largest_record_size); 41748761c62SAndrew Jeffery response->data_transfer_handle_timeout = 41848761c62SAndrew Jeffery data_transfer_handle_timeout; 41948761c62SAndrew Jeffery } 42048761c62SAndrew Jeffery 42148761c62SAndrew Jeffery return PLDM_SUCCESS; 42248761c62SAndrew Jeffery } 42348761c62SAndrew Jeffery 4240a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED 42548761c62SAndrew Jeffery int decode_get_pdr_repository_info_resp( 42648761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 42748761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *repository_state, 42848761c62SAndrew Jeffery uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count, 42948761c62SAndrew Jeffery uint32_t *repository_size, uint32_t *largest_record_size, 43048761c62SAndrew Jeffery uint8_t *data_transfer_handle_timeout) 43148761c62SAndrew Jeffery { 43248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 43348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 43448761c62SAndrew Jeffery int rc; 43548761c62SAndrew Jeffery 43648761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 43748761c62SAndrew Jeffery repository_state == NULL || update_time == NULL || 43848761c62SAndrew Jeffery oem_update_time == NULL || record_count == NULL || 43948761c62SAndrew Jeffery repository_size == NULL || largest_record_size == NULL || 44048761c62SAndrew Jeffery data_transfer_handle_timeout == NULL) { 44148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 44248761c62SAndrew Jeffery } 44348761c62SAndrew Jeffery 44448761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 44548761c62SAndrew Jeffery msg->payload, payload_length); 44648761c62SAndrew Jeffery if (rc) { 44748761c62SAndrew Jeffery return rc; 44848761c62SAndrew Jeffery } 44948761c62SAndrew Jeffery 45048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, completion_code); 45148761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 45248761c62SAndrew Jeffery return PLDM_SUCCESS; 45348761c62SAndrew Jeffery } 45448761c62SAndrew Jeffery 45548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, repository_state); 45648761c62SAndrew Jeffery if (*repository_state > PLDM_FAILED) { 45748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 45848761c62SAndrew Jeffery } 45948761c62SAndrew Jeffery 4600a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 4610a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time, 4620a1be3cbSAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 4630a1be3cbSAndrew Jeffery if (rc) { 4640a1be3cbSAndrew Jeffery return rc; 4650a1be3cbSAndrew Jeffery } 4660a1be3cbSAndrew Jeffery 4670a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 4680a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, 4690a1be3cbSAndrew Jeffery oem_update_time, PLDM_TIMESTAMP104_SIZE); 4700a1be3cbSAndrew Jeffery if (rc) { 4710a1be3cbSAndrew Jeffery return rc; 4720a1be3cbSAndrew Jeffery } 4730a1be3cbSAndrew Jeffery 47448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_count); 47548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, repository_size); 47648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, largest_record_size); 47748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout); 47848761c62SAndrew Jeffery 47948761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 48048761c62SAndrew Jeffery } 48148761c62SAndrew Jeffery 4820a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING 4830a1be3cbSAndrew Jeffery int decode_get_pdr_repository_info_resp_safe( 4840a1be3cbSAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 4850a1be3cbSAndrew Jeffery struct pldm_pdr_repository_info_resp *resp) 4860a1be3cbSAndrew Jeffery { 4870a1be3cbSAndrew Jeffery struct pldm_msgbuf _buf; 4880a1be3cbSAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 4890a1be3cbSAndrew Jeffery int rc; 4900a1be3cbSAndrew Jeffery 4910a1be3cbSAndrew Jeffery if (msg == NULL || resp == NULL) { 4920a1be3cbSAndrew Jeffery return -EINVAL; 4930a1be3cbSAndrew Jeffery } 4940a1be3cbSAndrew Jeffery 4950a1be3cbSAndrew Jeffery rc = pldm_msg_has_error(msg, payload_length); 4960a1be3cbSAndrew Jeffery if (rc) { 4970a1be3cbSAndrew Jeffery resp->completion_code = rc; 4980a1be3cbSAndrew Jeffery return 0; 4990a1be3cbSAndrew Jeffery } 5000a1be3cbSAndrew Jeffery 5010a1be3cbSAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 5020a1be3cbSAndrew Jeffery PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 5030a1be3cbSAndrew Jeffery msg->payload, payload_length); 5040a1be3cbSAndrew Jeffery if (rc) { 5050a1be3cbSAndrew Jeffery return rc; 5060a1be3cbSAndrew Jeffery } 5070a1be3cbSAndrew Jeffery 5080a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->completion_code); 5090a1be3cbSAndrew Jeffery if (rc) { 5100a1be3cbSAndrew Jeffery return rc; 5110a1be3cbSAndrew Jeffery } 5120a1be3cbSAndrew Jeffery 5130a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->repository_state); 5140a1be3cbSAndrew Jeffery 5150a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time), 5160a1be3cbSAndrew Jeffery resp->update_time, 5170a1be3cbSAndrew Jeffery sizeof(resp->update_time)); 5180a1be3cbSAndrew Jeffery if (rc) { 5190a1be3cbSAndrew Jeffery return rc; 5200a1be3cbSAndrew Jeffery } 5210a1be3cbSAndrew Jeffery 5220a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time), 5230a1be3cbSAndrew Jeffery resp->oem_update_time, 5240a1be3cbSAndrew Jeffery sizeof(resp->oem_update_time)); 5250a1be3cbSAndrew Jeffery if (rc) { 5260a1be3cbSAndrew Jeffery return rc; 5270a1be3cbSAndrew Jeffery } 5280a1be3cbSAndrew Jeffery 5290a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->record_count); 5300a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->repository_size); 5310a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->largest_record_size); 5320a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout); 5330a1be3cbSAndrew Jeffery 5340a1be3cbSAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 5350a1be3cbSAndrew Jeffery } 5360a1be3cbSAndrew Jeffery 53748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 53848761c62SAndrew Jeffery int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl, 53948761c62SAndrew Jeffery uint32_t data_transfer_hndl, uint8_t transfer_op_flag, 54048761c62SAndrew Jeffery uint16_t request_cnt, uint16_t record_chg_num, 54148761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 54248761c62SAndrew Jeffery { 54348761c62SAndrew Jeffery if (msg == NULL) { 54448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 54548761c62SAndrew Jeffery } 54648761c62SAndrew Jeffery 54748761c62SAndrew Jeffery if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 54848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 54948761c62SAndrew Jeffery } 55048761c62SAndrew Jeffery 55148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 55248761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 55348761c62SAndrew Jeffery header.instance = instance_id; 55448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 55548761c62SAndrew Jeffery header.command = PLDM_GET_PDR; 55648761c62SAndrew Jeffery 55748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 55848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 55948761c62SAndrew Jeffery return rc; 56048761c62SAndrew Jeffery } 56148761c62SAndrew Jeffery 56248761c62SAndrew Jeffery struct pldm_get_pdr_req *request = 56348761c62SAndrew Jeffery (struct pldm_get_pdr_req *)msg->payload; 56448761c62SAndrew Jeffery request->record_handle = htole32(record_hndl); 56548761c62SAndrew Jeffery request->data_transfer_handle = htole32(data_transfer_hndl); 56648761c62SAndrew Jeffery request->transfer_op_flag = transfer_op_flag; 56748761c62SAndrew Jeffery request->request_count = htole16(request_cnt); 56848761c62SAndrew Jeffery request->record_change_number = htole16(record_chg_num); 56948761c62SAndrew Jeffery 57048761c62SAndrew Jeffery return PLDM_SUCCESS; 57148761c62SAndrew Jeffery } 57248761c62SAndrew Jeffery 5730a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED 57448761c62SAndrew Jeffery int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length, 57548761c62SAndrew Jeffery uint8_t *completion_code, uint32_t *next_record_hndl, 57648761c62SAndrew Jeffery uint32_t *next_data_transfer_hndl, 57748761c62SAndrew Jeffery uint8_t *transfer_flag, uint16_t *resp_cnt, 57848761c62SAndrew Jeffery uint8_t *record_data, size_t record_data_length, 57948761c62SAndrew Jeffery uint8_t *transfer_crc) 58048761c62SAndrew Jeffery { 58148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 58248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 58348761c62SAndrew Jeffery int rc; 58448761c62SAndrew Jeffery 58548761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 58648761c62SAndrew Jeffery next_record_hndl == NULL || next_data_transfer_hndl == NULL || 58748761c62SAndrew Jeffery transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) { 58848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 58948761c62SAndrew Jeffery } 59048761c62SAndrew Jeffery 59148761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload, 59248761c62SAndrew Jeffery payload_length); 59348761c62SAndrew Jeffery if (rc) { 59448761c62SAndrew Jeffery return rc; 59548761c62SAndrew Jeffery } 59648761c62SAndrew Jeffery 59748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, completion_code); 59848761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 59948761c62SAndrew Jeffery return PLDM_SUCCESS; 60048761c62SAndrew Jeffery } 60148761c62SAndrew Jeffery 60248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_record_hndl); 60348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_data_transfer_hndl); 60448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_flag); 60548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, resp_cnt); 60648761c62SAndrew Jeffery if (rc) { 60748761c62SAndrew Jeffery return rc; 60848761c62SAndrew Jeffery } 60948761c62SAndrew Jeffery 61048761c62SAndrew Jeffery if (*resp_cnt > 0 && record_data != NULL) { 61148761c62SAndrew Jeffery if (record_data_length < *resp_cnt) { 61248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 61348761c62SAndrew Jeffery } 6140a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 6150a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data, 6160a1be3cbSAndrew Jeffery *resp_cnt); 6170a1be3cbSAndrew Jeffery if (rc) { 6180a1be3cbSAndrew Jeffery return rc; 6190a1be3cbSAndrew Jeffery } 62048761c62SAndrew Jeffery } 62148761c62SAndrew Jeffery 62248761c62SAndrew Jeffery if (*transfer_flag == PLDM_END) { 62348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_crc); 62448761c62SAndrew Jeffery } 62548761c62SAndrew Jeffery 62648761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 62748761c62SAndrew Jeffery } 62848761c62SAndrew Jeffery 6290a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING 6300a1be3cbSAndrew Jeffery int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length, 6310a1be3cbSAndrew Jeffery struct pldm_get_pdr_resp *resp, size_t resp_len, 6320a1be3cbSAndrew Jeffery uint8_t *transfer_crc) 6330a1be3cbSAndrew Jeffery { 6340a1be3cbSAndrew Jeffery struct pldm_msgbuf _buf; 6350a1be3cbSAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 6360a1be3cbSAndrew Jeffery int rc; 6370a1be3cbSAndrew Jeffery 6380a1be3cbSAndrew Jeffery if (msg == NULL || resp == NULL || transfer_crc == NULL) { 6390a1be3cbSAndrew Jeffery return -EINVAL; 6400a1be3cbSAndrew Jeffery } 6410a1be3cbSAndrew Jeffery 6420a1be3cbSAndrew Jeffery rc = pldm_msg_has_error(msg, payload_length); 6430a1be3cbSAndrew Jeffery if (rc) { 6440a1be3cbSAndrew Jeffery resp->completion_code = rc; 6450a1be3cbSAndrew Jeffery return 0; 6460a1be3cbSAndrew Jeffery } 6470a1be3cbSAndrew Jeffery 6480a1be3cbSAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 6490a1be3cbSAndrew Jeffery msg->payload, payload_length); 6500a1be3cbSAndrew Jeffery if (rc) { 6510a1be3cbSAndrew Jeffery return rc; 6520a1be3cbSAndrew Jeffery } 6530a1be3cbSAndrew Jeffery 6540a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->completion_code); 6550a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->next_record_handle); 6560a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->next_data_transfer_handle); 6570a1be3cbSAndrew Jeffery 6580a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->transfer_flag); 6590a1be3cbSAndrew Jeffery if (rc) { 6600a1be3cbSAndrew Jeffery return rc; 6610a1be3cbSAndrew Jeffery } 6620a1be3cbSAndrew Jeffery 6630a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->response_count); 6640a1be3cbSAndrew Jeffery if (rc) { 6650a1be3cbSAndrew Jeffery return rc; 6660a1be3cbSAndrew Jeffery } 6670a1be3cbSAndrew Jeffery 6680a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array( 6690a1be3cbSAndrew Jeffery buf, resp->response_count, resp->record_data, 6700a1be3cbSAndrew Jeffery resp_len - (sizeof(*resp) - sizeof(resp->record_data))); 6710a1be3cbSAndrew Jeffery if (rc) { 6720a1be3cbSAndrew Jeffery return rc; 6730a1be3cbSAndrew Jeffery } 6740a1be3cbSAndrew Jeffery 6750a1be3cbSAndrew Jeffery if (resp->transfer_flag == PLDM_END) { 6760a1be3cbSAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_crc); 6770a1be3cbSAndrew Jeffery } 6780a1be3cbSAndrew Jeffery 6790a1be3cbSAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 6800a1be3cbSAndrew Jeffery } 6810a1be3cbSAndrew Jeffery 68248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 68348761c62SAndrew Jeffery int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg, 68448761c62SAndrew Jeffery size_t payload_length, 68548761c62SAndrew Jeffery uint16_t *effecter_id, 68648761c62SAndrew Jeffery uint8_t *effecter_data_size, 68748761c62SAndrew Jeffery uint8_t effecter_value[4]) 68848761c62SAndrew Jeffery { 68948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 69048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 69148761c62SAndrew Jeffery int rc; 69248761c62SAndrew Jeffery 69348761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL || 69448761c62SAndrew Jeffery effecter_value == NULL) { 69548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 69648761c62SAndrew Jeffery } 69748761c62SAndrew Jeffery 69848761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 69948761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES, 70048761c62SAndrew Jeffery msg->payload, payload_length); 70148761c62SAndrew Jeffery if (rc) { 70248761c62SAndrew Jeffery return rc; 70348761c62SAndrew Jeffery } 70448761c62SAndrew Jeffery 70548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 70648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 70748761c62SAndrew Jeffery if (rc) { 70848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 70948761c62SAndrew Jeffery } 71048761c62SAndrew Jeffery 71148761c62SAndrew Jeffery if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 71248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 71348761c62SAndrew Jeffery } 71448761c62SAndrew Jeffery 71548761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 71648761c62SAndrew Jeffery effecter_value); 71748761c62SAndrew Jeffery 71848761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 71948761c62SAndrew Jeffery } 72048761c62SAndrew Jeffery 72148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 72248761c62SAndrew Jeffery int encode_set_numeric_effecter_value_resp(uint8_t instance_id, 72348761c62SAndrew Jeffery uint8_t completion_code, 72448761c62SAndrew Jeffery struct pldm_msg *msg, 72548761c62SAndrew Jeffery size_t payload_length) 72648761c62SAndrew Jeffery { 72748761c62SAndrew Jeffery if (msg == NULL) { 72848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 72948761c62SAndrew Jeffery } 73048761c62SAndrew Jeffery 73148761c62SAndrew Jeffery if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 73248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 73348761c62SAndrew Jeffery } 73448761c62SAndrew Jeffery 73548761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 73648761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 73748761c62SAndrew Jeffery header.instance = instance_id; 73848761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 73948761c62SAndrew Jeffery header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 74048761c62SAndrew Jeffery 74148761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 74248761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 74348761c62SAndrew Jeffery return rc; 74448761c62SAndrew Jeffery } 74548761c62SAndrew Jeffery 74648761c62SAndrew Jeffery msg->payload[0] = completion_code; 74748761c62SAndrew Jeffery 74848761c62SAndrew Jeffery return rc; 74948761c62SAndrew Jeffery } 75048761c62SAndrew Jeffery 75148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 75248761c62SAndrew Jeffery int encode_set_numeric_effecter_value_req(uint8_t instance_id, 75348761c62SAndrew Jeffery uint16_t effecter_id, 75448761c62SAndrew Jeffery uint8_t effecter_data_size, 75548761c62SAndrew Jeffery const uint8_t *effecter_value, 75648761c62SAndrew Jeffery struct pldm_msg *msg, 75748761c62SAndrew Jeffery size_t payload_length) 75848761c62SAndrew Jeffery { 75948761c62SAndrew Jeffery if (msg == NULL || effecter_value == NULL) { 76048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 76148761c62SAndrew Jeffery } 76248761c62SAndrew Jeffery 76348761c62SAndrew Jeffery if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 76448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 76548761c62SAndrew Jeffery } 76648761c62SAndrew Jeffery 76748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 76848761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 76948761c62SAndrew Jeffery header.instance = instance_id; 77048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 77148761c62SAndrew Jeffery header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 77248761c62SAndrew Jeffery 77348761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 77448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 77548761c62SAndrew Jeffery return rc; 77648761c62SAndrew Jeffery } 77748761c62SAndrew Jeffery 77848761c62SAndrew Jeffery struct pldm_set_numeric_effecter_value_req *request = 77948761c62SAndrew Jeffery (struct pldm_set_numeric_effecter_value_req *)msg->payload; 78048761c62SAndrew Jeffery if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 78148761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 78248761c62SAndrew Jeffery if (payload_length != 78348761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) { 78448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 78548761c62SAndrew Jeffery } 78648761c62SAndrew Jeffery request->effecter_value[0] = *effecter_value; 78748761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 78848761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 78948761c62SAndrew Jeffery if (payload_length != 79048761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) { 79148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 79248761c62SAndrew Jeffery } 79348761c62SAndrew Jeffery 79448761c62SAndrew Jeffery uint16_t val = *(uint16_t *)(effecter_value); 79548761c62SAndrew Jeffery val = htole16(val); 79648761c62SAndrew Jeffery memcpy(request->effecter_value, &val, sizeof(uint16_t)); 79748761c62SAndrew Jeffery 79848761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 79948761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 80048761c62SAndrew Jeffery if (payload_length != 80148761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) { 80248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 80348761c62SAndrew Jeffery } 80448761c62SAndrew Jeffery 80548761c62SAndrew Jeffery uint32_t val = *(uint32_t *)(effecter_value); 80648761c62SAndrew Jeffery val = htole32(val); 80748761c62SAndrew Jeffery memcpy(request->effecter_value, &val, sizeof(uint32_t)); 80848761c62SAndrew Jeffery } 80948761c62SAndrew Jeffery 81048761c62SAndrew Jeffery request->effecter_id = htole16(effecter_id); 81148761c62SAndrew Jeffery request->effecter_data_size = effecter_data_size; 81248761c62SAndrew Jeffery 81348761c62SAndrew Jeffery return PLDM_SUCCESS; 81448761c62SAndrew Jeffery } 81548761c62SAndrew Jeffery 81648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 81748761c62SAndrew Jeffery int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg, 81848761c62SAndrew Jeffery size_t payload_length, 81948761c62SAndrew Jeffery uint8_t *completion_code) 82048761c62SAndrew Jeffery { 82148761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 82248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 82348761c62SAndrew Jeffery } 82448761c62SAndrew Jeffery 82548761c62SAndrew Jeffery if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 82648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 82748761c62SAndrew Jeffery } 82848761c62SAndrew Jeffery 82948761c62SAndrew Jeffery *completion_code = msg->payload[0]; 83048761c62SAndrew Jeffery 83148761c62SAndrew Jeffery return PLDM_SUCCESS; 83248761c62SAndrew Jeffery } 83348761c62SAndrew Jeffery 83448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 83548761c62SAndrew Jeffery int encode_get_state_sensor_readings_resp(uint8_t instance_id, 83648761c62SAndrew Jeffery uint8_t completion_code, 83748761c62SAndrew Jeffery uint8_t comp_sensor_count, 83848761c62SAndrew Jeffery get_sensor_state_field *field, 83948761c62SAndrew Jeffery struct pldm_msg *msg) 84048761c62SAndrew Jeffery { 84148761c62SAndrew Jeffery if (msg == NULL) { 84248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 84348761c62SAndrew Jeffery } 84448761c62SAndrew Jeffery 84548761c62SAndrew Jeffery if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) { 84648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 84748761c62SAndrew Jeffery } 84848761c62SAndrew Jeffery 84948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 85048761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 85148761c62SAndrew Jeffery header.instance = instance_id; 85248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 85348761c62SAndrew Jeffery header.command = PLDM_GET_STATE_SENSOR_READINGS; 85448761c62SAndrew Jeffery 85548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 85648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 85748761c62SAndrew Jeffery return rc; 85848761c62SAndrew Jeffery } 85948761c62SAndrew Jeffery 86048761c62SAndrew Jeffery struct pldm_get_state_sensor_readings_resp *response = 86148761c62SAndrew Jeffery (struct pldm_get_state_sensor_readings_resp *)msg->payload; 86248761c62SAndrew Jeffery 86348761c62SAndrew Jeffery response->completion_code = completion_code; 86448761c62SAndrew Jeffery response->comp_sensor_count = comp_sensor_count; 86548761c62SAndrew Jeffery memcpy(response->field, field, 86648761c62SAndrew Jeffery (sizeof(get_sensor_state_field) * comp_sensor_count)); 86748761c62SAndrew Jeffery 86848761c62SAndrew Jeffery return PLDM_SUCCESS; 86948761c62SAndrew Jeffery } 87048761c62SAndrew Jeffery 87148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 87248761c62SAndrew Jeffery int encode_get_state_sensor_readings_req(uint8_t instance_id, 87348761c62SAndrew Jeffery uint16_t sensor_id, 87448761c62SAndrew Jeffery bitfield8_t sensor_rearm, 87548761c62SAndrew Jeffery uint8_t reserved, struct pldm_msg *msg) 87648761c62SAndrew Jeffery { 87748761c62SAndrew Jeffery if (msg == NULL) { 87848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 87948761c62SAndrew Jeffery } 88048761c62SAndrew Jeffery 88148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 88248761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 88348761c62SAndrew Jeffery header.instance = instance_id; 88448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 88548761c62SAndrew Jeffery header.command = PLDM_GET_STATE_SENSOR_READINGS; 88648761c62SAndrew Jeffery 88748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 88848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 88948761c62SAndrew Jeffery return rc; 89048761c62SAndrew Jeffery } 89148761c62SAndrew Jeffery 89248761c62SAndrew Jeffery struct pldm_get_state_sensor_readings_req *request = 89348761c62SAndrew Jeffery (struct pldm_get_state_sensor_readings_req *)msg->payload; 89448761c62SAndrew Jeffery 89548761c62SAndrew Jeffery request->sensor_id = htole16(sensor_id); 89648761c62SAndrew Jeffery request->reserved = reserved; 89748761c62SAndrew Jeffery request->sensor_rearm = sensor_rearm; 89848761c62SAndrew Jeffery 89948761c62SAndrew Jeffery return PLDM_SUCCESS; 90048761c62SAndrew Jeffery } 90148761c62SAndrew Jeffery 90248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 90348761c62SAndrew Jeffery int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg, 90448761c62SAndrew Jeffery size_t payload_length, 90548761c62SAndrew Jeffery uint8_t *completion_code, 90648761c62SAndrew Jeffery uint8_t *comp_sensor_count, 90748761c62SAndrew Jeffery get_sensor_state_field *field) 90848761c62SAndrew Jeffery { 90948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 91048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 91148761c62SAndrew Jeffery uint8_t i; 91248761c62SAndrew Jeffery int rc; 91348761c62SAndrew Jeffery 91448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 91548761c62SAndrew Jeffery comp_sensor_count == NULL || field == NULL) { 91648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 91748761c62SAndrew Jeffery } 91848761c62SAndrew Jeffery 91948761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 92048761c62SAndrew Jeffery PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES, 92148761c62SAndrew Jeffery msg->payload, payload_length); 92248761c62SAndrew Jeffery if (rc) { 92348761c62SAndrew Jeffery return rc; 92448761c62SAndrew Jeffery } 92548761c62SAndrew Jeffery 92648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 92748761c62SAndrew Jeffery if (rc) { 92848761c62SAndrew Jeffery return rc; 92948761c62SAndrew Jeffery } 93048761c62SAndrew Jeffery 93148761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 93248761c62SAndrew Jeffery return PLDM_SUCCESS; 93348761c62SAndrew Jeffery } 93448761c62SAndrew Jeffery 93548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, comp_sensor_count); 93648761c62SAndrew Jeffery if (rc) { 93748761c62SAndrew Jeffery return rc; 93848761c62SAndrew Jeffery } 93948761c62SAndrew Jeffery 94048761c62SAndrew Jeffery if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) { 94148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 94248761c62SAndrew Jeffery } 94348761c62SAndrew Jeffery 94448761c62SAndrew Jeffery for (i = 0; i < *comp_sensor_count; i++) { 94548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].sensor_op_state); 94648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].present_state); 94748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].previous_state); 94848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].event_state); 94948761c62SAndrew Jeffery } 95048761c62SAndrew Jeffery 95148761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 95248761c62SAndrew Jeffery } 95348761c62SAndrew Jeffery 95448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 95548761c62SAndrew Jeffery int decode_get_state_sensor_readings_req(const struct pldm_msg *msg, 95648761c62SAndrew Jeffery size_t payload_length, 95748761c62SAndrew Jeffery uint16_t *sensor_id, 95848761c62SAndrew Jeffery bitfield8_t *sensor_rearm, 95948761c62SAndrew Jeffery uint8_t *reserved) 96048761c62SAndrew Jeffery { 96148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 96248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 96348761c62SAndrew Jeffery int rc; 96448761c62SAndrew Jeffery 96548761c62SAndrew Jeffery if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) { 96648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 96748761c62SAndrew Jeffery } 96848761c62SAndrew Jeffery 96948761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES, 97048761c62SAndrew Jeffery msg->payload, payload_length); 97148761c62SAndrew Jeffery if (rc) { 97248761c62SAndrew Jeffery return rc; 97348761c62SAndrew Jeffery } 97448761c62SAndrew Jeffery 97548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 97648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, sensor_rearm->byte); 97748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, reserved); 97848761c62SAndrew Jeffery 97948761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 98048761c62SAndrew Jeffery } 98148761c62SAndrew Jeffery 98248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 98348761c62SAndrew Jeffery int encode_sensor_event_data( 98448761c62SAndrew Jeffery struct pldm_sensor_event_data *const event_data, 98548761c62SAndrew Jeffery const size_t event_data_size, const uint16_t sensor_id, 98648761c62SAndrew Jeffery const enum sensor_event_class_states sensor_event_class, 98748761c62SAndrew Jeffery const uint8_t sensor_offset, const uint8_t event_state, 98848761c62SAndrew Jeffery const uint8_t previous_event_state, 98948761c62SAndrew Jeffery size_t *const actual_event_data_size) 99048761c62SAndrew Jeffery { 99148761c62SAndrew Jeffery *actual_event_data_size = 99248761c62SAndrew Jeffery (sizeof(*event_data) - sizeof(event_data->event_class) + 99348761c62SAndrew Jeffery sizeof(struct pldm_sensor_event_state_sensor_state)); 99448761c62SAndrew Jeffery 99548761c62SAndrew Jeffery if (!event_data) { 99648761c62SAndrew Jeffery return PLDM_SUCCESS; 99748761c62SAndrew Jeffery } 99848761c62SAndrew Jeffery 99948761c62SAndrew Jeffery if (event_data_size < *actual_event_data_size) { 100048761c62SAndrew Jeffery *actual_event_data_size = 0; 100148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 100248761c62SAndrew Jeffery } 100348761c62SAndrew Jeffery 100448761c62SAndrew Jeffery event_data->sensor_id = htole16(sensor_id); 100548761c62SAndrew Jeffery event_data->sensor_event_class_type = sensor_event_class; 100648761c62SAndrew Jeffery 100748761c62SAndrew Jeffery struct pldm_sensor_event_state_sensor_state *const state_data = 100848761c62SAndrew Jeffery (struct pldm_sensor_event_state_sensor_state *) 100948761c62SAndrew Jeffery event_data->event_class; 101048761c62SAndrew Jeffery 101148761c62SAndrew Jeffery state_data->sensor_offset = sensor_offset; 101248761c62SAndrew Jeffery state_data->event_state = event_state; 101348761c62SAndrew Jeffery state_data->previous_event_state = previous_event_state; 101448761c62SAndrew Jeffery 101548761c62SAndrew Jeffery return PLDM_SUCCESS; 101648761c62SAndrew Jeffery } 101748761c62SAndrew Jeffery 101848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 101948761c62SAndrew Jeffery int decode_platform_event_message_req(const struct pldm_msg *msg, 102048761c62SAndrew Jeffery size_t payload_length, 102148761c62SAndrew Jeffery uint8_t *format_version, uint8_t *tid, 102248761c62SAndrew Jeffery uint8_t *event_class, 102348761c62SAndrew Jeffery size_t *event_data_offset) 102448761c62SAndrew Jeffery { 102548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 102648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 102748761c62SAndrew Jeffery int rc; 102848761c62SAndrew Jeffery 102948761c62SAndrew Jeffery if (msg == NULL || format_version == NULL || tid == NULL || 103048761c62SAndrew Jeffery event_class == NULL || event_data_offset == NULL) { 103148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 103248761c62SAndrew Jeffery } 103348761c62SAndrew Jeffery 103448761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES, 103548761c62SAndrew Jeffery msg->payload, payload_length); 103648761c62SAndrew Jeffery if (rc) { 103748761c62SAndrew Jeffery return rc; 103848761c62SAndrew Jeffery } 103948761c62SAndrew Jeffery 104048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, format_version); 104148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, tid); 104248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_class); 104348761c62SAndrew Jeffery *event_data_offset = 104448761c62SAndrew Jeffery sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class); 104548761c62SAndrew Jeffery 104648761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 104748761c62SAndrew Jeffery } 104848761c62SAndrew Jeffery 1049387b10f6SThu Nguyen static int pldm_platform_poll_for_platform_event_message_validate( 1050387b10f6SThu Nguyen uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge) 1051387b10f6SThu Nguyen { 1052387b10f6SThu Nguyen if (((transfer_operation_flag == PLDM_GET_FIRSTPART) && 1053387b10f6SThu Nguyen (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) || 1054387b10f6SThu Nguyen ((transfer_operation_flag == PLDM_GET_NEXTPART) && 1055387b10f6SThu Nguyen (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1056387b10f6SThu Nguyen ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 1057*9e16b18bSThu Nguyen (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1058*9e16b18bSThu Nguyen ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 1059*9e16b18bSThu Nguyen (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) || 1060387b10f6SThu Nguyen (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) { 1061387b10f6SThu Nguyen return -EPROTO; 1062387b10f6SThu Nguyen } 1063387b10f6SThu Nguyen 1064387b10f6SThu Nguyen return 0; 1065387b10f6SThu Nguyen } 1066387b10f6SThu Nguyen 106748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 106848761c62SAndrew Jeffery int decode_poll_for_platform_event_message_req( 106948761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 107048761c62SAndrew Jeffery uint8_t *format_version, uint8_t *transfer_operation_flag, 107148761c62SAndrew Jeffery uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge) 107248761c62SAndrew Jeffery { 107348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 107448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 107548761c62SAndrew Jeffery int rc; 107648761c62SAndrew Jeffery 107790bbe6c0SAndrew Jeffery if (msg == NULL || format_version == NULL || 107890bbe6c0SAndrew Jeffery transfer_operation_flag == NULL || data_transfer_handle == NULL || 107990bbe6c0SAndrew Jeffery event_id_to_acknowledge == NULL) { 108048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 108148761c62SAndrew Jeffery } 108248761c62SAndrew Jeffery 108348761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 108448761c62SAndrew Jeffery PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, 108548761c62SAndrew Jeffery msg->payload, payload_length); 108648761c62SAndrew Jeffery if (rc) { 108748761c62SAndrew Jeffery return rc; 108848761c62SAndrew Jeffery } 108948761c62SAndrew Jeffery 109048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, format_version); 109148761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag); 109248761c62SAndrew Jeffery if (rc) { 109348761c62SAndrew Jeffery return rc; 109448761c62SAndrew Jeffery } 109548761c62SAndrew Jeffery if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) { 109648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 109748761c62SAndrew Jeffery } 109848761c62SAndrew Jeffery 109948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_handle); 110048761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge); 110148761c62SAndrew Jeffery if (rc) { 110248761c62SAndrew Jeffery return rc; 110348761c62SAndrew Jeffery } 110448761c62SAndrew Jeffery 1105387b10f6SThu Nguyen rc = pldm_platform_poll_for_platform_event_message_validate( 1106387b10f6SThu Nguyen *transfer_operation_flag, *event_id_to_acknowledge); 1107387b10f6SThu Nguyen if (rc < 0) { 110848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 110948761c62SAndrew Jeffery } 111048761c62SAndrew Jeffery 111148761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 111248761c62SAndrew Jeffery } 111348761c62SAndrew Jeffery 111448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 111548761c62SAndrew Jeffery int encode_platform_event_message_resp(uint8_t instance_id, 111648761c62SAndrew Jeffery uint8_t completion_code, 111748761c62SAndrew Jeffery uint8_t platform_event_status, 111848761c62SAndrew Jeffery struct pldm_msg *msg) 111948761c62SAndrew Jeffery { 112048761c62SAndrew Jeffery if (msg == NULL) { 112148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 112248761c62SAndrew Jeffery } 112348761c62SAndrew Jeffery 112448761c62SAndrew Jeffery if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 112548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 112648761c62SAndrew Jeffery } 112748761c62SAndrew Jeffery 112848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 112948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 113048761c62SAndrew Jeffery header.instance = instance_id; 113148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 113248761c62SAndrew Jeffery header.command = PLDM_PLATFORM_EVENT_MESSAGE; 113348761c62SAndrew Jeffery 113448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 113548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 113648761c62SAndrew Jeffery return rc; 113748761c62SAndrew Jeffery } 113848761c62SAndrew Jeffery 113948761c62SAndrew Jeffery struct pldm_platform_event_message_resp *response = 114048761c62SAndrew Jeffery (struct pldm_platform_event_message_resp *)msg->payload; 114148761c62SAndrew Jeffery response->completion_code = completion_code; 114248761c62SAndrew Jeffery response->platform_event_status = platform_event_status; 114348761c62SAndrew Jeffery 114448761c62SAndrew Jeffery return PLDM_SUCCESS; 114548761c62SAndrew Jeffery } 114648761c62SAndrew Jeffery 114748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 114848761c62SAndrew Jeffery int encode_poll_for_platform_event_message_resp( 114948761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, uint8_t tid, 115048761c62SAndrew Jeffery uint16_t event_id, uint32_t next_data_transfer_handle, 115148761c62SAndrew Jeffery uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size, 115248761c62SAndrew Jeffery uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg, 115348761c62SAndrew Jeffery size_t payload_length) 115448761c62SAndrew Jeffery { 115548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 115648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 115748761c62SAndrew Jeffery int rc; 115848761c62SAndrew Jeffery 115948761c62SAndrew Jeffery if (!msg) { 116048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 116148761c62SAndrew Jeffery } 116248761c62SAndrew Jeffery 116348761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 116448761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 116548761c62SAndrew Jeffery header.instance = instance_id; 116648761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 116748761c62SAndrew Jeffery header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 116848761c62SAndrew Jeffery 116948761c62SAndrew Jeffery rc = pack_pldm_header(&header, &(msg->hdr)); 117048761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 117148761c62SAndrew Jeffery return rc; 117248761c62SAndrew Jeffery } 117348761c62SAndrew Jeffery 117448761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc( 117548761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 117648761c62SAndrew Jeffery msg->payload, payload_length); 117748761c62SAndrew Jeffery if (rc) { 117848761c62SAndrew Jeffery return rc; 117948761c62SAndrew Jeffery } 118048761c62SAndrew Jeffery 118148761c62SAndrew Jeffery pldm_msgbuf_insert(buf, completion_code); 118248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, tid); 118348761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_id); 118448761c62SAndrew Jeffery 118548761c62SAndrew Jeffery if (event_id == 0xffff || event_id == 0x0000) { 118648761c62SAndrew Jeffery if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES != 118748761c62SAndrew Jeffery payload_length) { 118848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 118948761c62SAndrew Jeffery } 119048761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 119148761c62SAndrew Jeffery } 119248761c62SAndrew Jeffery 119348761c62SAndrew Jeffery if ((event_data == NULL) && (event_data_size > 0)) { 119448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 119548761c62SAndrew Jeffery } 119648761c62SAndrew Jeffery 119748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, next_data_transfer_handle); 119848761c62SAndrew Jeffery pldm_msgbuf_insert(buf, transfer_flag); 119948761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_class); 120048761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_data_size); 120148761c62SAndrew Jeffery 120248761c62SAndrew Jeffery if ((event_data_size > 0) && event_data) { 12030a1be3cbSAndrew Jeffery rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data, 12040a1be3cbSAndrew Jeffery event_data_size); 12050a1be3cbSAndrew Jeffery if (rc) { 12060a1be3cbSAndrew Jeffery return rc; 12070a1be3cbSAndrew Jeffery } 120848761c62SAndrew Jeffery } 120948761c62SAndrew Jeffery 121048761c62SAndrew Jeffery if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) { 121148761c62SAndrew Jeffery pldm_msgbuf_insert(buf, checksum); 121248761c62SAndrew Jeffery } 121348761c62SAndrew Jeffery 121448761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 121548761c62SAndrew Jeffery } 121648761c62SAndrew Jeffery 121748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 121848761c62SAndrew Jeffery int encode_platform_event_message_req( 121948761c62SAndrew Jeffery uint8_t instance_id, uint8_t format_version, uint8_t tid, 122048761c62SAndrew Jeffery uint8_t event_class, const uint8_t *event_data, 122148761c62SAndrew Jeffery size_t event_data_length, struct pldm_msg *msg, size_t payload_length) 122248761c62SAndrew Jeffery 122348761c62SAndrew Jeffery { 122448761c62SAndrew Jeffery if (format_version != 1) { 122548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 122648761c62SAndrew Jeffery } 122748761c62SAndrew Jeffery 122848761c62SAndrew Jeffery if (msg == NULL || event_data == NULL) { 122948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 123048761c62SAndrew Jeffery } 123148761c62SAndrew Jeffery 123248761c62SAndrew Jeffery if (event_data_length == 0) { 123348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 123448761c62SAndrew Jeffery } 123548761c62SAndrew Jeffery 123648761c62SAndrew Jeffery if (payload_length != 123748761c62SAndrew Jeffery PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) { 123848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 123948761c62SAndrew Jeffery } 124048761c62SAndrew Jeffery 1241b43a7787SJohn Chung if (event_class > PLDM_CPER_EVENT && 124248761c62SAndrew Jeffery !(event_class >= 0xf0 && event_class <= 0xfe)) { 124348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 124448761c62SAndrew Jeffery } 124548761c62SAndrew Jeffery 124648761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 124748761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 124848761c62SAndrew Jeffery header.instance = instance_id; 124948761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 125048761c62SAndrew Jeffery header.command = PLDM_PLATFORM_EVENT_MESSAGE; 125148761c62SAndrew Jeffery 125248761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 125348761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 125448761c62SAndrew Jeffery return rc; 125548761c62SAndrew Jeffery } 125648761c62SAndrew Jeffery 125748761c62SAndrew Jeffery struct pldm_platform_event_message_req *request = 125848761c62SAndrew Jeffery (struct pldm_platform_event_message_req *)msg->payload; 125948761c62SAndrew Jeffery request->format_version = format_version; 126048761c62SAndrew Jeffery request->tid = tid; 126148761c62SAndrew Jeffery request->event_class = event_class; 126248761c62SAndrew Jeffery memcpy(request->event_data, event_data, event_data_length); 126348761c62SAndrew Jeffery 126448761c62SAndrew Jeffery return PLDM_SUCCESS; 126548761c62SAndrew Jeffery } 126648761c62SAndrew Jeffery 126748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 126848761c62SAndrew Jeffery int decode_platform_event_message_resp(const struct pldm_msg *msg, 126948761c62SAndrew Jeffery size_t payload_length, 127048761c62SAndrew Jeffery uint8_t *completion_code, 127148761c62SAndrew Jeffery uint8_t *platform_event_status) 127248761c62SAndrew Jeffery { 127348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 127448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 127548761c62SAndrew Jeffery int rc; 127648761c62SAndrew Jeffery 127748761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 127848761c62SAndrew Jeffery platform_event_status == NULL) { 127948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 128048761c62SAndrew Jeffery } 128148761c62SAndrew Jeffery 128248761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 128348761c62SAndrew Jeffery msg->payload, payload_length); 128448761c62SAndrew Jeffery if (rc) { 128548761c62SAndrew Jeffery return rc; 128648761c62SAndrew Jeffery } 128748761c62SAndrew Jeffery 128848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 128948761c62SAndrew Jeffery if (rc) { 129048761c62SAndrew Jeffery return rc; 129148761c62SAndrew Jeffery } 129248761c62SAndrew Jeffery 129348761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 129448761c62SAndrew Jeffery return PLDM_SUCCESS; 129548761c62SAndrew Jeffery } 129648761c62SAndrew Jeffery 129748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, platform_event_status); 129848761c62SAndrew Jeffery if (rc) { 129948761c62SAndrew Jeffery return rc; 130048761c62SAndrew Jeffery } 130148761c62SAndrew Jeffery 130248761c62SAndrew Jeffery if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 130348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 130448761c62SAndrew Jeffery } 130548761c62SAndrew Jeffery 130648761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 130748761c62SAndrew Jeffery } 130848761c62SAndrew Jeffery 130948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 131048761c62SAndrew Jeffery int encode_event_message_buffer_size_req(uint8_t instance_id, 131148761c62SAndrew Jeffery uint16_t event_receiver_max_buffer_size, 131248761c62SAndrew Jeffery struct pldm_msg *msg) 131348761c62SAndrew Jeffery { 131448761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 131548761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 131648761c62SAndrew Jeffery header.instance = instance_id; 131748761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 131848761c62SAndrew Jeffery header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE; 131948761c62SAndrew Jeffery 132048761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 132148761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 132248761c62SAndrew Jeffery return rc; 132348761c62SAndrew Jeffery } 132448761c62SAndrew Jeffery 132548761c62SAndrew Jeffery struct pldm_event_message_buffer_size_req *request = 132648761c62SAndrew Jeffery (struct pldm_event_message_buffer_size_req *)msg->payload; 132748761c62SAndrew Jeffery request->event_receiver_max_buffer_size = 132848761c62SAndrew Jeffery event_receiver_max_buffer_size; 132948761c62SAndrew Jeffery 133048761c62SAndrew Jeffery return PLDM_SUCCESS; 133148761c62SAndrew Jeffery } 133248761c62SAndrew Jeffery 133348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 133448761c62SAndrew Jeffery int decode_event_message_buffer_size_resp(const struct pldm_msg *msg, 133548761c62SAndrew Jeffery size_t payload_length, 133648761c62SAndrew Jeffery uint8_t *completion_code, 133748761c62SAndrew Jeffery uint16_t *terminus_max_buffer_size) 133848761c62SAndrew Jeffery { 133948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 134048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 134148761c62SAndrew Jeffery int rc; 134248761c62SAndrew Jeffery 134348761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 134448761c62SAndrew Jeffery terminus_max_buffer_size == NULL) { 134548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 134648761c62SAndrew Jeffery } 134748761c62SAndrew Jeffery 134848761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES, 134948761c62SAndrew Jeffery msg->payload, payload_length); 135048761c62SAndrew Jeffery if (rc) { 135148761c62SAndrew Jeffery return rc; 135248761c62SAndrew Jeffery } 135348761c62SAndrew Jeffery 135448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 135548761c62SAndrew Jeffery if (rc) { 135648761c62SAndrew Jeffery return rc; 135748761c62SAndrew Jeffery } 135848761c62SAndrew Jeffery 135948761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 136048761c62SAndrew Jeffery return PLDM_SUCCESS; 136148761c62SAndrew Jeffery } 136248761c62SAndrew Jeffery 136348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, terminus_max_buffer_size); 136448761c62SAndrew Jeffery 136548761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 136648761c62SAndrew Jeffery } 136748761c62SAndrew Jeffery 136848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 136948761c62SAndrew Jeffery int encode_event_message_supported_req(uint8_t instance_id, 137048761c62SAndrew Jeffery uint8_t format_version, 137148761c62SAndrew Jeffery struct pldm_msg *msg) 137248761c62SAndrew Jeffery { 137348761c62SAndrew Jeffery if (format_version != 1) { 137448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 137548761c62SAndrew Jeffery } 137648761c62SAndrew Jeffery 137748761c62SAndrew Jeffery if (msg == NULL) { 137848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 137948761c62SAndrew Jeffery } 138048761c62SAndrew Jeffery 138148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 138248761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 138348761c62SAndrew Jeffery header.instance = instance_id; 138448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 138548761c62SAndrew Jeffery header.command = PLDM_EVENT_MESSAGE_SUPPORTED; 138648761c62SAndrew Jeffery 138748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 138848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 138948761c62SAndrew Jeffery return rc; 139048761c62SAndrew Jeffery } 139148761c62SAndrew Jeffery 139248761c62SAndrew Jeffery struct pldm_event_message_supported_req *request = 139348761c62SAndrew Jeffery (struct pldm_event_message_supported_req *)msg->payload; 139448761c62SAndrew Jeffery request->format_version = format_version; 139548761c62SAndrew Jeffery 139648761c62SAndrew Jeffery return PLDM_SUCCESS; 139748761c62SAndrew Jeffery } 139848761c62SAndrew Jeffery 139948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 140048761c62SAndrew Jeffery int decode_event_message_supported_resp(const struct pldm_msg *msg, 140148761c62SAndrew Jeffery size_t payload_length, 140248761c62SAndrew Jeffery uint8_t *completion_code, 140348761c62SAndrew Jeffery uint8_t *synchrony_config, 140448761c62SAndrew Jeffery bitfield8_t *synchrony_config_support, 140548761c62SAndrew Jeffery uint8_t *number_event_class_returned, 140648761c62SAndrew Jeffery uint8_t *event_class, 140748761c62SAndrew Jeffery uint8_t event_class_count) 140848761c62SAndrew Jeffery { 140948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 141048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 141148761c62SAndrew Jeffery int i; 141248761c62SAndrew Jeffery int rc; 141348761c62SAndrew Jeffery 141448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 141548761c62SAndrew Jeffery synchrony_config == NULL || synchrony_config_support == NULL || 141648761c62SAndrew Jeffery number_event_class_returned == NULL || event_class == NULL) { 141748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 141848761c62SAndrew Jeffery } 141948761c62SAndrew Jeffery 142048761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 142148761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES, 142248761c62SAndrew Jeffery msg->payload, payload_length); 142348761c62SAndrew Jeffery if (rc) { 142448761c62SAndrew Jeffery return rc; 142548761c62SAndrew Jeffery } 142648761c62SAndrew Jeffery 142748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 142848761c62SAndrew Jeffery if (rc) { 142948761c62SAndrew Jeffery return rc; 143048761c62SAndrew Jeffery } 143148761c62SAndrew Jeffery 143248761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 143348761c62SAndrew Jeffery return PLDM_SUCCESS; 143448761c62SAndrew Jeffery } 143548761c62SAndrew Jeffery 143648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, synchrony_config); 143748761c62SAndrew Jeffery if (rc) { 143848761c62SAndrew Jeffery return rc; 143948761c62SAndrew Jeffery } 144048761c62SAndrew Jeffery 144148761c62SAndrew Jeffery if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) { 144248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 144348761c62SAndrew Jeffery } 144448761c62SAndrew Jeffery 144548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte); 144648761c62SAndrew Jeffery 144748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, number_event_class_returned); 144848761c62SAndrew Jeffery if (rc) { 144948761c62SAndrew Jeffery return rc; 145048761c62SAndrew Jeffery } 145148761c62SAndrew Jeffery 145248761c62SAndrew Jeffery if (*number_event_class_returned == 0) { 145348761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 145448761c62SAndrew Jeffery } 145548761c62SAndrew Jeffery 145648761c62SAndrew Jeffery if (event_class_count < *number_event_class_returned) { 145748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 145848761c62SAndrew Jeffery } 145948761c62SAndrew Jeffery 146048761c62SAndrew Jeffery for (i = 0; i < *number_event_class_returned; i++) { 146148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, event_class[i]); 146248761c62SAndrew Jeffery } 146348761c62SAndrew Jeffery 146448761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 146548761c62SAndrew Jeffery } 146648761c62SAndrew Jeffery 146748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 146848761c62SAndrew Jeffery int decode_sensor_event_data(const uint8_t *event_data, 146948761c62SAndrew Jeffery size_t event_data_length, uint16_t *sensor_id, 147048761c62SAndrew Jeffery uint8_t *sensor_event_class_type, 147148761c62SAndrew Jeffery size_t *event_class_data_offset) 147248761c62SAndrew Jeffery { 147348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 147448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 147548761c62SAndrew Jeffery int rc; 147648761c62SAndrew Jeffery 147790bbe6c0SAndrew Jeffery if (event_data == NULL || sensor_id == NULL || 147890bbe6c0SAndrew Jeffery sensor_event_class_type == NULL || 147990bbe6c0SAndrew Jeffery event_class_data_offset == NULL) { 148090bbe6c0SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 148190bbe6c0SAndrew Jeffery } 148290bbe6c0SAndrew Jeffery 148348761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH, 148448761c62SAndrew Jeffery event_data, event_data_length); 148548761c62SAndrew Jeffery if (rc) { 148648761c62SAndrew Jeffery return rc; 148748761c62SAndrew Jeffery } 148848761c62SAndrew Jeffery 148948761c62SAndrew Jeffery size_t event_class_data_length = 149048761c62SAndrew Jeffery event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES; 149148761c62SAndrew Jeffery 149248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 149348761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type); 149448761c62SAndrew Jeffery if (rc) { 149548761c62SAndrew Jeffery return rc; 149648761c62SAndrew Jeffery } 149748761c62SAndrew Jeffery 149848761c62SAndrew Jeffery if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) { 149948761c62SAndrew Jeffery if (event_class_data_length != 150048761c62SAndrew Jeffery PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) { 150148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 150248761c62SAndrew Jeffery } 150348761c62SAndrew Jeffery } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) { 150448761c62SAndrew Jeffery if (event_class_data_length != 150548761c62SAndrew Jeffery PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) { 150648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 150748761c62SAndrew Jeffery } 150848761c62SAndrew Jeffery } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) { 150948761c62SAndrew Jeffery if (event_class_data_length < 151048761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH || 151148761c62SAndrew Jeffery event_class_data_length > 151248761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 151348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 151448761c62SAndrew Jeffery } 151548761c62SAndrew Jeffery } else { 151648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 151748761c62SAndrew Jeffery } 151848761c62SAndrew Jeffery 151948761c62SAndrew Jeffery *event_class_data_offset = 152048761c62SAndrew Jeffery sizeof(*sensor_id) + sizeof(*sensor_event_class_type); 152148761c62SAndrew Jeffery 152248761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 152348761c62SAndrew Jeffery } 152448761c62SAndrew Jeffery 152548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 152648761c62SAndrew Jeffery int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length, 152748761c62SAndrew Jeffery uint8_t *present_op_state, uint8_t *previous_op_state) 152848761c62SAndrew Jeffery { 152948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 153048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 153148761c62SAndrew Jeffery int rc; 153248761c62SAndrew Jeffery 153390bbe6c0SAndrew Jeffery if (sensor_data == NULL || present_op_state == NULL || 153490bbe6c0SAndrew Jeffery previous_op_state == NULL) { 153548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 153648761c62SAndrew Jeffery } 153748761c62SAndrew Jeffery 153848761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 153948761c62SAndrew Jeffery PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, 154048761c62SAndrew Jeffery sensor_data, sensor_data_length); 154148761c62SAndrew Jeffery if (rc) { 154248761c62SAndrew Jeffery return rc; 154348761c62SAndrew Jeffery } 154448761c62SAndrew Jeffery 154548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, present_op_state); 154648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_op_state); 154748761c62SAndrew Jeffery 154848761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 154948761c62SAndrew Jeffery } 155048761c62SAndrew Jeffery 155148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 155248761c62SAndrew Jeffery int decode_state_sensor_data(const uint8_t *sensor_data, 155348761c62SAndrew Jeffery size_t sensor_data_length, uint8_t *sensor_offset, 155448761c62SAndrew Jeffery uint8_t *event_state, 155548761c62SAndrew Jeffery uint8_t *previous_event_state) 155648761c62SAndrew Jeffery { 155748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 155848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 155948761c62SAndrew Jeffery int rc; 156048761c62SAndrew Jeffery 156190bbe6c0SAndrew Jeffery if (sensor_data == NULL || sensor_offset == NULL || 156290bbe6c0SAndrew Jeffery event_state == NULL || previous_event_state == NULL) { 156348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 156448761c62SAndrew Jeffery } 156548761c62SAndrew Jeffery 156648761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc( 156748761c62SAndrew Jeffery buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH, 156848761c62SAndrew Jeffery sensor_data, sensor_data_length); 156948761c62SAndrew Jeffery if (rc) { 157048761c62SAndrew Jeffery return rc; 157148761c62SAndrew Jeffery } 157248761c62SAndrew Jeffery 157348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_offset); 157448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 157548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_event_state); 157648761c62SAndrew Jeffery 157748761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 157848761c62SAndrew Jeffery } 157948761c62SAndrew Jeffery 158048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 158148761c62SAndrew Jeffery int decode_numeric_sensor_data(const uint8_t *sensor_data, 158248761c62SAndrew Jeffery size_t sensor_data_length, uint8_t *event_state, 158348761c62SAndrew Jeffery uint8_t *previous_event_state, 158448761c62SAndrew Jeffery uint8_t *sensor_data_size, 158548761c62SAndrew Jeffery uint32_t *present_reading) 158648761c62SAndrew Jeffery { 158748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 158848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 158948761c62SAndrew Jeffery int rc; 159048761c62SAndrew Jeffery 159190bbe6c0SAndrew Jeffery if (sensor_data == NULL || sensor_data_size == NULL || 159290bbe6c0SAndrew Jeffery event_state == NULL || previous_event_state == NULL || 159390bbe6c0SAndrew Jeffery present_reading == NULL) { 159448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 159548761c62SAndrew Jeffery } 159648761c62SAndrew Jeffery 159748761c62SAndrew Jeffery if (sensor_data_length > 159848761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 159948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 160048761c62SAndrew Jeffery } 160148761c62SAndrew Jeffery 160248761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc( 160348761c62SAndrew Jeffery buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH, 160448761c62SAndrew Jeffery sensor_data, sensor_data_length); 160548761c62SAndrew Jeffery if (rc) { 160648761c62SAndrew Jeffery return rc; 160748761c62SAndrew Jeffery } 160848761c62SAndrew Jeffery 160948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 161048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_event_state); 161148761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 161248761c62SAndrew Jeffery if (rc) { 161348761c62SAndrew Jeffery return rc; 161448761c62SAndrew Jeffery } 161548761c62SAndrew Jeffery 161648761c62SAndrew Jeffery /* 161748761c62SAndrew Jeffery * The implementation below is bonkers, but it's because the function 161848761c62SAndrew Jeffery * prototype is bonkers. The `present_reading` argument should have been 161948761c62SAndrew Jeffery * a tagged union. 162048761c62SAndrew Jeffery */ 162148761c62SAndrew Jeffery switch (*sensor_data_size) { 162248761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT8: { 162348761c62SAndrew Jeffery uint8_t val; 162448761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 162548761c62SAndrew Jeffery *present_reading = (uint32_t)val; 162648761c62SAndrew Jeffery } 162748761c62SAndrew Jeffery break; 162848761c62SAndrew Jeffery } 162948761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: { 163048761c62SAndrew Jeffery int8_t val; 163148761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 163248761c62SAndrew Jeffery *present_reading = (uint32_t)(int32_t)val; 163348761c62SAndrew Jeffery } 163448761c62SAndrew Jeffery break; 163548761c62SAndrew Jeffery } 163648761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: { 163748761c62SAndrew Jeffery uint16_t val; 163848761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 163948761c62SAndrew Jeffery *present_reading = (uint32_t)val; 164048761c62SAndrew Jeffery } 164148761c62SAndrew Jeffery break; 164248761c62SAndrew Jeffery } 164348761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: { 164448761c62SAndrew Jeffery int16_t val; 164548761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 164648761c62SAndrew Jeffery *present_reading = (uint32_t)(int32_t)val; 164748761c62SAndrew Jeffery } 164848761c62SAndrew Jeffery break; 164948761c62SAndrew Jeffery } 165048761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: { 165148761c62SAndrew Jeffery uint32_t val; 165248761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 165348761c62SAndrew Jeffery *present_reading = (uint32_t)val; 165448761c62SAndrew Jeffery } 165548761c62SAndrew Jeffery break; 165648761c62SAndrew Jeffery } 165748761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: { 165848761c62SAndrew Jeffery int32_t val; 165948761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 166048761c62SAndrew Jeffery *present_reading = (uint32_t)val; 166148761c62SAndrew Jeffery } 166248761c62SAndrew Jeffery break; 166348761c62SAndrew Jeffery } 166448761c62SAndrew Jeffery default: 166548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 166648761c62SAndrew Jeffery } 166748761c62SAndrew Jeffery 166848761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 166948761c62SAndrew Jeffery } 167048761c62SAndrew Jeffery 167148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 167248761c62SAndrew Jeffery int decode_numeric_sensor_pdr_data( 167348761c62SAndrew Jeffery const void *pdr_data, size_t pdr_data_length, 167448761c62SAndrew Jeffery struct pldm_numeric_sensor_value_pdr *pdr_value) 167548761c62SAndrew Jeffery { 167648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 167748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 167848761c62SAndrew Jeffery int rc; 167948761c62SAndrew Jeffery 168048761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 168148761c62SAndrew Jeffery pdr_data, pdr_data_length); 168248761c62SAndrew Jeffery if (rc) { 168348761c62SAndrew Jeffery return rc; 168448761c62SAndrew Jeffery } 168548761c62SAndrew Jeffery 168648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr); 168748761c62SAndrew Jeffery if (rc) { 168848761c62SAndrew Jeffery return rc; 168948761c62SAndrew Jeffery } 169048761c62SAndrew Jeffery 169148761c62SAndrew Jeffery rc = pldm_platform_pdr_hdr_validate( 169248761c62SAndrew Jeffery &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 169348761c62SAndrew Jeffery pdr_data_length); 169448761c62SAndrew Jeffery if (rc) { 169548761c62SAndrew Jeffery return rc; 169648761c62SAndrew Jeffery } 169748761c62SAndrew Jeffery 169848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 169948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_id); 170048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_type); 170148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_instance_num); 170248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->container_id); 170348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_init); 170448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr); 170548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_unit); 170648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 170748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rate_unit); 170848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 170948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit); 171048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 171148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 171248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rel); 171348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 171448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->is_linear); 171548761c62SAndrew Jeffery 171648761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size); 171748761c62SAndrew Jeffery if (rc) { 171848761c62SAndrew Jeffery return rc; 171948761c62SAndrew Jeffery } 172048761c62SAndrew Jeffery if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 172148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 172248761c62SAndrew Jeffery } 172348761c62SAndrew Jeffery 172448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->resolution); 172548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->offset); 172648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->accuracy); 172748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 172848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 172948761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 173048761c62SAndrew Jeffery &pdr_value->hysteresis); 173148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte); 173248761c62SAndrew Jeffery pldm_msgbuf_extract( 173348761c62SAndrew Jeffery buf, pdr_value->threshold_and_hysteresis_volatility.byte); 173448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 173548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->update_interval); 173648761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 173748761c62SAndrew Jeffery &pdr_value->max_readable); 173848761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 173948761c62SAndrew Jeffery &pdr_value->min_readable); 174048761c62SAndrew Jeffery 174148761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 174248761c62SAndrew Jeffery if (rc) { 174348761c62SAndrew Jeffery return rc; 174448761c62SAndrew Jeffery } 174548761c62SAndrew Jeffery if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 174648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 174748761c62SAndrew Jeffery } 174848761c62SAndrew Jeffery 174948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 175048761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 175148761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->nominal_value); 175248761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 175348761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_max); 175448761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 175548761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_min); 175648761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 175748761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->warning_high); 175848761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 175948761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->warning_low); 176048761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 176148761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->critical_high); 176248761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 176348761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->critical_low); 176448761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 176548761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->fatal_high); 176648761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 176748761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->fatal_low); 176848761c62SAndrew Jeffery 176948761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 177048761c62SAndrew Jeffery } 177148761c62SAndrew Jeffery 177248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 177348761c62SAndrew Jeffery int encode_get_numeric_effecter_value_req(uint8_t instance_id, 177448761c62SAndrew Jeffery uint16_t effecter_id, 177548761c62SAndrew Jeffery struct pldm_msg *msg) 177648761c62SAndrew Jeffery { 177748761c62SAndrew Jeffery if (msg == NULL) { 177848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 177948761c62SAndrew Jeffery } 178048761c62SAndrew Jeffery 178148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 178248761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 178348761c62SAndrew Jeffery header.instance = instance_id; 178448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 178548761c62SAndrew Jeffery header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 178648761c62SAndrew Jeffery 178748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 178848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 178948761c62SAndrew Jeffery return rc; 179048761c62SAndrew Jeffery } 179148761c62SAndrew Jeffery 179248761c62SAndrew Jeffery struct pldm_get_numeric_effecter_value_req *request = 179348761c62SAndrew Jeffery (struct pldm_get_numeric_effecter_value_req *)msg->payload; 179448761c62SAndrew Jeffery request->effecter_id = htole16(effecter_id); 179548761c62SAndrew Jeffery 179648761c62SAndrew Jeffery return PLDM_SUCCESS; 179748761c62SAndrew Jeffery } 179848761c62SAndrew Jeffery 179948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 180048761c62SAndrew Jeffery int encode_get_numeric_effecter_value_resp( 180148761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, 180248761c62SAndrew Jeffery uint8_t effecter_data_size, uint8_t effecter_oper_state, 180348761c62SAndrew Jeffery const uint8_t *pending_value, const uint8_t *present_value, 180448761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 180548761c62SAndrew Jeffery { 180648761c62SAndrew Jeffery if (msg == NULL || pending_value == NULL || present_value == NULL) { 180748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 180848761c62SAndrew Jeffery } 180948761c62SAndrew Jeffery 181048761c62SAndrew Jeffery if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 181148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 181248761c62SAndrew Jeffery } 181348761c62SAndrew Jeffery 181448761c62SAndrew Jeffery if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 181548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 181648761c62SAndrew Jeffery } 181748761c62SAndrew Jeffery 181848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 181948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 182048761c62SAndrew Jeffery header.instance = instance_id; 182148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 182248761c62SAndrew Jeffery header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 182348761c62SAndrew Jeffery 182448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 182548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 182648761c62SAndrew Jeffery return rc; 182748761c62SAndrew Jeffery } 182848761c62SAndrew Jeffery 182948761c62SAndrew Jeffery struct pldm_get_numeric_effecter_value_resp *response = 183048761c62SAndrew Jeffery (struct pldm_get_numeric_effecter_value_resp *)msg->payload; 183148761c62SAndrew Jeffery 183248761c62SAndrew Jeffery response->completion_code = completion_code; 183348761c62SAndrew Jeffery response->effecter_data_size = effecter_data_size; 183448761c62SAndrew Jeffery response->effecter_oper_state = effecter_oper_state; 183548761c62SAndrew Jeffery 183648761c62SAndrew Jeffery if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 183748761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 183848761c62SAndrew Jeffery if (payload_length != 183948761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) { 184048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 184148761c62SAndrew Jeffery } 184248761c62SAndrew Jeffery response->pending_and_present_values[0] = *pending_value; 184348761c62SAndrew Jeffery response->pending_and_present_values[1] = *present_value; 184448761c62SAndrew Jeffery 184548761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 184648761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 184748761c62SAndrew Jeffery if (payload_length != 184848761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) { 184948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 185048761c62SAndrew Jeffery } 185148761c62SAndrew Jeffery uint16_t val_pending = *(uint16_t *)pending_value; 185248761c62SAndrew Jeffery val_pending = htole16(val_pending); 185348761c62SAndrew Jeffery memcpy(response->pending_and_present_values, &val_pending, 185448761c62SAndrew Jeffery sizeof(uint16_t)); 185548761c62SAndrew Jeffery uint16_t val_present = *(uint16_t *)present_value; 185648761c62SAndrew Jeffery val_present = htole16(val_present); 185748761c62SAndrew Jeffery memcpy((response->pending_and_present_values + 185848761c62SAndrew Jeffery sizeof(uint16_t)), 185948761c62SAndrew Jeffery &val_present, sizeof(uint16_t)); 186048761c62SAndrew Jeffery 186148761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 186248761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 186348761c62SAndrew Jeffery if (payload_length != 186448761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) { 186548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 186648761c62SAndrew Jeffery } 186748761c62SAndrew Jeffery uint32_t val_pending = *(uint32_t *)pending_value; 186848761c62SAndrew Jeffery val_pending = htole32(val_pending); 186948761c62SAndrew Jeffery memcpy(response->pending_and_present_values, &val_pending, 187048761c62SAndrew Jeffery sizeof(uint32_t)); 187148761c62SAndrew Jeffery uint32_t val_present = *(uint32_t *)present_value; 187248761c62SAndrew Jeffery val_present = htole32(val_present); 187348761c62SAndrew Jeffery memcpy((response->pending_and_present_values + 187448761c62SAndrew Jeffery sizeof(uint32_t)), 187548761c62SAndrew Jeffery &val_present, sizeof(uint32_t)); 187648761c62SAndrew Jeffery } 187748761c62SAndrew Jeffery return PLDM_SUCCESS; 187848761c62SAndrew Jeffery } 187948761c62SAndrew Jeffery 188048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 188148761c62SAndrew Jeffery int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg, 188248761c62SAndrew Jeffery size_t payload_length, 188348761c62SAndrew Jeffery uint16_t *effecter_id) 188448761c62SAndrew Jeffery { 188548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 188648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 188748761c62SAndrew Jeffery int rc; 188848761c62SAndrew Jeffery 188948761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL) { 189048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 189148761c62SAndrew Jeffery } 189248761c62SAndrew Jeffery 189348761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES, 189448761c62SAndrew Jeffery msg->payload, payload_length); 189548761c62SAndrew Jeffery if (rc) { 189648761c62SAndrew Jeffery return rc; 189748761c62SAndrew Jeffery } 189848761c62SAndrew Jeffery 189948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 190048761c62SAndrew Jeffery 190148761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 190248761c62SAndrew Jeffery } 190348761c62SAndrew Jeffery 190448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 190548761c62SAndrew Jeffery int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg, 190648761c62SAndrew Jeffery size_t payload_length, 190748761c62SAndrew Jeffery uint8_t *completion_code, 190848761c62SAndrew Jeffery uint8_t *effecter_data_size, 190948761c62SAndrew Jeffery uint8_t *effecter_oper_state, 191048761c62SAndrew Jeffery uint8_t *pending_value, 191148761c62SAndrew Jeffery uint8_t *present_value) 191248761c62SAndrew Jeffery { 191348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 191448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 191548761c62SAndrew Jeffery int rc; 191648761c62SAndrew Jeffery 191748761c62SAndrew Jeffery if (msg == NULL || effecter_data_size == NULL || 191848761c62SAndrew Jeffery effecter_oper_state == NULL || pending_value == NULL || 191948761c62SAndrew Jeffery present_value == NULL) { 192048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 192148761c62SAndrew Jeffery } 192248761c62SAndrew Jeffery 192348761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 192448761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES, 192548761c62SAndrew Jeffery msg->payload, payload_length); 192648761c62SAndrew Jeffery if (rc) { 192748761c62SAndrew Jeffery return rc; 192848761c62SAndrew Jeffery } 192948761c62SAndrew Jeffery 193048761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 193148761c62SAndrew Jeffery if (rc) { 193248761c62SAndrew Jeffery return rc; 193348761c62SAndrew Jeffery } 193448761c62SAndrew Jeffery 193548761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 193648761c62SAndrew Jeffery return PLDM_SUCCESS; 193748761c62SAndrew Jeffery } 193848761c62SAndrew Jeffery 193948761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 194048761c62SAndrew Jeffery if (rc) { 194148761c62SAndrew Jeffery return rc; 194248761c62SAndrew Jeffery } 194348761c62SAndrew Jeffery 194448761c62SAndrew Jeffery if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 194548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 194648761c62SAndrew Jeffery } 194748761c62SAndrew Jeffery 194848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_oper_state); 194948761c62SAndrew Jeffery if (rc) { 195048761c62SAndrew Jeffery return rc; 195148761c62SAndrew Jeffery } 195248761c62SAndrew Jeffery 195348761c62SAndrew Jeffery if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 195448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 195548761c62SAndrew Jeffery } 195648761c62SAndrew Jeffery 195748761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 195848761c62SAndrew Jeffery pending_value); 195948761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 196048761c62SAndrew Jeffery present_value); 196148761c62SAndrew Jeffery 196248761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 196348761c62SAndrew Jeffery } 196448761c62SAndrew Jeffery 196548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 196648761c62SAndrew Jeffery int encode_pldm_pdr_repository_chg_event_data( 196748761c62SAndrew Jeffery uint8_t event_data_format, uint8_t number_of_change_records, 196848761c62SAndrew Jeffery const uint8_t *event_data_operations, 196948761c62SAndrew Jeffery const uint8_t *numbers_of_change_entries, 197048761c62SAndrew Jeffery const uint32_t *const *change_entries, 197148761c62SAndrew Jeffery struct pldm_pdr_repository_chg_event_data *event_data, 197248761c62SAndrew Jeffery size_t *actual_change_records_size, size_t max_change_records_size) 197348761c62SAndrew Jeffery { 197448761c62SAndrew Jeffery if (event_data_operations == NULL || 197548761c62SAndrew Jeffery numbers_of_change_entries == NULL || change_entries == NULL) { 197648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 197748761c62SAndrew Jeffery } 197848761c62SAndrew Jeffery 197948761c62SAndrew Jeffery size_t expected_size = 198048761c62SAndrew Jeffery sizeof(event_data_format) + sizeof(number_of_change_records); 198148761c62SAndrew Jeffery 198248761c62SAndrew Jeffery expected_size += 198348761c62SAndrew Jeffery sizeof(*event_data_operations) * number_of_change_records; 198448761c62SAndrew Jeffery expected_size += 198548761c62SAndrew Jeffery sizeof(*numbers_of_change_entries) * number_of_change_records; 198648761c62SAndrew Jeffery 198748761c62SAndrew Jeffery for (uint8_t i = 0; i < number_of_change_records; ++i) { 198848761c62SAndrew Jeffery expected_size += sizeof(*change_entries[0]) * 198948761c62SAndrew Jeffery numbers_of_change_entries[i]; 199048761c62SAndrew Jeffery } 199148761c62SAndrew Jeffery 199248761c62SAndrew Jeffery *actual_change_records_size = expected_size; 199348761c62SAndrew Jeffery 199448761c62SAndrew Jeffery if (event_data == NULL) { 199548761c62SAndrew Jeffery return PLDM_SUCCESS; 199648761c62SAndrew Jeffery } 199748761c62SAndrew Jeffery 199848761c62SAndrew Jeffery if (max_change_records_size < expected_size) { 199948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 200048761c62SAndrew Jeffery } 200148761c62SAndrew Jeffery 200248761c62SAndrew Jeffery event_data->event_data_format = event_data_format; 200348761c62SAndrew Jeffery event_data->number_of_change_records = number_of_change_records; 200448761c62SAndrew Jeffery 200548761c62SAndrew Jeffery struct pldm_pdr_repository_change_record_data *record_data = 200648761c62SAndrew Jeffery (struct pldm_pdr_repository_change_record_data *) 200748761c62SAndrew Jeffery event_data->change_records; 200848761c62SAndrew Jeffery 200948761c62SAndrew Jeffery for (uint8_t i = 0; i < number_of_change_records; ++i) { 201048761c62SAndrew Jeffery record_data->event_data_operation = event_data_operations[i]; 201148761c62SAndrew Jeffery record_data->number_of_change_entries = 201248761c62SAndrew Jeffery numbers_of_change_entries[i]; 201348761c62SAndrew Jeffery 201448761c62SAndrew Jeffery for (uint8_t j = 0; j < record_data->number_of_change_entries; 201548761c62SAndrew Jeffery ++j) { 201648761c62SAndrew Jeffery record_data->change_entry[j] = 201748761c62SAndrew Jeffery htole32(change_entries[i][j]); 201848761c62SAndrew Jeffery } 201948761c62SAndrew Jeffery 202048761c62SAndrew Jeffery record_data = 202148761c62SAndrew Jeffery (struct pldm_pdr_repository_change_record_data 202248761c62SAndrew Jeffery *)(record_data->change_entry + 202348761c62SAndrew Jeffery record_data->number_of_change_entries); 202448761c62SAndrew Jeffery } 202548761c62SAndrew Jeffery 202648761c62SAndrew Jeffery return PLDM_SUCCESS; 202748761c62SAndrew Jeffery } 202848761c62SAndrew Jeffery 202948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 203048761c62SAndrew Jeffery int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data, 203148761c62SAndrew Jeffery size_t event_data_size, 203248761c62SAndrew Jeffery uint8_t *event_data_format, 203348761c62SAndrew Jeffery uint8_t *number_of_change_records, 203448761c62SAndrew Jeffery size_t *change_record_data_offset) 203548761c62SAndrew Jeffery { 203648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 203748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 203848761c62SAndrew Jeffery int rc; 203948761c62SAndrew Jeffery 204090bbe6c0SAndrew Jeffery if (event_data == NULL || event_data_format == NULL || 204190bbe6c0SAndrew Jeffery number_of_change_records == NULL || 204248761c62SAndrew Jeffery change_record_data_offset == NULL) { 204348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 204448761c62SAndrew Jeffery } 204548761c62SAndrew Jeffery 204648761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH, 204748761c62SAndrew Jeffery event_data, event_data_size); 204848761c62SAndrew Jeffery if (rc) { 204948761c62SAndrew Jeffery return rc; 205048761c62SAndrew Jeffery } 205148761c62SAndrew Jeffery 205248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_format); 205348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, number_of_change_records); 205448761c62SAndrew Jeffery 205548761c62SAndrew Jeffery *change_record_data_offset = 205648761c62SAndrew Jeffery sizeof(*event_data_format) + sizeof(*number_of_change_records); 205748761c62SAndrew Jeffery 205848761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 205948761c62SAndrew Jeffery } 206048761c62SAndrew Jeffery 2061f874b383SThu Nguyen LIBPLDM_ABI_STABLE 20627739d123SThu Nguyen int decode_pldm_message_poll_event_data( 20637739d123SThu Nguyen const void *event_data, size_t event_data_length, 20647739d123SThu Nguyen struct pldm_message_poll_event *poll_event) 206548761c62SAndrew Jeffery { 206648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 206748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 206848761c62SAndrew Jeffery int rc; 206948761c62SAndrew Jeffery 207090bbe6c0SAndrew Jeffery if (!event_data || !poll_event) { 20717739d123SThu Nguyen return -EINVAL; 207248761c62SAndrew Jeffery } 207348761c62SAndrew Jeffery 20747739d123SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 207548761c62SAndrew Jeffery event_data_length); 207648761c62SAndrew Jeffery if (rc) { 207748761c62SAndrew Jeffery return rc; 207848761c62SAndrew Jeffery } 207948761c62SAndrew Jeffery 20807739d123SThu Nguyen pldm_msgbuf_extract(buf, poll_event->format_version); 20817739d123SThu Nguyen rc = pldm_msgbuf_extract(buf, poll_event->event_id); 208248761c62SAndrew Jeffery if (rc) { 208348761c62SAndrew Jeffery return rc; 208448761c62SAndrew Jeffery } 208548761c62SAndrew Jeffery 20867739d123SThu Nguyen if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 20877739d123SThu Nguyen return -EPROTO; 208848761c62SAndrew Jeffery } 208948761c62SAndrew Jeffery 20907739d123SThu Nguyen pldm_msgbuf_extract(buf, poll_event->data_transfer_handle); 209148761c62SAndrew Jeffery 209248761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 209348761c62SAndrew Jeffery } 209448761c62SAndrew Jeffery 209548761c62SAndrew Jeffery LIBPLDM_ABI_TESTING 20967739d123SThu Nguyen int encode_pldm_message_poll_event_data( 20977739d123SThu Nguyen const struct pldm_message_poll_event *poll_event, void *event_data, 209848761c62SAndrew Jeffery size_t event_data_length) 209948761c62SAndrew Jeffery { 210048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 210148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 210248761c62SAndrew Jeffery int rc; 210348761c62SAndrew Jeffery 210490bbe6c0SAndrew Jeffery if (poll_event == NULL || event_data == NULL) { 210590bbe6c0SAndrew Jeffery return -EINVAL; 210690bbe6c0SAndrew Jeffery } 210790bbe6c0SAndrew Jeffery 21087739d123SThu Nguyen if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 21097739d123SThu Nguyen return -EPROTO; 211048761c62SAndrew Jeffery } 211148761c62SAndrew Jeffery 21127739d123SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 211348761c62SAndrew Jeffery event_data_length); 211448761c62SAndrew Jeffery if (rc) { 211548761c62SAndrew Jeffery return rc; 211648761c62SAndrew Jeffery } 21177739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->format_version); 21187739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->event_id); 21197739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->data_transfer_handle); 212048761c62SAndrew Jeffery 21217739d123SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 212248761c62SAndrew Jeffery } 212348761c62SAndrew Jeffery 212448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 212548761c62SAndrew Jeffery int decode_pldm_pdr_repository_change_record_data( 212648761c62SAndrew Jeffery const uint8_t *change_record_data, size_t change_record_data_size, 212748761c62SAndrew Jeffery uint8_t *event_data_operation, uint8_t *number_of_change_entries, 212848761c62SAndrew Jeffery size_t *change_entry_data_offset) 212948761c62SAndrew Jeffery { 213048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 213148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 213248761c62SAndrew Jeffery int rc; 213348761c62SAndrew Jeffery 213490bbe6c0SAndrew Jeffery if (change_record_data == NULL || event_data_operation == NULL || 213590bbe6c0SAndrew Jeffery number_of_change_entries == NULL || 213648761c62SAndrew Jeffery change_entry_data_offset == NULL) { 213748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 213848761c62SAndrew Jeffery } 213948761c62SAndrew Jeffery 214048761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, 214148761c62SAndrew Jeffery PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH, 214248761c62SAndrew Jeffery change_record_data, change_record_data_size); 214348761c62SAndrew Jeffery if (rc) { 214448761c62SAndrew Jeffery return rc; 214548761c62SAndrew Jeffery } 214648761c62SAndrew Jeffery 214748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_operation); 214848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, number_of_change_entries); 214948761c62SAndrew Jeffery 215048761c62SAndrew Jeffery *change_entry_data_offset = sizeof(*event_data_operation) + 215148761c62SAndrew Jeffery sizeof(*number_of_change_entries); 215248761c62SAndrew Jeffery 215348761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 215448761c62SAndrew Jeffery } 215548761c62SAndrew Jeffery 215648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 215748761c62SAndrew Jeffery int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id, 215848761c62SAndrew Jeffery uint8_t rearm_event_state, 215948761c62SAndrew Jeffery struct pldm_msg *msg) 216048761c62SAndrew Jeffery { 216148761c62SAndrew Jeffery if (msg == NULL) { 216248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 216348761c62SAndrew Jeffery } 216448761c62SAndrew Jeffery 216548761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 216648761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 216748761c62SAndrew Jeffery header.instance = instance_id; 216848761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 216948761c62SAndrew Jeffery header.command = PLDM_GET_SENSOR_READING; 217048761c62SAndrew Jeffery 217148761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 217248761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 217348761c62SAndrew Jeffery return rc; 217448761c62SAndrew Jeffery } 217548761c62SAndrew Jeffery 217648761c62SAndrew Jeffery struct pldm_get_sensor_reading_req *request = 217748761c62SAndrew Jeffery (struct pldm_get_sensor_reading_req *)msg->payload; 217848761c62SAndrew Jeffery 217948761c62SAndrew Jeffery request->sensor_id = htole16(sensor_id); 218048761c62SAndrew Jeffery request->rearm_event_state = rearm_event_state; 218148761c62SAndrew Jeffery 218248761c62SAndrew Jeffery return PLDM_SUCCESS; 218348761c62SAndrew Jeffery } 218448761c62SAndrew Jeffery 218548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 218648761c62SAndrew Jeffery int decode_get_sensor_reading_resp( 218748761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 218848761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *sensor_data_size, 218948761c62SAndrew Jeffery uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable, 219048761c62SAndrew Jeffery uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state, 219148761c62SAndrew Jeffery uint8_t *present_reading) 219248761c62SAndrew Jeffery { 219348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 219448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 219548761c62SAndrew Jeffery int rc; 219648761c62SAndrew Jeffery 219748761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 219848761c62SAndrew Jeffery sensor_data_size == NULL || sensor_operational_state == NULL || 219948761c62SAndrew Jeffery sensor_event_message_enable == NULL || present_state == NULL || 220048761c62SAndrew Jeffery previous_state == NULL || event_state == NULL || 220148761c62SAndrew Jeffery present_reading == NULL) { 220248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 220348761c62SAndrew Jeffery } 220448761c62SAndrew Jeffery 220548761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES, 220648761c62SAndrew Jeffery msg->payload, payload_length); 220748761c62SAndrew Jeffery if (rc) { 220848761c62SAndrew Jeffery return rc; 220948761c62SAndrew Jeffery } 221048761c62SAndrew Jeffery 221148761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 221248761c62SAndrew Jeffery if (rc) { 221348761c62SAndrew Jeffery return rc; 221448761c62SAndrew Jeffery } 221548761c62SAndrew Jeffery 221648761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 221748761c62SAndrew Jeffery return PLDM_SUCCESS; 221848761c62SAndrew Jeffery } 221948761c62SAndrew Jeffery 222048761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 222148761c62SAndrew Jeffery if (rc) { 222248761c62SAndrew Jeffery return rc; 222348761c62SAndrew Jeffery } 222448761c62SAndrew Jeffery 222548761c62SAndrew Jeffery if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) { 222648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 222748761c62SAndrew Jeffery } 222848761c62SAndrew Jeffery 222948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_operational_state); 223048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_event_message_enable); 223148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, present_state); 223248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_state); 223348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 223448761c62SAndrew Jeffery 223548761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size, 223648761c62SAndrew Jeffery present_reading); 223748761c62SAndrew Jeffery 223848761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 223948761c62SAndrew Jeffery } 224048761c62SAndrew Jeffery 224148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 224248761c62SAndrew Jeffery int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code, 224348761c62SAndrew Jeffery uint8_t sensor_data_size, 224448761c62SAndrew Jeffery uint8_t sensor_operational_state, 224548761c62SAndrew Jeffery uint8_t sensor_event_message_enable, 224648761c62SAndrew Jeffery uint8_t present_state, 224748761c62SAndrew Jeffery uint8_t previous_state, uint8_t event_state, 224848761c62SAndrew Jeffery const uint8_t *present_reading, 224948761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 225048761c62SAndrew Jeffery { 225148761c62SAndrew Jeffery if (msg == NULL || present_reading == NULL) { 225248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 225348761c62SAndrew Jeffery } 225448761c62SAndrew Jeffery 225548761c62SAndrew Jeffery if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 225648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 225748761c62SAndrew Jeffery } 225848761c62SAndrew Jeffery 225948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 226048761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 226148761c62SAndrew Jeffery header.instance = instance_id; 226248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 226348761c62SAndrew Jeffery header.command = PLDM_GET_SENSOR_READING; 226448761c62SAndrew Jeffery 226548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 226648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 226748761c62SAndrew Jeffery return rc; 226848761c62SAndrew Jeffery } 226948761c62SAndrew Jeffery 227048761c62SAndrew Jeffery struct pldm_get_sensor_reading_resp *response = 227148761c62SAndrew Jeffery (struct pldm_get_sensor_reading_resp *)msg->payload; 227248761c62SAndrew Jeffery 227348761c62SAndrew Jeffery response->completion_code = completion_code; 227448761c62SAndrew Jeffery response->sensor_data_size = sensor_data_size; 227548761c62SAndrew Jeffery response->sensor_operational_state = sensor_operational_state; 227648761c62SAndrew Jeffery response->sensor_event_message_enable = sensor_event_message_enable; 227748761c62SAndrew Jeffery response->present_state = present_state; 227848761c62SAndrew Jeffery response->previous_state = previous_state; 227948761c62SAndrew Jeffery response->event_state = event_state; 228048761c62SAndrew Jeffery 228148761c62SAndrew Jeffery if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 228248761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 228348761c62SAndrew Jeffery if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) { 228448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 228548761c62SAndrew Jeffery } 228648761c62SAndrew Jeffery response->present_reading[0] = *present_reading; 228748761c62SAndrew Jeffery 228848761c62SAndrew Jeffery } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 228948761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 229048761c62SAndrew Jeffery if (payload_length != 229148761c62SAndrew Jeffery PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) { 229248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 229348761c62SAndrew Jeffery } 229448761c62SAndrew Jeffery uint16_t val = *(uint16_t *)present_reading; 229548761c62SAndrew Jeffery val = htole16(val); 229648761c62SAndrew Jeffery memcpy(response->present_reading, &val, 2); 229748761c62SAndrew Jeffery 229848761c62SAndrew Jeffery } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 229948761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 230048761c62SAndrew Jeffery if (payload_length != 230148761c62SAndrew Jeffery PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) { 230248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 230348761c62SAndrew Jeffery } 230448761c62SAndrew Jeffery uint32_t val = *(uint32_t *)present_reading; 230548761c62SAndrew Jeffery val = htole32(val); 230648761c62SAndrew Jeffery memcpy(response->present_reading, &val, 4); 230748761c62SAndrew Jeffery } 230848761c62SAndrew Jeffery 230948761c62SAndrew Jeffery return PLDM_SUCCESS; 231048761c62SAndrew Jeffery } 231148761c62SAndrew Jeffery 231248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 231348761c62SAndrew Jeffery int decode_get_sensor_reading_req(const struct pldm_msg *msg, 231448761c62SAndrew Jeffery size_t payload_length, uint16_t *sensor_id, 231548761c62SAndrew Jeffery uint8_t *rearm_event_state) 231648761c62SAndrew Jeffery { 231748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 231848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 231948761c62SAndrew Jeffery int rc; 232048761c62SAndrew Jeffery 232148761c62SAndrew Jeffery if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) { 232248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 232348761c62SAndrew Jeffery } 232448761c62SAndrew Jeffery 232548761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_REQ_BYTES, 232648761c62SAndrew Jeffery msg->payload, payload_length); 232748761c62SAndrew Jeffery if (rc) { 232848761c62SAndrew Jeffery return rc; 232948761c62SAndrew Jeffery } 233048761c62SAndrew Jeffery 233148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 233248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, rearm_event_state); 233348761c62SAndrew Jeffery 233448761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 233548761c62SAndrew Jeffery } 233648761c62SAndrew Jeffery 233748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 233848761c62SAndrew Jeffery int encode_set_event_receiver_req(uint8_t instance_id, 233948761c62SAndrew Jeffery uint8_t event_message_global_enable, 234048761c62SAndrew Jeffery uint8_t transport_protocol_type, 234148761c62SAndrew Jeffery uint8_t event_receiver_address_info, 234248761c62SAndrew Jeffery uint16_t heartbeat_timer, 234348761c62SAndrew Jeffery struct pldm_msg *msg) 234448761c62SAndrew Jeffery { 234548761c62SAndrew Jeffery if (msg == NULL) { 234648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 234748761c62SAndrew Jeffery } 234848761c62SAndrew Jeffery 234948761c62SAndrew Jeffery if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) { 235048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 235148761c62SAndrew Jeffery } 235248761c62SAndrew Jeffery 235348761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 235448761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 235548761c62SAndrew Jeffery header.instance = instance_id; 235648761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 235748761c62SAndrew Jeffery header.command = PLDM_SET_EVENT_RECEIVER; 235848761c62SAndrew Jeffery 235948761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 236048761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 236148761c62SAndrew Jeffery return rc; 236248761c62SAndrew Jeffery } 236348761c62SAndrew Jeffery 236448761c62SAndrew Jeffery struct pldm_set_event_receiver_req *request = 236548761c62SAndrew Jeffery (struct pldm_set_event_receiver_req *)msg->payload; 236648761c62SAndrew Jeffery request->event_message_global_enable = event_message_global_enable; 236748761c62SAndrew Jeffery 236848761c62SAndrew Jeffery request->transport_protocol_type = transport_protocol_type; 236948761c62SAndrew Jeffery request->event_receiver_address_info = event_receiver_address_info; 237048761c62SAndrew Jeffery 237148761c62SAndrew Jeffery if (event_message_global_enable == 237248761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 237348761c62SAndrew Jeffery if (heartbeat_timer == 0) { 237448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 237548761c62SAndrew Jeffery } 237648761c62SAndrew Jeffery request->heartbeat_timer = htole16(heartbeat_timer); 237748761c62SAndrew Jeffery } 237848761c62SAndrew Jeffery 237948761c62SAndrew Jeffery return PLDM_SUCCESS; 238048761c62SAndrew Jeffery } 238148761c62SAndrew Jeffery 238248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 238348761c62SAndrew Jeffery int decode_set_event_receiver_resp(const struct pldm_msg *msg, 238448761c62SAndrew Jeffery size_t payload_length, 238548761c62SAndrew Jeffery uint8_t *completion_code) 238648761c62SAndrew Jeffery { 238748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 238848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 238948761c62SAndrew Jeffery int rc; 239048761c62SAndrew Jeffery 239148761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 239248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 239348761c62SAndrew Jeffery } 239448761c62SAndrew Jeffery 239548761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES, 239648761c62SAndrew Jeffery msg->payload, payload_length); 239748761c62SAndrew Jeffery if (rc) { 239848761c62SAndrew Jeffery return rc; 239948761c62SAndrew Jeffery } 240048761c62SAndrew Jeffery 240148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, completion_code); 240248761c62SAndrew Jeffery 240348761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 240448761c62SAndrew Jeffery } 240548761c62SAndrew Jeffery 240648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 240748761c62SAndrew Jeffery int decode_set_event_receiver_req(const struct pldm_msg *msg, 240848761c62SAndrew Jeffery size_t payload_length, 240948761c62SAndrew Jeffery uint8_t *event_message_global_enable, 241048761c62SAndrew Jeffery uint8_t *transport_protocol_type, 241148761c62SAndrew Jeffery uint8_t *event_receiver_address_info, 241248761c62SAndrew Jeffery uint16_t *heartbeat_timer) 241348761c62SAndrew Jeffery 241448761c62SAndrew Jeffery { 241548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 241648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 241748761c62SAndrew Jeffery int rc; 241848761c62SAndrew Jeffery 241948761c62SAndrew Jeffery if (msg == NULL || event_message_global_enable == NULL || 242048761c62SAndrew Jeffery transport_protocol_type == NULL || 242148761c62SAndrew Jeffery event_receiver_address_info == NULL || heartbeat_timer == NULL) { 242248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 242348761c62SAndrew Jeffery } 242448761c62SAndrew Jeffery 242548761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES, 242648761c62SAndrew Jeffery msg->payload, payload_length); 242748761c62SAndrew Jeffery if (rc) { 242848761c62SAndrew Jeffery return rc; 242948761c62SAndrew Jeffery } 243048761c62SAndrew Jeffery 243148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_message_global_enable); 243248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transport_protocol_type); 243348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_receiver_address_info); 243448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, heartbeat_timer); 243548761c62SAndrew Jeffery 243648761c62SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 243748761c62SAndrew Jeffery if (rc) { 243848761c62SAndrew Jeffery return rc; 243948761c62SAndrew Jeffery } 244048761c62SAndrew Jeffery 244148761c62SAndrew Jeffery if ((*event_message_global_enable == 244248761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) && 244348761c62SAndrew Jeffery (*heartbeat_timer == 0)) { 244448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 244548761c62SAndrew Jeffery } 244648761c62SAndrew Jeffery 244748761c62SAndrew Jeffery return PLDM_SUCCESS; 244848761c62SAndrew Jeffery } 244948761c62SAndrew Jeffery 245048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 245148761c62SAndrew Jeffery int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code, 245248761c62SAndrew Jeffery struct pldm_msg *msg) 245348761c62SAndrew Jeffery 245448761c62SAndrew Jeffery { 245548761c62SAndrew Jeffery if (msg == NULL) { 245648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 245748761c62SAndrew Jeffery } 245848761c62SAndrew Jeffery 245948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 246048761c62SAndrew Jeffery header.instance = instance_id; 246148761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 246248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 246348761c62SAndrew Jeffery header.command = PLDM_SET_EVENT_RECEIVER; 246448761c62SAndrew Jeffery 246548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 246648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 246748761c62SAndrew Jeffery return rc; 246848761c62SAndrew Jeffery } 246948761c62SAndrew Jeffery 247048761c62SAndrew Jeffery msg->payload[0] = completion_code; 247148761c62SAndrew Jeffery 247248761c62SAndrew Jeffery return PLDM_SUCCESS; 247348761c62SAndrew Jeffery } 247448761c62SAndrew Jeffery 247548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 247648761c62SAndrew Jeffery int encode_poll_for_platform_event_message_req(uint8_t instance_id, 247748761c62SAndrew Jeffery uint8_t format_version, 247848761c62SAndrew Jeffery uint8_t transfer_operation_flag, 247948761c62SAndrew Jeffery uint32_t data_transfer_handle, 248048761c62SAndrew Jeffery uint16_t event_id_to_acknowledge, 248148761c62SAndrew Jeffery struct pldm_msg *msg, 248248761c62SAndrew Jeffery size_t payload_length) 248348761c62SAndrew Jeffery { 248448761c62SAndrew Jeffery struct pldm_msgbuf _buf; 248548761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 248648761c62SAndrew Jeffery int rc; 248748761c62SAndrew Jeffery 248848761c62SAndrew Jeffery if (msg == NULL) { 248948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 249048761c62SAndrew Jeffery } 249148761c62SAndrew Jeffery 2492387b10f6SThu Nguyen rc = pldm_platform_poll_for_platform_event_message_validate( 2493387b10f6SThu Nguyen transfer_operation_flag, event_id_to_acknowledge); 2494387b10f6SThu Nguyen if (rc < 0) { 2495387b10f6SThu Nguyen return PLDM_ERROR_INVALID_DATA; 2496387b10f6SThu Nguyen } 2497387b10f6SThu Nguyen 249848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 249948761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 250048761c62SAndrew Jeffery header.instance = instance_id; 250148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 250248761c62SAndrew Jeffery header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 250348761c62SAndrew Jeffery 250448761c62SAndrew Jeffery rc = pack_pldm_header(&header, &(msg->hdr)); 250548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 250648761c62SAndrew Jeffery return rc; 250748761c62SAndrew Jeffery } 250848761c62SAndrew Jeffery 250948761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc( 251048761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 251148761c62SAndrew Jeffery msg->payload, payload_length); 251248761c62SAndrew Jeffery if (rc) { 251348761c62SAndrew Jeffery return rc; 251448761c62SAndrew Jeffery } 251548761c62SAndrew Jeffery 251648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, format_version); 251748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, transfer_operation_flag); 251848761c62SAndrew Jeffery pldm_msgbuf_insert(buf, data_transfer_handle); 251948761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_id_to_acknowledge); 252048761c62SAndrew Jeffery 252148761c62SAndrew Jeffery return pldm_msgbuf_destroy(buf); 252248761c62SAndrew Jeffery } 252348761c62SAndrew Jeffery 252448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 252548761c62SAndrew Jeffery int decode_poll_for_platform_event_message_resp( 252648761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 252748761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *tid, uint16_t *event_id, 252848761c62SAndrew Jeffery uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 252948761c62SAndrew Jeffery uint8_t *event_class, uint32_t *event_data_size, void **event_data, 253048761c62SAndrew Jeffery uint32_t *event_data_integrity_checksum) 253148761c62SAndrew Jeffery { 253248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 253348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 253448761c62SAndrew Jeffery int rc; 253548761c62SAndrew Jeffery 253648761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || tid == NULL || 253748761c62SAndrew Jeffery event_id == NULL || next_data_transfer_handle == NULL || 253848761c62SAndrew Jeffery transfer_flag == NULL || event_class == NULL || 253948761c62SAndrew Jeffery event_data_size == NULL || event_data == NULL || 254048761c62SAndrew Jeffery event_data_integrity_checksum == NULL) { 254148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 254248761c62SAndrew Jeffery } 254348761c62SAndrew Jeffery 254448761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc( 254548761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 254648761c62SAndrew Jeffery msg->payload, payload_length); 254748761c62SAndrew Jeffery if (rc) { 254848761c62SAndrew Jeffery return rc; 254948761c62SAndrew Jeffery } 255048761c62SAndrew Jeffery 255148761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 255248761c62SAndrew Jeffery if (rc) { 255348761c62SAndrew Jeffery return rc; 255448761c62SAndrew Jeffery } 255548761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 255648761c62SAndrew Jeffery return *completion_code; 255748761c62SAndrew Jeffery } 255848761c62SAndrew Jeffery 255948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, tid); 256048761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_id); 256148761c62SAndrew Jeffery if (rc) { 256248761c62SAndrew Jeffery return rc; 256348761c62SAndrew Jeffery } 256448761c62SAndrew Jeffery if ((*event_id == 0) || (*event_id == 0xffff)) { 256548761c62SAndrew Jeffery return PLDM_SUCCESS; 256648761c62SAndrew Jeffery } 256748761c62SAndrew Jeffery 256848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_data_transfer_handle); 256948761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, transfer_flag); 257048761c62SAndrew Jeffery if (rc) { 257148761c62SAndrew Jeffery return rc; 257248761c62SAndrew Jeffery } 257348761c62SAndrew Jeffery 257448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_class); 257548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_data_size); 257648761c62SAndrew Jeffery if (rc) { 257748761c62SAndrew Jeffery return rc; 257848761c62SAndrew Jeffery } 257948761c62SAndrew Jeffery if (*event_data_size > payload_length) { 258048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 258148761c62SAndrew Jeffery } 258248761c62SAndrew Jeffery 258348761c62SAndrew Jeffery if (*event_data_size > 0) { 258448761c62SAndrew Jeffery pldm_msgbuf_span_required(buf, *event_data_size, event_data); 258548761c62SAndrew Jeffery } 258648761c62SAndrew Jeffery 258748761c62SAndrew Jeffery if (*transfer_flag == PLDM_END || 258848761c62SAndrew Jeffery *transfer_flag == PLDM_START_AND_END) { 258948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_integrity_checksum); 259048761c62SAndrew Jeffery } 259148761c62SAndrew Jeffery 259248761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 259348761c62SAndrew Jeffery } 259448761c62SAndrew Jeffery 259548761c62SAndrew Jeffery LIBPLDM_ABI_TESTING 259648761c62SAndrew Jeffery int decode_numeric_effecter_pdr_data( 259748761c62SAndrew Jeffery const void *pdr_data, size_t pdr_data_length, 259848761c62SAndrew Jeffery struct pldm_numeric_effecter_value_pdr *pdr_value) 259948761c62SAndrew Jeffery { 260048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 260148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 260248761c62SAndrew Jeffery struct pldm_value_pdr_hdr hdr; 260348761c62SAndrew Jeffery int rc; 260448761c62SAndrew Jeffery 260590bbe6c0SAndrew Jeffery if (!pdr_data || !pdr_value) { 260690bbe6c0SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 260790bbe6c0SAndrew Jeffery } 260890bbe6c0SAndrew Jeffery 260948761c62SAndrew Jeffery rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 261048761c62SAndrew Jeffery pdr_data, pdr_data_length); 261148761c62SAndrew Jeffery if (rc) { 261248761c62SAndrew Jeffery return rc; 261348761c62SAndrew Jeffery } 261448761c62SAndrew Jeffery 261548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &hdr); 261648761c62SAndrew Jeffery if (rc) { 261748761c62SAndrew Jeffery return rc; 261848761c62SAndrew Jeffery } 261948761c62SAndrew Jeffery 262048761c62SAndrew Jeffery rc = pldm_platform_pdr_hdr_validate( 262148761c62SAndrew Jeffery &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 262248761c62SAndrew Jeffery pdr_data_length); 262348761c62SAndrew Jeffery if (rc) { 262448761c62SAndrew Jeffery return rc; 262548761c62SAndrew Jeffery } 262648761c62SAndrew Jeffery 262748761c62SAndrew Jeffery memcpy(&pdr_value->hdr, &hdr, sizeof(hdr)); 262848761c62SAndrew Jeffery 262948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 263048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_id); 263148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_type); 263248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_instance); 263348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->container_id); 263448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id); 263548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_init); 263648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names); 263748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_unit); 263848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 263948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rate_unit); 264048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 264148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit); 264248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 264348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 264448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 264548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->is_linear); 264648761c62SAndrew Jeffery 264748761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size); 264848761c62SAndrew Jeffery if (rc) { 264948761c62SAndrew Jeffery return rc; 265048761c62SAndrew Jeffery } 265148761c62SAndrew Jeffery if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 265248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 265348761c62SAndrew Jeffery } 265448761c62SAndrew Jeffery 265548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->resolution); 265648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->offset); 265748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->accuracy); 265848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 265948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 266048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 266148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->transition_interval); 266248761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 266348761c62SAndrew Jeffery pdr_value->max_settable); 266448761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 266548761c62SAndrew Jeffery pdr_value->min_settable); 266648761c62SAndrew Jeffery 266748761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 266848761c62SAndrew Jeffery if (rc) { 266948761c62SAndrew Jeffery return rc; 267048761c62SAndrew Jeffery } 267148761c62SAndrew Jeffery if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 267248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 267348761c62SAndrew Jeffery } 267448761c62SAndrew Jeffery 267548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 267648761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 267748761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->nominal_value); 267848761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 267948761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_max); 268048761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 268148761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_min); 268248761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 268348761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->rated_max); 268448761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 268548761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->rated_min); 268648761c62SAndrew Jeffery 268748761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 268848761c62SAndrew Jeffery } 268948761c62SAndrew Jeffery 2690de67ab62STal Yacobi LIBPLDM_ABI_STABLE 269148761c62SAndrew Jeffery int encode_get_state_effecter_states_req(uint8_t instance_id, 269248761c62SAndrew Jeffery uint16_t effecter_id, 269348761c62SAndrew Jeffery struct pldm_msg *msg, 269448761c62SAndrew Jeffery size_t payload_length) 269548761c62SAndrew Jeffery { 269648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 269748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 269848761c62SAndrew Jeffery int rc; 269948761c62SAndrew Jeffery 270048761c62SAndrew Jeffery if (msg == NULL) { 2701f490a38fSTal Yacobi return -EINVAL; 270248761c62SAndrew Jeffery } 270348761c62SAndrew Jeffery 270448761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 270548761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 270648761c62SAndrew Jeffery header.instance = instance_id; 270748761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 270848761c62SAndrew Jeffery header.command = PLDM_GET_STATE_EFFECTER_STATES; 270948761c62SAndrew Jeffery 2710f490a38fSTal Yacobi rc = pack_pldm_header_errno(&header, &msg->hdr); 2711f490a38fSTal Yacobi if (rc < 0) { 271248761c62SAndrew Jeffery return rc; 271348761c62SAndrew Jeffery } 271448761c62SAndrew Jeffery 2715f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno(buf, 2716f490a38fSTal Yacobi PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES, 271748761c62SAndrew Jeffery msg->payload, payload_length); 271848761c62SAndrew Jeffery if (rc) { 271948761c62SAndrew Jeffery return rc; 272048761c62SAndrew Jeffery } 272148761c62SAndrew Jeffery 272248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, effecter_id); 272348761c62SAndrew Jeffery 272448761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 272548761c62SAndrew Jeffery } 272648761c62SAndrew Jeffery 2727de67ab62STal Yacobi LIBPLDM_ABI_STABLE 272848761c62SAndrew Jeffery int decode_get_state_effecter_states_req(const struct pldm_msg *msg, 272948761c62SAndrew Jeffery size_t payload_length, 273048761c62SAndrew Jeffery uint16_t *effecter_id) 273148761c62SAndrew Jeffery { 273248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 273348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 273448761c62SAndrew Jeffery int rc; 273548761c62SAndrew Jeffery 273648761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL) { 2737f490a38fSTal Yacobi return -EINVAL; 273848761c62SAndrew Jeffery } 273948761c62SAndrew Jeffery 2740f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2741f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 274248761c62SAndrew Jeffery msg->payload, payload_length); 274348761c62SAndrew Jeffery if (rc) { 274448761c62SAndrew Jeffery return rc; 274548761c62SAndrew Jeffery } 274648761c62SAndrew Jeffery 274748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 274848761c62SAndrew Jeffery 274948761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 275048761c62SAndrew Jeffery } 275148761c62SAndrew Jeffery 2752de67ab62STal Yacobi LIBPLDM_ABI_STABLE 275348761c62SAndrew Jeffery int decode_get_state_effecter_states_resp( 275448761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 275548761c62SAndrew Jeffery struct pldm_get_state_effecter_states_resp *resp) 275648761c62SAndrew Jeffery { 275748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 275848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 275948761c62SAndrew Jeffery get_effecter_state_field *field; 276048761c62SAndrew Jeffery int rc; 276148761c62SAndrew Jeffery int i; 276248761c62SAndrew Jeffery 276348761c62SAndrew Jeffery if (msg == NULL || resp == NULL) { 2764f490a38fSTal Yacobi return -EINVAL; 276548761c62SAndrew Jeffery } 276648761c62SAndrew Jeffery 2767f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2768f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 276948761c62SAndrew Jeffery msg->payload, payload_length); 277048761c62SAndrew Jeffery if (rc) { 277148761c62SAndrew Jeffery return rc; 277248761c62SAndrew Jeffery } 277348761c62SAndrew Jeffery 277448761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->completion_code); 277548761c62SAndrew Jeffery if (rc) { 277648761c62SAndrew Jeffery return rc; 277748761c62SAndrew Jeffery } 277848761c62SAndrew Jeffery 277948761c62SAndrew Jeffery if (PLDM_SUCCESS != resp->completion_code) { 2780f490a38fSTal Yacobi return 0; 278148761c62SAndrew Jeffery } 278248761c62SAndrew Jeffery 278348761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count); 278448761c62SAndrew Jeffery if (rc) { 278548761c62SAndrew Jeffery return rc; 278648761c62SAndrew Jeffery } 278748761c62SAndrew Jeffery 278848761c62SAndrew Jeffery uint8_t comp_effecter_count = resp->comp_effecter_count; 278948761c62SAndrew Jeffery 279048761c62SAndrew Jeffery if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 279148761c62SAndrew Jeffery comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2792f490a38fSTal Yacobi return -EBADMSG; 279348761c62SAndrew Jeffery } 279448761c62SAndrew Jeffery 279548761c62SAndrew Jeffery for (i = 0, field = resp->field; i < comp_effecter_count; 279648761c62SAndrew Jeffery i++, field++) { 279748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->effecter_op_state); 279848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->pending_state); 279948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->present_state); 280048761c62SAndrew Jeffery } 280148761c62SAndrew Jeffery 280248761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 280348761c62SAndrew Jeffery } 280448761c62SAndrew Jeffery 2805de67ab62STal Yacobi LIBPLDM_ABI_STABLE 280648761c62SAndrew Jeffery int encode_get_state_effecter_states_resp( 280748761c62SAndrew Jeffery uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp, 280848761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 280948761c62SAndrew Jeffery { 281048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 281148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 281248761c62SAndrew Jeffery get_effecter_state_field *field; 281348761c62SAndrew Jeffery int rc; 281448761c62SAndrew Jeffery int i; 281548761c62SAndrew Jeffery 281648761c62SAndrew Jeffery if (msg == NULL || resp == NULL) { 2817f490a38fSTal Yacobi return -EINVAL; 281848761c62SAndrew Jeffery } 281948761c62SAndrew Jeffery 282048761c62SAndrew Jeffery uint8_t comp_effecter_count = resp->comp_effecter_count; 282148761c62SAndrew Jeffery 282248761c62SAndrew Jeffery if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 282348761c62SAndrew Jeffery comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2824f490a38fSTal Yacobi return -EBADMSG; 282548761c62SAndrew Jeffery } 282648761c62SAndrew Jeffery 282748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 282848761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 282948761c62SAndrew Jeffery header.instance = instance_id; 283048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 283148761c62SAndrew Jeffery header.command = PLDM_GET_STATE_EFFECTER_STATES; 283248761c62SAndrew Jeffery 2833f490a38fSTal Yacobi rc = pack_pldm_header_errno(&header, &msg->hdr); 2834f490a38fSTal Yacobi if (rc < 0) { 283548761c62SAndrew Jeffery return rc; 283648761c62SAndrew Jeffery } 283748761c62SAndrew Jeffery 2838f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2839f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 284048761c62SAndrew Jeffery msg->payload, payload_length); 284148761c62SAndrew Jeffery if (rc) { 284248761c62SAndrew Jeffery return rc; 284348761c62SAndrew Jeffery } 284448761c62SAndrew Jeffery 284548761c62SAndrew Jeffery pldm_msgbuf_insert(buf, resp->completion_code); 284648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, comp_effecter_count); 284748761c62SAndrew Jeffery 284848761c62SAndrew Jeffery for (i = 0, field = resp->field; i < comp_effecter_count; 284948761c62SAndrew Jeffery i++, field++) { 285048761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->effecter_op_state); 285148761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->pending_state); 285248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->present_state); 285348761c62SAndrew Jeffery } 285448761c62SAndrew Jeffery 285548761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 285648761c62SAndrew Jeffery } 2857dacfa354SThu Nguyen 285843cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE 2859dacfa354SThu Nguyen int decode_entity_auxiliary_names_pdr( 2860dacfa354SThu Nguyen const void *data, size_t data_length, 2861dacfa354SThu Nguyen struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length) 2862dacfa354SThu Nguyen { 2863dacfa354SThu Nguyen struct pldm_msgbuf _buf; 2864dacfa354SThu Nguyen struct pldm_msgbuf *buf = &_buf; 2865dacfa354SThu Nguyen struct pldm_msgbuf _src; 2866dacfa354SThu Nguyen struct pldm_msgbuf *src = &_src; 2867dacfa354SThu Nguyen struct pldm_msgbuf _dst; 2868dacfa354SThu Nguyen struct pldm_msgbuf *dst = &_dst; 2869dacfa354SThu Nguyen size_t names_len = 0; 2870dacfa354SThu Nguyen void *names = NULL; 2871dacfa354SThu Nguyen int rc; 2872dacfa354SThu Nguyen int i; 2873dacfa354SThu Nguyen 287490bbe6c0SAndrew Jeffery if (!data || !pdr) { 287590bbe6c0SAndrew Jeffery return -EINVAL; 287690bbe6c0SAndrew Jeffery } 287790bbe6c0SAndrew Jeffery 2878dacfa354SThu Nguyen /* 2879dacfa354SThu Nguyen * Alignment of auxiliary_name_data is an invariant as we statically assert 2880dacfa354SThu Nguyen * its behaviour in the header. 2881dacfa354SThu Nguyen */ 2882dacfa354SThu Nguyen assert(!((uintptr_t)pdr->auxiliary_name_data & 2883dacfa354SThu Nguyen (alignof(pldm_utf16be) - 1))); 2884dacfa354SThu Nguyen 2885dacfa354SThu Nguyen /* Reject any lengths that are obviously invalid */ 2886dacfa354SThu Nguyen if (pdr_length < data_length || pdr_length < sizeof(*pdr)) { 2887dacfa354SThu Nguyen return -EINVAL; 2888dacfa354SThu Nguyen } 2889dacfa354SThu Nguyen 2890dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno( 2891dacfa354SThu Nguyen buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data, 2892dacfa354SThu Nguyen data_length); 2893dacfa354SThu Nguyen if (rc) { 2894dacfa354SThu Nguyen return rc; 2895dacfa354SThu Nguyen } 2896dacfa354SThu Nguyen 2897dacfa354SThu Nguyen rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr->hdr); 2898dacfa354SThu Nguyen if (rc) { 2899dacfa354SThu Nguyen return rc; 2900dacfa354SThu Nguyen } 2901dacfa354SThu Nguyen 2902dacfa354SThu Nguyen rc = pldm_platform_pdr_hdr_validate( 2903dacfa354SThu Nguyen &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, 2904dacfa354SThu Nguyen data_length); 2905dacfa354SThu Nguyen if (rc) { 2906dacfa354SThu Nguyen return rc; 2907dacfa354SThu Nguyen } 2908dacfa354SThu Nguyen 2909dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_type); 2910dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_instance_num); 2911dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_container_id); 2912dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->shared_name_count); 2913dacfa354SThu Nguyen rc = pldm_msgbuf_extract(buf, pdr->name_string_count); 2914dacfa354SThu Nguyen if (rc < 0) { 2915dacfa354SThu Nguyen return rc; 2916dacfa354SThu Nguyen } 2917dacfa354SThu Nguyen 2918dacfa354SThu Nguyen rc = pldm_msgbuf_span_remaining(buf, &names, &names_len); 2919dacfa354SThu Nguyen if (rc < 0) { 2920dacfa354SThu Nguyen return rc; 2921dacfa354SThu Nguyen } 292290bbe6c0SAndrew Jeffery assert(names); 2923dacfa354SThu Nguyen 2924dacfa354SThu Nguyen pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr); 2925dacfa354SThu Nguyen 2926dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size, 2927dacfa354SThu Nguyen pdr->auxiliary_name_data, 2928dacfa354SThu Nguyen pdr->auxiliary_name_data_size); 2929dacfa354SThu Nguyen if (rc < 0) { 2930dacfa354SThu Nguyen return rc; 2931dacfa354SThu Nguyen } 2932dacfa354SThu Nguyen 2933dacfa354SThu Nguyen /* 2934dacfa354SThu Nguyen * Below we do two passes over the same region. This is to first pack the 2935dacfa354SThu Nguyen * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings, 2936dacfa354SThu Nguyen * to maintain appropriate alignment. 2937dacfa354SThu Nguyen */ 2938dacfa354SThu Nguyen 2939dacfa354SThu Nguyen /* Initialise for the first pass to extract the UTF16-BE name strings */ 2940dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 2941dacfa354SThu Nguyen if (rc < 0) { 2942dacfa354SThu Nguyen return rc; 2943dacfa354SThu Nguyen } 2944dacfa354SThu Nguyen 2945dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 2946dacfa354SThu Nguyen pldm_msgbuf_span_string_ascii(src, NULL, NULL); 29470a1be3cbSAndrew Jeffery rc = pldm_msgbuf_copy_string_utf16(dst, src); 29480a1be3cbSAndrew Jeffery if (rc) { 29490a1be3cbSAndrew Jeffery return rc; 29500a1be3cbSAndrew Jeffery } 2951dacfa354SThu Nguyen } 2952dacfa354SThu Nguyen 2953dacfa354SThu Nguyen rc = pldm_msgbuf_destroy_consumed(src); 2954dacfa354SThu Nguyen if (rc < 0) { 2955dacfa354SThu Nguyen return rc; 2956dacfa354SThu Nguyen } 2957dacfa354SThu Nguyen 2958dacfa354SThu Nguyen /* Reinitialise for the second pass to extract the ASCII tag strings */ 2959dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 2960dacfa354SThu Nguyen if (rc < 0) { 2961dacfa354SThu Nguyen return rc; 2962dacfa354SThu Nguyen } 2963dacfa354SThu Nguyen 2964dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 29650a1be3cbSAndrew Jeffery rc = pldm_msgbuf_copy_string_ascii(dst, src); 29660a1be3cbSAndrew Jeffery if (rc) { 29670a1be3cbSAndrew Jeffery return rc; 29680a1be3cbSAndrew Jeffery } 2969dacfa354SThu Nguyen pldm_msgbuf_span_string_utf16(src, NULL, NULL); 2970dacfa354SThu Nguyen } 2971dacfa354SThu Nguyen 2972dacfa354SThu Nguyen if ((rc = pldm_msgbuf_destroy(dst)) || 2973dacfa354SThu Nguyen (rc = pldm_msgbuf_destroy(src)) || 2974dacfa354SThu Nguyen (rc = pldm_msgbuf_destroy(buf))) { 2975dacfa354SThu Nguyen return rc; 2976dacfa354SThu Nguyen } 2977dacfa354SThu Nguyen 2978dacfa354SThu Nguyen return 0; 2979dacfa354SThu Nguyen } 2980dacfa354SThu Nguyen 298143cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE 2982dacfa354SThu Nguyen int decode_pldm_entity_auxiliary_names_pdr_index( 2983dacfa354SThu Nguyen struct pldm_entity_auxiliary_names_pdr *pdr) 2984dacfa354SThu Nguyen { 2985dacfa354SThu Nguyen struct pldm_msgbuf _buf; 2986dacfa354SThu Nguyen struct pldm_msgbuf *buf = &_buf; 2987dacfa354SThu Nguyen int rc; 2988dacfa354SThu Nguyen int i; 2989dacfa354SThu Nguyen 2990dacfa354SThu Nguyen if (!pdr) { 2991dacfa354SThu Nguyen return -EINVAL; 2992dacfa354SThu Nguyen } 2993dacfa354SThu Nguyen 2994dacfa354SThu Nguyen if (pdr->name_string_count == 0 && pdr->names) { 2995dacfa354SThu Nguyen return -EINVAL; 2996dacfa354SThu Nguyen } 2997dacfa354SThu Nguyen 2998dacfa354SThu Nguyen if (pdr->name_string_count > 0 && !pdr->names) { 2999dacfa354SThu Nguyen return -EINVAL; 3000dacfa354SThu Nguyen } 3001dacfa354SThu Nguyen 3002dacfa354SThu Nguyen if (pdr->name_string_count == 0) { 3003dacfa354SThu Nguyen return 0; 3004dacfa354SThu Nguyen } 3005dacfa354SThu Nguyen 3006dacfa354SThu Nguyen /* 3007dacfa354SThu Nguyen * Minimum size is one NUL for each member of each entry 3008dacfa354SThu Nguyen * 3009dacfa354SThu Nguyen * Note that the definition of nameLanguageTag in DSP0248 v1.2.2 3010dacfa354SThu Nguyen * states the following: 3011dacfa354SThu Nguyen * 3012dacfa354SThu Nguyen * > A null-terminated ISO646 ASCII string ... 3013dacfa354SThu Nguyen * > 3014dacfa354SThu Nguyen * > special value: null string = 0x0000 = unspecified. 3015dacfa354SThu Nguyen * 3016dacfa354SThu Nguyen * Until proven otherwise we will assume the "0x0000" is a 3017dacfa354SThu Nguyen * misrepresentation of an ASCII NUL, and that ASCII NUL is 3018dacfa354SThu Nguyen * represented by a single byte. 3019dacfa354SThu Nguyen */ 3020dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno( 3021dacfa354SThu Nguyen buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)), 3022dacfa354SThu Nguyen pdr->auxiliary_name_data, pdr->auxiliary_name_data_size); 3023dacfa354SThu Nguyen if (rc) { 3024dacfa354SThu Nguyen return rc; 3025dacfa354SThu Nguyen } 3026dacfa354SThu Nguyen 3027dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3028dacfa354SThu Nguyen void *loc = NULL; 3029dacfa354SThu Nguyen pldm_msgbuf_span_string_utf16(buf, &loc, NULL); 3030dacfa354SThu Nguyen pdr->names[i].name = loc; 3031dacfa354SThu Nguyen } 3032dacfa354SThu Nguyen 3033dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3034dacfa354SThu Nguyen void *loc = NULL; 3035dacfa354SThu Nguyen pldm_msgbuf_span_string_ascii(buf, &loc, NULL); 3036dacfa354SThu Nguyen pdr->names[i].tag = loc; 3037dacfa354SThu Nguyen } 3038dacfa354SThu Nguyen 3039dacfa354SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 3040dacfa354SThu Nguyen } 3041a5d18dc7SThu Nguyen 30423559aa1fSThu Nguyen LIBPLDM_ABI_STABLE 304302903038SThu Nguyen int decode_pldm_platform_cper_event(const void *event_data, 304402903038SThu Nguyen size_t event_data_length, 304502903038SThu Nguyen struct pldm_platform_cper_event *cper_event, 304602903038SThu Nguyen size_t cper_event_length) 3047a5d18dc7SThu Nguyen { 3048a5d18dc7SThu Nguyen struct pldm_msgbuf _buf; 3049a5d18dc7SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3050a5d18dc7SThu Nguyen int rc; 3051a5d18dc7SThu Nguyen 3052a5d18dc7SThu Nguyen if (!cper_event || !event_data) { 3053a5d18dc7SThu Nguyen return -EINVAL; 3054a5d18dc7SThu Nguyen } 3055a5d18dc7SThu Nguyen 3056a5d18dc7SThu Nguyen if (cper_event_length < sizeof(*cper_event)) { 3057a5d18dc7SThu Nguyen return -EINVAL; 3058a5d18dc7SThu Nguyen } 3059a5d18dc7SThu Nguyen 3060a5d18dc7SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH, 3061a5d18dc7SThu Nguyen event_data, event_data_length); 3062a5d18dc7SThu Nguyen if (rc) { 3063a5d18dc7SThu Nguyen return rc; 3064a5d18dc7SThu Nguyen } 3065a5d18dc7SThu Nguyen 3066a5d18dc7SThu Nguyen pldm_msgbuf_extract(buf, cper_event->format_version); 3067a5d18dc7SThu Nguyen rc = pldm_msgbuf_extract(buf, cper_event->format_type); 3068a5d18dc7SThu Nguyen if (rc) { 3069a5d18dc7SThu Nguyen return rc; 3070a5d18dc7SThu Nguyen } 3071a5d18dc7SThu Nguyen if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER && 3072a5d18dc7SThu Nguyen cper_event->format_type != 3073a5d18dc7SThu Nguyen PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) { 3074a5d18dc7SThu Nguyen return -EPROTO; 3075a5d18dc7SThu Nguyen } 3076a5d18dc7SThu Nguyen 3077a5d18dc7SThu Nguyen rc = pldm_msgbuf_extract(buf, cper_event->event_data_length); 3078a5d18dc7SThu Nguyen if (rc) { 3079a5d18dc7SThu Nguyen return rc; 3080a5d18dc7SThu Nguyen } 3081a5d18dc7SThu Nguyen 3082a5d18dc7SThu Nguyen if (cper_event->event_data_length > 3083a5d18dc7SThu Nguyen (cper_event_length - sizeof(*cper_event))) { 3084a5d18dc7SThu Nguyen return -EOVERFLOW; 3085a5d18dc7SThu Nguyen } 3086a5d18dc7SThu Nguyen 30870a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array_uint8( 30880a1be3cbSAndrew Jeffery buf, cper_event->event_data_length, cper_event->event_data, 30890a1be3cbSAndrew Jeffery cper_event_length - sizeof(*cper_event)); 30900a1be3cbSAndrew Jeffery if (rc) { 30910a1be3cbSAndrew Jeffery return rc; 30920a1be3cbSAndrew Jeffery } 3093a5d18dc7SThu Nguyen 3094a5d18dc7SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 3095a5d18dc7SThu Nguyen } 3096a5d18dc7SThu Nguyen 30973559aa1fSThu Nguyen LIBPLDM_ABI_STABLE 3098a5d18dc7SThu Nguyen uint8_t * 3099a5d18dc7SThu Nguyen pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event) 3100a5d18dc7SThu Nguyen { 3101a5d18dc7SThu Nguyen return event->event_data; 3102a5d18dc7SThu Nguyen } 3103