148761c62SAndrew Jeffery /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2830c1eb4SAndrew Jeffery #include "api.h" 3830c1eb4SAndrew Jeffery #include "compiler.h" 4f490a38fSTal Yacobi #include "dsp/base.h" 548761c62SAndrew Jeffery #include "msgbuf.h" 648761c62SAndrew Jeffery #include "msgbuf/platform.h" 748761c62SAndrew Jeffery 848761c62SAndrew Jeffery #include <libpldm/base.h> 948761c62SAndrew Jeffery #include <libpldm/platform.h> 1048761c62SAndrew Jeffery #include <libpldm/pldm_types.h> 1148761c62SAndrew Jeffery 1248761c62SAndrew Jeffery #include <endian.h> 1348761c62SAndrew Jeffery #include <stdint.h> 1448761c62SAndrew Jeffery #include <stdlib.h> 1548761c62SAndrew Jeffery #include <string.h> 16dacfa354SThu Nguyen #include <uchar.h> 1748761c62SAndrew Jeffery 1848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 1948761c62SAndrew Jeffery int encode_state_effecter_pdr( 2048761c62SAndrew Jeffery struct pldm_state_effecter_pdr *const effecter, 2148761c62SAndrew Jeffery const size_t allocation_size, 2248761c62SAndrew Jeffery const struct state_effecter_possible_states *const possible_states, 2348761c62SAndrew Jeffery const size_t possible_states_size, size_t *const actual_size) 2448761c62SAndrew Jeffery { 2548761c62SAndrew Jeffery // Encode possible states 2648761c62SAndrew Jeffery 2748761c62SAndrew Jeffery size_t calculated_possible_states_size = 0; 2848761c62SAndrew Jeffery 2948761c62SAndrew Jeffery { 3048761c62SAndrew Jeffery char *states_ptr = (char *)possible_states; 3148761c62SAndrew Jeffery char *const begin_states_ptr = states_ptr; 3248761c62SAndrew Jeffery 3348761c62SAndrew Jeffery for (int i = 0; i < effecter->composite_effecter_count; ++i) { 3448761c62SAndrew Jeffery struct state_effecter_possible_states *states = 3548761c62SAndrew Jeffery (struct state_effecter_possible_states *) 3648761c62SAndrew Jeffery states_ptr; 3748761c62SAndrew Jeffery 3848761c62SAndrew Jeffery HTOLE16(states->state_set_id); 3948761c62SAndrew Jeffery 4048761c62SAndrew Jeffery states_ptr += 4148761c62SAndrew Jeffery (sizeof(*states) - sizeof(states->states) + 4248761c62SAndrew Jeffery states->possible_states_size); 4348761c62SAndrew Jeffery } 4448761c62SAndrew Jeffery 4548761c62SAndrew Jeffery calculated_possible_states_size = states_ptr - begin_states_ptr; 4648761c62SAndrew Jeffery } 4748761c62SAndrew Jeffery 4848761c62SAndrew Jeffery // Check lengths 4948761c62SAndrew Jeffery 5048761c62SAndrew Jeffery if (possible_states_size != calculated_possible_states_size) { 5148761c62SAndrew Jeffery *actual_size = 0; 5248761c62SAndrew Jeffery return PLDM_ERROR; 5348761c62SAndrew Jeffery } 5448761c62SAndrew Jeffery 5548761c62SAndrew Jeffery *actual_size = 5648761c62SAndrew Jeffery (sizeof(struct pldm_state_effecter_pdr) + possible_states_size - 5748761c62SAndrew Jeffery sizeof(effecter->possible_states)); 5848761c62SAndrew Jeffery 5948761c62SAndrew Jeffery if (allocation_size < *actual_size) { 6048761c62SAndrew Jeffery *actual_size = 0; 6148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 6248761c62SAndrew Jeffery } 6348761c62SAndrew Jeffery 6448761c62SAndrew Jeffery // Encode rest of PDR 6548761c62SAndrew Jeffery 6648761c62SAndrew Jeffery effecter->hdr.version = 1; 6748761c62SAndrew Jeffery effecter->hdr.type = PLDM_STATE_EFFECTER_PDR; 6848761c62SAndrew Jeffery effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 6948761c62SAndrew Jeffery 7048761c62SAndrew Jeffery memcpy(effecter->possible_states, possible_states, 7148761c62SAndrew Jeffery possible_states_size); 7248761c62SAndrew Jeffery 7348761c62SAndrew Jeffery // Convert effecter PDR body 7448761c62SAndrew Jeffery HTOLE16(effecter->terminus_handle); 7548761c62SAndrew Jeffery HTOLE16(effecter->effecter_id); 7648761c62SAndrew Jeffery HTOLE16(effecter->entity_type); 7748761c62SAndrew Jeffery HTOLE16(effecter->entity_instance); 7848761c62SAndrew Jeffery HTOLE16(effecter->container_id); 7948761c62SAndrew Jeffery HTOLE16(effecter->effecter_semantic_id); 8048761c62SAndrew Jeffery 8148761c62SAndrew Jeffery // Convert header 8248761c62SAndrew Jeffery HTOLE32(effecter->hdr.record_handle); 8348761c62SAndrew Jeffery HTOLE16(effecter->hdr.record_change_num); 8448761c62SAndrew Jeffery HTOLE16(effecter->hdr.length); 8548761c62SAndrew Jeffery 8648761c62SAndrew Jeffery return PLDM_SUCCESS; 8748761c62SAndrew Jeffery } 8848761c62SAndrew Jeffery 8948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 9048761c62SAndrew Jeffery int encode_state_sensor_pdr( 9148761c62SAndrew Jeffery struct pldm_state_sensor_pdr *const sensor, 9248761c62SAndrew Jeffery const size_t allocation_size, 9348761c62SAndrew Jeffery const struct state_sensor_possible_states *const possible_states, 9448761c62SAndrew Jeffery const size_t possible_states_size, size_t *const actual_size) 9548761c62SAndrew Jeffery { 9648761c62SAndrew Jeffery // Encode possible states 9748761c62SAndrew Jeffery 9848761c62SAndrew Jeffery size_t calculated_possible_states_size = 0; 9948761c62SAndrew Jeffery 10048761c62SAndrew Jeffery { 10148761c62SAndrew Jeffery char *states_ptr = (char *)possible_states; 10248761c62SAndrew Jeffery char *const begin_states_ptr = states_ptr; 10348761c62SAndrew Jeffery 10448761c62SAndrew Jeffery for (int i = 0; i < sensor->composite_sensor_count; ++i) { 10548761c62SAndrew Jeffery struct state_sensor_possible_states *states = 10648761c62SAndrew Jeffery (struct state_sensor_possible_states *) 10748761c62SAndrew Jeffery states_ptr; 10848761c62SAndrew Jeffery 10948761c62SAndrew Jeffery HTOLE16(states->state_set_id); 11048761c62SAndrew Jeffery 11148761c62SAndrew Jeffery states_ptr += 11248761c62SAndrew Jeffery (sizeof(*states) - sizeof(states->states) + 11348761c62SAndrew Jeffery states->possible_states_size); 11448761c62SAndrew Jeffery } 11548761c62SAndrew Jeffery 11648761c62SAndrew Jeffery calculated_possible_states_size = states_ptr - begin_states_ptr; 11748761c62SAndrew Jeffery } 11848761c62SAndrew Jeffery 11948761c62SAndrew Jeffery // Check lengths 12048761c62SAndrew Jeffery 12148761c62SAndrew Jeffery if (possible_states_size != calculated_possible_states_size) { 12248761c62SAndrew Jeffery *actual_size = 0; 12348761c62SAndrew Jeffery return PLDM_ERROR; 12448761c62SAndrew Jeffery } 12548761c62SAndrew Jeffery 12648761c62SAndrew Jeffery *actual_size = (sizeof(struct pldm_state_sensor_pdr) + 12748761c62SAndrew Jeffery possible_states_size - sizeof(sensor->possible_states)); 12848761c62SAndrew Jeffery 12948761c62SAndrew Jeffery if (allocation_size < *actual_size) { 13048761c62SAndrew Jeffery *actual_size = 0; 13148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 13248761c62SAndrew Jeffery } 13348761c62SAndrew Jeffery 13448761c62SAndrew Jeffery // Encode rest of PDR 13548761c62SAndrew Jeffery 13648761c62SAndrew Jeffery sensor->hdr.version = 1; 13748761c62SAndrew Jeffery sensor->hdr.type = PLDM_STATE_SENSOR_PDR; 13848761c62SAndrew Jeffery sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 13948761c62SAndrew Jeffery 14048761c62SAndrew Jeffery memcpy(sensor->possible_states, possible_states, possible_states_size); 14148761c62SAndrew Jeffery 14248761c62SAndrew Jeffery // Convert sensor PDR body 14348761c62SAndrew Jeffery HTOLE16(sensor->terminus_handle); 14448761c62SAndrew Jeffery HTOLE16(sensor->sensor_id); 14548761c62SAndrew Jeffery HTOLE16(sensor->entity_type); 14648761c62SAndrew Jeffery HTOLE16(sensor->entity_instance); 14748761c62SAndrew Jeffery HTOLE16(sensor->container_id); 14848761c62SAndrew Jeffery 14948761c62SAndrew Jeffery // Convert header 15048761c62SAndrew Jeffery HTOLE32(sensor->hdr.record_handle); 15148761c62SAndrew Jeffery HTOLE16(sensor->hdr.record_change_num); 15248761c62SAndrew Jeffery HTOLE16(sensor->hdr.length); 15348761c62SAndrew Jeffery 15448761c62SAndrew Jeffery return PLDM_SUCCESS; 15548761c62SAndrew Jeffery } 15648761c62SAndrew Jeffery 15748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 15848761c62SAndrew Jeffery int encode_set_state_effecter_states_resp(uint8_t instance_id, 15948761c62SAndrew Jeffery uint8_t completion_code, 16048761c62SAndrew Jeffery struct pldm_msg *msg) 16148761c62SAndrew Jeffery { 16248761c62SAndrew Jeffery if (msg == NULL) { 16348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 16448761c62SAndrew Jeffery } 16548761c62SAndrew Jeffery 16648761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 16748761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 16848761c62SAndrew Jeffery header.instance = instance_id; 16948761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 17048761c62SAndrew Jeffery header.command = PLDM_SET_STATE_EFFECTER_STATES; 17148761c62SAndrew Jeffery 17248761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 17348761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 17448761c62SAndrew Jeffery return rc; 17548761c62SAndrew Jeffery } 17648761c62SAndrew Jeffery 17748761c62SAndrew Jeffery msg->payload[0] = completion_code; 17848761c62SAndrew Jeffery 17948761c62SAndrew Jeffery return PLDM_SUCCESS; 18048761c62SAndrew Jeffery } 18148761c62SAndrew Jeffery 18248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 18348761c62SAndrew Jeffery int encode_set_state_effecter_states_req(uint8_t instance_id, 18448761c62SAndrew Jeffery uint16_t effecter_id, 18548761c62SAndrew Jeffery uint8_t comp_effecter_count, 18648761c62SAndrew Jeffery set_effecter_state_field *field, 18748761c62SAndrew Jeffery struct pldm_msg *msg) 18848761c62SAndrew Jeffery { 18948761c62SAndrew Jeffery if (msg == NULL) { 19048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 19148761c62SAndrew Jeffery } 19248761c62SAndrew Jeffery 19348761c62SAndrew Jeffery if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 || 19448761c62SAndrew Jeffery field == NULL) { 19548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 19648761c62SAndrew Jeffery } 19748761c62SAndrew Jeffery 19848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 19948761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 20048761c62SAndrew Jeffery header.instance = instance_id; 20148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 20248761c62SAndrew Jeffery header.command = PLDM_SET_STATE_EFFECTER_STATES; 20348761c62SAndrew Jeffery 20448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 20548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 20648761c62SAndrew Jeffery return rc; 20748761c62SAndrew Jeffery } 20848761c62SAndrew Jeffery 20948761c62SAndrew Jeffery struct pldm_set_state_effecter_states_req *request = 21048761c62SAndrew Jeffery (struct pldm_set_state_effecter_states_req *)msg->payload; 21148761c62SAndrew Jeffery effecter_id = htole16(effecter_id); 21248761c62SAndrew Jeffery request->effecter_id = effecter_id; 21348761c62SAndrew Jeffery request->comp_effecter_count = comp_effecter_count; 21448761c62SAndrew Jeffery memcpy(request->field, field, 21548761c62SAndrew Jeffery (sizeof(set_effecter_state_field) * comp_effecter_count)); 21648761c62SAndrew Jeffery 21748761c62SAndrew Jeffery return PLDM_SUCCESS; 21848761c62SAndrew Jeffery } 21948761c62SAndrew Jeffery 22048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 22148761c62SAndrew Jeffery int decode_set_state_effecter_states_resp(const struct pldm_msg *msg, 22248761c62SAndrew Jeffery size_t payload_length, 22348761c62SAndrew Jeffery uint8_t *completion_code) 22448761c62SAndrew Jeffery { 22548761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 22648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 22748761c62SAndrew Jeffery } 22848761c62SAndrew Jeffery 22948761c62SAndrew Jeffery *completion_code = msg->payload[0]; 23048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 23148761c62SAndrew Jeffery return PLDM_SUCCESS; 23248761c62SAndrew Jeffery } 23348761c62SAndrew Jeffery 23448761c62SAndrew Jeffery if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) { 23548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 23648761c62SAndrew Jeffery } 23748761c62SAndrew Jeffery 23848761c62SAndrew Jeffery return PLDM_SUCCESS; 23948761c62SAndrew Jeffery } 24048761c62SAndrew Jeffery 24148761c62SAndrew Jeffery #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3 24248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 24348761c62SAndrew Jeffery int decode_set_state_effecter_states_req(const struct pldm_msg *msg, 24448761c62SAndrew Jeffery size_t payload_length, 24548761c62SAndrew Jeffery uint16_t *effecter_id, 24648761c62SAndrew Jeffery uint8_t *comp_effecter_count, 24748761c62SAndrew Jeffery set_effecter_state_field *field) 24848761c62SAndrew Jeffery { 24948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 25048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 25148761c62SAndrew Jeffery int rc; 25248761c62SAndrew Jeffery int i; 25348761c62SAndrew Jeffery 25448761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL || 25548761c62SAndrew Jeffery field == NULL) { 25648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 25748761c62SAndrew Jeffery } 25848761c62SAndrew Jeffery 25948761c62SAndrew Jeffery if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) { 26048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 26148761c62SAndrew Jeffery } 26248761c62SAndrew Jeffery 263830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 264830c1eb4SAndrew Jeffery PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE, 26548761c62SAndrew Jeffery msg->payload, payload_length); 26648761c62SAndrew Jeffery if (rc) { 267830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 26848761c62SAndrew Jeffery } 26948761c62SAndrew Jeffery 27048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 27148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, comp_effecter_count); 27248761c62SAndrew Jeffery 27348761c62SAndrew Jeffery if (*comp_effecter_count > 8) { 27448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 27548761c62SAndrew Jeffery } 27648761c62SAndrew Jeffery 27748761c62SAndrew Jeffery for (i = 0; i < *comp_effecter_count; i++) { 27848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].set_request); 27948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].effecter_state); 28048761c62SAndrew Jeffery } 28148761c62SAndrew Jeffery 282830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 283830c1eb4SAndrew Jeffery if (rc) { 284830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 285830c1eb4SAndrew Jeffery } 286830c1eb4SAndrew Jeffery 287830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 28848761c62SAndrew Jeffery } 28948761c62SAndrew Jeffery 29048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 29148761c62SAndrew Jeffery int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length, 29248761c62SAndrew Jeffery uint32_t *record_hndl, uint32_t *data_transfer_hndl, 29348761c62SAndrew Jeffery uint8_t *transfer_op_flag, uint16_t *request_cnt, 29448761c62SAndrew Jeffery uint16_t *record_chg_num) 29548761c62SAndrew Jeffery { 29648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 29748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 29848761c62SAndrew Jeffery int rc; 29948761c62SAndrew Jeffery 30048761c62SAndrew Jeffery if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL || 30148761c62SAndrew Jeffery transfer_op_flag == NULL || request_cnt == NULL || 30248761c62SAndrew Jeffery record_chg_num == NULL) { 30348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 30448761c62SAndrew Jeffery } 30548761c62SAndrew Jeffery 30648761c62SAndrew Jeffery if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 30748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 30848761c62SAndrew Jeffery } 30948761c62SAndrew Jeffery 310830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload, 31148761c62SAndrew Jeffery payload_length); 31248761c62SAndrew Jeffery if (rc) { 313830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 31448761c62SAndrew Jeffery } 31548761c62SAndrew Jeffery 31648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_hndl); 31748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_hndl); 31848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_op_flag); 31948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, request_cnt); 32048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_chg_num); 32148761c62SAndrew Jeffery 322830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 323830c1eb4SAndrew Jeffery if (rc) { 324830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 325830c1eb4SAndrew Jeffery } 326830c1eb4SAndrew Jeffery 327830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 32848761c62SAndrew Jeffery } 32948761c62SAndrew Jeffery 33048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 33148761c62SAndrew Jeffery int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code, 33248761c62SAndrew Jeffery uint32_t next_record_hndl, 33348761c62SAndrew Jeffery uint32_t next_data_transfer_hndl, uint8_t transfer_flag, 33448761c62SAndrew Jeffery uint16_t resp_cnt, const uint8_t *record_data, 33548761c62SAndrew Jeffery uint8_t transfer_crc, struct pldm_msg *msg) 33648761c62SAndrew Jeffery { 33748761c62SAndrew Jeffery if (msg == NULL) { 33848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 33948761c62SAndrew Jeffery } 34048761c62SAndrew Jeffery 34148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 34248761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 34348761c62SAndrew Jeffery header.instance = instance_id; 34448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 34548761c62SAndrew Jeffery header.command = PLDM_GET_PDR; 34648761c62SAndrew Jeffery 34748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 34848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 34948761c62SAndrew Jeffery return rc; 35048761c62SAndrew Jeffery } 35148761c62SAndrew Jeffery 35248761c62SAndrew Jeffery struct pldm_get_pdr_resp *response = 35348761c62SAndrew Jeffery (struct pldm_get_pdr_resp *)msg->payload; 35448761c62SAndrew Jeffery response->completion_code = completion_code; 35548761c62SAndrew Jeffery 35648761c62SAndrew Jeffery if (response->completion_code == PLDM_SUCCESS) { 35748761c62SAndrew Jeffery response->next_record_handle = htole32(next_record_hndl); 35848761c62SAndrew Jeffery response->next_data_transfer_handle = 35948761c62SAndrew Jeffery htole32(next_data_transfer_hndl); 36048761c62SAndrew Jeffery response->transfer_flag = transfer_flag; 36148761c62SAndrew Jeffery response->response_count = htole16(resp_cnt); 36248761c62SAndrew Jeffery if (record_data != NULL && resp_cnt > 0) { 36348761c62SAndrew Jeffery memcpy(response->record_data, record_data, resp_cnt); 36448761c62SAndrew Jeffery } 36548761c62SAndrew Jeffery if (transfer_flag == PLDM_END) { 36648761c62SAndrew Jeffery uint8_t *dst = msg->payload; 36748761c62SAndrew Jeffery dst += (sizeof(struct pldm_get_pdr_resp) - 1) + 36848761c62SAndrew Jeffery resp_cnt; 36948761c62SAndrew Jeffery *dst = transfer_crc; 37048761c62SAndrew Jeffery } 37148761c62SAndrew Jeffery } 37248761c62SAndrew Jeffery 37348761c62SAndrew Jeffery return PLDM_SUCCESS; 37448761c62SAndrew Jeffery } 37548761c62SAndrew Jeffery 37648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 37748761c62SAndrew Jeffery int encode_get_pdr_repository_info_resp( 37848761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, uint8_t repository_state, 37948761c62SAndrew Jeffery const uint8_t *update_time, const uint8_t *oem_update_time, 38048761c62SAndrew Jeffery uint32_t record_count, uint32_t repository_size, 38148761c62SAndrew Jeffery uint32_t largest_record_size, uint8_t data_transfer_handle_timeout, 38248761c62SAndrew Jeffery struct pldm_msg *msg) 38348761c62SAndrew Jeffery { 38448761c62SAndrew Jeffery if (msg == NULL) { 38548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 38648761c62SAndrew Jeffery } 38748761c62SAndrew Jeffery 38848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 38948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 39048761c62SAndrew Jeffery header.instance = instance_id; 39148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 39248761c62SAndrew Jeffery header.command = PLDM_GET_PDR_REPOSITORY_INFO; 39348761c62SAndrew Jeffery 39448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 39548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 39648761c62SAndrew Jeffery return rc; 39748761c62SAndrew Jeffery } 39848761c62SAndrew Jeffery 39948761c62SAndrew Jeffery struct pldm_pdr_repository_info_resp *response = 40048761c62SAndrew Jeffery (struct pldm_pdr_repository_info_resp *)msg->payload; 40148761c62SAndrew Jeffery response->completion_code = completion_code; 40248761c62SAndrew Jeffery 40348761c62SAndrew Jeffery if (response->completion_code == PLDM_SUCCESS) { 40448761c62SAndrew Jeffery response->repository_state = repository_state; 40548761c62SAndrew Jeffery if (update_time != NULL) { 40648761c62SAndrew Jeffery memcpy(response->update_time, update_time, 40748761c62SAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 40848761c62SAndrew Jeffery } 40948761c62SAndrew Jeffery if (oem_update_time != NULL) { 41048761c62SAndrew Jeffery memcpy(response->oem_update_time, oem_update_time, 41148761c62SAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 41248761c62SAndrew Jeffery } 41348761c62SAndrew Jeffery response->record_count = htole32(record_count); 41448761c62SAndrew Jeffery response->repository_size = htole32(repository_size); 41548761c62SAndrew Jeffery response->largest_record_size = htole32(largest_record_size); 41648761c62SAndrew Jeffery response->data_transfer_handle_timeout = 41748761c62SAndrew Jeffery data_transfer_handle_timeout; 41848761c62SAndrew Jeffery } 41948761c62SAndrew Jeffery 42048761c62SAndrew Jeffery return PLDM_SUCCESS; 42148761c62SAndrew Jeffery } 42248761c62SAndrew Jeffery 4230a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED 42448761c62SAndrew Jeffery int decode_get_pdr_repository_info_resp( 42548761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 42648761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *repository_state, 42748761c62SAndrew Jeffery uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count, 42848761c62SAndrew Jeffery uint32_t *repository_size, uint32_t *largest_record_size, 42948761c62SAndrew Jeffery uint8_t *data_transfer_handle_timeout) 43048761c62SAndrew Jeffery { 43148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 43248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 43348761c62SAndrew Jeffery int rc; 43448761c62SAndrew Jeffery 43548761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 43648761c62SAndrew Jeffery repository_state == NULL || update_time == NULL || 43748761c62SAndrew Jeffery oem_update_time == NULL || record_count == NULL || 43848761c62SAndrew Jeffery repository_size == NULL || largest_record_size == NULL || 43948761c62SAndrew Jeffery data_transfer_handle_timeout == NULL) { 44048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 44148761c62SAndrew Jeffery } 44248761c62SAndrew Jeffery 443830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 444830c1eb4SAndrew Jeffery PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 44548761c62SAndrew Jeffery msg->payload, payload_length); 44648761c62SAndrew Jeffery if (rc) { 447830c1eb4SAndrew Jeffery return pldm_xlate_errno(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 455830c1eb4SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, repository_state); 456830c1eb4SAndrew Jeffery if (rc) { 457830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 458830c1eb4SAndrew Jeffery } 459830c1eb4SAndrew Jeffery 46048761c62SAndrew Jeffery if (*repository_state > PLDM_FAILED) { 46148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 46248761c62SAndrew Jeffery } 46348761c62SAndrew Jeffery 4640a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 4650a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time, 4660a1be3cbSAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 4670a1be3cbSAndrew Jeffery if (rc) { 468830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 4690a1be3cbSAndrew Jeffery } 4700a1be3cbSAndrew Jeffery 4710a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 4720a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, 4730a1be3cbSAndrew Jeffery oem_update_time, PLDM_TIMESTAMP104_SIZE); 4740a1be3cbSAndrew Jeffery if (rc) { 475830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 4760a1be3cbSAndrew Jeffery } 4770a1be3cbSAndrew Jeffery 47848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_count); 47948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, repository_size); 48048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, largest_record_size); 48148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout); 48248761c62SAndrew Jeffery 483830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 484830c1eb4SAndrew Jeffery if (rc) { 485830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 486830c1eb4SAndrew Jeffery } 487830c1eb4SAndrew Jeffery 488830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 48948761c62SAndrew Jeffery } 49048761c62SAndrew Jeffery 4910a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING 4920a1be3cbSAndrew Jeffery int decode_get_pdr_repository_info_resp_safe( 4930a1be3cbSAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 4940a1be3cbSAndrew Jeffery struct pldm_pdr_repository_info_resp *resp) 4950a1be3cbSAndrew Jeffery { 4960a1be3cbSAndrew Jeffery struct pldm_msgbuf _buf; 4970a1be3cbSAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 4980a1be3cbSAndrew Jeffery int rc; 4990a1be3cbSAndrew Jeffery 5000a1be3cbSAndrew Jeffery if (msg == NULL || resp == NULL) { 5010a1be3cbSAndrew Jeffery return -EINVAL; 5020a1be3cbSAndrew Jeffery } 5030a1be3cbSAndrew Jeffery 5040a1be3cbSAndrew Jeffery rc = pldm_msg_has_error(msg, payload_length); 5050a1be3cbSAndrew Jeffery if (rc) { 5060a1be3cbSAndrew Jeffery resp->completion_code = rc; 5070a1be3cbSAndrew Jeffery return 0; 5080a1be3cbSAndrew Jeffery } 5090a1be3cbSAndrew Jeffery 5100a1be3cbSAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 5110a1be3cbSAndrew Jeffery PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 5120a1be3cbSAndrew Jeffery msg->payload, payload_length); 5130a1be3cbSAndrew Jeffery if (rc) { 5140a1be3cbSAndrew Jeffery return rc; 5150a1be3cbSAndrew Jeffery } 5160a1be3cbSAndrew Jeffery 5170a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->completion_code); 5180a1be3cbSAndrew Jeffery if (rc) { 5190a1be3cbSAndrew Jeffery return rc; 5200a1be3cbSAndrew Jeffery } 5210a1be3cbSAndrew Jeffery 5220a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->repository_state); 5230a1be3cbSAndrew Jeffery 5240a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time), 5250a1be3cbSAndrew Jeffery resp->update_time, 5260a1be3cbSAndrew Jeffery sizeof(resp->update_time)); 5270a1be3cbSAndrew Jeffery if (rc) { 5280a1be3cbSAndrew Jeffery return rc; 5290a1be3cbSAndrew Jeffery } 5300a1be3cbSAndrew Jeffery 5310a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time), 5320a1be3cbSAndrew Jeffery resp->oem_update_time, 5330a1be3cbSAndrew Jeffery sizeof(resp->oem_update_time)); 5340a1be3cbSAndrew Jeffery if (rc) { 5350a1be3cbSAndrew Jeffery return rc; 5360a1be3cbSAndrew Jeffery } 5370a1be3cbSAndrew Jeffery 5380a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->record_count); 5390a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->repository_size); 5400a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->largest_record_size); 5410a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout); 5420a1be3cbSAndrew Jeffery 5430a1be3cbSAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 5440a1be3cbSAndrew Jeffery } 5450a1be3cbSAndrew Jeffery 54648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 54748761c62SAndrew Jeffery int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl, 54848761c62SAndrew Jeffery uint32_t data_transfer_hndl, uint8_t transfer_op_flag, 54948761c62SAndrew Jeffery uint16_t request_cnt, uint16_t record_chg_num, 55048761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 55148761c62SAndrew Jeffery { 55248761c62SAndrew Jeffery if (msg == NULL) { 55348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 55448761c62SAndrew Jeffery } 55548761c62SAndrew Jeffery 55648761c62SAndrew Jeffery if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 55748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 55848761c62SAndrew Jeffery } 55948761c62SAndrew Jeffery 56048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 56148761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 56248761c62SAndrew Jeffery header.instance = instance_id; 56348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 56448761c62SAndrew Jeffery header.command = PLDM_GET_PDR; 56548761c62SAndrew Jeffery 56648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 56748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 56848761c62SAndrew Jeffery return rc; 56948761c62SAndrew Jeffery } 57048761c62SAndrew Jeffery 57148761c62SAndrew Jeffery struct pldm_get_pdr_req *request = 57248761c62SAndrew Jeffery (struct pldm_get_pdr_req *)msg->payload; 57348761c62SAndrew Jeffery request->record_handle = htole32(record_hndl); 57448761c62SAndrew Jeffery request->data_transfer_handle = htole32(data_transfer_hndl); 57548761c62SAndrew Jeffery request->transfer_op_flag = transfer_op_flag; 57648761c62SAndrew Jeffery request->request_count = htole16(request_cnt); 57748761c62SAndrew Jeffery request->record_change_number = htole16(record_chg_num); 57848761c62SAndrew Jeffery 57948761c62SAndrew Jeffery return PLDM_SUCCESS; 58048761c62SAndrew Jeffery } 58148761c62SAndrew Jeffery 5820a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED 58348761c62SAndrew Jeffery int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length, 58448761c62SAndrew Jeffery uint8_t *completion_code, uint32_t *next_record_hndl, 58548761c62SAndrew Jeffery uint32_t *next_data_transfer_hndl, 58648761c62SAndrew Jeffery uint8_t *transfer_flag, uint16_t *resp_cnt, 58748761c62SAndrew Jeffery uint8_t *record_data, size_t record_data_length, 58848761c62SAndrew Jeffery uint8_t *transfer_crc) 58948761c62SAndrew Jeffery { 59048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 59148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 59248761c62SAndrew Jeffery int rc; 59348761c62SAndrew Jeffery 59448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 59548761c62SAndrew Jeffery next_record_hndl == NULL || next_data_transfer_hndl == NULL || 59648761c62SAndrew Jeffery transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) { 59748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 59848761c62SAndrew Jeffery } 59948761c62SAndrew Jeffery 600830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 601830c1eb4SAndrew Jeffery msg->payload, payload_length); 60248761c62SAndrew Jeffery if (rc) { 603830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 60448761c62SAndrew Jeffery } 60548761c62SAndrew Jeffery 606830c1eb4SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 607830c1eb4SAndrew Jeffery if (rc) { 608830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 609830c1eb4SAndrew Jeffery } 610830c1eb4SAndrew Jeffery 61148761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 61248761c62SAndrew Jeffery return PLDM_SUCCESS; 61348761c62SAndrew Jeffery } 61448761c62SAndrew Jeffery 61548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_record_hndl); 61648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_data_transfer_hndl); 61748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_flag); 61848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, resp_cnt); 61948761c62SAndrew Jeffery if (rc) { 620830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 62148761c62SAndrew Jeffery } 62248761c62SAndrew Jeffery 62348761c62SAndrew Jeffery if (*resp_cnt > 0 && record_data != NULL) { 62448761c62SAndrew Jeffery if (record_data_length < *resp_cnt) { 62548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 62648761c62SAndrew Jeffery } 6270a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 6280a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data, 6290a1be3cbSAndrew Jeffery *resp_cnt); 6300a1be3cbSAndrew Jeffery if (rc) { 631830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 6320a1be3cbSAndrew Jeffery } 63348761c62SAndrew Jeffery } 63448761c62SAndrew Jeffery 63548761c62SAndrew Jeffery if (*transfer_flag == PLDM_END) { 63648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_crc); 63748761c62SAndrew Jeffery } 63848761c62SAndrew Jeffery 639830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 640830c1eb4SAndrew Jeffery if (rc) { 641830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 642830c1eb4SAndrew Jeffery } 643830c1eb4SAndrew Jeffery 644830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 64548761c62SAndrew Jeffery } 64648761c62SAndrew Jeffery 6470a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING 6480a1be3cbSAndrew Jeffery int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length, 6490a1be3cbSAndrew Jeffery struct pldm_get_pdr_resp *resp, size_t resp_len, 6500a1be3cbSAndrew Jeffery uint8_t *transfer_crc) 6510a1be3cbSAndrew Jeffery { 6520a1be3cbSAndrew Jeffery struct pldm_msgbuf _buf; 6530a1be3cbSAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 6540a1be3cbSAndrew Jeffery int rc; 6550a1be3cbSAndrew Jeffery 6560a1be3cbSAndrew Jeffery if (msg == NULL || resp == NULL || transfer_crc == NULL) { 6570a1be3cbSAndrew Jeffery return -EINVAL; 6580a1be3cbSAndrew Jeffery } 6590a1be3cbSAndrew Jeffery 6600a1be3cbSAndrew Jeffery rc = pldm_msg_has_error(msg, payload_length); 6610a1be3cbSAndrew Jeffery if (rc) { 6620a1be3cbSAndrew Jeffery resp->completion_code = rc; 6630a1be3cbSAndrew Jeffery return 0; 6640a1be3cbSAndrew Jeffery } 6650a1be3cbSAndrew Jeffery 6660a1be3cbSAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 6670a1be3cbSAndrew Jeffery msg->payload, payload_length); 6680a1be3cbSAndrew Jeffery if (rc) { 6690a1be3cbSAndrew Jeffery return rc; 6700a1be3cbSAndrew Jeffery } 6710a1be3cbSAndrew Jeffery 6720a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->completion_code); 6730a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->next_record_handle); 6740a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->next_data_transfer_handle); 6750a1be3cbSAndrew Jeffery 6760a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->transfer_flag); 6770a1be3cbSAndrew Jeffery if (rc) { 6780a1be3cbSAndrew Jeffery return rc; 6790a1be3cbSAndrew Jeffery } 6800a1be3cbSAndrew Jeffery 6810a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->response_count); 6820a1be3cbSAndrew Jeffery if (rc) { 6830a1be3cbSAndrew Jeffery return rc; 6840a1be3cbSAndrew Jeffery } 6850a1be3cbSAndrew Jeffery 6860a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array( 6870a1be3cbSAndrew Jeffery buf, resp->response_count, resp->record_data, 6880a1be3cbSAndrew Jeffery resp_len - (sizeof(*resp) - sizeof(resp->record_data))); 6890a1be3cbSAndrew Jeffery if (rc) { 6900a1be3cbSAndrew Jeffery return rc; 6910a1be3cbSAndrew Jeffery } 6920a1be3cbSAndrew Jeffery 6930a1be3cbSAndrew Jeffery if (resp->transfer_flag == PLDM_END) { 6940a1be3cbSAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_crc); 6950a1be3cbSAndrew Jeffery } 6960a1be3cbSAndrew Jeffery 6970a1be3cbSAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 6980a1be3cbSAndrew Jeffery } 6990a1be3cbSAndrew Jeffery 70048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 70148761c62SAndrew Jeffery int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg, 70248761c62SAndrew Jeffery size_t payload_length, 70348761c62SAndrew Jeffery uint16_t *effecter_id, 70448761c62SAndrew Jeffery uint8_t *effecter_data_size, 70548761c62SAndrew Jeffery uint8_t effecter_value[4]) 70648761c62SAndrew Jeffery { 70748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 70848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 70948761c62SAndrew Jeffery int rc; 71048761c62SAndrew Jeffery 71148761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL || 71248761c62SAndrew Jeffery effecter_value == NULL) { 71348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 71448761c62SAndrew Jeffery } 71548761c62SAndrew Jeffery 716830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 717830c1eb4SAndrew Jeffery buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES, 71848761c62SAndrew Jeffery msg->payload, payload_length); 71948761c62SAndrew Jeffery if (rc) { 720830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 72148761c62SAndrew Jeffery } 72248761c62SAndrew Jeffery 72348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 72448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 72548761c62SAndrew Jeffery if (rc) { 72648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 72748761c62SAndrew Jeffery } 72848761c62SAndrew Jeffery 72948761c62SAndrew Jeffery if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 73048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 73148761c62SAndrew Jeffery } 73248761c62SAndrew Jeffery 73348761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 73448761c62SAndrew Jeffery effecter_value); 73548761c62SAndrew Jeffery 736830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 737830c1eb4SAndrew Jeffery if (rc) { 738830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 739830c1eb4SAndrew Jeffery } 740830c1eb4SAndrew Jeffery 741830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 74248761c62SAndrew Jeffery } 74348761c62SAndrew Jeffery 74448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 74548761c62SAndrew Jeffery int encode_set_numeric_effecter_value_resp(uint8_t instance_id, 74648761c62SAndrew Jeffery uint8_t completion_code, 74748761c62SAndrew Jeffery struct pldm_msg *msg, 74848761c62SAndrew Jeffery size_t payload_length) 74948761c62SAndrew Jeffery { 75048761c62SAndrew Jeffery if (msg == NULL) { 75148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 75248761c62SAndrew Jeffery } 75348761c62SAndrew Jeffery 75448761c62SAndrew Jeffery if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 75548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 75648761c62SAndrew Jeffery } 75748761c62SAndrew Jeffery 75848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 75948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 76048761c62SAndrew Jeffery header.instance = instance_id; 76148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 76248761c62SAndrew Jeffery header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 76348761c62SAndrew Jeffery 76448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 76548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 76648761c62SAndrew Jeffery return rc; 76748761c62SAndrew Jeffery } 76848761c62SAndrew Jeffery 76948761c62SAndrew Jeffery msg->payload[0] = completion_code; 77048761c62SAndrew Jeffery 77148761c62SAndrew Jeffery return rc; 77248761c62SAndrew Jeffery } 77348761c62SAndrew Jeffery 77448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 77548761c62SAndrew Jeffery int encode_set_numeric_effecter_value_req(uint8_t instance_id, 77648761c62SAndrew Jeffery uint16_t effecter_id, 77748761c62SAndrew Jeffery uint8_t effecter_data_size, 77848761c62SAndrew Jeffery const uint8_t *effecter_value, 77948761c62SAndrew Jeffery struct pldm_msg *msg, 78048761c62SAndrew Jeffery size_t payload_length) 78148761c62SAndrew Jeffery { 78248761c62SAndrew Jeffery if (msg == NULL || effecter_value == NULL) { 78348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 78448761c62SAndrew Jeffery } 78548761c62SAndrew Jeffery 78648761c62SAndrew Jeffery if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 78748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 78848761c62SAndrew Jeffery } 78948761c62SAndrew Jeffery 79048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 79148761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 79248761c62SAndrew Jeffery header.instance = instance_id; 79348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 79448761c62SAndrew Jeffery header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 79548761c62SAndrew Jeffery 79648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 79748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 79848761c62SAndrew Jeffery return rc; 79948761c62SAndrew Jeffery } 80048761c62SAndrew Jeffery 80148761c62SAndrew Jeffery struct pldm_set_numeric_effecter_value_req *request = 80248761c62SAndrew Jeffery (struct pldm_set_numeric_effecter_value_req *)msg->payload; 80348761c62SAndrew Jeffery if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 80448761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 80548761c62SAndrew Jeffery if (payload_length != 80648761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) { 80748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 80848761c62SAndrew Jeffery } 80948761c62SAndrew Jeffery request->effecter_value[0] = *effecter_value; 81048761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 81148761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 81248761c62SAndrew Jeffery if (payload_length != 81348761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) { 81448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 81548761c62SAndrew Jeffery } 81648761c62SAndrew Jeffery 81748761c62SAndrew Jeffery uint16_t val = *(uint16_t *)(effecter_value); 81848761c62SAndrew Jeffery val = htole16(val); 81948761c62SAndrew Jeffery memcpy(request->effecter_value, &val, sizeof(uint16_t)); 82048761c62SAndrew Jeffery 82148761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 82248761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 82348761c62SAndrew Jeffery if (payload_length != 82448761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) { 82548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 82648761c62SAndrew Jeffery } 82748761c62SAndrew Jeffery 82848761c62SAndrew Jeffery uint32_t val = *(uint32_t *)(effecter_value); 82948761c62SAndrew Jeffery val = htole32(val); 83048761c62SAndrew Jeffery memcpy(request->effecter_value, &val, sizeof(uint32_t)); 83148761c62SAndrew Jeffery } 83248761c62SAndrew Jeffery 83348761c62SAndrew Jeffery request->effecter_id = htole16(effecter_id); 83448761c62SAndrew Jeffery request->effecter_data_size = effecter_data_size; 83548761c62SAndrew Jeffery 83648761c62SAndrew Jeffery return PLDM_SUCCESS; 83748761c62SAndrew Jeffery } 83848761c62SAndrew Jeffery 83948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 84048761c62SAndrew Jeffery int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg, 84148761c62SAndrew Jeffery size_t payload_length, 84248761c62SAndrew Jeffery uint8_t *completion_code) 84348761c62SAndrew Jeffery { 84448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 84548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 84648761c62SAndrew Jeffery } 84748761c62SAndrew Jeffery 84848761c62SAndrew Jeffery if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 84948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 85048761c62SAndrew Jeffery } 85148761c62SAndrew Jeffery 85248761c62SAndrew Jeffery *completion_code = msg->payload[0]; 85348761c62SAndrew Jeffery 85448761c62SAndrew Jeffery return PLDM_SUCCESS; 85548761c62SAndrew Jeffery } 85648761c62SAndrew Jeffery 85748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 85848761c62SAndrew Jeffery int encode_get_state_sensor_readings_resp(uint8_t instance_id, 85948761c62SAndrew Jeffery uint8_t completion_code, 86048761c62SAndrew Jeffery uint8_t comp_sensor_count, 86148761c62SAndrew Jeffery get_sensor_state_field *field, 86248761c62SAndrew Jeffery struct pldm_msg *msg) 86348761c62SAndrew Jeffery { 86448761c62SAndrew Jeffery if (msg == NULL) { 86548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 86648761c62SAndrew Jeffery } 86748761c62SAndrew Jeffery 86848761c62SAndrew Jeffery if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) { 86948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 87048761c62SAndrew Jeffery } 87148761c62SAndrew Jeffery 87248761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 87348761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 87448761c62SAndrew Jeffery header.instance = instance_id; 87548761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 87648761c62SAndrew Jeffery header.command = PLDM_GET_STATE_SENSOR_READINGS; 87748761c62SAndrew Jeffery 87848761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 87948761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 88048761c62SAndrew Jeffery return rc; 88148761c62SAndrew Jeffery } 88248761c62SAndrew Jeffery 88348761c62SAndrew Jeffery struct pldm_get_state_sensor_readings_resp *response = 88448761c62SAndrew Jeffery (struct pldm_get_state_sensor_readings_resp *)msg->payload; 88548761c62SAndrew Jeffery 88648761c62SAndrew Jeffery response->completion_code = completion_code; 88748761c62SAndrew Jeffery response->comp_sensor_count = comp_sensor_count; 88848761c62SAndrew Jeffery memcpy(response->field, field, 88948761c62SAndrew Jeffery (sizeof(get_sensor_state_field) * comp_sensor_count)); 89048761c62SAndrew Jeffery 89148761c62SAndrew Jeffery return PLDM_SUCCESS; 89248761c62SAndrew Jeffery } 89348761c62SAndrew Jeffery 89448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 89548761c62SAndrew Jeffery int encode_get_state_sensor_readings_req(uint8_t instance_id, 89648761c62SAndrew Jeffery uint16_t sensor_id, 89748761c62SAndrew Jeffery bitfield8_t sensor_rearm, 89848761c62SAndrew Jeffery uint8_t reserved, struct pldm_msg *msg) 89948761c62SAndrew Jeffery { 90048761c62SAndrew Jeffery if (msg == NULL) { 90148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 90248761c62SAndrew Jeffery } 90348761c62SAndrew Jeffery 90448761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 90548761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 90648761c62SAndrew Jeffery header.instance = instance_id; 90748761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 90848761c62SAndrew Jeffery header.command = PLDM_GET_STATE_SENSOR_READINGS; 90948761c62SAndrew Jeffery 91048761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 91148761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 91248761c62SAndrew Jeffery return rc; 91348761c62SAndrew Jeffery } 91448761c62SAndrew Jeffery 91548761c62SAndrew Jeffery struct pldm_get_state_sensor_readings_req *request = 91648761c62SAndrew Jeffery (struct pldm_get_state_sensor_readings_req *)msg->payload; 91748761c62SAndrew Jeffery 91848761c62SAndrew Jeffery request->sensor_id = htole16(sensor_id); 91948761c62SAndrew Jeffery request->reserved = reserved; 92048761c62SAndrew Jeffery request->sensor_rearm = sensor_rearm; 92148761c62SAndrew Jeffery 92248761c62SAndrew Jeffery return PLDM_SUCCESS; 92348761c62SAndrew Jeffery } 92448761c62SAndrew Jeffery 92548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 92648761c62SAndrew Jeffery int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg, 92748761c62SAndrew Jeffery size_t payload_length, 92848761c62SAndrew Jeffery uint8_t *completion_code, 92948761c62SAndrew Jeffery uint8_t *comp_sensor_count, 93048761c62SAndrew Jeffery get_sensor_state_field *field) 93148761c62SAndrew Jeffery { 93248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 93348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 93448761c62SAndrew Jeffery uint8_t i; 93548761c62SAndrew Jeffery int rc; 93648761c62SAndrew Jeffery 93748761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 93848761c62SAndrew Jeffery comp_sensor_count == NULL || field == NULL) { 93948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 94048761c62SAndrew Jeffery } 94148761c62SAndrew Jeffery 942830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 943830c1eb4SAndrew Jeffery buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES, 94448761c62SAndrew Jeffery msg->payload, payload_length); 94548761c62SAndrew Jeffery if (rc) { 946830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 94748761c62SAndrew Jeffery } 94848761c62SAndrew Jeffery 94948761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 95048761c62SAndrew Jeffery if (rc) { 951830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 95248761c62SAndrew Jeffery } 95348761c62SAndrew Jeffery 95448761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 95548761c62SAndrew Jeffery return PLDM_SUCCESS; 95648761c62SAndrew Jeffery } 95748761c62SAndrew Jeffery 95848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, comp_sensor_count); 95948761c62SAndrew Jeffery if (rc) { 960830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 96148761c62SAndrew Jeffery } 96248761c62SAndrew Jeffery 96348761c62SAndrew Jeffery if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) { 96448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 96548761c62SAndrew Jeffery } 96648761c62SAndrew Jeffery 96748761c62SAndrew Jeffery for (i = 0; i < *comp_sensor_count; i++) { 96848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].sensor_op_state); 96948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].present_state); 97048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].previous_state); 97148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].event_state); 97248761c62SAndrew Jeffery } 97348761c62SAndrew Jeffery 974830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 975830c1eb4SAndrew Jeffery if (rc) { 976830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 977830c1eb4SAndrew Jeffery } 978830c1eb4SAndrew Jeffery 979830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 98048761c62SAndrew Jeffery } 98148761c62SAndrew Jeffery 98248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 98348761c62SAndrew Jeffery int decode_get_state_sensor_readings_req(const struct pldm_msg *msg, 98448761c62SAndrew Jeffery size_t payload_length, 98548761c62SAndrew Jeffery uint16_t *sensor_id, 98648761c62SAndrew Jeffery bitfield8_t *sensor_rearm, 98748761c62SAndrew Jeffery uint8_t *reserved) 98848761c62SAndrew Jeffery { 98948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 99048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 99148761c62SAndrew Jeffery int rc; 99248761c62SAndrew Jeffery 99348761c62SAndrew Jeffery if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) { 99448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 99548761c62SAndrew Jeffery } 99648761c62SAndrew Jeffery 997830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 998830c1eb4SAndrew Jeffery PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES, 99948761c62SAndrew Jeffery msg->payload, payload_length); 100048761c62SAndrew Jeffery if (rc) { 1001830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 100248761c62SAndrew Jeffery } 100348761c62SAndrew Jeffery 100448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 100548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, sensor_rearm->byte); 100648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, reserved); 100748761c62SAndrew Jeffery 1008830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1009830c1eb4SAndrew Jeffery if (rc) { 1010830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1011830c1eb4SAndrew Jeffery } 1012830c1eb4SAndrew Jeffery 1013830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 101448761c62SAndrew Jeffery } 101548761c62SAndrew Jeffery 101648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 101748761c62SAndrew Jeffery int encode_sensor_event_data( 101848761c62SAndrew Jeffery struct pldm_sensor_event_data *const event_data, 101948761c62SAndrew Jeffery const size_t event_data_size, const uint16_t sensor_id, 102048761c62SAndrew Jeffery const enum sensor_event_class_states sensor_event_class, 102148761c62SAndrew Jeffery const uint8_t sensor_offset, const uint8_t event_state, 102248761c62SAndrew Jeffery const uint8_t previous_event_state, 102348761c62SAndrew Jeffery size_t *const actual_event_data_size) 102448761c62SAndrew Jeffery { 102548761c62SAndrew Jeffery *actual_event_data_size = 102648761c62SAndrew Jeffery (sizeof(*event_data) - sizeof(event_data->event_class) + 102748761c62SAndrew Jeffery sizeof(struct pldm_sensor_event_state_sensor_state)); 102848761c62SAndrew Jeffery 102948761c62SAndrew Jeffery if (!event_data) { 103048761c62SAndrew Jeffery return PLDM_SUCCESS; 103148761c62SAndrew Jeffery } 103248761c62SAndrew Jeffery 103348761c62SAndrew Jeffery if (event_data_size < *actual_event_data_size) { 103448761c62SAndrew Jeffery *actual_event_data_size = 0; 103548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 103648761c62SAndrew Jeffery } 103748761c62SAndrew Jeffery 103848761c62SAndrew Jeffery event_data->sensor_id = htole16(sensor_id); 103948761c62SAndrew Jeffery event_data->sensor_event_class_type = sensor_event_class; 104048761c62SAndrew Jeffery 104148761c62SAndrew Jeffery struct pldm_sensor_event_state_sensor_state *const state_data = 104248761c62SAndrew Jeffery (struct pldm_sensor_event_state_sensor_state *) 104348761c62SAndrew Jeffery event_data->event_class; 104448761c62SAndrew Jeffery 104548761c62SAndrew Jeffery state_data->sensor_offset = sensor_offset; 104648761c62SAndrew Jeffery state_data->event_state = event_state; 104748761c62SAndrew Jeffery state_data->previous_event_state = previous_event_state; 104848761c62SAndrew Jeffery 104948761c62SAndrew Jeffery return PLDM_SUCCESS; 105048761c62SAndrew Jeffery } 105148761c62SAndrew Jeffery 105248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 105348761c62SAndrew Jeffery int decode_platform_event_message_req(const struct pldm_msg *msg, 105448761c62SAndrew Jeffery size_t payload_length, 105548761c62SAndrew Jeffery uint8_t *format_version, uint8_t *tid, 105648761c62SAndrew Jeffery uint8_t *event_class, 105748761c62SAndrew Jeffery size_t *event_data_offset) 105848761c62SAndrew Jeffery { 105948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 106048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 106148761c62SAndrew Jeffery int rc; 106248761c62SAndrew Jeffery 106348761c62SAndrew Jeffery if (msg == NULL || format_version == NULL || tid == NULL || 106448761c62SAndrew Jeffery event_class == NULL || event_data_offset == NULL) { 106548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 106648761c62SAndrew Jeffery } 106748761c62SAndrew Jeffery 1068830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 1069830c1eb4SAndrew Jeffery PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES, 107048761c62SAndrew Jeffery msg->payload, payload_length); 107148761c62SAndrew Jeffery if (rc) { 1072830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 107348761c62SAndrew Jeffery } 107448761c62SAndrew Jeffery 107548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, format_version); 107648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, tid); 107748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_class); 1078830c1eb4SAndrew Jeffery 1079830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1080830c1eb4SAndrew Jeffery if (rc) { 1081830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1082830c1eb4SAndrew Jeffery } 1083830c1eb4SAndrew Jeffery 108448761c62SAndrew Jeffery *event_data_offset = 108548761c62SAndrew Jeffery sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class); 108648761c62SAndrew Jeffery 1087830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 108848761c62SAndrew Jeffery } 108948761c62SAndrew Jeffery 1090387b10f6SThu Nguyen static int pldm_platform_poll_for_platform_event_message_validate( 1091387b10f6SThu Nguyen uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge) 1092387b10f6SThu Nguyen { 1093387b10f6SThu Nguyen if (((transfer_operation_flag == PLDM_GET_FIRSTPART) && 1094387b10f6SThu Nguyen (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) || 1095387b10f6SThu Nguyen ((transfer_operation_flag == PLDM_GET_NEXTPART) && 1096387b10f6SThu Nguyen (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1097387b10f6SThu Nguyen ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 10989e16b18bSThu Nguyen (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 10999e16b18bSThu Nguyen ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 11009e16b18bSThu Nguyen (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) || 1101387b10f6SThu Nguyen (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) { 1102387b10f6SThu Nguyen return -EPROTO; 1103387b10f6SThu Nguyen } 1104387b10f6SThu Nguyen 1105387b10f6SThu Nguyen return 0; 1106387b10f6SThu Nguyen } 1107387b10f6SThu Nguyen 110848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 110948761c62SAndrew Jeffery int decode_poll_for_platform_event_message_req( 111048761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 111148761c62SAndrew Jeffery uint8_t *format_version, uint8_t *transfer_operation_flag, 111248761c62SAndrew Jeffery uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge) 111348761c62SAndrew Jeffery { 111448761c62SAndrew Jeffery struct pldm_msgbuf _buf; 111548761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 111648761c62SAndrew Jeffery int rc; 111748761c62SAndrew Jeffery 111890bbe6c0SAndrew Jeffery if (msg == NULL || format_version == NULL || 111990bbe6c0SAndrew Jeffery transfer_operation_flag == NULL || data_transfer_handle == NULL || 112090bbe6c0SAndrew Jeffery event_id_to_acknowledge == NULL) { 112148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 112248761c62SAndrew Jeffery } 112348761c62SAndrew Jeffery 1124830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 1125830c1eb4SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, 112648761c62SAndrew Jeffery msg->payload, payload_length); 112748761c62SAndrew Jeffery if (rc) { 1128830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 112948761c62SAndrew Jeffery } 113048761c62SAndrew Jeffery 113148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, format_version); 113248761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag); 113348761c62SAndrew Jeffery if (rc) { 1134830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 113548761c62SAndrew Jeffery } 113648761c62SAndrew Jeffery if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) { 113748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 113848761c62SAndrew Jeffery } 113948761c62SAndrew Jeffery 114048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_handle); 114148761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge); 114248761c62SAndrew Jeffery if (rc) { 1143830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 114448761c62SAndrew Jeffery } 114548761c62SAndrew Jeffery 1146387b10f6SThu Nguyen rc = pldm_platform_poll_for_platform_event_message_validate( 1147387b10f6SThu Nguyen *transfer_operation_flag, *event_id_to_acknowledge); 1148387b10f6SThu Nguyen if (rc < 0) { 114948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 115048761c62SAndrew Jeffery } 115148761c62SAndrew Jeffery 1152830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1153830c1eb4SAndrew Jeffery if (rc) { 1154830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1155830c1eb4SAndrew Jeffery } 1156830c1eb4SAndrew Jeffery 1157830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 115848761c62SAndrew Jeffery } 115948761c62SAndrew Jeffery 116048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 116148761c62SAndrew Jeffery int encode_platform_event_message_resp(uint8_t instance_id, 116248761c62SAndrew Jeffery uint8_t completion_code, 116348761c62SAndrew Jeffery uint8_t platform_event_status, 116448761c62SAndrew Jeffery struct pldm_msg *msg) 116548761c62SAndrew Jeffery { 116648761c62SAndrew Jeffery if (msg == NULL) { 116748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 116848761c62SAndrew Jeffery } 116948761c62SAndrew Jeffery 117048761c62SAndrew Jeffery if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 117148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 117248761c62SAndrew Jeffery } 117348761c62SAndrew Jeffery 117448761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 117548761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 117648761c62SAndrew Jeffery header.instance = instance_id; 117748761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 117848761c62SAndrew Jeffery header.command = PLDM_PLATFORM_EVENT_MESSAGE; 117948761c62SAndrew Jeffery 118048761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 118148761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 118248761c62SAndrew Jeffery return rc; 118348761c62SAndrew Jeffery } 118448761c62SAndrew Jeffery 118548761c62SAndrew Jeffery struct pldm_platform_event_message_resp *response = 118648761c62SAndrew Jeffery (struct pldm_platform_event_message_resp *)msg->payload; 118748761c62SAndrew Jeffery response->completion_code = completion_code; 118848761c62SAndrew Jeffery response->platform_event_status = platform_event_status; 118948761c62SAndrew Jeffery 119048761c62SAndrew Jeffery return PLDM_SUCCESS; 119148761c62SAndrew Jeffery } 119248761c62SAndrew Jeffery 119348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 119448761c62SAndrew Jeffery int encode_poll_for_platform_event_message_resp( 119548761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, uint8_t tid, 119648761c62SAndrew Jeffery uint16_t event_id, uint32_t next_data_transfer_handle, 119748761c62SAndrew Jeffery uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size, 119848761c62SAndrew Jeffery uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg, 119948761c62SAndrew Jeffery size_t payload_length) 120048761c62SAndrew Jeffery { 120148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 120248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 120348761c62SAndrew Jeffery int rc; 120448761c62SAndrew Jeffery 120548761c62SAndrew Jeffery if (!msg) { 120648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 120748761c62SAndrew Jeffery } 120848761c62SAndrew Jeffery 120948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 121048761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 121148761c62SAndrew Jeffery header.instance = instance_id; 121248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 121348761c62SAndrew Jeffery header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 121448761c62SAndrew Jeffery 121548761c62SAndrew Jeffery rc = pack_pldm_header(&header, &(msg->hdr)); 121648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 121748761c62SAndrew Jeffery return rc; 121848761c62SAndrew Jeffery } 121948761c62SAndrew Jeffery 1220830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 122148761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 122248761c62SAndrew Jeffery msg->payload, payload_length); 122348761c62SAndrew Jeffery if (rc) { 1224830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 122548761c62SAndrew Jeffery } 122648761c62SAndrew Jeffery 122748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, completion_code); 122848761c62SAndrew Jeffery pldm_msgbuf_insert(buf, tid); 1229830c1eb4SAndrew Jeffery rc = pldm_msgbuf_insert(buf, event_id); 1230830c1eb4SAndrew Jeffery if (rc) { 1231830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1232830c1eb4SAndrew Jeffery } 123348761c62SAndrew Jeffery 123448761c62SAndrew Jeffery if (event_id == 0xffff || event_id == 0x0000) { 123548761c62SAndrew Jeffery if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES != 123648761c62SAndrew Jeffery payload_length) { 123748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 123848761c62SAndrew Jeffery } 1239830c1eb4SAndrew Jeffery 1240830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1241830c1eb4SAndrew Jeffery if (rc) { 1242830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1243830c1eb4SAndrew Jeffery } 1244830c1eb4SAndrew Jeffery 1245830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 124648761c62SAndrew Jeffery } 124748761c62SAndrew Jeffery 124848761c62SAndrew Jeffery if ((event_data == NULL) && (event_data_size > 0)) { 124948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 125048761c62SAndrew Jeffery } 125148761c62SAndrew Jeffery 125248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, next_data_transfer_handle); 125348761c62SAndrew Jeffery pldm_msgbuf_insert(buf, transfer_flag); 125448761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_class); 1255830c1eb4SAndrew Jeffery rc = pldm_msgbuf_insert(buf, event_data_size); 1256830c1eb4SAndrew Jeffery if (rc) { 1257830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1258830c1eb4SAndrew Jeffery } 125948761c62SAndrew Jeffery 126048761c62SAndrew Jeffery if ((event_data_size > 0) && event_data) { 12610a1be3cbSAndrew Jeffery rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data, 12620a1be3cbSAndrew Jeffery event_data_size); 12630a1be3cbSAndrew Jeffery if (rc) { 1264830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 12650a1be3cbSAndrew Jeffery } 126648761c62SAndrew Jeffery } 126748761c62SAndrew Jeffery 126848761c62SAndrew Jeffery if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) { 126948761c62SAndrew Jeffery pldm_msgbuf_insert(buf, checksum); 127048761c62SAndrew Jeffery } 127148761c62SAndrew Jeffery 1272830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1273830c1eb4SAndrew Jeffery if (rc) { 1274830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1275830c1eb4SAndrew Jeffery } 1276830c1eb4SAndrew Jeffery 1277830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 127848761c62SAndrew Jeffery } 127948761c62SAndrew Jeffery 128048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 128148761c62SAndrew Jeffery int encode_platform_event_message_req( 128248761c62SAndrew Jeffery uint8_t instance_id, uint8_t format_version, uint8_t tid, 128348761c62SAndrew Jeffery uint8_t event_class, const uint8_t *event_data, 128448761c62SAndrew Jeffery size_t event_data_length, struct pldm_msg *msg, size_t payload_length) 128548761c62SAndrew Jeffery 128648761c62SAndrew Jeffery { 128748761c62SAndrew Jeffery if (format_version != 1) { 128848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 128948761c62SAndrew Jeffery } 129048761c62SAndrew Jeffery 129148761c62SAndrew Jeffery if (msg == NULL || event_data == NULL) { 129248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 129348761c62SAndrew Jeffery } 129448761c62SAndrew Jeffery 129548761c62SAndrew Jeffery if (event_data_length == 0) { 129648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 129748761c62SAndrew Jeffery } 129848761c62SAndrew Jeffery 1299*225530abSAndrew Jeffery if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) < 1300*225530abSAndrew Jeffery event_data_length) { 1301*225530abSAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 1302*225530abSAndrew Jeffery } 1303*225530abSAndrew Jeffery 130448761c62SAndrew Jeffery if (payload_length != 130548761c62SAndrew Jeffery PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) { 130648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 130748761c62SAndrew Jeffery } 130848761c62SAndrew Jeffery 1309b43a7787SJohn Chung if (event_class > PLDM_CPER_EVENT && 131048761c62SAndrew Jeffery !(event_class >= 0xf0 && event_class <= 0xfe)) { 131148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 131248761c62SAndrew Jeffery } 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_PLATFORM_EVENT_MESSAGE; 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_platform_event_message_req *request = 132648761c62SAndrew Jeffery (struct pldm_platform_event_message_req *)msg->payload; 132748761c62SAndrew Jeffery request->format_version = format_version; 132848761c62SAndrew Jeffery request->tid = tid; 132948761c62SAndrew Jeffery request->event_class = event_class; 133048761c62SAndrew Jeffery memcpy(request->event_data, event_data, event_data_length); 133148761c62SAndrew Jeffery 133248761c62SAndrew Jeffery return PLDM_SUCCESS; 133348761c62SAndrew Jeffery } 133448761c62SAndrew Jeffery 133548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 133648761c62SAndrew Jeffery int decode_platform_event_message_resp(const struct pldm_msg *msg, 133748761c62SAndrew Jeffery size_t payload_length, 133848761c62SAndrew Jeffery uint8_t *completion_code, 133948761c62SAndrew Jeffery uint8_t *platform_event_status) 134048761c62SAndrew Jeffery { 134148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 134248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 134348761c62SAndrew Jeffery int rc; 134448761c62SAndrew Jeffery 134548761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 134648761c62SAndrew Jeffery platform_event_status == NULL) { 134748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 134848761c62SAndrew Jeffery } 134948761c62SAndrew Jeffery 1350830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 135148761c62SAndrew Jeffery msg->payload, payload_length); 135248761c62SAndrew Jeffery if (rc) { 1353830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 135448761c62SAndrew Jeffery } 135548761c62SAndrew Jeffery 135648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 135748761c62SAndrew Jeffery if (rc) { 1358830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 135948761c62SAndrew Jeffery } 136048761c62SAndrew Jeffery 136148761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 136248761c62SAndrew Jeffery return PLDM_SUCCESS; 136348761c62SAndrew Jeffery } 136448761c62SAndrew Jeffery 136548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, platform_event_status); 136648761c62SAndrew Jeffery if (rc) { 1367830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 136848761c62SAndrew Jeffery } 136948761c62SAndrew Jeffery 137048761c62SAndrew Jeffery if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 137148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 137248761c62SAndrew Jeffery } 137348761c62SAndrew Jeffery 1374830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1375830c1eb4SAndrew Jeffery if (rc) { 1376830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1377830c1eb4SAndrew Jeffery } 1378830c1eb4SAndrew Jeffery 1379830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 138048761c62SAndrew Jeffery } 138148761c62SAndrew Jeffery 138248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 138348761c62SAndrew Jeffery int encode_event_message_buffer_size_req(uint8_t instance_id, 138448761c62SAndrew Jeffery uint16_t event_receiver_max_buffer_size, 138548761c62SAndrew Jeffery struct pldm_msg *msg) 138648761c62SAndrew Jeffery { 138748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 138848761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 138948761c62SAndrew Jeffery header.instance = instance_id; 139048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 139148761c62SAndrew Jeffery header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE; 139248761c62SAndrew Jeffery 139348761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 139448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 139548761c62SAndrew Jeffery return rc; 139648761c62SAndrew Jeffery } 139748761c62SAndrew Jeffery 139848761c62SAndrew Jeffery struct pldm_event_message_buffer_size_req *request = 139948761c62SAndrew Jeffery (struct pldm_event_message_buffer_size_req *)msg->payload; 140048761c62SAndrew Jeffery request->event_receiver_max_buffer_size = 140148761c62SAndrew Jeffery event_receiver_max_buffer_size; 140248761c62SAndrew Jeffery 140348761c62SAndrew Jeffery return PLDM_SUCCESS; 140448761c62SAndrew Jeffery } 140548761c62SAndrew Jeffery 140648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 140748761c62SAndrew Jeffery int decode_event_message_buffer_size_resp(const struct pldm_msg *msg, 140848761c62SAndrew Jeffery size_t payload_length, 140948761c62SAndrew Jeffery uint8_t *completion_code, 141048761c62SAndrew Jeffery uint16_t *terminus_max_buffer_size) 141148761c62SAndrew Jeffery { 141248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 141348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 141448761c62SAndrew Jeffery int rc; 141548761c62SAndrew Jeffery 141648761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 141748761c62SAndrew Jeffery terminus_max_buffer_size == NULL) { 141848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 141948761c62SAndrew Jeffery } 142048761c62SAndrew Jeffery 1421830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 1422830c1eb4SAndrew Jeffery PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES, 142348761c62SAndrew Jeffery msg->payload, payload_length); 142448761c62SAndrew Jeffery if (rc) { 1425830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 142648761c62SAndrew Jeffery } 142748761c62SAndrew Jeffery 142848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 142948761c62SAndrew Jeffery if (rc) { 1430830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 143148761c62SAndrew Jeffery } 143248761c62SAndrew Jeffery 143348761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 143448761c62SAndrew Jeffery return PLDM_SUCCESS; 143548761c62SAndrew Jeffery } 143648761c62SAndrew Jeffery 143748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, terminus_max_buffer_size); 143848761c62SAndrew Jeffery 1439830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1440830c1eb4SAndrew Jeffery if (rc) { 1441830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1442830c1eb4SAndrew Jeffery } 1443830c1eb4SAndrew Jeffery 1444830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 144548761c62SAndrew Jeffery } 144648761c62SAndrew Jeffery 144748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 144848761c62SAndrew Jeffery int encode_event_message_supported_req(uint8_t instance_id, 144948761c62SAndrew Jeffery uint8_t format_version, 145048761c62SAndrew Jeffery struct pldm_msg *msg) 145148761c62SAndrew Jeffery { 145248761c62SAndrew Jeffery if (format_version != 1) { 145348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 145448761c62SAndrew Jeffery } 145548761c62SAndrew Jeffery 145648761c62SAndrew Jeffery if (msg == NULL) { 145748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 145848761c62SAndrew Jeffery } 145948761c62SAndrew Jeffery 146048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 146148761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 146248761c62SAndrew Jeffery header.instance = instance_id; 146348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 146448761c62SAndrew Jeffery header.command = PLDM_EVENT_MESSAGE_SUPPORTED; 146548761c62SAndrew Jeffery 146648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 146748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 146848761c62SAndrew Jeffery return rc; 146948761c62SAndrew Jeffery } 147048761c62SAndrew Jeffery 147148761c62SAndrew Jeffery struct pldm_event_message_supported_req *request = 147248761c62SAndrew Jeffery (struct pldm_event_message_supported_req *)msg->payload; 147348761c62SAndrew Jeffery request->format_version = format_version; 147448761c62SAndrew Jeffery 147548761c62SAndrew Jeffery return PLDM_SUCCESS; 147648761c62SAndrew Jeffery } 147748761c62SAndrew Jeffery 147848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 147948761c62SAndrew Jeffery int decode_event_message_supported_resp(const struct pldm_msg *msg, 148048761c62SAndrew Jeffery size_t payload_length, 148148761c62SAndrew Jeffery uint8_t *completion_code, 148248761c62SAndrew Jeffery uint8_t *synchrony_config, 148348761c62SAndrew Jeffery bitfield8_t *synchrony_config_support, 148448761c62SAndrew Jeffery uint8_t *number_event_class_returned, 148548761c62SAndrew Jeffery uint8_t *event_class, 148648761c62SAndrew Jeffery uint8_t event_class_count) 148748761c62SAndrew Jeffery { 148848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 148948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 149048761c62SAndrew Jeffery int i; 149148761c62SAndrew Jeffery int rc; 149248761c62SAndrew Jeffery 149348761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 149448761c62SAndrew Jeffery synchrony_config == NULL || synchrony_config_support == NULL || 149548761c62SAndrew Jeffery number_event_class_returned == NULL || event_class == NULL) { 149648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 149748761c62SAndrew Jeffery } 149848761c62SAndrew Jeffery 1499830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 150048761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES, 150148761c62SAndrew Jeffery msg->payload, payload_length); 150248761c62SAndrew Jeffery if (rc) { 1503830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 150448761c62SAndrew Jeffery } 150548761c62SAndrew Jeffery 150648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 150748761c62SAndrew Jeffery if (rc) { 1508830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 150948761c62SAndrew Jeffery } 151048761c62SAndrew Jeffery 151148761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 151248761c62SAndrew Jeffery return PLDM_SUCCESS; 151348761c62SAndrew Jeffery } 151448761c62SAndrew Jeffery 151548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, synchrony_config); 151648761c62SAndrew Jeffery if (rc) { 1517830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 151848761c62SAndrew Jeffery } 151948761c62SAndrew Jeffery 152048761c62SAndrew Jeffery if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) { 152148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 152248761c62SAndrew Jeffery } 152348761c62SAndrew Jeffery 152448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte); 152548761c62SAndrew Jeffery 152648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, number_event_class_returned); 152748761c62SAndrew Jeffery if (rc) { 1528830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 152948761c62SAndrew Jeffery } 153048761c62SAndrew Jeffery 153148761c62SAndrew Jeffery if (*number_event_class_returned == 0) { 1532830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1533830c1eb4SAndrew Jeffery if (rc) { 1534830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1535830c1eb4SAndrew Jeffery } 1536830c1eb4SAndrew Jeffery 1537830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 153848761c62SAndrew Jeffery } 153948761c62SAndrew Jeffery 154048761c62SAndrew Jeffery if (event_class_count < *number_event_class_returned) { 154148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 154248761c62SAndrew Jeffery } 154348761c62SAndrew Jeffery 154448761c62SAndrew Jeffery for (i = 0; i < *number_event_class_returned; i++) { 154548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, event_class[i]); 154648761c62SAndrew Jeffery } 154748761c62SAndrew Jeffery 1548830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1549830c1eb4SAndrew Jeffery if (rc) { 1550830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1551830c1eb4SAndrew Jeffery } 1552830c1eb4SAndrew Jeffery 1553830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 155448761c62SAndrew Jeffery } 155548761c62SAndrew Jeffery 155648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 155748761c62SAndrew Jeffery int decode_sensor_event_data(const uint8_t *event_data, 155848761c62SAndrew Jeffery size_t event_data_length, uint16_t *sensor_id, 155948761c62SAndrew Jeffery uint8_t *sensor_event_class_type, 156048761c62SAndrew Jeffery size_t *event_class_data_offset) 156148761c62SAndrew Jeffery { 156248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 156348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 156448761c62SAndrew Jeffery int rc; 156548761c62SAndrew Jeffery 156690bbe6c0SAndrew Jeffery if (event_data == NULL || sensor_id == NULL || 156790bbe6c0SAndrew Jeffery sensor_event_class_type == NULL || 156890bbe6c0SAndrew Jeffery event_class_data_offset == NULL) { 156990bbe6c0SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 157090bbe6c0SAndrew Jeffery } 157190bbe6c0SAndrew Jeffery 1572830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH, 157348761c62SAndrew Jeffery event_data, event_data_length); 157448761c62SAndrew Jeffery if (rc) { 1575830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1576830c1eb4SAndrew Jeffery } 1577830c1eb4SAndrew Jeffery 1578830c1eb4SAndrew Jeffery if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) { 1579830c1eb4SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 158048761c62SAndrew Jeffery } 158148761c62SAndrew Jeffery 158248761c62SAndrew Jeffery size_t event_class_data_length = 158348761c62SAndrew Jeffery event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES; 158448761c62SAndrew Jeffery 158548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 158648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type); 158748761c62SAndrew Jeffery if (rc) { 1588830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 158948761c62SAndrew Jeffery } 159048761c62SAndrew Jeffery 159148761c62SAndrew Jeffery if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) { 159248761c62SAndrew Jeffery if (event_class_data_length != 159348761c62SAndrew Jeffery PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) { 159448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 159548761c62SAndrew Jeffery } 159648761c62SAndrew Jeffery } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) { 159748761c62SAndrew Jeffery if (event_class_data_length != 159848761c62SAndrew Jeffery PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) { 159948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 160048761c62SAndrew Jeffery } 160148761c62SAndrew Jeffery } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) { 160248761c62SAndrew Jeffery if (event_class_data_length < 160348761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH || 160448761c62SAndrew Jeffery event_class_data_length > 160548761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 160648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 160748761c62SAndrew Jeffery } 160848761c62SAndrew Jeffery } else { 160948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 161048761c62SAndrew Jeffery } 161148761c62SAndrew Jeffery 161248761c62SAndrew Jeffery *event_class_data_offset = 161348761c62SAndrew Jeffery sizeof(*sensor_id) + sizeof(*sensor_event_class_type); 161448761c62SAndrew Jeffery 1615830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1616830c1eb4SAndrew Jeffery if (rc) { 1617830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1618830c1eb4SAndrew Jeffery } 1619830c1eb4SAndrew Jeffery 1620830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 162148761c62SAndrew Jeffery } 162248761c62SAndrew Jeffery 162348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 162448761c62SAndrew Jeffery int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length, 162548761c62SAndrew Jeffery uint8_t *present_op_state, uint8_t *previous_op_state) 162648761c62SAndrew Jeffery { 162748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 162848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 162948761c62SAndrew Jeffery int rc; 163048761c62SAndrew Jeffery 163190bbe6c0SAndrew Jeffery if (sensor_data == NULL || present_op_state == NULL || 163290bbe6c0SAndrew Jeffery previous_op_state == NULL) { 163348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 163448761c62SAndrew Jeffery } 163548761c62SAndrew Jeffery 1636830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 1637830c1eb4SAndrew Jeffery buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data, 1638830c1eb4SAndrew Jeffery sensor_data_length); 163948761c62SAndrew Jeffery if (rc) { 1640830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 164148761c62SAndrew Jeffery } 164248761c62SAndrew Jeffery 164348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, present_op_state); 164448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_op_state); 164548761c62SAndrew Jeffery 1646830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1647830c1eb4SAndrew Jeffery if (rc) { 1648830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1649830c1eb4SAndrew Jeffery } 1650830c1eb4SAndrew Jeffery 1651830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 165248761c62SAndrew Jeffery } 165348761c62SAndrew Jeffery 165448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 165548761c62SAndrew Jeffery int decode_state_sensor_data(const uint8_t *sensor_data, 165648761c62SAndrew Jeffery size_t sensor_data_length, uint8_t *sensor_offset, 165748761c62SAndrew Jeffery uint8_t *event_state, 165848761c62SAndrew Jeffery uint8_t *previous_event_state) 165948761c62SAndrew Jeffery { 166048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 166148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 166248761c62SAndrew Jeffery int rc; 166348761c62SAndrew Jeffery 166490bbe6c0SAndrew Jeffery if (sensor_data == NULL || sensor_offset == NULL || 166590bbe6c0SAndrew Jeffery event_state == NULL || previous_event_state == NULL) { 166648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 166748761c62SAndrew Jeffery } 166848761c62SAndrew Jeffery 1669830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 167048761c62SAndrew Jeffery buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH, 167148761c62SAndrew Jeffery sensor_data, sensor_data_length); 167248761c62SAndrew Jeffery if (rc) { 1673830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 167448761c62SAndrew Jeffery } 167548761c62SAndrew Jeffery 167648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_offset); 167748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 167848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_event_state); 167948761c62SAndrew Jeffery 1680830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1681830c1eb4SAndrew Jeffery if (rc) { 1682830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1683830c1eb4SAndrew Jeffery } 1684830c1eb4SAndrew Jeffery 1685830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 168648761c62SAndrew Jeffery } 168748761c62SAndrew Jeffery 168848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 168948761c62SAndrew Jeffery int decode_numeric_sensor_data(const uint8_t *sensor_data, 169048761c62SAndrew Jeffery size_t sensor_data_length, uint8_t *event_state, 169148761c62SAndrew Jeffery uint8_t *previous_event_state, 169248761c62SAndrew Jeffery uint8_t *sensor_data_size, 169348761c62SAndrew Jeffery uint32_t *present_reading) 169448761c62SAndrew Jeffery { 169548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 169648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 169748761c62SAndrew Jeffery int rc; 169848761c62SAndrew Jeffery 169990bbe6c0SAndrew Jeffery if (sensor_data == NULL || sensor_data_size == NULL || 170090bbe6c0SAndrew Jeffery event_state == NULL || previous_event_state == NULL || 170190bbe6c0SAndrew Jeffery present_reading == NULL) { 170248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 170348761c62SAndrew Jeffery } 170448761c62SAndrew Jeffery 170548761c62SAndrew Jeffery if (sensor_data_length > 170648761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 170748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 170848761c62SAndrew Jeffery } 170948761c62SAndrew Jeffery 1710830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 171148761c62SAndrew Jeffery buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH, 171248761c62SAndrew Jeffery sensor_data, sensor_data_length); 171348761c62SAndrew Jeffery if (rc) { 1714830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 171548761c62SAndrew Jeffery } 171648761c62SAndrew Jeffery 171748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 171848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_event_state); 171948761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 172048761c62SAndrew Jeffery if (rc) { 1721830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 172248761c62SAndrew Jeffery } 172348761c62SAndrew Jeffery 172448761c62SAndrew Jeffery /* 172548761c62SAndrew Jeffery * The implementation below is bonkers, but it's because the function 172648761c62SAndrew Jeffery * prototype is bonkers. The `present_reading` argument should have been 172748761c62SAndrew Jeffery * a tagged union. 172848761c62SAndrew Jeffery */ 172948761c62SAndrew Jeffery switch (*sensor_data_size) { 173048761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT8: { 173148761c62SAndrew Jeffery uint8_t val; 173248761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 173348761c62SAndrew Jeffery *present_reading = (uint32_t)val; 173448761c62SAndrew Jeffery } 173548761c62SAndrew Jeffery break; 173648761c62SAndrew Jeffery } 173748761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: { 173848761c62SAndrew Jeffery int8_t val; 173948761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 174048761c62SAndrew Jeffery *present_reading = (uint32_t)(int32_t)val; 174148761c62SAndrew Jeffery } 174248761c62SAndrew Jeffery break; 174348761c62SAndrew Jeffery } 174448761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: { 174548761c62SAndrew Jeffery uint16_t val; 174648761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 174748761c62SAndrew Jeffery *present_reading = (uint32_t)val; 174848761c62SAndrew Jeffery } 174948761c62SAndrew Jeffery break; 175048761c62SAndrew Jeffery } 175148761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: { 175248761c62SAndrew Jeffery int16_t val; 175348761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 175448761c62SAndrew Jeffery *present_reading = (uint32_t)(int32_t)val; 175548761c62SAndrew Jeffery } 175648761c62SAndrew Jeffery break; 175748761c62SAndrew Jeffery } 175848761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: { 175948761c62SAndrew Jeffery uint32_t val; 176048761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 176148761c62SAndrew Jeffery *present_reading = (uint32_t)val; 176248761c62SAndrew Jeffery } 176348761c62SAndrew Jeffery break; 176448761c62SAndrew Jeffery } 176548761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: { 176648761c62SAndrew Jeffery int32_t val; 176748761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 176848761c62SAndrew Jeffery *present_reading = (uint32_t)val; 176948761c62SAndrew Jeffery } 177048761c62SAndrew Jeffery break; 177148761c62SAndrew Jeffery } 177248761c62SAndrew Jeffery default: 177348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 177448761c62SAndrew Jeffery } 177548761c62SAndrew Jeffery 1776830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1777830c1eb4SAndrew Jeffery if (rc) { 1778830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1779830c1eb4SAndrew Jeffery } 1780830c1eb4SAndrew Jeffery 1781830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 178248761c62SAndrew Jeffery } 178348761c62SAndrew Jeffery 178448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 178548761c62SAndrew Jeffery int decode_numeric_sensor_pdr_data( 178648761c62SAndrew Jeffery const void *pdr_data, size_t pdr_data_length, 178748761c62SAndrew Jeffery struct pldm_numeric_sensor_value_pdr *pdr_value) 178848761c62SAndrew Jeffery { 178948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 179048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 179148761c62SAndrew Jeffery int rc; 179248761c62SAndrew Jeffery 1793830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 179448761c62SAndrew Jeffery pdr_data, pdr_data_length); 179548761c62SAndrew Jeffery if (rc) { 1796830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 179748761c62SAndrew Jeffery } 179848761c62SAndrew Jeffery 1799329176a8SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr( 1800329176a8SAndrew Jeffery buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 180148761c62SAndrew Jeffery pdr_data_length); 180248761c62SAndrew Jeffery if (rc) { 1803329176a8SAndrew Jeffery return pldm_xlate_errno(rc); 180448761c62SAndrew Jeffery } 180548761c62SAndrew Jeffery 180648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 180748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_id); 180848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_type); 180948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_instance_num); 181048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->container_id); 181148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_init); 181248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr); 181348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_unit); 181448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 181548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rate_unit); 181648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 181748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit); 181848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 181948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 182048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rel); 182148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 182248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->is_linear); 182348761c62SAndrew Jeffery 182448761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size); 182548761c62SAndrew Jeffery if (rc) { 1826830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 182748761c62SAndrew Jeffery } 182848761c62SAndrew Jeffery if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 182948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 183048761c62SAndrew Jeffery } 183148761c62SAndrew Jeffery 183248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->resolution); 183348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->offset); 183448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->accuracy); 183548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 183648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 183748761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 183848761c62SAndrew Jeffery &pdr_value->hysteresis); 183948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte); 184048761c62SAndrew Jeffery pldm_msgbuf_extract( 184148761c62SAndrew Jeffery buf, pdr_value->threshold_and_hysteresis_volatility.byte); 184248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 184348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->update_interval); 184448761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 184548761c62SAndrew Jeffery &pdr_value->max_readable); 184648761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 184748761c62SAndrew Jeffery &pdr_value->min_readable); 184848761c62SAndrew Jeffery 184948761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 185048761c62SAndrew Jeffery if (rc) { 1851830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 185248761c62SAndrew Jeffery } 185348761c62SAndrew Jeffery if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 185448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 185548761c62SAndrew Jeffery } 185648761c62SAndrew Jeffery 185748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 185848761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 185948761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->nominal_value); 186048761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 186148761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_max); 186248761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 186348761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_min); 186448761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 186548761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->warning_high); 186648761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 186748761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->warning_low); 186848761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 186948761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->critical_high); 187048761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 187148761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->critical_low); 187248761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 187348761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->fatal_high); 187448761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 187548761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->fatal_low); 187648761c62SAndrew Jeffery 1877830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1878830c1eb4SAndrew Jeffery if (rc) { 1879830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1880830c1eb4SAndrew Jeffery } 1881830c1eb4SAndrew Jeffery 1882830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 188348761c62SAndrew Jeffery } 188448761c62SAndrew Jeffery 188548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 188648761c62SAndrew Jeffery int encode_get_numeric_effecter_value_req(uint8_t instance_id, 188748761c62SAndrew Jeffery uint16_t effecter_id, 188848761c62SAndrew Jeffery struct pldm_msg *msg) 188948761c62SAndrew Jeffery { 189048761c62SAndrew Jeffery if (msg == NULL) { 189148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 189248761c62SAndrew Jeffery } 189348761c62SAndrew Jeffery 189448761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 189548761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 189648761c62SAndrew Jeffery header.instance = instance_id; 189748761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 189848761c62SAndrew Jeffery header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 189948761c62SAndrew Jeffery 190048761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 190148761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 190248761c62SAndrew Jeffery return rc; 190348761c62SAndrew Jeffery } 190448761c62SAndrew Jeffery 190548761c62SAndrew Jeffery struct pldm_get_numeric_effecter_value_req *request = 190648761c62SAndrew Jeffery (struct pldm_get_numeric_effecter_value_req *)msg->payload; 190748761c62SAndrew Jeffery request->effecter_id = htole16(effecter_id); 190848761c62SAndrew Jeffery 190948761c62SAndrew Jeffery return PLDM_SUCCESS; 191048761c62SAndrew Jeffery } 191148761c62SAndrew Jeffery 191248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 191348761c62SAndrew Jeffery int encode_get_numeric_effecter_value_resp( 191448761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, 191548761c62SAndrew Jeffery uint8_t effecter_data_size, uint8_t effecter_oper_state, 191648761c62SAndrew Jeffery const uint8_t *pending_value, const uint8_t *present_value, 191748761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 191848761c62SAndrew Jeffery { 191948761c62SAndrew Jeffery if (msg == NULL || pending_value == NULL || present_value == NULL) { 192048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 192148761c62SAndrew Jeffery } 192248761c62SAndrew Jeffery 192348761c62SAndrew Jeffery if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 192448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 192548761c62SAndrew Jeffery } 192648761c62SAndrew Jeffery 192748761c62SAndrew Jeffery if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 192848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 192948761c62SAndrew Jeffery } 193048761c62SAndrew Jeffery 193148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 193248761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 193348761c62SAndrew Jeffery header.instance = instance_id; 193448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 193548761c62SAndrew Jeffery header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 193648761c62SAndrew Jeffery 193748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 193848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 193948761c62SAndrew Jeffery return rc; 194048761c62SAndrew Jeffery } 194148761c62SAndrew Jeffery 194248761c62SAndrew Jeffery struct pldm_get_numeric_effecter_value_resp *response = 194348761c62SAndrew Jeffery (struct pldm_get_numeric_effecter_value_resp *)msg->payload; 194448761c62SAndrew Jeffery 194548761c62SAndrew Jeffery response->completion_code = completion_code; 194648761c62SAndrew Jeffery response->effecter_data_size = effecter_data_size; 194748761c62SAndrew Jeffery response->effecter_oper_state = effecter_oper_state; 194848761c62SAndrew Jeffery 194948761c62SAndrew Jeffery if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 195048761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 195148761c62SAndrew Jeffery if (payload_length != 195248761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) { 195348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 195448761c62SAndrew Jeffery } 195548761c62SAndrew Jeffery response->pending_and_present_values[0] = *pending_value; 195648761c62SAndrew Jeffery response->pending_and_present_values[1] = *present_value; 195748761c62SAndrew Jeffery 195848761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 195948761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 196048761c62SAndrew Jeffery if (payload_length != 196148761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) { 196248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 196348761c62SAndrew Jeffery } 196448761c62SAndrew Jeffery uint16_t val_pending = *(uint16_t *)pending_value; 196548761c62SAndrew Jeffery val_pending = htole16(val_pending); 196648761c62SAndrew Jeffery memcpy(response->pending_and_present_values, &val_pending, 196748761c62SAndrew Jeffery sizeof(uint16_t)); 196848761c62SAndrew Jeffery uint16_t val_present = *(uint16_t *)present_value; 196948761c62SAndrew Jeffery val_present = htole16(val_present); 197048761c62SAndrew Jeffery memcpy((response->pending_and_present_values + 197148761c62SAndrew Jeffery sizeof(uint16_t)), 197248761c62SAndrew Jeffery &val_present, sizeof(uint16_t)); 197348761c62SAndrew Jeffery 197448761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 197548761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 197648761c62SAndrew Jeffery if (payload_length != 197748761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) { 197848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 197948761c62SAndrew Jeffery } 198048761c62SAndrew Jeffery uint32_t val_pending = *(uint32_t *)pending_value; 198148761c62SAndrew Jeffery val_pending = htole32(val_pending); 198248761c62SAndrew Jeffery memcpy(response->pending_and_present_values, &val_pending, 198348761c62SAndrew Jeffery sizeof(uint32_t)); 198448761c62SAndrew Jeffery uint32_t val_present = *(uint32_t *)present_value; 198548761c62SAndrew Jeffery val_present = htole32(val_present); 198648761c62SAndrew Jeffery memcpy((response->pending_and_present_values + 198748761c62SAndrew Jeffery sizeof(uint32_t)), 198848761c62SAndrew Jeffery &val_present, sizeof(uint32_t)); 198948761c62SAndrew Jeffery } 199048761c62SAndrew Jeffery return PLDM_SUCCESS; 199148761c62SAndrew Jeffery } 199248761c62SAndrew Jeffery 199348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 199448761c62SAndrew Jeffery int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg, 199548761c62SAndrew Jeffery size_t payload_length, 199648761c62SAndrew Jeffery uint16_t *effecter_id) 199748761c62SAndrew Jeffery { 199848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 199948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 200048761c62SAndrew Jeffery int rc; 200148761c62SAndrew Jeffery 200248761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL) { 200348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 200448761c62SAndrew Jeffery } 200548761c62SAndrew Jeffery 2006830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 2007830c1eb4SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES, 200848761c62SAndrew Jeffery msg->payload, payload_length); 200948761c62SAndrew Jeffery if (rc) { 2010830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 201148761c62SAndrew Jeffery } 201248761c62SAndrew Jeffery 201348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 201448761c62SAndrew Jeffery 2015830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2016830c1eb4SAndrew Jeffery if (rc) { 2017830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2018830c1eb4SAndrew Jeffery } 2019830c1eb4SAndrew Jeffery 2020830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 202148761c62SAndrew Jeffery } 202248761c62SAndrew Jeffery 202348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 202448761c62SAndrew Jeffery int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg, 202548761c62SAndrew Jeffery size_t payload_length, 202648761c62SAndrew Jeffery uint8_t *completion_code, 202748761c62SAndrew Jeffery uint8_t *effecter_data_size, 202848761c62SAndrew Jeffery uint8_t *effecter_oper_state, 202948761c62SAndrew Jeffery uint8_t *pending_value, 203048761c62SAndrew Jeffery uint8_t *present_value) 203148761c62SAndrew Jeffery { 203248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 203348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 203448761c62SAndrew Jeffery int rc; 203548761c62SAndrew Jeffery 203648761c62SAndrew Jeffery if (msg == NULL || effecter_data_size == NULL || 203748761c62SAndrew Jeffery effecter_oper_state == NULL || pending_value == NULL || 203848761c62SAndrew Jeffery present_value == NULL) { 203948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 204048761c62SAndrew Jeffery } 204148761c62SAndrew Jeffery 2042830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 2043830c1eb4SAndrew Jeffery buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES, 204448761c62SAndrew Jeffery msg->payload, payload_length); 204548761c62SAndrew Jeffery if (rc) { 2046830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 204748761c62SAndrew Jeffery } 204848761c62SAndrew Jeffery 204948761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 205048761c62SAndrew Jeffery if (rc) { 2051830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 205248761c62SAndrew Jeffery } 205348761c62SAndrew Jeffery 205448761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 205548761c62SAndrew Jeffery return PLDM_SUCCESS; 205648761c62SAndrew Jeffery } 205748761c62SAndrew Jeffery 205848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 205948761c62SAndrew Jeffery if (rc) { 2060830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 206148761c62SAndrew Jeffery } 206248761c62SAndrew Jeffery 206348761c62SAndrew Jeffery if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 206448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 206548761c62SAndrew Jeffery } 206648761c62SAndrew Jeffery 206748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_oper_state); 206848761c62SAndrew Jeffery if (rc) { 2069830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 207048761c62SAndrew Jeffery } 207148761c62SAndrew Jeffery 207248761c62SAndrew Jeffery if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 207348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 207448761c62SAndrew Jeffery } 207548761c62SAndrew Jeffery 207648761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 207748761c62SAndrew Jeffery pending_value); 207848761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 207948761c62SAndrew Jeffery present_value); 208048761c62SAndrew Jeffery 2081830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2082830c1eb4SAndrew Jeffery if (rc) { 2083830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2084830c1eb4SAndrew Jeffery } 2085830c1eb4SAndrew Jeffery 2086830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 208748761c62SAndrew Jeffery } 208848761c62SAndrew Jeffery 208948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 209048761c62SAndrew Jeffery int encode_pldm_pdr_repository_chg_event_data( 209148761c62SAndrew Jeffery uint8_t event_data_format, uint8_t number_of_change_records, 209248761c62SAndrew Jeffery const uint8_t *event_data_operations, 209348761c62SAndrew Jeffery const uint8_t *numbers_of_change_entries, 209448761c62SAndrew Jeffery const uint32_t *const *change_entries, 209548761c62SAndrew Jeffery struct pldm_pdr_repository_chg_event_data *event_data, 209648761c62SAndrew Jeffery size_t *actual_change_records_size, size_t max_change_records_size) 209748761c62SAndrew Jeffery { 209848761c62SAndrew Jeffery if (event_data_operations == NULL || 209948761c62SAndrew Jeffery numbers_of_change_entries == NULL || change_entries == NULL) { 210048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 210148761c62SAndrew Jeffery } 210248761c62SAndrew Jeffery 210348761c62SAndrew Jeffery size_t expected_size = 210448761c62SAndrew Jeffery sizeof(event_data_format) + sizeof(number_of_change_records); 210548761c62SAndrew Jeffery 210648761c62SAndrew Jeffery expected_size += 210748761c62SAndrew Jeffery sizeof(*event_data_operations) * number_of_change_records; 210848761c62SAndrew Jeffery expected_size += 210948761c62SAndrew Jeffery sizeof(*numbers_of_change_entries) * number_of_change_records; 211048761c62SAndrew Jeffery 211148761c62SAndrew Jeffery for (uint8_t i = 0; i < number_of_change_records; ++i) { 211248761c62SAndrew Jeffery expected_size += sizeof(*change_entries[0]) * 211348761c62SAndrew Jeffery numbers_of_change_entries[i]; 211448761c62SAndrew Jeffery } 211548761c62SAndrew Jeffery 211648761c62SAndrew Jeffery *actual_change_records_size = expected_size; 211748761c62SAndrew Jeffery 211848761c62SAndrew Jeffery if (event_data == NULL) { 211948761c62SAndrew Jeffery return PLDM_SUCCESS; 212048761c62SAndrew Jeffery } 212148761c62SAndrew Jeffery 212248761c62SAndrew Jeffery if (max_change_records_size < expected_size) { 212348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 212448761c62SAndrew Jeffery } 212548761c62SAndrew Jeffery 212648761c62SAndrew Jeffery event_data->event_data_format = event_data_format; 212748761c62SAndrew Jeffery event_data->number_of_change_records = number_of_change_records; 212848761c62SAndrew Jeffery 212948761c62SAndrew Jeffery struct pldm_pdr_repository_change_record_data *record_data = 213048761c62SAndrew Jeffery (struct pldm_pdr_repository_change_record_data *) 213148761c62SAndrew Jeffery event_data->change_records; 213248761c62SAndrew Jeffery 213348761c62SAndrew Jeffery for (uint8_t i = 0; i < number_of_change_records; ++i) { 213448761c62SAndrew Jeffery record_data->event_data_operation = event_data_operations[i]; 213548761c62SAndrew Jeffery record_data->number_of_change_entries = 213648761c62SAndrew Jeffery numbers_of_change_entries[i]; 213748761c62SAndrew Jeffery 213848761c62SAndrew Jeffery for (uint8_t j = 0; j < record_data->number_of_change_entries; 213948761c62SAndrew Jeffery ++j) { 214048761c62SAndrew Jeffery record_data->change_entry[j] = 214148761c62SAndrew Jeffery htole32(change_entries[i][j]); 214248761c62SAndrew Jeffery } 214348761c62SAndrew Jeffery 214448761c62SAndrew Jeffery record_data = 214548761c62SAndrew Jeffery (struct pldm_pdr_repository_change_record_data 214648761c62SAndrew Jeffery *)(record_data->change_entry + 214748761c62SAndrew Jeffery record_data->number_of_change_entries); 214848761c62SAndrew Jeffery } 214948761c62SAndrew Jeffery 215048761c62SAndrew Jeffery return PLDM_SUCCESS; 215148761c62SAndrew Jeffery } 215248761c62SAndrew Jeffery 215348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 215448761c62SAndrew Jeffery int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data, 215548761c62SAndrew Jeffery size_t event_data_size, 215648761c62SAndrew Jeffery uint8_t *event_data_format, 215748761c62SAndrew Jeffery uint8_t *number_of_change_records, 215848761c62SAndrew Jeffery size_t *change_record_data_offset) 215948761c62SAndrew Jeffery { 216048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 216148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 216248761c62SAndrew Jeffery int rc; 216348761c62SAndrew Jeffery 216490bbe6c0SAndrew Jeffery if (event_data == NULL || event_data_format == NULL || 216590bbe6c0SAndrew Jeffery number_of_change_records == NULL || 216648761c62SAndrew Jeffery change_record_data_offset == NULL) { 216748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 216848761c62SAndrew Jeffery } 216948761c62SAndrew Jeffery 2170830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 2171830c1eb4SAndrew Jeffery PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH, 217248761c62SAndrew Jeffery event_data, event_data_size); 217348761c62SAndrew Jeffery if (rc) { 2174830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 217548761c62SAndrew Jeffery } 217648761c62SAndrew Jeffery 217748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_format); 217848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, number_of_change_records); 217948761c62SAndrew Jeffery 218048761c62SAndrew Jeffery *change_record_data_offset = 218148761c62SAndrew Jeffery sizeof(*event_data_format) + sizeof(*number_of_change_records); 218248761c62SAndrew Jeffery 2183830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2184830c1eb4SAndrew Jeffery if (rc) { 2185830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2186830c1eb4SAndrew Jeffery } 2187830c1eb4SAndrew Jeffery 2188830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 218948761c62SAndrew Jeffery } 219048761c62SAndrew Jeffery 2191f874b383SThu Nguyen LIBPLDM_ABI_STABLE 21927739d123SThu Nguyen int decode_pldm_message_poll_event_data( 21937739d123SThu Nguyen const void *event_data, size_t event_data_length, 21947739d123SThu Nguyen struct pldm_message_poll_event *poll_event) 219548761c62SAndrew Jeffery { 219648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 219748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 219848761c62SAndrew Jeffery int rc; 219948761c62SAndrew Jeffery 220090bbe6c0SAndrew Jeffery if (!event_data || !poll_event) { 22017739d123SThu Nguyen return -EINVAL; 220248761c62SAndrew Jeffery } 220348761c62SAndrew Jeffery 22047739d123SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 220548761c62SAndrew Jeffery event_data_length); 220648761c62SAndrew Jeffery if (rc) { 220748761c62SAndrew Jeffery return rc; 220848761c62SAndrew Jeffery } 220948761c62SAndrew Jeffery 22107739d123SThu Nguyen pldm_msgbuf_extract(buf, poll_event->format_version); 22117739d123SThu Nguyen rc = pldm_msgbuf_extract(buf, poll_event->event_id); 221248761c62SAndrew Jeffery if (rc) { 221348761c62SAndrew Jeffery return rc; 221448761c62SAndrew Jeffery } 221548761c62SAndrew Jeffery 22167739d123SThu Nguyen if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 22177739d123SThu Nguyen return -EPROTO; 221848761c62SAndrew Jeffery } 221948761c62SAndrew Jeffery 22207739d123SThu Nguyen pldm_msgbuf_extract(buf, poll_event->data_transfer_handle); 222148761c62SAndrew Jeffery 222248761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 222348761c62SAndrew Jeffery } 222448761c62SAndrew Jeffery 222548761c62SAndrew Jeffery LIBPLDM_ABI_TESTING 22267739d123SThu Nguyen int encode_pldm_message_poll_event_data( 22277739d123SThu Nguyen const struct pldm_message_poll_event *poll_event, void *event_data, 222848761c62SAndrew Jeffery size_t event_data_length) 222948761c62SAndrew Jeffery { 223048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 223148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 223248761c62SAndrew Jeffery int rc; 223348761c62SAndrew Jeffery 223490bbe6c0SAndrew Jeffery if (poll_event == NULL || event_data == NULL) { 223590bbe6c0SAndrew Jeffery return -EINVAL; 223690bbe6c0SAndrew Jeffery } 223790bbe6c0SAndrew Jeffery 22387739d123SThu Nguyen if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 22397739d123SThu Nguyen return -EPROTO; 224048761c62SAndrew Jeffery } 224148761c62SAndrew Jeffery 22427739d123SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 224348761c62SAndrew Jeffery event_data_length); 224448761c62SAndrew Jeffery if (rc) { 224548761c62SAndrew Jeffery return rc; 224648761c62SAndrew Jeffery } 22477739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->format_version); 22487739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->event_id); 22497739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->data_transfer_handle); 225048761c62SAndrew Jeffery 22517739d123SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 225248761c62SAndrew Jeffery } 225348761c62SAndrew Jeffery 225448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 225548761c62SAndrew Jeffery int decode_pldm_pdr_repository_change_record_data( 225648761c62SAndrew Jeffery const uint8_t *change_record_data, size_t change_record_data_size, 225748761c62SAndrew Jeffery uint8_t *event_data_operation, uint8_t *number_of_change_entries, 225848761c62SAndrew Jeffery size_t *change_entry_data_offset) 225948761c62SAndrew Jeffery { 226048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 226148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 226248761c62SAndrew Jeffery int rc; 226348761c62SAndrew Jeffery 226490bbe6c0SAndrew Jeffery if (change_record_data == NULL || event_data_operation == NULL || 226590bbe6c0SAndrew Jeffery number_of_change_entries == NULL || 226648761c62SAndrew Jeffery change_entry_data_offset == NULL) { 226748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 226848761c62SAndrew Jeffery } 226948761c62SAndrew Jeffery 2270830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 2271830c1eb4SAndrew Jeffery buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH, 227248761c62SAndrew Jeffery change_record_data, change_record_data_size); 227348761c62SAndrew Jeffery if (rc) { 2274830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 227548761c62SAndrew Jeffery } 227648761c62SAndrew Jeffery 227748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_operation); 227848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, number_of_change_entries); 227948761c62SAndrew Jeffery 228048761c62SAndrew Jeffery *change_entry_data_offset = sizeof(*event_data_operation) + 228148761c62SAndrew Jeffery sizeof(*number_of_change_entries); 228248761c62SAndrew Jeffery 2283830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2284830c1eb4SAndrew Jeffery if (rc) { 2285830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2286830c1eb4SAndrew Jeffery } 2287830c1eb4SAndrew Jeffery 2288830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 228948761c62SAndrew Jeffery } 229048761c62SAndrew Jeffery 229148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 229248761c62SAndrew Jeffery int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id, 229348761c62SAndrew Jeffery uint8_t rearm_event_state, 229448761c62SAndrew Jeffery struct pldm_msg *msg) 229548761c62SAndrew Jeffery { 229648761c62SAndrew Jeffery if (msg == NULL) { 229748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 229848761c62SAndrew Jeffery } 229948761c62SAndrew Jeffery 230048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 230148761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 230248761c62SAndrew Jeffery header.instance = instance_id; 230348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 230448761c62SAndrew Jeffery header.command = PLDM_GET_SENSOR_READING; 230548761c62SAndrew Jeffery 230648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 230748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 230848761c62SAndrew Jeffery return rc; 230948761c62SAndrew Jeffery } 231048761c62SAndrew Jeffery 231148761c62SAndrew Jeffery struct pldm_get_sensor_reading_req *request = 231248761c62SAndrew Jeffery (struct pldm_get_sensor_reading_req *)msg->payload; 231348761c62SAndrew Jeffery 231448761c62SAndrew Jeffery request->sensor_id = htole16(sensor_id); 231548761c62SAndrew Jeffery request->rearm_event_state = rearm_event_state; 231648761c62SAndrew Jeffery 231748761c62SAndrew Jeffery return PLDM_SUCCESS; 231848761c62SAndrew Jeffery } 231948761c62SAndrew Jeffery 232048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 232148761c62SAndrew Jeffery int decode_get_sensor_reading_resp( 232248761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 232348761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *sensor_data_size, 232448761c62SAndrew Jeffery uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable, 232548761c62SAndrew Jeffery uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state, 232648761c62SAndrew Jeffery uint8_t *present_reading) 232748761c62SAndrew Jeffery { 232848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 232948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 233048761c62SAndrew Jeffery int rc; 233148761c62SAndrew Jeffery 233248761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 233348761c62SAndrew Jeffery sensor_data_size == NULL || sensor_operational_state == NULL || 233448761c62SAndrew Jeffery sensor_event_message_enable == NULL || present_state == NULL || 233548761c62SAndrew Jeffery previous_state == NULL || event_state == NULL || 233648761c62SAndrew Jeffery present_reading == NULL) { 233748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 233848761c62SAndrew Jeffery } 233948761c62SAndrew Jeffery 2340830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES, 234148761c62SAndrew Jeffery msg->payload, payload_length); 234248761c62SAndrew Jeffery if (rc) { 2343830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 234448761c62SAndrew Jeffery } 234548761c62SAndrew Jeffery 234648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 234748761c62SAndrew Jeffery if (rc) { 2348830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 234948761c62SAndrew Jeffery } 235048761c62SAndrew Jeffery 235148761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 235248761c62SAndrew Jeffery return PLDM_SUCCESS; 235348761c62SAndrew Jeffery } 235448761c62SAndrew Jeffery 235548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 235648761c62SAndrew Jeffery if (rc) { 2357830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 235848761c62SAndrew Jeffery } 235948761c62SAndrew Jeffery 236048761c62SAndrew Jeffery if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) { 236148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 236248761c62SAndrew Jeffery } 236348761c62SAndrew Jeffery 236448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_operational_state); 236548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_event_message_enable); 236648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, present_state); 236748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_state); 236848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 236948761c62SAndrew Jeffery 237048761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size, 237148761c62SAndrew Jeffery present_reading); 237248761c62SAndrew Jeffery 2373830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2374830c1eb4SAndrew Jeffery if (rc) { 2375830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2376830c1eb4SAndrew Jeffery } 2377830c1eb4SAndrew Jeffery 2378830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 237948761c62SAndrew Jeffery } 238048761c62SAndrew Jeffery 238148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 238248761c62SAndrew Jeffery int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code, 238348761c62SAndrew Jeffery uint8_t sensor_data_size, 238448761c62SAndrew Jeffery uint8_t sensor_operational_state, 238548761c62SAndrew Jeffery uint8_t sensor_event_message_enable, 238648761c62SAndrew Jeffery uint8_t present_state, 238748761c62SAndrew Jeffery uint8_t previous_state, uint8_t event_state, 238848761c62SAndrew Jeffery const uint8_t *present_reading, 238948761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 239048761c62SAndrew Jeffery { 239148761c62SAndrew Jeffery if (msg == NULL || present_reading == NULL) { 239248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 239348761c62SAndrew Jeffery } 239448761c62SAndrew Jeffery 239548761c62SAndrew Jeffery if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 239648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 239748761c62SAndrew Jeffery } 239848761c62SAndrew Jeffery 239948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 240048761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 240148761c62SAndrew Jeffery header.instance = instance_id; 240248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 240348761c62SAndrew Jeffery header.command = PLDM_GET_SENSOR_READING; 240448761c62SAndrew Jeffery 240548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 240648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 240748761c62SAndrew Jeffery return rc; 240848761c62SAndrew Jeffery } 240948761c62SAndrew Jeffery 241048761c62SAndrew Jeffery struct pldm_get_sensor_reading_resp *response = 241148761c62SAndrew Jeffery (struct pldm_get_sensor_reading_resp *)msg->payload; 241248761c62SAndrew Jeffery 241348761c62SAndrew Jeffery response->completion_code = completion_code; 241448761c62SAndrew Jeffery response->sensor_data_size = sensor_data_size; 241548761c62SAndrew Jeffery response->sensor_operational_state = sensor_operational_state; 241648761c62SAndrew Jeffery response->sensor_event_message_enable = sensor_event_message_enable; 241748761c62SAndrew Jeffery response->present_state = present_state; 241848761c62SAndrew Jeffery response->previous_state = previous_state; 241948761c62SAndrew Jeffery response->event_state = event_state; 242048761c62SAndrew Jeffery 242148761c62SAndrew Jeffery if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 242248761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 242348761c62SAndrew Jeffery if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) { 242448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 242548761c62SAndrew Jeffery } 242648761c62SAndrew Jeffery response->present_reading[0] = *present_reading; 242748761c62SAndrew Jeffery 242848761c62SAndrew Jeffery } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 242948761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 243048761c62SAndrew Jeffery if (payload_length != 243148761c62SAndrew Jeffery PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) { 243248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 243348761c62SAndrew Jeffery } 243448761c62SAndrew Jeffery uint16_t val = *(uint16_t *)present_reading; 243548761c62SAndrew Jeffery val = htole16(val); 243648761c62SAndrew Jeffery memcpy(response->present_reading, &val, 2); 243748761c62SAndrew Jeffery 243848761c62SAndrew Jeffery } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 243948761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 244048761c62SAndrew Jeffery if (payload_length != 244148761c62SAndrew Jeffery PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) { 244248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 244348761c62SAndrew Jeffery } 244448761c62SAndrew Jeffery uint32_t val = *(uint32_t *)present_reading; 244548761c62SAndrew Jeffery val = htole32(val); 244648761c62SAndrew Jeffery memcpy(response->present_reading, &val, 4); 244748761c62SAndrew Jeffery } 244848761c62SAndrew Jeffery 244948761c62SAndrew Jeffery return PLDM_SUCCESS; 245048761c62SAndrew Jeffery } 245148761c62SAndrew Jeffery 245248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 245348761c62SAndrew Jeffery int decode_get_sensor_reading_req(const struct pldm_msg *msg, 245448761c62SAndrew Jeffery size_t payload_length, uint16_t *sensor_id, 245548761c62SAndrew Jeffery uint8_t *rearm_event_state) 245648761c62SAndrew Jeffery { 245748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 245848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 245948761c62SAndrew Jeffery int rc; 246048761c62SAndrew Jeffery 246148761c62SAndrew Jeffery if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) { 246248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 246348761c62SAndrew Jeffery } 246448761c62SAndrew Jeffery 2465830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES, 246648761c62SAndrew Jeffery msg->payload, payload_length); 246748761c62SAndrew Jeffery if (rc) { 2468830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 246948761c62SAndrew Jeffery } 247048761c62SAndrew Jeffery 247148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 247248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, rearm_event_state); 247348761c62SAndrew Jeffery 2474830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2475830c1eb4SAndrew Jeffery if (rc) { 2476830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2477830c1eb4SAndrew Jeffery } 2478830c1eb4SAndrew Jeffery 2479830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 248048761c62SAndrew Jeffery } 248148761c62SAndrew Jeffery 248248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 248348761c62SAndrew Jeffery int encode_set_event_receiver_req(uint8_t instance_id, 248448761c62SAndrew Jeffery uint8_t event_message_global_enable, 248548761c62SAndrew Jeffery uint8_t transport_protocol_type, 248648761c62SAndrew Jeffery uint8_t event_receiver_address_info, 248748761c62SAndrew Jeffery uint16_t heartbeat_timer, 248848761c62SAndrew Jeffery struct pldm_msg *msg) 248948761c62SAndrew Jeffery { 249048761c62SAndrew Jeffery if (msg == NULL) { 249148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 249248761c62SAndrew Jeffery } 249348761c62SAndrew Jeffery 249448761c62SAndrew Jeffery if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) { 249548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 249648761c62SAndrew Jeffery } 249748761c62SAndrew Jeffery 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_SET_EVENT_RECEIVER; 250348761c62SAndrew Jeffery 250448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 250548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 250648761c62SAndrew Jeffery return rc; 250748761c62SAndrew Jeffery } 250848761c62SAndrew Jeffery 250948761c62SAndrew Jeffery struct pldm_set_event_receiver_req *request = 251048761c62SAndrew Jeffery (struct pldm_set_event_receiver_req *)msg->payload; 251148761c62SAndrew Jeffery request->event_message_global_enable = event_message_global_enable; 251248761c62SAndrew Jeffery 251348761c62SAndrew Jeffery request->transport_protocol_type = transport_protocol_type; 251448761c62SAndrew Jeffery request->event_receiver_address_info = event_receiver_address_info; 251548761c62SAndrew Jeffery 251648761c62SAndrew Jeffery if (event_message_global_enable == 251748761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 251848761c62SAndrew Jeffery if (heartbeat_timer == 0) { 251948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 252048761c62SAndrew Jeffery } 252148761c62SAndrew Jeffery request->heartbeat_timer = htole16(heartbeat_timer); 252248761c62SAndrew Jeffery } 252348761c62SAndrew Jeffery 252448761c62SAndrew Jeffery return PLDM_SUCCESS; 252548761c62SAndrew Jeffery } 252648761c62SAndrew Jeffery 252748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 252848761c62SAndrew Jeffery int decode_set_event_receiver_resp(const struct pldm_msg *msg, 252948761c62SAndrew Jeffery size_t payload_length, 253048761c62SAndrew Jeffery uint8_t *completion_code) 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) { 253748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 253848761c62SAndrew Jeffery } 253948761c62SAndrew Jeffery 2540830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES, 254148761c62SAndrew Jeffery msg->payload, payload_length); 254248761c62SAndrew Jeffery if (rc) { 2543830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 254448761c62SAndrew Jeffery } 254548761c62SAndrew Jeffery 254648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, completion_code); 254748761c62SAndrew Jeffery 2548830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2549830c1eb4SAndrew Jeffery if (rc) { 2550830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2551830c1eb4SAndrew Jeffery } 2552830c1eb4SAndrew Jeffery 2553830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 255448761c62SAndrew Jeffery } 255548761c62SAndrew Jeffery 255648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 255748761c62SAndrew Jeffery int decode_set_event_receiver_req(const struct pldm_msg *msg, 255848761c62SAndrew Jeffery size_t payload_length, 255948761c62SAndrew Jeffery uint8_t *event_message_global_enable, 256048761c62SAndrew Jeffery uint8_t *transport_protocol_type, 256148761c62SAndrew Jeffery uint8_t *event_receiver_address_info, 256248761c62SAndrew Jeffery uint16_t *heartbeat_timer) 256348761c62SAndrew Jeffery 256448761c62SAndrew Jeffery { 256548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 256648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 256748761c62SAndrew Jeffery int rc; 256848761c62SAndrew Jeffery 256948761c62SAndrew Jeffery if (msg == NULL || event_message_global_enable == NULL || 257048761c62SAndrew Jeffery transport_protocol_type == NULL || 257148761c62SAndrew Jeffery event_receiver_address_info == NULL || heartbeat_timer == NULL) { 257248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 257348761c62SAndrew Jeffery } 257448761c62SAndrew Jeffery 2575830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES, 257648761c62SAndrew Jeffery msg->payload, payload_length); 257748761c62SAndrew Jeffery if (rc) { 2578830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 257948761c62SAndrew Jeffery } 258048761c62SAndrew Jeffery 258148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_message_global_enable); 258248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transport_protocol_type); 258348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_receiver_address_info); 258448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, heartbeat_timer); 258548761c62SAndrew Jeffery 258648761c62SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 258748761c62SAndrew Jeffery if (rc) { 2588830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 258948761c62SAndrew Jeffery } 259048761c62SAndrew Jeffery 259148761c62SAndrew Jeffery if ((*event_message_global_enable == 259248761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) && 259348761c62SAndrew Jeffery (*heartbeat_timer == 0)) { 259448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 259548761c62SAndrew Jeffery } 259648761c62SAndrew Jeffery 259748761c62SAndrew Jeffery return PLDM_SUCCESS; 259848761c62SAndrew Jeffery } 259948761c62SAndrew Jeffery 260048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 260148761c62SAndrew Jeffery int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code, 260248761c62SAndrew Jeffery struct pldm_msg *msg) 260348761c62SAndrew Jeffery 260448761c62SAndrew Jeffery { 260548761c62SAndrew Jeffery if (msg == NULL) { 260648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 260748761c62SAndrew Jeffery } 260848761c62SAndrew Jeffery 260948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 261048761c62SAndrew Jeffery header.instance = instance_id; 261148761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 261248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 261348761c62SAndrew Jeffery header.command = PLDM_SET_EVENT_RECEIVER; 261448761c62SAndrew Jeffery 261548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 261648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 261748761c62SAndrew Jeffery return rc; 261848761c62SAndrew Jeffery } 261948761c62SAndrew Jeffery 262048761c62SAndrew Jeffery msg->payload[0] = completion_code; 262148761c62SAndrew Jeffery 262248761c62SAndrew Jeffery return PLDM_SUCCESS; 262348761c62SAndrew Jeffery } 262448761c62SAndrew Jeffery 262548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 262648761c62SAndrew Jeffery int encode_poll_for_platform_event_message_req(uint8_t instance_id, 262748761c62SAndrew Jeffery uint8_t format_version, 262848761c62SAndrew Jeffery uint8_t transfer_operation_flag, 262948761c62SAndrew Jeffery uint32_t data_transfer_handle, 263048761c62SAndrew Jeffery uint16_t event_id_to_acknowledge, 263148761c62SAndrew Jeffery struct pldm_msg *msg, 263248761c62SAndrew Jeffery size_t payload_length) 263348761c62SAndrew Jeffery { 263448761c62SAndrew Jeffery struct pldm_msgbuf _buf; 263548761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 263648761c62SAndrew Jeffery int rc; 263748761c62SAndrew Jeffery 263848761c62SAndrew Jeffery if (msg == NULL) { 263948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 264048761c62SAndrew Jeffery } 264148761c62SAndrew Jeffery 2642387b10f6SThu Nguyen rc = pldm_platform_poll_for_platform_event_message_validate( 2643387b10f6SThu Nguyen transfer_operation_flag, event_id_to_acknowledge); 2644387b10f6SThu Nguyen if (rc < 0) { 2645387b10f6SThu Nguyen return PLDM_ERROR_INVALID_DATA; 2646387b10f6SThu Nguyen } 2647387b10f6SThu Nguyen 264848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 264948761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 265048761c62SAndrew Jeffery header.instance = instance_id; 265148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 265248761c62SAndrew Jeffery header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 265348761c62SAndrew Jeffery 265448761c62SAndrew Jeffery rc = pack_pldm_header(&header, &(msg->hdr)); 265548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 265648761c62SAndrew Jeffery return rc; 265748761c62SAndrew Jeffery } 265848761c62SAndrew Jeffery 2659830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 266048761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 266148761c62SAndrew Jeffery msg->payload, payload_length); 266248761c62SAndrew Jeffery if (rc) { 2663830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 266448761c62SAndrew Jeffery } 266548761c62SAndrew Jeffery 266648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, format_version); 266748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, transfer_operation_flag); 266848761c62SAndrew Jeffery pldm_msgbuf_insert(buf, data_transfer_handle); 266948761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_id_to_acknowledge); 267048761c62SAndrew Jeffery 2671830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2672830c1eb4SAndrew Jeffery if (rc) { 2673830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2674830c1eb4SAndrew Jeffery } 2675830c1eb4SAndrew Jeffery 2676830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 267748761c62SAndrew Jeffery } 267848761c62SAndrew Jeffery 267948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 268048761c62SAndrew Jeffery int decode_poll_for_platform_event_message_resp( 268148761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 268248761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *tid, uint16_t *event_id, 268348761c62SAndrew Jeffery uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 268448761c62SAndrew Jeffery uint8_t *event_class, uint32_t *event_data_size, void **event_data, 268548761c62SAndrew Jeffery uint32_t *event_data_integrity_checksum) 268648761c62SAndrew Jeffery { 268748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 268848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 268948761c62SAndrew Jeffery int rc; 269048761c62SAndrew Jeffery 269148761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || tid == NULL || 269248761c62SAndrew Jeffery event_id == NULL || next_data_transfer_handle == NULL || 269348761c62SAndrew Jeffery transfer_flag == NULL || event_class == NULL || 269448761c62SAndrew Jeffery event_data_size == NULL || event_data == NULL || 269548761c62SAndrew Jeffery event_data_integrity_checksum == NULL) { 269648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 269748761c62SAndrew Jeffery } 269848761c62SAndrew Jeffery 2699830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 270048761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 270148761c62SAndrew Jeffery msg->payload, payload_length); 270248761c62SAndrew Jeffery if (rc) { 2703830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 270448761c62SAndrew Jeffery } 270548761c62SAndrew Jeffery 270648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 270748761c62SAndrew Jeffery if (rc) { 2708830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 270948761c62SAndrew Jeffery } 271048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 271148761c62SAndrew Jeffery return *completion_code; 271248761c62SAndrew Jeffery } 271348761c62SAndrew Jeffery 271448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, tid); 271548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_id); 271648761c62SAndrew Jeffery if (rc) { 2717830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 271848761c62SAndrew Jeffery } 271948761c62SAndrew Jeffery if ((*event_id == 0) || (*event_id == 0xffff)) { 272048761c62SAndrew Jeffery return PLDM_SUCCESS; 272148761c62SAndrew Jeffery } 272248761c62SAndrew Jeffery 272348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_data_transfer_handle); 272448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, transfer_flag); 272548761c62SAndrew Jeffery if (rc) { 2726830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 272748761c62SAndrew Jeffery } 272848761c62SAndrew Jeffery 272948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_class); 273048761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_data_size); 273148761c62SAndrew Jeffery if (rc) { 2732830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 273348761c62SAndrew Jeffery } 273448761c62SAndrew Jeffery if (*event_data_size > payload_length) { 273548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 273648761c62SAndrew Jeffery } 273748761c62SAndrew Jeffery 273848761c62SAndrew Jeffery if (*event_data_size > 0) { 273948761c62SAndrew Jeffery pldm_msgbuf_span_required(buf, *event_data_size, event_data); 274048761c62SAndrew Jeffery } 274148761c62SAndrew Jeffery 274248761c62SAndrew Jeffery if (*transfer_flag == PLDM_END || 274348761c62SAndrew Jeffery *transfer_flag == PLDM_START_AND_END) { 274448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_integrity_checksum); 274548761c62SAndrew Jeffery } 274648761c62SAndrew Jeffery 2747830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2748830c1eb4SAndrew Jeffery if (rc) { 2749830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2750830c1eb4SAndrew Jeffery } 2751830c1eb4SAndrew Jeffery 2752830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 275348761c62SAndrew Jeffery } 275448761c62SAndrew Jeffery 275548761c62SAndrew Jeffery LIBPLDM_ABI_TESTING 275648761c62SAndrew Jeffery int decode_numeric_effecter_pdr_data( 275748761c62SAndrew Jeffery const void *pdr_data, size_t pdr_data_length, 275848761c62SAndrew Jeffery struct pldm_numeric_effecter_value_pdr *pdr_value) 275948761c62SAndrew Jeffery { 276048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 276148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 276248761c62SAndrew Jeffery struct pldm_value_pdr_hdr hdr; 276348761c62SAndrew Jeffery int rc; 276448761c62SAndrew Jeffery 276590bbe6c0SAndrew Jeffery if (!pdr_data || !pdr_value) { 276690bbe6c0SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 276790bbe6c0SAndrew Jeffery } 276890bbe6c0SAndrew Jeffery 2769830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 2770830c1eb4SAndrew Jeffery PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 277148761c62SAndrew Jeffery pdr_data, pdr_data_length); 277248761c62SAndrew Jeffery if (rc) { 2773830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 277448761c62SAndrew Jeffery } 277548761c62SAndrew Jeffery 2776329176a8SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr( 2777329176a8SAndrew Jeffery buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 277848761c62SAndrew Jeffery pdr_data_length); 277948761c62SAndrew Jeffery if (rc) { 2780329176a8SAndrew Jeffery return pldm_xlate_errno(rc); 278148761c62SAndrew Jeffery } 278248761c62SAndrew Jeffery 278348761c62SAndrew Jeffery memcpy(&pdr_value->hdr, &hdr, sizeof(hdr)); 278448761c62SAndrew Jeffery 278548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 278648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_id); 278748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_type); 278848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_instance); 278948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->container_id); 279048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id); 279148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_init); 279248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names); 279348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_unit); 279448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 279548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rate_unit); 279648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 279748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit); 279848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 279948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 280048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 280148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->is_linear); 280248761c62SAndrew Jeffery 280348761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size); 280448761c62SAndrew Jeffery if (rc) { 2805830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 280648761c62SAndrew Jeffery } 280748761c62SAndrew Jeffery if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 280848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 280948761c62SAndrew Jeffery } 281048761c62SAndrew Jeffery 281148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->resolution); 281248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->offset); 281348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->accuracy); 281448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 281548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 281648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 281748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->transition_interval); 281848761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 281948761c62SAndrew Jeffery pdr_value->max_settable); 282048761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 282148761c62SAndrew Jeffery pdr_value->min_settable); 282248761c62SAndrew Jeffery 282348761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 282448761c62SAndrew Jeffery if (rc) { 2825830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 282648761c62SAndrew Jeffery } 282748761c62SAndrew Jeffery if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 282848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 282948761c62SAndrew Jeffery } 283048761c62SAndrew Jeffery 283148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 283248761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 283348761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->nominal_value); 283448761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 283548761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_max); 283648761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 283748761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_min); 283848761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 283948761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->rated_max); 284048761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 284148761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->rated_min); 284248761c62SAndrew Jeffery 2843830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2844830c1eb4SAndrew Jeffery if (rc) { 2845830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2846830c1eb4SAndrew Jeffery } 2847830c1eb4SAndrew Jeffery 2848830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 284948761c62SAndrew Jeffery } 285048761c62SAndrew Jeffery 2851de67ab62STal Yacobi LIBPLDM_ABI_STABLE 285248761c62SAndrew Jeffery int encode_get_state_effecter_states_req(uint8_t instance_id, 285348761c62SAndrew Jeffery uint16_t effecter_id, 285448761c62SAndrew Jeffery struct pldm_msg *msg, 285548761c62SAndrew Jeffery size_t payload_length) 285648761c62SAndrew Jeffery { 285748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 285848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 285948761c62SAndrew Jeffery int rc; 286048761c62SAndrew Jeffery 286148761c62SAndrew Jeffery if (msg == NULL) { 2862f490a38fSTal Yacobi return -EINVAL; 286348761c62SAndrew Jeffery } 286448761c62SAndrew Jeffery 286548761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 286648761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 286748761c62SAndrew Jeffery header.instance = instance_id; 286848761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 286948761c62SAndrew Jeffery header.command = PLDM_GET_STATE_EFFECTER_STATES; 287048761c62SAndrew Jeffery 2871f490a38fSTal Yacobi rc = pack_pldm_header_errno(&header, &msg->hdr); 2872f490a38fSTal Yacobi if (rc < 0) { 287348761c62SAndrew Jeffery return rc; 287448761c62SAndrew Jeffery } 287548761c62SAndrew Jeffery 2876f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno(buf, 2877f490a38fSTal Yacobi PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES, 287848761c62SAndrew Jeffery msg->payload, payload_length); 287948761c62SAndrew Jeffery if (rc) { 288048761c62SAndrew Jeffery return rc; 288148761c62SAndrew Jeffery } 288248761c62SAndrew Jeffery 288348761c62SAndrew Jeffery pldm_msgbuf_insert(buf, effecter_id); 288448761c62SAndrew Jeffery 288548761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 288648761c62SAndrew Jeffery } 288748761c62SAndrew Jeffery 2888de67ab62STal Yacobi LIBPLDM_ABI_STABLE 288948761c62SAndrew Jeffery int decode_get_state_effecter_states_req(const struct pldm_msg *msg, 289048761c62SAndrew Jeffery size_t payload_length, 289148761c62SAndrew Jeffery uint16_t *effecter_id) 289248761c62SAndrew Jeffery { 289348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 289448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 289548761c62SAndrew Jeffery int rc; 289648761c62SAndrew Jeffery 289748761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL) { 2898f490a38fSTal Yacobi return -EINVAL; 289948761c62SAndrew Jeffery } 290048761c62SAndrew Jeffery 2901f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2902f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 290348761c62SAndrew Jeffery msg->payload, payload_length); 290448761c62SAndrew Jeffery if (rc) { 290548761c62SAndrew Jeffery return rc; 290648761c62SAndrew Jeffery } 290748761c62SAndrew Jeffery 290848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 290948761c62SAndrew Jeffery 291048761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 291148761c62SAndrew Jeffery } 291248761c62SAndrew Jeffery 2913de67ab62STal Yacobi LIBPLDM_ABI_STABLE 291448761c62SAndrew Jeffery int decode_get_state_effecter_states_resp( 291548761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 291648761c62SAndrew Jeffery struct pldm_get_state_effecter_states_resp *resp) 291748761c62SAndrew Jeffery { 291848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 291948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 292048761c62SAndrew Jeffery get_effecter_state_field *field; 292148761c62SAndrew Jeffery int rc; 292248761c62SAndrew Jeffery int i; 292348761c62SAndrew Jeffery 292448761c62SAndrew Jeffery if (msg == NULL || resp == NULL) { 2925f490a38fSTal Yacobi return -EINVAL; 292648761c62SAndrew Jeffery } 292748761c62SAndrew Jeffery 2928f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2929f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 293048761c62SAndrew Jeffery msg->payload, payload_length); 293148761c62SAndrew Jeffery if (rc) { 293248761c62SAndrew Jeffery return rc; 293348761c62SAndrew Jeffery } 293448761c62SAndrew Jeffery 293548761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->completion_code); 293648761c62SAndrew Jeffery if (rc) { 293748761c62SAndrew Jeffery return rc; 293848761c62SAndrew Jeffery } 293948761c62SAndrew Jeffery 294048761c62SAndrew Jeffery if (PLDM_SUCCESS != resp->completion_code) { 2941f490a38fSTal Yacobi return 0; 294248761c62SAndrew Jeffery } 294348761c62SAndrew Jeffery 294448761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count); 294548761c62SAndrew Jeffery if (rc) { 294648761c62SAndrew Jeffery return rc; 294748761c62SAndrew Jeffery } 294848761c62SAndrew Jeffery 294948761c62SAndrew Jeffery uint8_t comp_effecter_count = resp->comp_effecter_count; 295048761c62SAndrew Jeffery 295148761c62SAndrew Jeffery if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 295248761c62SAndrew Jeffery comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2953f490a38fSTal Yacobi return -EBADMSG; 295448761c62SAndrew Jeffery } 295548761c62SAndrew Jeffery 295648761c62SAndrew Jeffery for (i = 0, field = resp->field; i < comp_effecter_count; 295748761c62SAndrew Jeffery i++, field++) { 295848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->effecter_op_state); 295948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->pending_state); 296048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->present_state); 296148761c62SAndrew Jeffery } 296248761c62SAndrew Jeffery 296348761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 296448761c62SAndrew Jeffery } 296548761c62SAndrew Jeffery 2966de67ab62STal Yacobi LIBPLDM_ABI_STABLE 296748761c62SAndrew Jeffery int encode_get_state_effecter_states_resp( 296848761c62SAndrew Jeffery uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp, 296948761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 297048761c62SAndrew Jeffery { 297148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 297248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 297348761c62SAndrew Jeffery get_effecter_state_field *field; 297448761c62SAndrew Jeffery int rc; 297548761c62SAndrew Jeffery int i; 297648761c62SAndrew Jeffery 297748761c62SAndrew Jeffery if (msg == NULL || resp == NULL) { 2978f490a38fSTal Yacobi return -EINVAL; 297948761c62SAndrew Jeffery } 298048761c62SAndrew Jeffery 298148761c62SAndrew Jeffery uint8_t comp_effecter_count = resp->comp_effecter_count; 298248761c62SAndrew Jeffery 298348761c62SAndrew Jeffery if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 298448761c62SAndrew Jeffery comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2985f490a38fSTal Yacobi return -EBADMSG; 298648761c62SAndrew Jeffery } 298748761c62SAndrew Jeffery 298848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 298948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 299048761c62SAndrew Jeffery header.instance = instance_id; 299148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 299248761c62SAndrew Jeffery header.command = PLDM_GET_STATE_EFFECTER_STATES; 299348761c62SAndrew Jeffery 2994f490a38fSTal Yacobi rc = pack_pldm_header_errno(&header, &msg->hdr); 2995f490a38fSTal Yacobi if (rc < 0) { 299648761c62SAndrew Jeffery return rc; 299748761c62SAndrew Jeffery } 299848761c62SAndrew Jeffery 2999f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 3000f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 300148761c62SAndrew Jeffery msg->payload, payload_length); 300248761c62SAndrew Jeffery if (rc) { 300348761c62SAndrew Jeffery return rc; 300448761c62SAndrew Jeffery } 300548761c62SAndrew Jeffery 300648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, resp->completion_code); 300748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, comp_effecter_count); 300848761c62SAndrew Jeffery 300948761c62SAndrew Jeffery for (i = 0, field = resp->field; i < comp_effecter_count; 301048761c62SAndrew Jeffery i++, field++) { 301148761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->effecter_op_state); 301248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->pending_state); 301348761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->present_state); 301448761c62SAndrew Jeffery } 301548761c62SAndrew Jeffery 301648761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 301748761c62SAndrew Jeffery } 3018dacfa354SThu Nguyen 301943cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE 3020dacfa354SThu Nguyen int decode_entity_auxiliary_names_pdr( 3021dacfa354SThu Nguyen const void *data, size_t data_length, 3022dacfa354SThu Nguyen struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length) 3023dacfa354SThu Nguyen { 3024dacfa354SThu Nguyen struct pldm_msgbuf _buf; 3025dacfa354SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3026dacfa354SThu Nguyen struct pldm_msgbuf _src; 3027dacfa354SThu Nguyen struct pldm_msgbuf *src = &_src; 3028dacfa354SThu Nguyen struct pldm_msgbuf _dst; 3029dacfa354SThu Nguyen struct pldm_msgbuf *dst = &_dst; 3030dacfa354SThu Nguyen size_t names_len = 0; 3031dacfa354SThu Nguyen void *names = NULL; 3032dacfa354SThu Nguyen int rc; 3033dacfa354SThu Nguyen int i; 3034dacfa354SThu Nguyen 303590bbe6c0SAndrew Jeffery if (!data || !pdr) { 303690bbe6c0SAndrew Jeffery return -EINVAL; 303790bbe6c0SAndrew Jeffery } 303890bbe6c0SAndrew Jeffery 3039dacfa354SThu Nguyen /* 3040dacfa354SThu Nguyen * Alignment of auxiliary_name_data is an invariant as we statically assert 3041dacfa354SThu Nguyen * its behaviour in the header. 3042dacfa354SThu Nguyen */ 3043dacfa354SThu Nguyen assert(!((uintptr_t)pdr->auxiliary_name_data & 3044dacfa354SThu Nguyen (alignof(pldm_utf16be) - 1))); 3045dacfa354SThu Nguyen 3046dacfa354SThu Nguyen /* Reject any lengths that are obviously invalid */ 3047dacfa354SThu Nguyen if (pdr_length < data_length || pdr_length < sizeof(*pdr)) { 3048dacfa354SThu Nguyen return -EINVAL; 3049dacfa354SThu Nguyen } 3050dacfa354SThu Nguyen 3051dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno( 3052dacfa354SThu Nguyen buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data, 3053dacfa354SThu Nguyen data_length); 3054dacfa354SThu Nguyen if (rc) { 3055dacfa354SThu Nguyen return rc; 3056dacfa354SThu Nguyen } 3057dacfa354SThu Nguyen 3058329176a8SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr( 3059329176a8SAndrew Jeffery buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, 3060dacfa354SThu Nguyen data_length); 3061dacfa354SThu Nguyen if (rc) { 3062dacfa354SThu Nguyen return rc; 3063dacfa354SThu Nguyen } 3064dacfa354SThu Nguyen 3065dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_type); 3066dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_instance_num); 3067dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_container_id); 3068dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->shared_name_count); 3069dacfa354SThu Nguyen rc = pldm_msgbuf_extract(buf, pdr->name_string_count); 3070dacfa354SThu Nguyen if (rc < 0) { 3071dacfa354SThu Nguyen return rc; 3072dacfa354SThu Nguyen } 3073dacfa354SThu Nguyen 3074dacfa354SThu Nguyen rc = pldm_msgbuf_span_remaining(buf, &names, &names_len); 3075dacfa354SThu Nguyen if (rc < 0) { 3076dacfa354SThu Nguyen return rc; 3077dacfa354SThu Nguyen } 307890bbe6c0SAndrew Jeffery assert(names); 3079dacfa354SThu Nguyen 3080dacfa354SThu Nguyen pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr); 3081dacfa354SThu Nguyen 3082dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size, 3083dacfa354SThu Nguyen pdr->auxiliary_name_data, 3084dacfa354SThu Nguyen pdr->auxiliary_name_data_size); 3085dacfa354SThu Nguyen if (rc < 0) { 3086dacfa354SThu Nguyen return rc; 3087dacfa354SThu Nguyen } 3088dacfa354SThu Nguyen 3089dacfa354SThu Nguyen /* 3090dacfa354SThu Nguyen * Below we do two passes over the same region. This is to first pack the 3091dacfa354SThu Nguyen * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings, 3092dacfa354SThu Nguyen * to maintain appropriate alignment. 3093dacfa354SThu Nguyen */ 3094dacfa354SThu Nguyen 3095dacfa354SThu Nguyen /* Initialise for the first pass to extract the UTF16-BE name strings */ 3096dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 3097dacfa354SThu Nguyen if (rc < 0) { 3098dacfa354SThu Nguyen return rc; 3099dacfa354SThu Nguyen } 3100dacfa354SThu Nguyen 3101dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3102dacfa354SThu Nguyen pldm_msgbuf_span_string_ascii(src, NULL, NULL); 31030a1be3cbSAndrew Jeffery rc = pldm_msgbuf_copy_string_utf16(dst, src); 31040a1be3cbSAndrew Jeffery if (rc) { 31050a1be3cbSAndrew Jeffery return rc; 31060a1be3cbSAndrew Jeffery } 3107dacfa354SThu Nguyen } 3108dacfa354SThu Nguyen 3109dacfa354SThu Nguyen rc = pldm_msgbuf_destroy_consumed(src); 3110dacfa354SThu Nguyen if (rc < 0) { 3111dacfa354SThu Nguyen return rc; 3112dacfa354SThu Nguyen } 3113dacfa354SThu Nguyen 3114dacfa354SThu Nguyen /* Reinitialise for the second pass to extract the ASCII tag strings */ 3115dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 3116dacfa354SThu Nguyen if (rc < 0) { 3117dacfa354SThu Nguyen return rc; 3118dacfa354SThu Nguyen } 3119dacfa354SThu Nguyen 3120dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 31210a1be3cbSAndrew Jeffery rc = pldm_msgbuf_copy_string_ascii(dst, src); 31220a1be3cbSAndrew Jeffery if (rc) { 31230a1be3cbSAndrew Jeffery return rc; 31240a1be3cbSAndrew Jeffery } 3125dacfa354SThu Nguyen pldm_msgbuf_span_string_utf16(src, NULL, NULL); 3126dacfa354SThu Nguyen } 3127dacfa354SThu Nguyen 3128dacfa354SThu Nguyen if ((rc = pldm_msgbuf_destroy(dst)) || 3129dacfa354SThu Nguyen (rc = pldm_msgbuf_destroy(src)) || 3130dacfa354SThu Nguyen (rc = pldm_msgbuf_destroy(buf))) { 3131dacfa354SThu Nguyen return rc; 3132dacfa354SThu Nguyen } 3133dacfa354SThu Nguyen 3134dacfa354SThu Nguyen return 0; 3135dacfa354SThu Nguyen } 3136dacfa354SThu Nguyen 313743cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE 3138dacfa354SThu Nguyen int decode_pldm_entity_auxiliary_names_pdr_index( 3139dacfa354SThu Nguyen struct pldm_entity_auxiliary_names_pdr *pdr) 3140dacfa354SThu Nguyen { 3141dacfa354SThu Nguyen struct pldm_msgbuf _buf; 3142dacfa354SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3143dacfa354SThu Nguyen int rc; 3144dacfa354SThu Nguyen int i; 3145dacfa354SThu Nguyen 3146dacfa354SThu Nguyen if (!pdr) { 3147dacfa354SThu Nguyen return -EINVAL; 3148dacfa354SThu Nguyen } 3149dacfa354SThu Nguyen 3150dacfa354SThu Nguyen if (pdr->name_string_count == 0 && pdr->names) { 3151dacfa354SThu Nguyen return -EINVAL; 3152dacfa354SThu Nguyen } 3153dacfa354SThu Nguyen 3154dacfa354SThu Nguyen if (pdr->name_string_count > 0 && !pdr->names) { 3155dacfa354SThu Nguyen return -EINVAL; 3156dacfa354SThu Nguyen } 3157dacfa354SThu Nguyen 3158dacfa354SThu Nguyen if (pdr->name_string_count == 0) { 3159dacfa354SThu Nguyen return 0; 3160dacfa354SThu Nguyen } 3161dacfa354SThu Nguyen 3162dacfa354SThu Nguyen /* 3163dacfa354SThu Nguyen * Minimum size is one NUL for each member of each entry 3164dacfa354SThu Nguyen * 3165dacfa354SThu Nguyen * Note that the definition of nameLanguageTag in DSP0248 v1.2.2 3166dacfa354SThu Nguyen * states the following: 3167dacfa354SThu Nguyen * 3168dacfa354SThu Nguyen * > A null-terminated ISO646 ASCII string ... 3169dacfa354SThu Nguyen * > 3170dacfa354SThu Nguyen * > special value: null string = 0x0000 = unspecified. 3171dacfa354SThu Nguyen * 3172dacfa354SThu Nguyen * Until proven otherwise we will assume the "0x0000" is a 3173dacfa354SThu Nguyen * misrepresentation of an ASCII NUL, and that ASCII NUL is 3174dacfa354SThu Nguyen * represented by a single byte. 3175dacfa354SThu Nguyen */ 3176dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno( 3177dacfa354SThu Nguyen buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)), 3178dacfa354SThu Nguyen pdr->auxiliary_name_data, pdr->auxiliary_name_data_size); 3179dacfa354SThu Nguyen if (rc) { 3180dacfa354SThu Nguyen return rc; 3181dacfa354SThu Nguyen } 3182dacfa354SThu Nguyen 3183dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3184dacfa354SThu Nguyen void *loc = NULL; 3185dacfa354SThu Nguyen pldm_msgbuf_span_string_utf16(buf, &loc, NULL); 3186dacfa354SThu Nguyen pdr->names[i].name = loc; 3187dacfa354SThu Nguyen } 3188dacfa354SThu Nguyen 3189dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3190dacfa354SThu Nguyen void *loc = NULL; 3191dacfa354SThu Nguyen pldm_msgbuf_span_string_ascii(buf, &loc, NULL); 3192dacfa354SThu Nguyen pdr->names[i].tag = loc; 3193dacfa354SThu Nguyen } 3194dacfa354SThu Nguyen 3195dacfa354SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 3196dacfa354SThu Nguyen } 3197a5d18dc7SThu Nguyen 31983559aa1fSThu Nguyen LIBPLDM_ABI_STABLE 319902903038SThu Nguyen int decode_pldm_platform_cper_event(const void *event_data, 320002903038SThu Nguyen size_t event_data_length, 320102903038SThu Nguyen struct pldm_platform_cper_event *cper_event, 320202903038SThu Nguyen size_t cper_event_length) 3203a5d18dc7SThu Nguyen { 3204a5d18dc7SThu Nguyen struct pldm_msgbuf _buf; 3205a5d18dc7SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3206a5d18dc7SThu Nguyen int rc; 3207a5d18dc7SThu Nguyen 3208a5d18dc7SThu Nguyen if (!cper_event || !event_data) { 3209a5d18dc7SThu Nguyen return -EINVAL; 3210a5d18dc7SThu Nguyen } 3211a5d18dc7SThu Nguyen 3212a5d18dc7SThu Nguyen if (cper_event_length < sizeof(*cper_event)) { 3213a5d18dc7SThu Nguyen return -EINVAL; 3214a5d18dc7SThu Nguyen } 3215a5d18dc7SThu Nguyen 3216a5d18dc7SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH, 3217a5d18dc7SThu Nguyen event_data, event_data_length); 3218a5d18dc7SThu Nguyen if (rc) { 3219a5d18dc7SThu Nguyen return rc; 3220a5d18dc7SThu Nguyen } 3221a5d18dc7SThu Nguyen 3222a5d18dc7SThu Nguyen pldm_msgbuf_extract(buf, cper_event->format_version); 3223a5d18dc7SThu Nguyen rc = pldm_msgbuf_extract(buf, cper_event->format_type); 3224a5d18dc7SThu Nguyen if (rc) { 3225a5d18dc7SThu Nguyen return rc; 3226a5d18dc7SThu Nguyen } 3227a5d18dc7SThu Nguyen if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER && 3228a5d18dc7SThu Nguyen cper_event->format_type != 3229a5d18dc7SThu Nguyen PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) { 3230a5d18dc7SThu Nguyen return -EPROTO; 3231a5d18dc7SThu Nguyen } 3232a5d18dc7SThu Nguyen 3233a5d18dc7SThu Nguyen rc = pldm_msgbuf_extract(buf, cper_event->event_data_length); 3234a5d18dc7SThu Nguyen if (rc) { 3235a5d18dc7SThu Nguyen return rc; 3236a5d18dc7SThu Nguyen } 3237a5d18dc7SThu Nguyen 3238a5d18dc7SThu Nguyen if (cper_event->event_data_length > 3239a5d18dc7SThu Nguyen (cper_event_length - sizeof(*cper_event))) { 3240a5d18dc7SThu Nguyen return -EOVERFLOW; 3241a5d18dc7SThu Nguyen } 3242a5d18dc7SThu Nguyen 32430a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array_uint8( 32440a1be3cbSAndrew Jeffery buf, cper_event->event_data_length, cper_event->event_data, 32450a1be3cbSAndrew Jeffery cper_event_length - sizeof(*cper_event)); 32460a1be3cbSAndrew Jeffery if (rc) { 32470a1be3cbSAndrew Jeffery return rc; 32480a1be3cbSAndrew Jeffery } 3249a5d18dc7SThu Nguyen 3250a5d18dc7SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 3251a5d18dc7SThu Nguyen } 3252a5d18dc7SThu Nguyen 32533559aa1fSThu Nguyen LIBPLDM_ABI_STABLE 3254a5d18dc7SThu Nguyen uint8_t * 3255a5d18dc7SThu Nguyen pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event) 3256a5d18dc7SThu Nguyen { 3257a5d18dc7SThu Nguyen return event->event_data; 3258a5d18dc7SThu Nguyen } 3259